diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index 32e37c502e358..8ce6608faa45c 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -44,7 +44,7 @@ # A quiet period between events, used to determine if we're done receiving # events in a given window, otherwise 'wait_for_stopped' would need to wait # until the DEFAULT_TIMEOUT occurs, slows down tests significantly. -EVENT_QUIET_PERIOD = 0.25 +EVENT_QUIET_PERIOD = 0.25 * (20.0 if ("ASAN_OPTIONS" in os.environ) else 1.0) # See lldbtest.Base.spawnSubprocess, which should help ensure any processes diff --git a/lldb/test/API/tools/lldb-dap/stopped-events/TestDAP_stopped_events.py b/lldb/test/API/tools/lldb-dap/stopped-events/TestDAP_stopped_events.py index 03dff39c82ed9..598ae49967989 100644 --- a/lldb/test/API/tools/lldb-dap/stopped-events/TestDAP_stopped_events.py +++ b/lldb/test/API/tools/lldb-dap/stopped-events/TestDAP_stopped_events.py @@ -7,6 +7,8 @@ import lldbdap_testcase +@skipIfWindows # This is flakey on Windows: llvm.org/pr24668, llvm.org/pr38373 +@skipIfLinux class TestDAP_stopped_events(lldbdap_testcase.DAPTestCaseBase): """ Test validates different operations that produce 'stopped' events. @@ -22,12 +24,17 @@ def verify_threads(self, expected_threads): threads_resp = self.dap_server.request_threads() self.assertTrue(threads_resp["success"]) threads = threads_resp["body"]["threads"] - self.assertEqual(len(threads), len(expected_threads)) + self.assertGreaterEqual( + len(threads), + len(expected_threads), + f"thread: {threads!r}\n expected threads: {expected_threads}", + ) + for idx, expected_thread in enumerate(expected_threads): thread = threads[idx] self.assertTrue( self.matches(thread, expected_thread), - f"Invalid thread state in {threads_resp}", + f"Invalid thread state in {threads_resp!r} for {expected_thread!r}", ) @expectedFailureAll( @@ -35,18 +42,29 @@ def verify_threads(self, expected_threads): bugnumber="llvm.org/pr18190 thread states not properly maintained", ) @expectedFailureNetBSD - @skipIfWindows # This is flakey on Windows: llvm.org/pr24668, llvm.org/pr38373 - def test_multiple_threads_sample_breakpoint(self): + def test_multiple_threads_same_breakpoint(self): """ - Test that multiple threads being stopped on the same breakpoint only produces a single 'stopped' event. + Test that multiple threads being stopped on the same breakpoint produces multiple 'stopped' event. """ program = self.getBuildArtifact("a.out") - self.build_and_launch(program) - line = line_number("main.cpp", "breakpoint") - [bp] = self.set_source_breakpoints("main.cpp", [line]) + launch_seq = self.build_and_launch(program) + self.dap_server.wait_for_event(["initialized"]) + [bp] = self.set_function_breakpoints(["my_add"]) + self.verify_configuration_done() + response = self.dap_server.receive_response(launch_seq) + self.assertTrue(response["success"]) + + events = self.dap_server.wait_for_stopped() + if len(events) == 1: + # we may not catch both events at the same time if we run with sanitizers + # enabled or on slow or heavily used computer. + events.extend(self.dap_server.wait_for_stopped()) - events = self.continue_to_next_stop() - self.assertEqual(len(events), 2, "Expected exactly two 'stopped' events") + self.assertEqual( + len(events), + 2, + f"Expected two 'stopped' events, seen events: {events!r}", + ) for event in events: body = event["body"] self.assertEqual(body["reason"], "breakpoint") @@ -63,7 +81,7 @@ def test_multiple_threads_sample_breakpoint(self): # thread #3: tid = 0x03, 0x0c a.out`add(a=4, b=5) at main.cpp:10:32, stop reason = breakpoint 1.1 self.verify_threads( [ - {}, + self.ANY_THREAD, { "reason": "breakpoint", "text": "breakpoint 1.1", @@ -90,18 +108,26 @@ def test_multiple_threads_sample_breakpoint(self): bugnumber="llvm.org/pr18190 thread states not properly maintained", ) @expectedFailureNetBSD - @skipIfWindows # This is flakey on Windows: llvm.org/pr24668, llvm.org/pr38373 def test_multiple_breakpoints_same_location(self): """ Test stopping at a location that reports multiple overlapping breakpoints. """ program = self.getBuildArtifact("a.out") - self.build_and_launch(program) + launch_seq = self.build_and_launch(program) + self.dap_server.wait_for_event(["initialized"]) line_1 = line_number("main.cpp", "breakpoint") [bp1] = self.set_source_breakpoints("main.cpp", [line_1]) [bp2] = self.set_function_breakpoints(["my_add"]) + self.verify_configuration_done() + response = self.dap_server.receive_response(launch_seq) + self.assertTrue(response["success"]) + + events = self.dap_server.wait_for_stopped() + if len(events) == 1: + # we may not catch both events at the same time if we run with sanitizers + # enabled or on slow or heavily used computer. + events.extend(self.dap_server.wait_for_stopped()) - events = self.continue_to_next_stop() self.assertEqual(len(events), 2, "Expected two stopped events") for event in events: body = event["body"] diff --git a/lldb/test/API/tools/lldb-dap/stopped-events/main.cpp b/lldb/test/API/tools/lldb-dap/stopped-events/main.cpp index 4ad66cac33b08..023a95cd76ada 100644 --- a/lldb/test/API/tools/lldb-dap/stopped-events/main.cpp +++ b/lldb/test/API/tools/lldb-dap/stopped-events/main.cpp @@ -7,7 +7,7 @@ static int my_add(int a, int b) { // breakpoint return a + b; } -int main(int argc, char const *argv[]) { +static void do_test() { // Don't let either thread do anything until they're both ready. pseudo_barrier_init(g_barrier, 2); @@ -24,6 +24,9 @@ int main(int argc, char const *argv[]) { t1.join(); t2.join(); +} +int main(int argc, char const *argv[]) { + do_test(); return 0; }