def test_wait_for_process_completion_or_timeout_should_kill_process_on_timeout(
            self):
        timeout = 5
        process = subprocess.Popen(  # pylint: disable=subprocess-popen-preexec-fn
            "sleep 1m",
            shell=True,
            cwd=self.tmp_dir,
            env={},
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            preexec_fn=os.setsid)

        # We don't actually mock the kill, just wrap it so we can assert its call count
        with patch(
                'azurelinuxagent.common.utils.extensionprocessutil.os.killpg',
                wraps=os.killpg) as patch_kill:
            with patch('time.sleep') as mock_sleep:
                timed_out, ret = wait_for_process_completion_or_timeout(
                    process=process, timeout=timeout)

                # We're mocking sleep to avoid prolonging the test execution time, but we still want to make sure
                # we're "waiting" the correct amount of time before killing the process
                self.assertEqual(mock_sleep.call_count, timeout)

                self.assertEqual(patch_kill.call_count, 1)
                self.assertEqual(timed_out, True)
                self.assertEqual(ret, None)
    def test_handle_process_completion_should_return_nonzero_when_process_fails(
            self):
        process = subprocess.Popen("ls folder_does_not_exist",
                                   shell=True,
                                   cwd=self.tmp_dir,
                                   env={},
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

        timed_out, ret = wait_for_process_completion_or_timeout(
            process=process, timeout=5)
        self.assertEqual(timed_out, False)
        self.assertEqual(ret, 2)
    def test_wait_for_process_completion_or_timeout_should_terminate_cleanly(
            self):
        process = subprocess.Popen("date",
                                   shell=True,
                                   cwd=self.tmp_dir,
                                   env={},
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

        timed_out, ret = wait_for_process_completion_or_timeout(
            process=process, timeout=5)
        self.assertEqual(timed_out, False)
        self.assertEqual(ret, 0)