Skip to content

Commit 5c22793

Browse files
authored
[lldb-dap][test] Refactor runInTerminal Tests. (#144954)
Replace `isTestSupported` function with `skipIfBuildType` annotation. Test that uses the `IsTestSupported` function are no longer run, as the size of lldb-dap binary is now more than `1mb`. Update the broken test. Fixes #108621 We could probably check if the test now passes on `linux arm` since it was disabled because it timed out. I experienced the timeout after replacing the `IsTestSupported` with `skipIfBuildType`.
1 parent e7c1da7 commit 5c22793

File tree

4 files changed

+78
-99
lines changed

4 files changed

+78
-99
lines changed

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,13 @@ def encode_content(cls, s: str) -> bytes:
179179
@classmethod
180180
def validate_response(cls, command, response):
181181
if command["command"] != response["command"]:
182-
raise ValueError("command mismatch in response")
182+
raise ValueError(
183+
f"command mismatch in response {command['command']} != {response['command']}"
184+
)
183185
if command["seq"] != response["request_seq"]:
184-
raise ValueError("seq mismatch in response")
186+
raise ValueError(
187+
f"seq mismatch in response {command['seq']} != {response['request_seq']}"
188+
)
185189

186190
def _read_packet_thread(self):
187191
done = False
@@ -404,8 +408,8 @@ def send_recv(self, command):
404408
self.reverse_requests.append(response_or_request)
405409
if response_or_request["command"] == "runInTerminal":
406410
subprocess.Popen(
407-
response_or_request["arguments"]["args"],
408-
env=response_or_request["arguments"]["env"],
411+
response_or_request["arguments"].get("args"),
412+
env=response_or_request["arguments"].get("env", {}),
409413
)
410414
self.send_packet(
411415
{

lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,35 @@
22
Test lldb-dap RestartRequest.
33
"""
44

5-
import os
6-
from lldbsuite.test.decorators import *
7-
from lldbsuite.test.lldbtest import line_number
5+
from typing import Dict, Any, List
6+
87
import lldbdap_testcase
8+
from lldbsuite.test.decorators import skipIfWindows, skipIf, skipIfBuildType
9+
from lldbsuite.test.lldbtest import line_number
910

1011

12+
@skipIfBuildType(["debug"])
1113
class TestDAP_restart_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
12-
def isTestSupported(self):
13-
try:
14-
# We skip this test for debug builds because it takes too long
15-
# parsing lldb's own debug info. Release builds are fine.
16-
# Checking the size of the lldb-dap binary seems to be a decent
17-
# proxy for a quick detection. It should be far less than 1 MB in
18-
# Release builds.
19-
return os.path.getsize(os.environ["LLDBDAP_EXEC"]) < 1000000
20-
except:
21-
return False
14+
def verify_stopped_on_entry(self, stopped_events: List[Dict[str, Any]]):
15+
seen_stopped_event = 0
16+
for stopped_event in stopped_events:
17+
body = stopped_event.get("body")
18+
if body is None:
19+
continue
20+
21+
reason = body.get("reason")
22+
if reason is None:
23+
continue
24+
25+
self.assertNotEqual(
26+
reason,
27+
"breakpoint",
28+
'verify stop after restart isn\'t "main" breakpoint',
29+
)
30+
if reason == "entry":
31+
seen_stopped_event += 1
32+
33+
self.assertEqual(seen_stopped_event, 1, "expect only one stopped entry event.")
2234

2335
@skipIfWindows
2436
@skipIf(oslist=["linux"], archs=["arm$"]) # Always times out on buildbot
@@ -27,8 +39,6 @@ def test_basic_functionality(self):
2739
Test basic restarting functionality when the process is running in
2840
a terminal.
2941
"""
30-
if not self.isTestSupported():
31-
return
3242
line_A = line_number("main.c", "// breakpoint A")
3343
line_B = line_number("main.c", "// breakpoint B")
3444

@@ -60,33 +70,31 @@ def test_basic_functionality(self):
6070
"i != 0 after hitting breakpoint A on restart",
6171
)
6272

73+
# Check breakpoint B
74+
self.dap_server.request_continue()
75+
self.verify_breakpoint_hit([bp_B])
76+
self.assertEqual(
77+
int(self.dap_server.get_local_variable_value("i")),
78+
1234,
79+
"i != 1234 after hitting breakpoint B",
80+
)
81+
self.continue_to_exit()
82+
6383
@skipIfWindows
6484
@skipIf(oslist=["linux"], archs=["arm$"]) # Always times out on buildbot
6585
def test_stopOnEntry(self):
6686
"""
6787
Check that stopOnEntry works correctly when using runInTerminal.
6888
"""
69-
if not self.isTestSupported():
70-
return
71-
line_A = line_number("main.c", "// breakpoint A")
72-
line_B = line_number("main.c", "// breakpoint B")
73-
7489
program = self.getBuildArtifact("a.out")
7590
self.build_and_launch(program, runInTerminal=True, stopOnEntry=True)
7691
[bp_main] = self.set_function_breakpoints(["main"])
7792

78-
# When using stopOnEntry, configurationDone doesn't result in a running
79-
# process, we should immediately get a stopped event instead.
93+
self.dap_server.request_continue() # sends configuration done
8094
stopped_events = self.dap_server.wait_for_stopped()
8195
# We should be stopped at the entry point.
82-
for stopped_event in stopped_events:
83-
if "body" in stopped_event:
84-
body = stopped_event["body"]
85-
if "reason" in body:
86-
reason = body["reason"]
87-
self.assertNotEqual(
88-
reason, "breakpoint", "verify stop isn't a breakpoint"
89-
)
96+
self.assertGreaterEqual(len(stopped_events), 0, "expect stopped events")
97+
self.verify_stopped_on_entry(stopped_events)
9098

9199
# Then, if we continue, we should hit the breakpoint at main.
92100
self.dap_server.request_continue()
@@ -95,14 +103,11 @@ def test_stopOnEntry(self):
95103
# Restart and check that we still get a stopped event before reaching
96104
# main.
97105
self.dap_server.request_restart()
98-
stopped_events = self.dap_server.wait_for_stopped()
99-
for stopped_event in stopped_events:
100-
if "body" in stopped_event:
101-
body = stopped_event["body"]
102-
if "reason" in body:
103-
reason = body["reason"]
104-
self.assertNotEqual(
105-
reason,
106-
"breakpoint",
107-
'verify stop after restart isn\'t "main" breakpoint',
108-
)
106+
stopped_events = self.dap_server.wait_for_stopped(timeout=20)
107+
self.verify_stopped_on_entry(stopped_events)
108+
109+
# continue to main
110+
self.dap_server.request_continue()
111+
self.verify_breakpoint_hit([bp_main])
112+
113+
self.continue_to_exit()

lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py

Lines changed: 21 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,33 @@
22
Test lldb-dap runInTerminal reverse request
33
"""
44

5-
6-
import dap_server
7-
from lldbsuite.test.decorators import *
8-
from lldbsuite.test.lldbtest import *
9-
from lldbsuite.test import lldbutil
5+
from lldbsuite.test.decorators import skipIfBuildType, skipIfWindows, skipIf, no_match
6+
from lldbsuite.test.lldbtest import line_number
107
import lldbdap_testcase
11-
import time
128
import os
139
import subprocess
14-
import shutil
1510
import json
16-
from threading import Thread
1711

1812

13+
@skipIfBuildType(["debug"])
1914
class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
20-
def readPidMessage(self, fifo_file):
15+
def read_pid_message(self, fifo_file):
2116
with open(fifo_file, "r") as file:
2217
self.assertIn("pid", file.readline())
2318

24-
def sendDidAttachMessage(self, fifo_file):
19+
@staticmethod
20+
def send_did_attach_message(fifo_file):
2521
with open(fifo_file, "w") as file:
2622
file.write(json.dumps({"kind": "didAttach"}) + "\n")
2723

28-
def readErrorMessage(self, fifo_file):
24+
@staticmethod
25+
def read_error_message(fifo_file):
2926
with open(fifo_file, "r") as file:
3027
return file.readline()
3128

32-
def isTestSupported(self):
33-
# For some strange reason, this test fails on python3.6
34-
if not (sys.version_info.major == 3 and sys.version_info.minor >= 7):
35-
return False
36-
try:
37-
# We skip this test for debug builds because it takes too long parsing lldb's own
38-
# debug info. Release builds are fine.
39-
# Checking the size of the lldb-dap binary seems to be a decent proxy for a quick
40-
# detection. It should be far less than 1 MB in Release builds.
41-
if os.path.getsize(os.environ["LLDBDAP_EXEC"]) < 1000000:
42-
return True
43-
except:
44-
return False
45-
4629
@skipIfWindows
4730
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
4831
def test_runInTerminal(self):
49-
if not self.isTestSupported():
50-
return
5132
"""
5233
Tests the "runInTerminal" reverse request. It makes sure that the IDE can
5334
launch the inferior with the correct environment variables and arguments.
@@ -77,7 +58,7 @@ def test_runInTerminal(self):
7758

7859
# We verify we actually stopped inside the loop
7960
counter = int(self.dap_server.get_local_variable_value("counter"))
80-
self.assertGreater(counter, 0)
61+
self.assertEqual(counter, 1)
8162

8263
# We verify we were able to set the launch arguments
8364
argc = int(self.dap_server.get_local_variable_value("argc"))
@@ -90,10 +71,10 @@ def test_runInTerminal(self):
9071
env = self.dap_server.request_evaluate("foo")["body"]["result"]
9172
self.assertIn("bar", env)
9273

74+
self.continue_to_exit()
75+
9376
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
9477
def test_runInTerminalWithObjectEnv(self):
95-
if not self.isTestSupported():
96-
return
9778
"""
9879
Tests the "runInTerminal" reverse request. It makes sure that the IDE can
9980
launch the inferior with the correct environment variables using an object.
@@ -113,11 +94,11 @@ def test_runInTerminalWithObjectEnv(self):
11394
self.assertIn("FOO", request_envs)
11495
self.assertEqual("BAR", request_envs["FOO"])
11596

97+
self.continue_to_exit()
98+
11699
@skipIfWindows
117100
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
118101
def test_runInTerminalInvalidTarget(self):
119-
if not self.isTestSupported():
120-
return
121102
self.build_and_create_debug_adapter()
122103
response = self.launch(
123104
"INVALIDPROGRAM",
@@ -135,8 +116,6 @@ def test_runInTerminalInvalidTarget(self):
135116
@skipIfWindows
136117
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
137118
def test_missingArgInRunInTerminalLauncher(self):
138-
if not self.isTestSupported():
139-
return
140119
proc = subprocess.run(
141120
[self.lldbDAPExec, "--launch-target", "INVALIDPROGRAM"],
142121
capture_output=True,
@@ -150,8 +129,6 @@ def test_missingArgInRunInTerminalLauncher(self):
150129
@skipIfWindows
151130
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
152131
def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self):
153-
if not self.isTestSupported():
154-
return
155132
comm_file = os.path.join(self.getBuildDir(), "comm-file")
156133
os.mkfifo(comm_file)
157134

@@ -167,18 +144,16 @@ def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self):
167144
stderr=subprocess.PIPE,
168145
)
169146

170-
self.readPidMessage(comm_file)
171-
self.sendDidAttachMessage(comm_file)
172-
self.assertIn("No such file or directory", self.readErrorMessage(comm_file))
147+
self.read_pid_message(comm_file)
148+
self.send_did_attach_message(comm_file)
149+
self.assertIn("No such file or directory", self.read_error_message(comm_file))
173150

174151
_, stderr = proc.communicate()
175152
self.assertIn("No such file or directory", stderr)
176153

177154
@skipIfWindows
178155
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
179156
def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self):
180-
if not self.isTestSupported():
181-
return
182157
comm_file = os.path.join(self.getBuildDir(), "comm-file")
183158
os.mkfifo(comm_file)
184159

@@ -195,17 +170,15 @@ def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self):
195170
stdout=subprocess.PIPE,
196171
)
197172

198-
self.readPidMessage(comm_file)
199-
self.sendDidAttachMessage(comm_file)
173+
self.read_pid_message(comm_file)
174+
self.send_did_attach_message(comm_file)
200175

201176
stdout, _ = proc.communicate()
202177
self.assertIn("foo", stdout)
203178

204179
@skipIfWindows
205180
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
206181
def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self):
207-
if not self.isTestSupported():
208-
return
209182
comm_file = os.path.join(self.getBuildDir(), "comm-file")
210183
os.mkfifo(comm_file)
211184

@@ -216,17 +189,15 @@ def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self):
216189
env={**os.environ, "FOO": "BAR"},
217190
)
218191

219-
self.readPidMessage(comm_file)
220-
self.sendDidAttachMessage(comm_file)
192+
self.read_pid_message(comm_file)
193+
self.send_did_attach_message(comm_file)
221194

222195
stdout, _ = proc.communicate()
223196
self.assertIn("FOO=BAR", stdout)
224197

225198
@skipIfWindows
226199
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
227200
def test_NonAttachedRunInTerminalLauncher(self):
228-
if not self.isTestSupported():
229-
return
230201
comm_file = os.path.join(self.getBuildDir(), "comm-file")
231202
os.mkfifo(comm_file)
232203

@@ -244,7 +215,7 @@ def test_NonAttachedRunInTerminalLauncher(self):
244215
env={**os.environ, "LLDB_DAP_RIT_TIMEOUT_IN_MS": "1000"},
245216
)
246217

247-
self.readPidMessage(comm_file)
218+
self.read_pid_message(comm_file)
248219

249220
_, stderr = proc.communicate()
250221
self.assertIn("Timed out trying to get messages from the debug adapter", stderr)

lldb/test/API/tools/lldb-dap/runInTerminal/main.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44

55
int main(int argc, char *argv[]) {
66
const char *foo = getenv("FOO");
7-
for (int counter = 1;; counter++) {
8-
sleep(1); // breakpoint
9-
}
10-
return 0;
7+
int counter = 1;
8+
9+
return 0; // breakpoint
1110
}

0 commit comments

Comments
 (0)