コード例 #1
0
ファイル: test_pygdbmi.py プロジェクト: cs01/pygdbmi
 def assert_advance(escaped_str: str, expected_unescaped_str: str,
                    expected_after: str, **kwargs) -> None:
     """Wrapper around advance_past_string_with_gdb_escapes to make testing
     easier
     """
     (
         actual_unescaped_str,
         after_quote_index,
     ) = advance_past_string_with_gdb_escapes(escaped_str, **kwargs)
     assert_match(actual_unescaped_str, expected_unescaped_str)
     actual_after = escaped_str[after_quote_index:]
     assert_match(actual_after, expected_after)
コード例 #2
0
    def test_api(self):
        raw_text = 'abc- "d" ""ef"" g'
        stream = StringStream(raw_text)
        assert stream.index == 0
        assert stream.len == len(raw_text)

        buf = stream.read(1)
        assert_match(buf, "a")
        assert stream.index == 1

        stream.seek(-1)
        assert stream.index == 0

        buf = stream.advance_past_chars(['"'])
        buf = stream.advance_past_string_with_gdb_escapes()
        assert_match(buf, "d")

        buf = stream.advance_past_chars(['"'])
        buf = stream.advance_past_chars(['"'])
        buf = stream.advance_past_string_with_gdb_escapes()
        assert_match(buf, "ef")

        # read way past end to test it gracefully returns the
        # remainder of the string without failing
        buf = stream.read(50)
        assert_match(buf, '" g')
コード例 #3
0
    def test_parser(self):
        """Test that the parser returns dictionaries from gdb mi strings as expected"""

        # Test basic types
        assert_match(parse_response('^done'), {
            'type': 'result',
            'payload': None,
            'message': 'done',
            "token": None
        })
        assert_match(parse_response('~"done"'), {
            'type': 'console',
            'payload': 'done',
            'message': None
        })
        assert_match(parse_response('@"done"'), {
            "type": 'target',
            "payload": 'done',
            'message': None
        })
        assert_match(parse_response('&"done"'), {
            "type": 'log',
            "payload": 'done',
            'message': None
        })
        assert_match(parse_response('done'), {
            'type': 'output',
            'payload': 'done',
            'message': None
        })

        # Test escape sequences
        assert_match(parse_response('~""'), {
            "type": "console",
            "payload": "",
            'message': None
        })
        assert_match(parse_response('~"\b\f\n\r\t\""'), {
            "type": "console",
            "payload": '\b\f\n\r\t\"',
            'message': None
        })
        assert_match(parse_response('@""'), {
            "type": "target",
            "payload": "",
            'message': None
        })
        assert_match(parse_response('@"\b\f\n\r\t\""'), {
            "type": "target",
            "payload": '\b\f\n\r\t\"',
            'message': None
        })
        assert_match(parse_response('&""'), {
            "type": "log",
            "payload": "",
            'message': None
        })
        assert_match(parse_response('&"\b\f\n\r\t\""'), {
            "type": "log",
            "payload": '\b\f\n\r\t\"',
            'message': None
        })

        # Test that a dictionary with repeated keys (a gdb bug) is gracefully worked-around  by pygdbmi
        # See https://sourceware.org/bugzilla/show_bug.cgi?id=22217
        # and https://github.com/cs01/pygdbmi/issues/19
        assert_match(
            parse_response(
                '^done,thread-ids={thread-id="3",thread-id="2",thread-id="1"}, current-thread-id="1",number-of-threads="3"'
            ), {
                "type": "result",
                "payload": {
                    'thread-ids': {
                        'thread-id': ['3', '2', '1']
                    },
                    'current-thread-id': '1',
                    'number-of-threads': '3',
                },
                'message': 'done',
                'token': None
            })

        # Test a real world Dictionary
        assert_match(
            parse_response(
                '=breakpoint-modified,bkpt={number="1",empty_arr=[],type="breakpoint",disp="keep",enabled="y",addr="0x000000000040059c",func="main",file="hello.c",fullname="/home/git/pygdbmi/tests/sample_c_app/hello.c",line="9",thread-groups=["i1"],times="1",original-location="hello.c:9"}'
            ), {
                'message': 'breakpoint-modified',
                'payload': {
                    'bkpt': {
                        'addr': '0x000000000040059c',
                        'disp': 'keep',
                        'enabled': 'y',
                        'file': 'hello.c',
                        'fullname':
                        '/home/git/pygdbmi/tests/sample_c_app/hello.c',
                        'func': 'main',
                        'line': '9',
                        'number': '1',
                        'empty_arr': [],
                        'original-location': 'hello.c:9',
                        'thread-groups': ['i1'],
                        'times': '1',
                        'type': 'breakpoint'
                    }
                },
                'type': 'notify',
                'token': None
            })

        # Test records with token
        assert_match(parse_response('1342^done'), {
            'type': 'result',
            'payload': None,
            'message': 'done',
            "token": 1342
        })
コード例 #4
0
    def test_controller_buffer_randomized(self):
        """
        The following code reads a sample gdb mi stream randomly to ensure partial
        output is read and that the buffer is working as expected on all streams.
        """
        test_directory = os.path.dirname(os.path.abspath(__file__))
        datafile_path = "%s/response_samples.txt" % (test_directory)

        gdbmi = GdbController()
        for stream in gdbmi._incomplete_output.keys():
            responses = []
            with open(datafile_path, "rb") as f:
                while True:
                    n = random.randint(1, 100)
                    # read random number of bytes to simulate incomplete responses
                    gdb_mi_simulated_output = f.read(n)
                    if gdb_mi_simulated_output == b"":
                        break  # EOF

                    # let the controller try to parse this additional raw gdb output
                    responses += gdbmi._get_responses_list(
                        gdb_mi_simulated_output, stream)
            assert len(responses) == 141

            # spot check a few
            assert_match(
                responses[0],
                {
                    "message": None,
                    "type": "console",
                    "payload":
                    u"0x00007fe2c5c58920 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81\\n",
                    "stream": stream,
                },
            )
            if not USING_WINDOWS:
                # can't get this to pass in windows
                assert_match(
                    responses[71],
                    {
                        "stream": stream,
                        "message": u"done",
                        "type": "result",
                        "payload": None,
                        "token": None,
                    },
                )
                assert_match(
                    responses[82],
                    {
                        "message": None,
                        "type": "output",
                        "payload":
                        u"The inferior program printed this! Can you still parse it?",
                        "stream": stream,
                    },
                )
            assert_match(
                responses[137],
                {
                    "stream": stream,
                    "message": u"thread-group-exited",
                    "type": "notify",
                    "payload": {
                        u"exit-code": u"0",
                        u"id": u"i1"
                    },
                    "token": None,
                },
            )
            assert_match(
                responses[138],
                {
                    "stream": stream,
                    "message": u"thread-group-started",
                    "type": "notify",
                    "payload": {
                        u"pid": u"48337",
                        u"id": u"i1"
                    },
                    "token": None,
                },
            )
            assert_match(
                responses[139],
                {
                    "stream": stream,
                    "message": u"tsv-created",
                    "type": "notify",
                    "payload": {
                        u"name": "trace_timestamp",
                        u"initial": "0"
                    },
                    "token": None,
                },
            )
            assert_match(
                responses[140],
                {
                    "stream": stream,
                    "message": u"tsv-created",
                    "type": "notify",
                    "payload": {
                        u"name": "trace_timestamp",
                        u"initial": "0"
                    },
                    "token": None,
                },
            )

            for stream in gdbmi._incomplete_output.keys():
                assert gdbmi._incomplete_output[stream] is None
コード例 #5
0
    def test_parser(self):
        """Test that the parser returns dictionaries from gdb mi strings as expected"""

        # Test basic types
        assert_match(
            parse_response("^done"),
            {
                "type": "result",
                "payload": None,
                "message": "done",
                "token": None
            },
        )
        assert_match(
            parse_response('~"done"'),
            {
                "type": "console",
                "payload": "done",
                "message": None
            },
        )
        assert_match(
            parse_response('@"done"'),
            {
                "type": "target",
                "payload": "done",
                "message": None
            },
        )
        assert_match(
            parse_response('&"done"'),
            {
                "type": "log",
                "payload": "done",
                "message": None
            },
        )
        assert_match(
            parse_response("done"),
            {
                "type": "output",
                "payload": "done",
                "message": None
            },
        )

        # Test escape sequences
        assert_match(parse_response('~""'), {
            "type": "console",
            "payload": "",
            "message": None
        })
        assert_match(
            parse_response('~"\b\f\n\r\t""'),
            {
                "type": "console",
                "payload": '\b\f\n\r\t"',
                "message": None
            },
        )
        assert_match(parse_response('@""'), {
            "type": "target",
            "payload": "",
            "message": None
        })
        assert_match(
            parse_response('@"\b\f\n\r\t""'),
            {
                "type": "target",
                "payload": '\b\f\n\r\t"',
                "message": None
            },
        )
        assert_match(parse_response('&""'), {
            "type": "log",
            "payload": "",
            "message": None
        })
        assert_match(
            parse_response('&"\b\f\n\r\t""'),
            {
                "type": "log",
                "payload": '\b\f\n\r\t"',
                "message": None
            },
        )
        assert_match(parse_response('&"\\"'), {
            "type": "log",
            "payload": "\\",
            "message": None
        })  # test that an escaped backslash gets captured

        # Test that a dictionary with repeated keys (a gdb bug) is gracefully worked-around  by pygdbmi
        # See https://sourceware.org/bugzilla/show_bug.cgi?id=22217
        # and https://github.com/cs01/pygdbmi/issues/19
        assert_match(
            parse_response(
                '^done,thread-ids={thread-id="3",thread-id="2",thread-id="1"}, current-thread-id="1",number-of-threads="3"'
            ),
            {
                "type": "result",
                "payload": {
                    "thread-ids": {
                        "thread-id": ["3", "2", "1"]
                    },
                    "current-thread-id": "1",
                    "number-of-threads": "3",
                },
                "message": "done",
                "token": None,
            },
        )

        # Test a real world Dictionary
        assert_match(
            parse_response(
                '=breakpoint-modified,bkpt={number="1",empty_arr=[],type="breakpoint",disp="keep",enabled="y",addr="0x000000000040059c",func="main",file="hello.c",fullname="/home/git/pygdbmi/tests/sample_c_app/hello.c",line="9",thread-groups=["i1"],times="1",original-location="hello.c:9"}'
            ),
            {
                "message": "breakpoint-modified",
                "payload": {
                    "bkpt": {
                        "addr": "0x000000000040059c",
                        "disp": "keep",
                        "enabled": "y",
                        "file": "hello.c",
                        "fullname":
                        "/home/git/pygdbmi/tests/sample_c_app/hello.c",
                        "func": "main",
                        "line": "9",
                        "number": "1",
                        "empty_arr": [],
                        "original-location": "hello.c:9",
                        "thread-groups": ["i1"],
                        "times": "1",
                        "type": "breakpoint",
                    }
                },
                "type": "notify",
                "token": None,
            },
        )

        # Test records with token
        assert_match(
            parse_response("1342^done"),
            {
                "type": "result",
                "payload": None,
                "message": "done",
                "token": 1342
            },
        )

        # Test extra characters at end of dictionary are discarded (issue #30)
        assert_match(
            parse_response('=event,name="gdb"discardme'),
            {
                "type": "notify",
                "payload": {
                    "name": "gdb"
                },
                "message": "event",
                "token": None,
            },
        )
コード例 #6
0
ファイル: test_app.py プロジェクト: mariusmue/pygdbmi
    def test_controller_buffer_randomized(self):
        """
        The following code reads a sample gdb mi stream randomly to ensure partial
        output is read and that the buffer is working as expected on all streams.
        """
        test_directory = os.path.dirname(os.path.abspath(__file__))
        datafile_path = '%s/response_samples.txt' % (test_directory)

        gdbmi = GdbController()
        for stream in gdbmi._incomplete_output.keys():
            responses = []
            with open(datafile_path, 'rb') as f:
                while(True):
                    n = random.randint(1, 100)
                    # read random number of bytes to simulate incomplete responses
                    gdb_mi_simulated_output = f.read(n)
                    if gdb_mi_simulated_output == b'':
                        break  # EOF
                    # let the controller try to parse this additional raw gdb output
                    responses += gdbmi._get_responses_list(gdb_mi_simulated_output, stream, False)
            assert(len(responses) == 141)

            # spot check a few
            assert_match(responses[0], {'message': None, 'type': 'console', 'payload': u'0x00007fe2c5c58920 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81\\n', 'stream': stream})
            if not USING_WINDOWS:
                # can't get this to pass in windows
                assert_match(responses[71], {'stream': stream, 'message': u'done', 'type': 'result', 'payload': None, 'token': None})
                assert_match(responses[82], {'message': None, 'type': 'output', 'payload': u'The inferior program printed this! Can you still parse it?', 'stream': stream})
            assert_match(responses[137], {'stream': stream, 'message': u'thread-group-exited', 'type': 'notify', 'payload': {u'exit-code': u'0', u'id': u'i1'}, 'token': None})
            assert_match(responses[138], {'stream': stream, 'message': u'thread-group-started', 'type': 'notify', 'payload': {u'pid': u'48337', u'id': u'i1'}, 'token': None})
            assert_match(responses[139], {'stream': stream, 'message': u'tsv-created', 'type': 'notify', 'payload': {u'name': 'trace_timestamp', u'initial': '0'}, 'token': None})
            assert_match(responses[140], {'stream': stream, 'message': u'tsv-created', 'type': 'notify', 'payload': {u'name': 'trace_timestamp', u'initial': '0'}, 'token': None})

            for stream in gdbmi._incomplete_output.keys():
                assert(gdbmi._incomplete_output[stream] is None)
コード例 #7
0
ファイル: test_app.py プロジェクト: johncf/pygdbmi
    def test_parser(self):
        """Test that the parser returns dictionaries from gdb mi strings as expected"""

        # Test basic types
        assert_match(parse_response('^done'), {
            'type': 'result',
            'payload': None,
            'message': 'done',
            "token": None
        })
        assert_match(parse_response('~"done"'), {
            'type': 'console',
            'payload': 'done',
            'message': None
        })
        assert_match(parse_response('@"done"'), {
            "type": 'target',
            "payload": 'done',
            'message': None
        })
        assert_match(parse_response('&"done"'), {
            "type": 'log',
            "payload": 'done',
            'message': None
        })
        assert_match(parse_response('done'), {
            'type': 'output',
            'payload': 'done',
            'message': None
        })

        # Test escape sequences
        assert_match(parse_response('~""'), {
            "type": "console",
            "payload": "",
            'message': None
        })
        assert_match(parse_response('~"\b\f\n\r\t\""'), {
            "type": "console",
            "payload": '\b\f\n\r\t\"',
            'message': None
        })
        assert_match(parse_response('@""'), {
            "type": "target",
            "payload": "",
            'message': None
        })
        assert_match(parse_response('@"\b\f\n\r\t\""'), {
            "type": "target",
            "payload": '\b\f\n\r\t\"',
            'message': None
        })
        assert_match(parse_response('&""'), {
            "type": "log",
            "payload": "",
            'message': None
        })
        assert_match(parse_response('&"\b\f\n\r\t\""'), {
            "type": "log",
            "payload": '\b\f\n\r\t\"',
            'message': None
        })

        # Test a real world Dictionary
        assert_match(
            parse_response(
                '=breakpoint-modified,bkpt={number="1",empty_arr=[],type="breakpoint",disp="keep",enabled="y",addr="0x000000000040059c",func="main",file="hello.c",fullname="/home/git/pygdbmi/tests/sample_c_app/hello.c",line="9",thread-groups=["i1"],times="1",original-location="hello.c:9"}'
            ), {
                'message': 'breakpoint-modified',
                'payload': {
                    'bkpt': {
                        'addr': '0x000000000040059c',
                        'disp': 'keep',
                        'enabled': 'y',
                        'file': 'hello.c',
                        'fullname':
                        '/home/git/pygdbmi/tests/sample_c_app/hello.c',
                        'func': 'main',
                        'line': '9',
                        'number': '1',
                        'empty_arr': [],
                        'original-location': 'hello.c:9',
                        'thread-groups': ['i1'],
                        'times': '1',
                        'type': 'breakpoint'
                    }
                },
                'type': 'notify',
                'token': None
            })

        #Test records with token
        assert_match(parse_response('1342^done'), {
            'type': 'result',
            'payload': None,
            'message': 'done',
            "token": 1342
        })
コード例 #8
0
ファイル: test_pygdbmi.py プロジェクト: cs01/pygdbmi
    def test_unescape(self) -> None:
        """Test the unescape function"""

        assert_match(unescape(r"a"), "a")
        assert_match(unescape(r"hello world"), "hello world")
        assert_match(unescape(r"hello\nworld"), "hello\nworld")
        assert_match(unescape(r"quote: <\">"), 'quote: <">')
        # UTF-8 text encoded as a sequence of octal characters.
        assert_match(unescape(self.GDB_ESCAPED_PIZZA), "\N{SLICE OF PIZZA}")
        # Similar but for a simple space.
        assert_match(unescape(self.GDB_ESCAPED_SPACE), " ")
        # Several escapes in the same string.
        assert_match(
            unescape(rf"\tmultiple\nescapes\tin\"the\'same\"string\"foo"
                     rf"{self.GDB_ESCAPED_SPACE}bar{self.GDB_ESCAPED_PIZZA}"),
            '\tmultiple\nescapes\tin"the\'same"string"foo bar\N{SLICE OF PIZZA}',
        )

        for bad in (r'"', r'"x', r'a"', r'a"x', r'a"x"foo'):
            with self.assertRaisesRegex(ValueError, "Unescaped quote found"):
                unescape(bad)

        for bad in (r"\777", r"\400"):
            with self.assertRaisesRegex(ValueError, "Invalid octal number"):
                unescape(bad)

        for bad in (r"\X", r"\1", r"\11"):
            with self.assertRaisesRegex(ValueError,
                                        "Invalid escape character"):
                unescape(bad)