示例#1
0
    def receive(self, blocking=True):
        with Timeout.DisableAlarm():
            if not blocking:
                return self.incoming.get(block=False)

            difference = Timeout.difference()
            if difference is not None:
                return self.incoming.get(timeout=difference)
            return self.incoming.get()
示例#2
0
    def test_check(self):
        with mocks.Time, OutputCapture() as capturer:
            with Timeout(1):
                Timeout.check()
                self.assertRaises(Timeout.Exception, time.sleep, 1)

        self.assertEqual(
            capturer.webkitcorepy.log.getvalue(),
            'Request to sleep 1 second exceeded the current timeout threshold\n'
        )
示例#3
0
    def run(*popenargs, **kwargs):
        timeout = kwargs.pop('timeout', None)

        with Timeout.DisableAlarm():
            current_time = time.time()
            Timeout.check(current_time=current_time)
            difference = Timeout.difference(current_time=current_time)

            if difference:
                timeout = min(timeout or sys.maxsize, int(math.ceil(difference)))
            return subprocess.run(*popenargs, timeout=timeout, **kwargs)
示例#4
0
    def test_nested_outer_timeout(self):
        with mocks.Time, OutputCapture() as capturer, self.assertRaises(
                Timeout.Exception):
            with Timeout(1):
                with Timeout(3, RuntimeError("This shouldn't be raised")):
                    time.sleep(2)

        self.assertEqual(
            capturer.webkitcorepy.log.getvalue(),
            'Request to sleep 2 seconds exceeded the current timeout threshold\n'
        )
示例#5
0
    def launch_app(self, bundle_id, args, env=None, timeout=300):
        environment_to_use = {}
        SIMCTL_ENV_PREFIX = 'SIMCTL_CHILD_'
        for value in (env or {}):
            if not value.startswith(SIMCTL_ENV_PREFIX):
                environment_to_use[SIMCTL_ENV_PREFIX + value] = env[value]
            else:
                environment_to_use[value] = env[value]

        # FIXME: This is a workaround for <rdar://problem/30172453>.
        def _log_debug_error(error):
            _log.debug(error.message_with_output())

        with Timeout(timeout, handler=RuntimeError(u'Timed out waiting for process to open {} on {}'.format(bundle_id, self.udid)), patch=False):
            while True:
                output = self.executive.run_command(
                    ['xcrun', 'simctl', 'launch', self.udid, bundle_id] + args,
                    env=environment_to_use,
                    error_handler=_log_debug_error,
                    return_stderr=False,
                )
                match = re.match(r'(?P<bundle>[^:]+): (?P<pid>\d+)\n', output)
                # FIXME: We shouldn't need to check the PID <rdar://problem/31154075>.
                if match and self.executive.check_running_pid(int(match.group('pid'))):
                    break
                if match:
                    _log.debug(u'simctl launch reported pid {}, but this process is not running'.format(match.group('pid')))
                else:
                    _log.debug('simctl launch did not report a pid')

        if match.group('bundle') != bundle_id:
            raise RuntimeError(u'Failed to find process id for {}: {}'.format(bundle_id, output))
        _log.debug(u'Returning pid {} of launched process'.format(match.group('pid')))
        return int(match.group('pid'))
示例#6
0
    def __exit__(self, *args, **kwargs):
        try:
            inflight = sys.exc_info()

            for worker in self.workers:
                if worker.is_alive():
                    worker.terminate()

            with Timeout(seconds=self.grace_period):
                try:
                    while self._started:
                        self.queue.receive()(self)
                except Exception:
                    if inflight[1]:
                        log.critical(
                            'Some workers failed to gracefully shut down, but in-flight exception taking precedence'
                        )
                        reraise(*inflight)
                    raise self.Exception(
                        'Some workers failed to gracefully shut down')

        finally:
            for worker in self.workers:
                if not worker.is_alive():
                    continue

                if sys.version_info >= (3, 7):
                    worker.kill()
                elif hasattr(signal, 'SIGKILL'):
                    os.kill(worker.pid, signal.SIGKILL)
                else:
                    worker.terminate()
示例#7
0
    def _run_google_test(self, test_program, subtest):
        command = [test_program, '--gtest_filter=%s' % (subtest)]
        timeout = self._options.timeout
        if self._expectations.is_slow(os.path.basename(test_program), subtest):
            timeout *= 10

        pid, fd = os.forkpty()
        if pid == 0:
            os.execvpe(command[0], command, self._test_env)
            sys.exit(0)

        with Timeout(timeout):
            try:
                common.parse_output_lines(fd, sys.stdout.write)
                status = self._waitpid(pid)
                os.close(fd)
            except Timeout.Exception:
                self._kill_process(pid)
                os.close(fd)
                sys.stdout.write("**TIMEOUT** %s\n" % subtest)
                sys.stdout.flush()
                return {subtest: "TIMEOUT"}

        if status == -SIGSEGV:
            sys.stdout.write("**CRASH** %s\n" % subtest)
            sys.stdout.flush()
            return {subtest: "CRASH"}

        if status != 0:
            return {subtest: "FAIL"}

        return {subtest: "PASS"}
示例#8
0
 def test_single_trigger(self):
     with mocks.Time, OutputCapture():
         with Timeout(1):
             with self.assertRaises(Timeout.Exception):
                 time.sleep(2)
             time.sleep(
                 2
             )  # The timeout has already been triggered, so it shouldn't be re-triggered.
示例#9
0
    def run(*popenargs, **kwargs):
        timeout = kwargs.pop('timeout', None)
        capture_output = kwargs.pop('capture_output', False)

        with Timeout.DisableAlarm():
            current_time = time.time()
            Timeout.check(current_time=current_time)
            difference = Timeout.difference(current_time=current_time)

            if difference:
                timeout = min(timeout or sys.maxsize, int(math.ceil(difference)))
            if capture_output:
                if ('stdout' in kwargs) or ('stderr' in kwargs):
                    raise ValueError('stdout and stderr arguments may not be used with capture_output.')
                kwargs['stdout'] = subprocess.PIPE
                kwargs['stderr'] = subprocess.PIPE
            return subprocess.run(*popenargs, timeout=timeout, **kwargs)
示例#10
0
 def __enter__(self):
     with Timeout(seconds=10,
                  patch=False,
                  handler=self.Exception('Failed to start all workers')):
         for worker in self.workers:
             worker.start()
         while self._started < len(self.workers):
             self.queue.receive()(self)
     return self
示例#11
0
    def run(*popenargs, **kwargs):
        input = kwargs.pop('input', None)
        capture_output = kwargs.pop('capture_output', False)
        timeout = kwargs.pop('timeout', None)
        check = kwargs.pop('check', False)

        encoding = kwargs.pop('encoding', None)
        errors = kwargs.pop('errors', None)
        if encoding or errors:
            def decode(string):
                return string_utils.decode(string, encoding=encoding or 'utf-8', errors=errors or 'strict')
        else:
            def decode(string):
                return string

        if input is not None:
            if 'stdin' in kwargs:
                raise ValueError('stdin and input arguments may not both be used.')
            kwargs['stdin'] = subprocess.PIPE

        if capture_output:
            if ('stdout' in kwargs) or ('stderr' in kwargs):
                raise ValueError('stdout and stderr arguments may not be used with capture_output.')
            kwargs['stdout'] = subprocess.PIPE
            kwargs['stderr'] = subprocess.PIPE

        process = subprocess.Popen(*popenargs, **kwargs)
        try:
            if timeout:
                with Timeout(timeout):
                    stdout, stderr = process.communicate(input)
            else:
                stdout, stderr = process.communicate(input)

        except Timeout.Exception:
            process.terminate()
            deadline = time.time() + .5
            while process.poll() is None and time.time() < deadline:
                time.sleep(.1)
            if process.poll() is None:
                process.kill()
                stdout, stderr = '', ''
            else:
                stdout, stderr = process.communicate()
            raise TimeoutExpired(popenargs[0], timeout, output=decode(stdout), stderr=decode(stderr))

        except BaseException:
            process.kill()
            raise

        finally:
            process.wait()

        retcode = process.poll()
        if check and retcode:
            raise subprocess.CalledProcessError(retcode, popenargs[0], output=decode(stdout), stderr=decode(stderr))
        return CompletedProcess(popenargs[0], retcode, decode(stdout), decode(stderr))
示例#12
0
 def test_timeout_data(self):
     tmp = Timeout(1)
     self.assertEqual(None, tmp.data)
     with tmp:
         self.assertNotEqual(None, tmp.data)
         self.assertEqual(threading.current_thread().ident,
                          tmp.data.thread_id)
         self.assertTrue(time.time() + 1 >= tmp.data.alarm_time)
     self.assertEqual(None, tmp.data)
示例#13
0
    def test_basic_timeout(self):
        with mocks.Time, OutputCapture() as capturer, self.assertRaises(
                Timeout.Exception):
            with Timeout(1):
                time.sleep(2)

        self.assertEqual(
            capturer.webkitcorepy.log.getvalue(),
            'Request to sleep 2 seconds exceeded the current timeout threshold\n'
        )
示例#14
0
    def test_exception_constructor_timeout(self):
        with mocks.Time, OutputCapture() as capturer, self.assertRaises(
                RuntimeError):
            with Timeout(1, RuntimeError('This should be raised')):
                time.sleep(2)

        self.assertEqual(
            capturer.webkitcorepy.log.getvalue(),
            'Request to sleep 2 seconds exceeded the current timeout threshold\n'
        )
示例#15
0
    def __exit__(self, *args, **kwargs):
        if not self.queue:
            TaskPool.Process.working = False
            try:
                if self._teardown_args[0]:
                    self._teardown_args[0](*self._teardown_args[1],
                                           **self._teardown_args[2])
            finally:
                TaskPool.Process.queue = None
                TaskPool.Process.name = None
            return

        from six import reraise
        try:
            inflight = sys.exc_info()

            for worker in self.workers:
                if worker.is_alive():
                    worker.terminate()

            with Timeout(seconds=self.grace_period):
                try:
                    while self._started:
                        self.queue.receive()(self)
                except Exception:
                    if inflight[1]:
                        log.critical(
                            'Some workers failed to gracefully shut down, but in-flight exception taking precedence'
                        )
                        reraise(*inflight)
                    raise self.Exception(
                        'Some workers failed to gracefully shut down')

        finally:
            for worker in self.workers:
                if not worker.is_alive():
                    continue

                if sys.version_info >= (3, 7):
                    worker.kill()
                elif hasattr(signal, 'SIGKILL'):
                    try:
                        os.kill(worker.pid, signal.SIGKILL)
                    except OSError as e:
                        log.warn('Failed to terminate worker ' +
                                 str(worker.pid) + ' with error ' + str(e))
                else:
                    worker.terminate()

            self.queue.close()
            self.queue = None
            self.workers = []
示例#16
0
 def test_nested_outer_precedence(self):
     tmp_outer = Timeout(1)
     tmp_inner = Timeout(2)
     with tmp_outer:
         self.assertEqual(tmp_outer.data, Timeout.current())
         with tmp_inner:
             self.assertEqual(tmp_outer.data, Timeout.current())
         self.assertEqual(tmp_outer.data, Timeout.current())
     self.assertEqual(None, Timeout.current())
示例#17
0
    def _start(self):
        if self._proc:
            raise ValueError('{} already running'.format(self._name))
        self._reset()

        # Each device has a listening socket intitilaized during the port's setup_test_run.
        # 3 client connections will be accepted for stdin, stdout and stderr in that order.
        self._target_host.listening_socket.listen(3)
        self._pid = self._target_host.launch_app(self._bundle_id,
                                                 self._cmd[1:],
                                                 env=self._env)
        self._system_pid = self._pid

        # FIXME <rdar://problem/57032042>: This timeout should be 15 seconds
        with Timeout(30,
                     handler=RuntimeError(
                         'Timed out waiting for pid {} to connect at port {}'.
                         format(self._pid,
                                self._target_host.listening_port())),
                     patch=False):
            stdin = None
            stdout = None
            stderr = None
            try:
                # This order matches the client side connections in Tools/TestRunnerShared/IOSLayoutTestCommunication.cpp setUpIOSLayoutTestCommunication()
                stdin = SimulatorProcess._accept_connection_create_file(
                    self._target_host.listening_socket, 'wb')
                stdout = SimulatorProcess._accept_connection_create_file(
                    self._target_host.listening_socket, 'rb')
                stderr = SimulatorProcess._accept_connection_create_file(
                    self._target_host.listening_socket, 'rb')
            except:
                # We set self._proc as _reset() and _kill() depend on it.
                self._proc = SimulatorProcess.Popen(self._pid, stdin, stdout,
                                                    stderr, self._target_host)
                if self._proc.poll() is not None:
                    self._reset()
                    raise Exception(
                        'App {} with pid {} crashed before stdin could be attached'
                        .format(os.path.basename(self._cmd[0]), self._pid))
                self._kill()
                self._reset()
                raise

        self._proc = SimulatorProcess.Popen(self._pid, stdin, stdout, stderr,
                                            self._target_host)
示例#18
0
    def _run_one_test(self, web_root, test_file):
        try:
            self._http_server_driver.serve(web_root)
            url = urljoin(self._http_server_driver.base_url(),
                          self._plan_name + '/' + test_file)
            self._browser_driver.launch_url(url, self._plan['options'],
                                            self._build_dir,
                                            self._browser_path)
            with Timeout(self._plan['timeout']):
                result = self._get_result(url)
        except Exception as error:
            self._browser_driver.diagnose_test_failure(self._diagnose_dir,
                                                       error)
            raise error
        finally:
            self._browser_driver.close_browsers()
            self._http_server_driver.kill_server()

        return json.loads(result)
示例#19
0
    def __enter__(self):
        if not self.force_fork and self._num_workers == 1:
            TaskPool.Process.queue = _DummyQueue()
            TaskPool.Process.name = TaskPool.Process.name or '{}/0'.format(
                self.name)
            if self._setup_args[0]:
                self._setup_args[0](*self._setup_args[1],
                                    **self._setup_args[2])
            TaskPool.Process.working = True
            return self

        from mock import patch

        self.queue = self.BiDirectionalQueue()
        self.workers = [
            multiprocessing.Process(
                target=self.Process.main,
                args=(
                    '{}/{}'.format(self.name, count),
                    logging.getLogger().getEffectiveLevel(),
                    self._setup_args[0],
                    self._setup_args[1],
                    self._setup_args[2],
                    self.BiDirectionalQueue(outgoing=self.queue.incoming,
                                            incoming=self.queue.outgoing),
                    self._teardown_args[0],
                    self._teardown_args[1],
                    self._teardown_args[2],
                ),
            ) for count in range(self._num_workers)
        ]

        with Timeout(seconds=10,
                     patch=False,
                     handler=self.Exception('Failed to start all workers')):
            for worker in self.workers:
                worker.start()
            while self._started < len(self.workers):
                self.queue.receive()(self)

        return self
示例#20
0
        def wait(self):
            if self.poll() is not None:
                return

            # Need to check the timeout context
            timeout = Timeout.difference()
            if timeout and (self._completion.elapsed is None
                            or timeout < self._completion.elapsed):
                raise TimeoutExpired(self._args, timeout)

            if self._completion.elapsed is None:
                raise ValueError(
                    'Running a command that hangs without a timeout')

            if self._completion.elapsed:
                time.sleep(self._completion.elapsed)

            self.returncode = self._completion.returncode
            if self.stdout:
                self.stdout.seek(0)
            if self.stderr:
                self.stderr.seek(0)
示例#21
0
 def test_run_timeout_context(self):
     with OutputCapture(), self.assertRaises(TimeoutExpired):
         with Timeout(1):
             run([sys.executable, '-c', 'import time;time.sleep(2)'])
示例#22
0
    def test_no_timeout(self):
        with mocks.Time, OutputCapture() as capturer:
            with Timeout(2):
                time.sleep(1)

        self.assertEqual(capturer.webkitcorepy.log.getvalue(), '')
示例#23
0
 def test_deadline(self):
     with mocks.Time:
         with Timeout(1):
             self.asssertIsClose(Timeout.deadline(), time.time() + 1)
示例#24
0
 def test_difference(self):
     with mocks.Time:
         with Timeout(1):
             self.asssertIsClose(Timeout.difference(), 1)
示例#25
0
 def test_current_timeout(self):
     self.assertEqual(None, Timeout.current())
     with Timeout(1) as tmp:
         self.assertEqual(tmp.data, Timeout.current())
     self.assertEqual(None, Timeout.current())