xref: /llvm-project/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart.py (revision fa6377119c0624773cb698935692d46843e9f6ec)
1"""
2Test lldb-dap RestartRequest.
3"""
4
5from lldbsuite.test.decorators import *
6from lldbsuite.test.lldbtest import line_number
7import lldbdap_testcase
8
9
10class TestDAP_restart(lldbdap_testcase.DAPTestCaseBase):
11    @skipIfWindows
12    def test_basic_functionality(self):
13        """
14        Tests the basic restarting functionality: set two breakpoints in
15        sequence, restart at the second, check that we hit the first one.
16        """
17        line_A = line_number("main.c", "// breakpoint A")
18        line_B = line_number("main.c", "// breakpoint B")
19
20        program = self.getBuildArtifact("a.out")
21        self.build_and_launch(program)
22        [bp_A, bp_B] = self.set_source_breakpoints("main.c", [line_A, line_B])
23
24        # Verify we hit A, then B.
25        self.dap_server.request_configurationDone()
26        self.verify_breakpoint_hit([bp_A])
27        self.dap_server.request_continue()
28        self.verify_breakpoint_hit([bp_B])
29
30        # Make sure i has been modified from its initial value of 0.
31        self.assertEqual(
32            int(self.dap_server.get_local_variable_value("i")),
33            1234,
34            "i != 1234 after hitting breakpoint B",
35        )
36
37        # Restart then check we stop back at A and program state has been reset.
38        self.dap_server.request_restart()
39        self.verify_breakpoint_hit([bp_A])
40        self.assertEqual(
41            int(self.dap_server.get_local_variable_value("i")),
42            0,
43            "i != 0 after hitting breakpoint A on restart",
44        )
45
46    @skipIfWindows
47    def test_stopOnEntry(self):
48        """
49        Check that the stopOnEntry setting is still honored after a restart.
50        """
51        program = self.getBuildArtifact("a.out")
52        self.build_and_launch(program, stopOnEntry=True)
53        [bp_main] = self.set_function_breakpoints(["main"])
54        self.dap_server.request_configurationDone()
55
56        # Once the "configuration done" event is sent, we should get a stopped
57        # event immediately because of stopOnEntry.
58        stopped_events = self.dap_server.wait_for_stopped()
59        for stopped_event in stopped_events:
60            if "body" in stopped_event:
61                body = stopped_event["body"]
62                if "reason" in body:
63                    reason = body["reason"]
64                    self.assertNotEqual(
65                        reason, "breakpoint", 'verify stop isn\'t "main" breakpoint'
66                    )
67
68        # Then, if we continue, we should hit the breakpoint at main.
69        self.dap_server.request_continue()
70        self.verify_breakpoint_hit([bp_main])
71
72        # Restart and check that we still get a stopped event before reaching
73        # main.
74        self.dap_server.request_restart()
75        stopped_events = self.dap_server.wait_for_stopped()
76        for stopped_event in stopped_events:
77            if "body" in stopped_event:
78                body = stopped_event["body"]
79                if "reason" in body:
80                    reason = body["reason"]
81                    self.assertNotEqual(
82                        reason,
83                        "breakpoint",
84                        'verify stop after restart isn\'t "main" breakpoint',
85                    )
86
87    @skipIfWindows
88    def test_arguments(self):
89        """
90        Tests that lldb-dap will use updated launch arguments included
91        with a restart request.
92        """
93        line_A = line_number("main.c", "// breakpoint A")
94
95        program = self.getBuildArtifact("a.out")
96        self.build_and_launch(program)
97        [bp_A] = self.set_source_breakpoints("main.c", [line_A])
98
99        # Verify we hit A, then B.
100        self.dap_server.request_configurationDone()
101        self.verify_breakpoint_hit([bp_A])
102
103        # We don't set any arguments in the initial launch request, so argc
104        # should be 1.
105        self.assertEqual(
106            int(self.dap_server.get_local_variable_value("argc")),
107            1,
108            "argc != 1 before restart",
109        )
110
111        # Restart with some extra 'args' and check that the new argc reflects
112        # the updated launch config.
113        self.dap_server.request_restart(
114            restartArguments={
115                "arguments": {
116                    "program": program,
117                    "args": ["a", "b", "c", "d"],
118                }
119            }
120        )
121        self.verify_breakpoint_hit([bp_A])
122        self.assertEqual(
123            int(self.dap_server.get_local_variable_value("argc")),
124            5,
125            "argc != 5 after restart",
126        )
127