def test_start_extension_command_should_add_the_child_process_to_the_extension_cgroup( self): api = FileSystemCgroupsApi() api.create_extension_cgroups_root() process, extension_cgroups = api.start_extension_command( extension_name="Microsoft.Compute.TestExtension-1.2.3", command="date", shell=False, cwd=self.tmp_dir, env={}, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process.wait() for cgroup in extension_cgroups: cgroups_procs_path = os.path.join(cgroup.path, "cgroup.procs") with open(cgroups_procs_path, "r") as f: contents = f.read() pid = int(contents) self.assertEquals( pid, process.pid, "The PID of the command was not added to {0}. Expected: {1}, got: {2}" .format(cgroups_procs_path, process.pid, pid))
def test_remove_extension_cgroups_should_remove_all_cgroups(self): api = FileSystemCgroupsApi() api.create_extension_cgroups_root() extension_cgroups = api.create_extension_cgroups("Microsoft.Compute.TestExtension-1.2.3") api.remove_extension_cgroups("Microsoft.Compute.TestExtension-1.2.3") for cgroup in extension_cgroups: self.assertFalse(os.path.exists(cgroup.path))
def test_get_extension_cgroups_should_return_all_cgroups(self): api = FileSystemCgroupsApi() api.create_extension_cgroups_root() created = api.create_extension_cgroups("Microsoft.Compute.TestExtension-1.2.3") retrieved = api.get_extension_cgroups("Microsoft.Compute.TestExtension-1.2.3") self.assertEqual(len(retrieved), len(created)) for cgroup in created: self.assertTrue(any(retrieved_cgroup.path == cgroup.path for retrieved_cgroup in retrieved))
def test_remove_extension_cgroups_should_log_a_warning_when_the_cgroup_contains_active_tasks(self): api = FileSystemCgroupsApi() api.create_extension_cgroups_root() api.create_extension_cgroups("Microsoft.Compute.TestExtension-1.2.3") with patch("azurelinuxagent.common.cgroupapi.logger.warn") as mock_logger_warn: with patch("azurelinuxagent.common.cgroupapi.os.rmdir", side_effect=OSError(16, "Device or resource busy")): api.remove_extension_cgroups("Microsoft.Compute.TestExtension-1.2.3") args, kwargs = mock_logger_warn.call_args message = args[0] self.assertIn("still has active tasks", message)
def test_create_extension_cgroups_should_create_cgroups_on_all_controllers(self): api = FileSystemCgroupsApi() api.create_extension_cgroups_root() extension_cgroups = api.create_extension_cgroups("Microsoft.Compute.TestExtension-1.2.3") def assert_cgroup_created(controller): cgroup_path = os.path.join(self.cgroups_file_system_root, controller, "walinuxagent.extensions", "Microsoft.Compute.TestExtension_1.2.3") self.assertTrue(any(cgroups.path == cgroup_path for cgroups in extension_cgroups)) self.assertTrue(os.path.exists(cgroup_path)) assert_cgroup_created("cpu") assert_cgroup_created("memory")
def test_start_extension_command_should_add_the_child_process_to_the_extension_cgroup( self, _): api = FileSystemCgroupsApi() api.create_extension_cgroups_root() with tempfile.TemporaryFile(dir=self.tmp_dir, mode="w+b") as stdout: with tempfile.TemporaryFile(dir=self.tmp_dir, mode="w+b") as stderr: extension_cgroups, process_output = api.start_extension_command( extension_name="Microsoft.Compute.TestExtension-1.2.3", command="echo $$", timeout=300, shell=True, cwd=self.tmp_dir, env={}, stdout=stdout, stderr=stderr) # The expected format of the process output is [stdout]\n{PID}\n\n\n[stderr]\n" pattern = re.compile(r"\[stdout\]\n(\d+)\n\n\n\[stderr\]\n") m = pattern.match(process_output) try: pid_from_output = int(m.group(1)) except Exception as e: self.fail( "No PID could be extracted from the process output! Error: {0}" .format(ustr(e))) for cgroup in extension_cgroups: cgroups_procs_path = os.path.join(cgroup.path, "cgroup.procs") with open(cgroups_procs_path, "r") as f: contents = f.read() pid_from_cgroup = int(contents) self.assertEquals( pid_from_output, pid_from_cgroup, "The PID from the process output ({0}) does not match the PID found in the" "process cgroup {1} ({2})".format(pid_from_output, cgroups_procs_path, pid_from_cgroup))