From 0a4e65b4a206b415935a19e13f143554ffeedfe0 Mon Sep 17 00:00:00 2001 From: Yutong Li <52769999+YutongLi291@users.noreply.github.com> Date: Fri, 15 Nov 2024 13:53:58 -0800 Subject: [PATCH] test: add linux job user override tests (#477) Signed-off-by: Li <52769999+YutongLi291@users.noreply.github.com> --- test/e2e/conftest.py | 22 ++- test/e2e/test_job_user.py | 93 ------------- test/e2e/test_override_job_user.py | 216 ++++++++++++++++++++++++++++- 3 files changed, 236 insertions(+), 95 deletions(-) delete mode 100644 test/e2e/test_job_user.py diff --git a/test/e2e/conftest.py b/test/e2e/conftest.py index 04a6e2e6..8c683a24 100644 --- a/test/e2e/conftest.py +++ b/test/e2e/conftest.py @@ -124,6 +124,9 @@ def worker_config( service_model, region, operating_system, + posix_job_user, + posix_env_override_job_user, + posix_config_override_job_user, windows_job_users, ) -> Generator[DeadlineWorkerConfiguration, None, None]: """ @@ -207,6 +210,7 @@ def worker_config( ), service_model_path=dst_path, file_mappings=file_mappings or None, + job_users=[posix_job_user, posix_config_override_job_user, posix_env_override_job_user], windows_job_users=windows_job_users, start_service=True, ) @@ -378,13 +382,29 @@ def region() -> str: @pytest.fixture(scope="session") -def job_run_as_user() -> PosixSessionUser: +def posix_job_user() -> PosixSessionUser: return PosixSessionUser( user="job-user", group="job-user", ) +@pytest.fixture(scope="session") +def posix_config_override_job_user() -> PosixSessionUser: + return PosixSessionUser( + user="config-override", + group="job-override-group", + ) + + +@pytest.fixture(scope="session") +def posix_env_override_job_user() -> PosixSessionUser: + return PosixSessionUser( + user="env-override", + group="job-override-group", + ) + + @pytest.fixture(scope="session") def windows_job_users() -> list: return [ diff --git a/test/e2e/test_job_user.py b/test/e2e/test_job_user.py deleted file mode 100644 index fc4242f9..00000000 --- a/test/e2e/test_job_user.py +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -""" -This test module contains tests that verify the Worker agent's behavior by submitting jobs to the -Deadline Cloud service and checking that the result/output of the jobs is as we expect it. -""" -import boto3 -import botocore.client -import botocore.config -import botocore.exceptions -import pytest -import logging -import os -import re - -from deadline_test_fixtures import ( - Job, - TaskStatus, - PosixSessionUser, - DeadlineClient, - EC2InstanceWorker, -) - - -LOG = logging.getLogger(__name__) - - -@pytest.mark.usefixtures("operating_system") -@pytest.mark.skipif( - os.environ["OPERATING_SYSTEM"] == "windows", - reason="Linux specific test", -) -@pytest.mark.parametrize("operating_system", ["linux"], indirect=True) -class TestJobUser: - def test_job_run_as_user( - self, - deadline_resources, - deadline_client: DeadlineClient, - session_worker: EC2InstanceWorker, - job_run_as_user: PosixSessionUser, - ) -> None: - # WHEN - job = Job.submit( - client=deadline_client, - farm=deadline_resources.farm, - queue=deadline_resources.queue_a, - priority=98, - template={ - "specificationVersion": "jobtemplate-2023-09", - "name": "whoami", - "steps": [ - { - "name": "Step0", - "hostRequirements": { - "attributes": [{"name": "attr.worker.os.family", "allOf": ["linux"]}] - }, - "script": { - "embeddedFiles": [ - { - "name": "whoami", - "type": "TEXT", - "runnable": True, - "data": "\n".join( - [ - "#!/bin/bash", - 'echo "I am: $(whoami)"', - ] - ), - }, - ], - "actions": { - "onRun": { - "command": "{{ Task.File.whoami }}", - }, - }, - }, - }, - ], - }, - ) - - # THEN - job.wait_until_complete(client=deadline_client, max_retries=20) - - job.assert_single_task_log_contains( - deadline_client=deadline_client, - logs_client=boto3.client( - "logs", - config=botocore.config.Config(retries={"max_attempts": 10, "mode": "adaptive"}), - ), - expected_pattern=rf"I am: {re.escape(job_run_as_user.user)}", - ) - - assert job.task_run_status == TaskStatus.SUCCEEDED diff --git a/test/e2e/test_override_job_user.py b/test/e2e/test_override_job_user.py index c9a5972f..4ca8600e 100644 --- a/test/e2e/test_override_job_user.py +++ b/test/e2e/test_override_job_user.py @@ -4,6 +4,8 @@ Deadline Cloud service and checking that the result/output of the jobs is as we expect it. """ +import re +import backoff import boto3 import botocore import pytest @@ -14,6 +16,7 @@ from deadline_test_fixtures import ( Job, Farm, + PosixSessionUser, Queue, TaskStatus, DeadlineClient, @@ -29,7 +32,7 @@ reason="Windows Specific Job User Override Tests.", ) @pytest.mark.parametrize("operating_system", ["windows"], indirect=True) -class TestJobUserOverride: +class TestWindowsJobUserOverride: @staticmethod def submit_whoami_job( test_name: str, deadline_client: DeadlineClient, farm: Farm, queue: Queue @@ -234,3 +237,214 @@ def test_env_var_user_override( assert ( cmd_result.exit_code == 0 ), f"Failed to unset DEADLINE_WORKER_WINDOWS_JOB_USER: {cmd_result}" + + +@pytest.mark.usefixtures("operating_system") +@pytest.mark.skipif( + os.environ["OPERATING_SYSTEM"] == "windows", + reason="Linux specific Job User Override tests", +) +@pytest.mark.parametrize("operating_system", ["linux"], indirect=True) +class TestLinuxJobUserOverride: + @staticmethod + def submit_whoami_job( + test_name: str, deadline_client: DeadlineClient, farm: Farm, queue: Queue + ) -> Job: + job = Job.submit( + client=deadline_client, + farm=farm, + queue=queue, + priority=98, + template={ + "specificationVersion": "jobtemplate-2023-09", + "name": f"whoami {test_name}", + "steps": [ + { + "name": "Step0", + "hostRequirements": { + "attributes": [{"name": "attr.worker.os.family", "allOf": ["linux"]}] + }, + "script": { + "embeddedFiles": [ + { + "name": "whoami", + "type": "TEXT", + "runnable": True, + "data": "\n".join( + [ + "#!/bin/bash", + 'echo "I am: $(whoami)"', + ] + ), + }, + ], + "actions": { + "onRun": { + "command": "{{ Task.File.whoami }}", + }, + }, + }, + }, + ], + }, + ) + return job + + def test_no_user_override( + self, + deadline_resources, + deadline_client: DeadlineClient, + class_worker: EC2InstanceWorker, + posix_job_user: PosixSessionUser, + ) -> None: + # WHEN + job = self.submit_whoami_job( + "No user override", + deadline_client, + deadline_resources.farm, + deadline_resources.queue_a, + ) + + # THEN + job.wait_until_complete(client=deadline_client, max_retries=20) + + job.assert_single_task_log_contains( + deadline_client=deadline_client, + logs_client=boto3.client( + "logs", + config=botocore.config.Config(retries={"max_attempts": 10, "mode": "adaptive"}), + ), + expected_pattern=rf"I am: {re.escape(posix_job_user.user)}", + ) + + assert job.task_run_status == TaskStatus.SUCCEEDED + + def test_config_file_user_override( + self, + deadline_resources, + class_worker: EC2InstanceWorker, + posix_config_override_job_user: PosixSessionUser, + deadline_client: DeadlineClient, + ) -> None: + + class_worker.stop_worker_service() + + @backoff.on_exception( + backoff.constant, + Exception, + max_time=45, + interval=5, + ) + def check_worker_service_stopped() -> None: + worker_status_cmd_response = class_worker.send_command( + "systemctl is-active deadline-worker" + ) + + assert worker_status_cmd_response.exit_code != 0 + assert worker_status_cmd_response.stdout != "active" + + check_worker_service_stopped() + + cmd_result = class_worker.send_command( + f'sed -i \'s/# posix_job_user = "user:group"/posix_job_user = "{posix_config_override_job_user.user}:{posix_config_override_job_user.group}"/g\' /etc/amazon/deadline/worker.toml' + ) + assert ( + cmd_result.exit_code == 0 + ), f"Setting the job user override via CLI failed: {cmd_result}" + + try: + class_worker.start_worker_service() + + job = self.submit_whoami_job( + "config user override", + deadline_client, + deadline_resources.farm, + deadline_resources.queue_a, + ) + + job.wait_until_complete(client=deadline_client, max_retries=20) + + job.assert_single_task_log_contains( + deadline_client=deadline_client, + logs_client=boto3.client( + "logs", + config=botocore.config.Config(retries={"max_attempts": 10, "mode": "adaptive"}), + ), + expected_pattern=f"I am: {posix_config_override_job_user.user}", + ) + + assert job.task_run_status == TaskStatus.SUCCEEDED + finally: + cmd_result = class_worker.send_command( + f"sed -i '/posix_job_user = \"{posix_config_override_job_user.user}:{posix_config_override_job_user.group}\"/d' /etc/amazon/deadline/worker.toml" + ) + assert ( + cmd_result.exit_code == 0 + ), f"Resetting the job user override via CLI failed: {cmd_result}" + + def test_env_var_user_override( + self, + deadline_resources, + class_worker: EC2InstanceWorker, + posix_env_override_job_user: PosixSessionUser, + deadline_client: DeadlineClient, + ) -> None: + + class_worker.stop_worker_service() + + @backoff.on_exception( + backoff.constant, + Exception, + max_time=45, + interval=5, + ) + def check_worker_service_stopped() -> None: + worker_status_cmd_response = class_worker.send_command( + "systemctl is-active deadline-worker" + ) + + assert worker_status_cmd_response.exit_code != 0 + assert worker_status_cmd_response.stdout != "active" + + check_worker_service_stopped() + + cmd_result = class_worker.send_command( + f'echo "Environment=DEADLINE_WORKER_POSIX_JOB_USER={posix_env_override_job_user.user}:{posix_env_override_job_user.group}" >> /etc/systemd/system/deadline-worker.service.d/config.conf', + ) + + assert ( + cmd_result.exit_code == 0 + ), f"Failed to set DEADLINE_WORKER_POSIX_JOB_USER: {cmd_result}" + + class_worker.send_command("systemctl daemon-reload") + + try: + class_worker.start_worker_service() + + job = self.submit_whoami_job( + "environment override", + deadline_client, + deadline_resources.farm, + deadline_resources.queue_a, + ) + + job.wait_until_complete(client=deadline_client, max_retries=20) + + job.assert_single_task_log_contains( + deadline_client=deadline_client, + logs_client=boto3.client( + "logs", + config=botocore.config.Config(retries={"max_attempts": 10, "mode": "adaptive"}), + ), + expected_pattern=f"I am: {posix_env_override_job_user.user}", + ) + + assert job.task_run_status == TaskStatus.SUCCEEDED + finally: + cmd_result = class_worker.send_command( + f"sed -i '/Environment=DEADLINE_WORKER_POSIX_JOB_USER={posix_env_override_job_user.user}/d' /etc/systemd/system/deadline-worker.service.d/config.conf" + ) + assert ( + cmd_result.exit_code == 0 + ), f"Resetting the job user override via CLI failed: {cmd_result}" + class_worker.send_command("sudo systemctl daemon-reload")