예제 #1
0
 def _new_execution_timeout(self, src):
     """
     Return a new execution timeout context manager.
     If not execution timeout is in place, returns ExitStack()
     """
     # We use green=False because this could be cpu bound. This will
     # still throw to the proper greenlet if this is gevented.
     return (Timeout(self.execution_timeout,
                     QdbExecutionTimeout(src, self.execution_timeout),
                     green=False)
             if self.execution_timeout else ExitStack())
예제 #2
0
    def test_eval_timeout(self):
        """
        Tests that evaluating user repl commands will raise Timeouts.
        """
        def g():
            while True:
                pass

        prints = []

        class cmd_manager(type(self.cmd_manager)):
            """
            Captures print commands to make assertions on them.
            """
            def send_print(self, input_, exc, output):
                prints.append({
                    'input': input_,
                    'exc': exc,
                    'output': output
                })

        to_eval = 'g()'

        db = Qdb(
            uuid='timeout_test',
            cmd_manager=cmd_manager(),
            host=self.tracer_host,
            port=self.tracer_port,
            redirect_output=False,
            execution_timeout=1,
            green=True,
        )
        gyield()
        self.server.session_store.send_to_tracer(
            uuid=db.uuid,
            event=fmt_msg('eval', to_eval)
        )
        self.server.session_store.send_to_tracer(
            uuid=db.uuid,
            event=fmt_msg('continue')
        )
        db.set_trace(stop=True)
        self.server.session_store.slaughter(db.uuid)

        self.assertTrue(prints)
        print_ = prints[0]

        self.assertEqual(print_['input'], to_eval)
        self.assertTrue(print_['exc'])
        self.assertEqual(
            print_['output'],
            db.exception_serializer(QdbExecutionTimeout(to_eval, 1))
        )
예제 #3
0
    def test_conditional_breakpoint_timeout(self):
        """
        Tests conditional breakpoints that cause timeouts.
        WARNING: This test relies on the relative line numbers inside the test.
        """
        stopped = [False]

        def stop():
            stopped[0] = True
            return True  # Execute the assertion.

        line = None
        cond = 'g()'

        cmd_manager = QueueCommandManager()
        db = Qdb(cmd_manager=cmd_manager, execution_timeout=1)
        cmd_manager.enqueue(lambda t: stop() and self.assertEqual(line, 1))
        line_offset = 10
        # Set a condition that will time out.
        db.set_break(
            self.filename,
            sys._getframe().f_lineno + line_offset,
            cond='g()',
        )
        db.set_trace(stop=False)

        def g():
            while True:
                pass

        line = 1
        line = 2
        line = 3

        db.disable()
        errors = [e['p'] for e in cmd_manager.sent if e['e'] == 'error']
        self.assertEqual(len(errors), 1)

        error = errors[0]
        self.assertEqual(error['type'], 'condition')

        negative_line_offset = 14
        exc = QdbExecutionTimeout(cond, db.execution_timeout)
        self.assertEqual(
            error['data'], {
                'line': sys._getframe().f_lineno - negative_line_offset,
                'cond': cond,
                'exc': type(exc).__name__,
                'output': db.exception_serializer(exc),
            }
        )
        # Make sure we stopped when we raised the exception.
        self.assertTrue(stopped[0])
예제 #4
0
    def test_watchlist(self):
        """
        Tests the watchlist by evaluating a constant, local function, local
        variable, global function, and global variable.
        """
        db = Qdb(cmd_manager=NopCommandManager, execution_timeout=1)

        too_long_msg = db.exception_serializer(
            QdbExecutionTimeout('too_long()', 1))
        db.extend_watchlist(
            '2 + 2',
            'local_var',
            'local_fn()',
            'global_var',
            'global_fn()',
            'too_long()',
        )

        def new_curframe():
            """
            Test function for checking for NameErrors on the watchlist.
            This changes the curframe of the tracer to eval the watchlist with
            a new set of locals.
            """
            self.assertEqual(db.watchlist['2 + 2'], (None, 4))
            self.assertEqual(
                db.watchlist['local_var'],
                ('NameError', "NameError: name 'local_var' is not defined"))
            self.assertEqual(
                db.watchlist['local_fn()'],
                ('NameError', "NameError: name 'local_fn' is not defined"))
            self.assertEqual(db.watchlist['global_var'], (None, 'global_var'))
            self.assertEqual(db.watchlist['global_fn()'], (None, 'global_fn'))

        local_var = 'local_var'  # NOQA
        local_fn = lambda: 'local_fn'  # NOQA

        def too_long():
            while True:
                pass

        # Set trace and check innitial assertions.
        db.set_trace()
        self.assertEqual(db.watchlist['2 + 2'], (None, 4))
        self.assertEqual(db.watchlist['local_var'], (None, 'local_var'))
        self.assertEqual(db.watchlist['local_fn()'], (None, 'local_fn'))
        self.assertEqual(db.watchlist['global_var'], (None, 'global_var'))
        self.assertEqual(db.watchlist['global_fn()'], (None, 'global_fn'))

        # Testing this as a tuple causes strange behavior.
        self.assertEqual(db.watchlist['too_long()'][0], 'QdbExecutionTimeout')
        self.assertEqual(db.watchlist['too_long()'][1], too_long_msg)

        local_var = 'updated_local_var'  # NOQA
        local_fn = lambda: 'updated_local_fn'  # NOQA

        self.assertEqual(db.watchlist['2 + 2'], (None, 4))
        self.assertEqual(db.watchlist['local_var'],
                         (None, 'updated_local_var'))
        self.assertEqual(db.watchlist['local_fn()'],
                         (None, 'updated_local_fn'))
        self.assertEqual(db.watchlist['global_var'], (None, 'global_var'))
        self.assertEqual(db.watchlist['global_fn()'], (None, 'global_fn'))

        new_curframe()