def test_process_bad_pgid(self):
        """
        If a timeout is requested but the process is not the root of the process group, raise an exception.
        """
        stdout = "stdout\n"
        stderr = "stderr\n"

        cmd = process_cmd_template.format(process_target, stdout, stderr)
        process = subprocess.Popen(cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   env=os.environ)

        if sys.version_info < (2, 7):
            self.assertRaises(ExtensionError, capture_from_process, process,
                              cmd, 10)
        else:
            with self.assertRaises(ExtensionError) as ee:
                capture_from_process(process, cmd, 10)

            body = str(ee.exception)
            if sys.version_info >= (3, 2):
                self.assertRegex(body, "process group")
            else:
                self.assertRegexpMatches(body, "process group")
    def test_process_bad_pgid(self):
        """
        If a timeout is requested but the process is not the root of the process group, raise an exception.
        """
        stdout = "stdout\n"
        stderr = "stderr\n"

        cmd = process_cmd_template.format(process_target, stdout, stderr)
        process = subprocess.Popen(cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   env=os.environ)

        if sys.version_info < (2, 7):
            self.assertRaises(ExtensionError, capture_from_process, process, cmd, 10)
        else:
            with self.assertRaises(ExtensionError) as ee:
                capture_from_process(process, cmd, 10)

            body = str(ee.exception)
            if sys.version_info >= (3, 2):
                self.assertRegex(body, "process group")
            else:
                self.assertRegexpMatches(body, "process group")
Esempio n. 3
0
    def test_process_timeout_non_forked(self):
        """
        non-forked process runs for 20 seconds, timeout is 10 seconds
        we expect:
            - test to run in just over 10 seconds
            - exception should be thrown
            - output should be collected
        """
        cmd = "{0} -t 20".format(process_target)
        process = subprocess.Popen(cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   env=os.environ,
                                   preexec_fn=os.setsid)

        try:
            capture_from_process(process, 'sleep 20', 10, EXTENSION_ERROR_CODE)
            self.fail('Timeout exception was expected')
        except ExtensionError as e:
            body = str(e)
            self.assertTrue('Timeout(10)' in body)
            self.assertTrue('Iteration 9' in body)
            self.assertFalse('Iteration 11' in body)
            self.assertEqual(EXTENSION_ERROR_CODE, e.code)
        except Exception as gen_ex:
            self.fail('Unexpected exception: {0}'.format(gen_ex))
Esempio n. 4
0
    def launch_command(self, cmd, timeout=300):
        begin_utc = datetime.datetime.utcnow()
        self.logger.verbose("Launch command: [{0}]", cmd)
        base_dir = self.get_base_dir()

        try:
            # This should be .run(), but due to the wide variety
            # of Python versions we must support we must use .communicate().
            # Some extensions erroneously begin cmd with a slash; don't interpret those
            # as root-relative. (Issue #1170)
            full_path = os.path.join(base_dir, cmd.lstrip(os.sep))
            process = subprocess.Popen(full_path,
                                       shell=True,
                                       cwd=base_dir,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE,
                                       env=os.environ,
                                       preexec_fn=os.setsid)
        except OSError as e:
            raise ExtensionError("Failed to launch '{0}': {1}".format(
                full_path, e.strerror))

        msg = capture_from_process(process, cmd, timeout)

        ret = process.poll()
        if ret is None or ret != 0:
            raise ExtensionError("Non-zero exit code: {0}, {1}\n{2}".format(
                ret, cmd, msg))

        duration = elapsed_milliseconds(begin_utc)
        self.report_event(message="{0}\n{1}".format(cmd, msg),
                          duration=duration,
                          log_event=False)
Esempio n. 5
0
    def test_process_behaved_forked(self):
        """
        forked process runs for 10 seconds, timeout is 20 seconds
        we expect:
            - test to run in under 3 seconds
            - no exception should be thrown
            - output is not collected
        """
        cmd = "{0} -t 10 &".format(process_target)
        process = subprocess.Popen(cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   env=os.environ,
                                   preexec_fn=os.setsid)

        start = datetime.datetime.utcnow()
        try:
            body = capture_from_process(process, 'sleep 10 &', 20)
        except Exception as e:
            self.fail('No exception should be thrown for a well behaved process which forks: {0}'.format(e))
        duration = datetime.datetime.utcnow() - start

        self.assertTrue(duration < datetime.timedelta(seconds=3))
        self.assertEqual('[stdout]\ncannot collect stdout\n\n[stderr]\n', body)
Esempio n. 6
0
    def launch_command(self, cmd, timeout=300, extension_error_code=1000, env=None):
        begin_utc = datetime.datetime.utcnow()
        self.logger.verbose("Launch command: [{0}]", cmd)
        base_dir = self.get_base_dir()

        if env is None:
            env = {}
        env.update(os.environ)

        try:
            # This should be .run(), but due to the wide variety
            # of Python versions we must support we must use .communicate().
            # Some extensions erroneously begin cmd with a slash; don't interpret those
            # as root-relative. (Issue #1170)
            full_path = os.path.join(base_dir, cmd.lstrip(os.path.sep))

            def pre_exec_function():
                """
                Change process state before the actual target process is started. Effectively, this runs between
                the fork() and the exec() of sub-process creation.
                :return:
                """
                os.setsid()
                CGroups.add_to_extension_cgroup(self.ext_handler.name)

            process = subprocess.Popen(full_path,
                                       shell=True,
                                       cwd=base_dir,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE,
                                       env=env,
                                       preexec_fn=pre_exec_function)
        except OSError as e:
            raise ExtensionError("Failed to launch '{0}': {1}".format(full_path, e.strerror),
                                 code=extension_error_code)

        cg = CGroups.for_extension(self.ext_handler.name)
        CGroupsTelemetry.track_extension(self.ext_handler.name, cg)
        msg = capture_from_process(process, cmd, timeout, extension_error_code)

        ret = process.poll()
        if ret is None:
            raise ExtensionError("Process {0} was not terminated: {1}\n{2}".format(process.pid, cmd, msg),
                                 code=extension_error_code)
        if ret != 0:
            raise ExtensionError("Non-zero exit code: {0}, {1}\n{2}".format(ret, cmd, msg),
                                 code=extension_error_code)

        duration = elapsed_milliseconds(begin_utc)
        log_msg = "{0}\n{1}".format(cmd, "\n".join([line for line in msg.split('\n') if line != ""]))
        self.logger.verbose(log_msg)
        self.report_event(message=log_msg, duration=duration, log_event=False)
Esempio n. 7
0
    def launch_command(self, cmd, timeout=300, extension_error_code=1000, env=None):
        begin_utc = datetime.datetime.utcnow()
        self.logger.verbose("Launch command: [{0}]", cmd)
        base_dir = self.get_base_dir()

        if env is None:
            env = {}
        env.update(os.environ)

        try:
            # This should be .run(), but due to the wide variety
            # of Python versions we must support we must use .communicate().
            # Some extensions erroneously begin cmd with a slash; don't interpret those
            # as root-relative. (Issue #1170)
            full_path = os.path.join(base_dir, cmd.lstrip(os.path.sep))

            def pre_exec_function():
                """
                Change process state before the actual target process is started. Effectively, this runs between
                the fork() and the exec() of sub-process creation.
                :return:
                """
                os.setsid()
                CGroups.add_to_extension_cgroup(self.ext_handler.name)

            process = subprocess.Popen(full_path,
                                       shell=True,
                                       cwd=base_dir,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE,
                                       env=env,
                                       preexec_fn=pre_exec_function)
        except OSError as e:
            raise ExtensionError("Failed to launch '{0}': {1}".format(full_path, e.strerror),
                                 code=extension_error_code)

        cg = CGroups.for_extension(self.ext_handler.name)
        CGroupsTelemetry.track_extension(self.ext_handler.name, cg)
        msg = capture_from_process(process, cmd, timeout, extension_error_code)

        ret = process.poll()
        if ret is None:
            raise ExtensionError("Process {0} was not terminated: {1}\n{2}".format(process.pid, cmd, msg),
                                 code=extension_error_code)
        if ret != 0:
            raise ExtensionError("Non-zero exit code: {0}, {1}\n{2}".format(ret, cmd, msg),
                                 code=extension_error_code)

        duration = elapsed_milliseconds(begin_utc)
        log_msg = "{0}\n{1}".format(cmd, "\n".join([line for line in msg.split('\n') if line != ""]))
        self.logger.verbose(log_msg)
        self.report_event(message=log_msg, duration=duration, log_event=False)
    def test_process_stdout_stderr(self):
        """
        If the command has no timeout, the process need not be the leader of its own process group.
        """
        stdout = "The quick brown fox jumps over the lazy dog.\n"
        stderr = "The five boxing wizards jump quickly.\n"

        expected = "[stdout]\n{0}\n\n[stderr]\n{1}".format(stdout, stderr)

        cmd = process_cmd_template.format(process_target, stdout, stderr)
        process = subprocess.Popen(cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   env=os.environ)

        actual = capture_from_process(process, cmd)
        self.assertEqual(expected, actual)
    def test_process_stdout_stderr(self):
        """
        If the command has no timeout, the process need not be the leader of its own process group.
        """
        stdout = "The quick brown fox jumps over the lazy dog.\n"
        stderr = "The five boxing wizards jump quickly.\n"

        expected = "[stdout]\n{0}\n\n[stderr]\n{1}".format(stdout, stderr)

        cmd = process_cmd_template.format(process_target, stdout, stderr)
        process = subprocess.Popen(cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   env=os.environ)

        actual = capture_from_process(process, cmd)
        self.assertEqual(expected, actual)
Esempio n. 10
0
    def test_process_behaved_non_forked(self):
        """
        non-forked process runs for 10 seconds, timeout is 20 seconds
        we expect:
            - test to run in just over 10 seconds
            - no exception should be thrown
            - output should be collected
        """
        cmd = "{0} -t 10".format(process_target)
        process = subprocess.Popen(cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   env=os.environ,
                                   preexec_fn=os.setsid)

        try:
            body = capture_from_process(process, 'sleep 10', 20)
        except Exception as gen_ex:
            self.fail('Unexpected exception: {0}'.format(gen_ex))

        self.assertFalse('Timeout' in body)
        self.assertTrue('Iteration 9' in body)
        self.assertTrue('Iteration 10' in body)