Example #1
0
    def test_start_extension_command_should_use_systemd_if_not_failing(self):
        original_popen = subprocess.Popen

        def mock_popen(*args, **kwargs):
            return original_popen(*args, **kwargs)

        with tempfile.TemporaryFile(dir=self.tmp_dir, mode="w+b") as stdout:
            with tempfile.TemporaryFile(dir=self.tmp_dir,
                                        mode="w+b") as stderr:
                with patch("azurelinuxagent.common.cgroupapi.subprocess.Popen",
                           side_effect=mock_popen) as patch_mock_popen:
                    process, extension_cgroups = SystemdCgroupsApi(
                    ).start_extension_command(
                        extension_name="Microsoft.Compute.TestExtension-1.2.3",
                        command="date",
                        shell=True,
                        cwd=self.tmp_dir,
                        env={},
                        stdout=stdout,
                        stderr=stderr)

                    process.wait()

                    ret = process.poll()

                    # We should have invoked the extension command only once and succeeded
                    self.assertEquals(0, ret)
                    self.assertEquals(1, patch_mock_popen.call_count)

                    args = patch_mock_popen.call_args[0][0]
                    self.assertIn("systemd-run --unit", args)

                    self.assert_cgroups_created(extension_cgroups)
Example #2
0
    def test_start_extension_command_should_not_use_systemd_if_failing(self):
        original_popen = subprocess.Popen

        def mock_popen(*args, **kwargs):
            # Inject a syntax error to the call
            systemd_command = args[0].replace('systemd-run',
                                              'systemd-run syntax_error')
            new_args = (systemd_command, )
            return original_popen(new_args, **kwargs)

        with tempfile.TemporaryFile(dir=self.tmp_dir, mode="w+b") as stdout:
            with tempfile.TemporaryFile(dir=self.tmp_dir,
                                        mode="w+b") as stderr:
                with patch("azurelinuxagent.common.cgroupapi.add_event"
                           ) as mock_add_event:
                    with patch(
                            "azurelinuxagent.common.cgroupapi.subprocess.Popen",
                            side_effect=mock_popen) as patch_mock_popen:

                        # We expect this call to fail because of the syntax error
                        process, extension_cgroups = SystemdCgroupsApi(
                        ).start_extension_command(
                            extension_name=
                            "Microsoft.Compute.TestExtension-1.2.3",
                            command="date",
                            shell=True,
                            cwd=self.tmp_dir,
                            env={},
                            stdout=stdout,
                            stderr=stderr)

                        process.wait()

                        args, kwargs = mock_add_event.call_args
                        self.assertIn(
                            "Failed to run systemd-run for unit Microsoft.Compute.TestExtension_1.2.3",
                            kwargs['message'])
                        self.assertIn(
                            "Failed to find executable syntax_error: No such file or directory",
                            kwargs['message'])
                        self.assertEquals(False, kwargs['is_success'])
                        self.assertEquals('InvokeCommandUsingSystemd',
                                          kwargs['op'])

                        # We expect the process to ultimately succeed since the fallback option worked
                        ret = process.poll()
                        self.assertEquals(0, ret)

                        # We expect two calls to Popen, first for the systemd-run call, second for the fallback option
                        self.assertEquals(2, patch_mock_popen.call_count)

                        first_call_args = patch_mock_popen.mock_calls[0][1][0]
                        second_call_args = patch_mock_popen.mock_calls[1][1][0]
                        self.assertIn("systemd-run --unit", first_call_args)
                        self.assertNotIn("systemd-run --unit",
                                         second_call_args)

                        # No cgroups should have been created
                        self.assertEquals(extension_cgroups, [])
Example #3
0
    def test_start_extension_command_should_use_systemd_if_not_failing(self):
        original_popen = subprocess.Popen

        def mock_popen(*args, **kwargs):
            return original_popen(*args, **kwargs)

        with tempfile.TemporaryFile(dir=self.tmp_dir, mode="w+b") as stdout:
            with tempfile.TemporaryFile(dir=self.tmp_dir, mode="w+b") as stderr:
                with patch("azurelinuxagent.common.cgroupapi.subprocess.Popen", side_effect=mock_popen) as patch_mock_popen:
                    process, extension_cgroups = SystemdCgroupsApi().start_extension_command(
                        extension_name="Microsoft.Compute.TestExtension-1.2.3",
                        command="date",
                        shell=True,
                        cwd=self.tmp_dir,
                        env={},
                        stdout=stdout,
                        stderr=stderr)

                    process.wait()

                    ret = process.poll()

                    # We should have invoked the extension command only once and succeeded
                    self.assertEquals(0, ret)
                    self.assertEquals(1, patch_mock_popen.call_count)

                    # Assert that the extension's cgroups were created as well
                    self.assertEqual(len(extension_cgroups), 2, 'start_extension_command did not return the expected number of cgroups')

                    cpu_found = memory_found = False

                    for cgroup in extension_cgroups:
                        match = re.match(r'^/sys/fs/cgroup/(cpu|memory)/system.slice/Microsoft.Compute.TestExtension_1\.2\.3\_([a-f0-9-]+)\.scope$', cgroup.path)

                        self.assertTrue(match is not None, "Unexpected path for cgroup: {0}".format(cgroup.path))

                        if match.group(1) == 'cpu':
                            cpu_found = True
                        if match.group(1) == 'memory':
                            memory_found = True

                    self.assertTrue(cpu_found, 'start_extension_command did not return a cpu cgroup')
                    self.assertTrue(memory_found, 'start_extension_command did not return a memory cgroup')
Example #4
0
    def test_start_extension_command_should_create_extension_scopes(self):
        original_popen = subprocess.Popen

        def mock_popen(*args, **kwargs):
            return original_popen("date", **kwargs)

        # we mock subprocess.Popen to execute a dummy command (date), so no actual cgroups are created; their paths
        # should be computed properly, though
        with patch("azurelinuxagent.common.cgroupapi.subprocess.Popen",
                   mock_popen):
            process, extension_cgroups = SystemdCgroupsApi(
            ).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()
            self.assert_cgroups_created(extension_cgroups)
Example #5
0
    def test_start_extension_command_should_create_extension_scopes(self):
        original_popen = subprocess.Popen

        def mock_popen(*args, **kwargs):
            return original_popen("date", **kwargs)

        # we mock subprocess.Popen to execute a dummy command (date), so no actual cgroups are created; their paths
        # should be computed properly, though
        with patch("azurelinuxagent.common.cgroupapi.subprocess.Popen", mock_popen):
            process, extension_cgroups = SystemdCgroupsApi().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()

            self.assertEqual(len(extension_cgroups), 2, 'start_extension_command did not return the expected number of cgroups')

            cpu_found = memory_found = False

            for cgroup in extension_cgroups:
                match = re.match(r'^/sys/fs/cgroup/(cpu|memory)/system.slice/Microsoft.Compute.TestExtension_1\.2\.3\_([a-f0-9-]+)\.scope$', cgroup.path)

                self.assertTrue(match is not None, "Unexpected path for cgroup: {0}".format(cgroup.path))

                if match.group(1) == 'cpu':
                    cpu_found = True
                if match.group(1) == 'memory':
                    memory_found = True

            self.assertTrue(cpu_found, 'start_extension_command did not return a cpu cgroup')
            self.assertTrue(memory_found, 'start_extension_command did not return a memory cgroup')
Example #6
0
    def test_start_extension_command_should_capture_only_the_last_subprocess_output(
            self):
        original_popen = subprocess.Popen

        def mock_popen(*args, **kwargs):
            # Inject a syntax error to the call
            systemd_command = args[0].replace('systemd-run',
                                              'systemd-run syntax_error')
            new_args = (systemd_command, )
            return original_popen(new_args, **kwargs)

        with tempfile.TemporaryFile(dir=self.tmp_dir, mode="w+b") as stdout:
            with tempfile.TemporaryFile(dir=self.tmp_dir,
                                        mode="w+b") as stderr:
                with patch("azurelinuxagent.common.cgroupapi.add_event"
                           ) as mock_add_event:
                    with patch(
                            "azurelinuxagent.common.cgroupapi.subprocess.Popen",
                            side_effect=mock_popen) as patch_mock_popen:
                        # We expect this call to fail because of the syntax error
                        process, extension_cgroups = SystemdCgroupsApi(
                        ).start_extension_command(
                            extension_name=
                            "Microsoft.Compute.TestExtension-1.2.3",
                            command="echo 'very specific test message'",
                            shell=True,
                            cwd=self.tmp_dir,
                            env={},
                            stdout=stdout,
                            stderr=stderr)

                        process.wait()
                        process_output = read_output(stdout, stderr)
                        self.assertEquals(
                            "[stdout]\nvery specific test message\n\n\n[stderr]\n",
                            process_output)