[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`.
This commit is contained in:
@@ -179,9 +179,13 @@ class DebugCommunication(object):
|
||||
@classmethod
|
||||
def validate_response(cls, command, response):
|
||||
if command["command"] != response["command"]:
|
||||
raise ValueError("command mismatch in response")
|
||||
raise ValueError(
|
||||
f"command mismatch in response {command['command']} != {response['command']}"
|
||||
)
|
||||
if command["seq"] != response["request_seq"]:
|
||||
raise ValueError("seq mismatch in response")
|
||||
raise ValueError(
|
||||
f"seq mismatch in response {command['seq']} != {response['request_seq']}"
|
||||
)
|
||||
|
||||
def _read_packet_thread(self):
|
||||
done = False
|
||||
@@ -404,8 +408,8 @@ class DebugCommunication(object):
|
||||
self.reverse_requests.append(response_or_request)
|
||||
if response_or_request["command"] == "runInTerminal":
|
||||
subprocess.Popen(
|
||||
response_or_request["arguments"]["args"],
|
||||
env=response_or_request["arguments"]["env"],
|
||||
response_or_request["arguments"].get("args"),
|
||||
env=response_or_request["arguments"].get("env", {}),
|
||||
)
|
||||
self.send_packet(
|
||||
{
|
||||
|
||||
@@ -2,23 +2,35 @@
|
||||
Test lldb-dap RestartRequest.
|
||||
"""
|
||||
|
||||
import os
|
||||
from lldbsuite.test.decorators import *
|
||||
from lldbsuite.test.lldbtest import line_number
|
||||
from typing import Dict, Any, List
|
||||
|
||||
import lldbdap_testcase
|
||||
from lldbsuite.test.decorators import skipIfWindows, skipIf, skipIfBuildType
|
||||
from lldbsuite.test.lldbtest import line_number
|
||||
|
||||
|
||||
@skipIfBuildType(["debug"])
|
||||
class TestDAP_restart_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
def isTestSupported(self):
|
||||
try:
|
||||
# We skip this test for debug builds because it takes too long
|
||||
# parsing lldb's own debug info. Release builds are fine.
|
||||
# Checking the size of the lldb-dap binary seems to be a decent
|
||||
# proxy for a quick detection. It should be far less than 1 MB in
|
||||
# Release builds.
|
||||
return os.path.getsize(os.environ["LLDBDAP_EXEC"]) < 1000000
|
||||
except:
|
||||
return False
|
||||
def verify_stopped_on_entry(self, stopped_events: List[Dict[str, Any]]):
|
||||
seen_stopped_event = 0
|
||||
for stopped_event in stopped_events:
|
||||
body = stopped_event.get("body")
|
||||
if body is None:
|
||||
continue
|
||||
|
||||
reason = body.get("reason")
|
||||
if reason is None:
|
||||
continue
|
||||
|
||||
self.assertNotEqual(
|
||||
reason,
|
||||
"breakpoint",
|
||||
'verify stop after restart isn\'t "main" breakpoint',
|
||||
)
|
||||
if reason == "entry":
|
||||
seen_stopped_event += 1
|
||||
|
||||
self.assertEqual(seen_stopped_event, 1, "expect only one stopped entry event.")
|
||||
|
||||
@skipIfWindows
|
||||
@skipIf(oslist=["linux"], archs=["arm$"]) # Always times out on buildbot
|
||||
@@ -27,8 +39,6 @@ class TestDAP_restart_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
Test basic restarting functionality when the process is running in
|
||||
a terminal.
|
||||
"""
|
||||
if not self.isTestSupported():
|
||||
return
|
||||
line_A = line_number("main.c", "// breakpoint A")
|
||||
line_B = line_number("main.c", "// breakpoint B")
|
||||
|
||||
@@ -60,33 +70,31 @@ class TestDAP_restart_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
"i != 0 after hitting breakpoint A on restart",
|
||||
)
|
||||
|
||||
# Check breakpoint B
|
||||
self.dap_server.request_continue()
|
||||
self.verify_breakpoint_hit([bp_B])
|
||||
self.assertEqual(
|
||||
int(self.dap_server.get_local_variable_value("i")),
|
||||
1234,
|
||||
"i != 1234 after hitting breakpoint B",
|
||||
)
|
||||
self.continue_to_exit()
|
||||
|
||||
@skipIfWindows
|
||||
@skipIf(oslist=["linux"], archs=["arm$"]) # Always times out on buildbot
|
||||
def test_stopOnEntry(self):
|
||||
"""
|
||||
Check that stopOnEntry works correctly when using runInTerminal.
|
||||
"""
|
||||
if not self.isTestSupported():
|
||||
return
|
||||
line_A = line_number("main.c", "// breakpoint A")
|
||||
line_B = line_number("main.c", "// breakpoint B")
|
||||
|
||||
program = self.getBuildArtifact("a.out")
|
||||
self.build_and_launch(program, runInTerminal=True, stopOnEntry=True)
|
||||
[bp_main] = self.set_function_breakpoints(["main"])
|
||||
|
||||
# When using stopOnEntry, configurationDone doesn't result in a running
|
||||
# process, we should immediately get a stopped event instead.
|
||||
self.dap_server.request_continue() # sends configuration done
|
||||
stopped_events = self.dap_server.wait_for_stopped()
|
||||
# We should be stopped at the entry point.
|
||||
for stopped_event in stopped_events:
|
||||
if "body" in stopped_event:
|
||||
body = stopped_event["body"]
|
||||
if "reason" in body:
|
||||
reason = body["reason"]
|
||||
self.assertNotEqual(
|
||||
reason, "breakpoint", "verify stop isn't a breakpoint"
|
||||
)
|
||||
self.assertGreaterEqual(len(stopped_events), 0, "expect stopped events")
|
||||
self.verify_stopped_on_entry(stopped_events)
|
||||
|
||||
# Then, if we continue, we should hit the breakpoint at main.
|
||||
self.dap_server.request_continue()
|
||||
@@ -95,14 +103,11 @@ class TestDAP_restart_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
# Restart and check that we still get a stopped event before reaching
|
||||
# main.
|
||||
self.dap_server.request_restart()
|
||||
stopped_events = self.dap_server.wait_for_stopped()
|
||||
for stopped_event in stopped_events:
|
||||
if "body" in stopped_event:
|
||||
body = stopped_event["body"]
|
||||
if "reason" in body:
|
||||
reason = body["reason"]
|
||||
self.assertNotEqual(
|
||||
reason,
|
||||
"breakpoint",
|
||||
'verify stop after restart isn\'t "main" breakpoint',
|
||||
)
|
||||
stopped_events = self.dap_server.wait_for_stopped(timeout=20)
|
||||
self.verify_stopped_on_entry(stopped_events)
|
||||
|
||||
# continue to main
|
||||
self.dap_server.request_continue()
|
||||
self.verify_breakpoint_hit([bp_main])
|
||||
|
||||
self.continue_to_exit()
|
||||
|
||||
@@ -2,52 +2,33 @@
|
||||
Test lldb-dap runInTerminal reverse request
|
||||
"""
|
||||
|
||||
|
||||
import dap_server
|
||||
from lldbsuite.test.decorators import *
|
||||
from lldbsuite.test.lldbtest import *
|
||||
from lldbsuite.test import lldbutil
|
||||
from lldbsuite.test.decorators import skipIfBuildType, skipIfWindows, skipIf, no_match
|
||||
from lldbsuite.test.lldbtest import line_number
|
||||
import lldbdap_testcase
|
||||
import time
|
||||
import os
|
||||
import subprocess
|
||||
import shutil
|
||||
import json
|
||||
from threading import Thread
|
||||
|
||||
|
||||
@skipIfBuildType(["debug"])
|
||||
class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
def readPidMessage(self, fifo_file):
|
||||
def read_pid_message(self, fifo_file):
|
||||
with open(fifo_file, "r") as file:
|
||||
self.assertIn("pid", file.readline())
|
||||
|
||||
def sendDidAttachMessage(self, fifo_file):
|
||||
@staticmethod
|
||||
def send_did_attach_message(fifo_file):
|
||||
with open(fifo_file, "w") as file:
|
||||
file.write(json.dumps({"kind": "didAttach"}) + "\n")
|
||||
|
||||
def readErrorMessage(self, fifo_file):
|
||||
@staticmethod
|
||||
def read_error_message(fifo_file):
|
||||
with open(fifo_file, "r") as file:
|
||||
return file.readline()
|
||||
|
||||
def isTestSupported(self):
|
||||
# For some strange reason, this test fails on python3.6
|
||||
if not (sys.version_info.major == 3 and sys.version_info.minor >= 7):
|
||||
return False
|
||||
try:
|
||||
# We skip this test for debug builds because it takes too long parsing lldb's own
|
||||
# debug info. Release builds are fine.
|
||||
# Checking the size of the lldb-dap binary seems to be a decent proxy for a quick
|
||||
# detection. It should be far less than 1 MB in Release builds.
|
||||
if os.path.getsize(os.environ["LLDBDAP_EXEC"]) < 1000000:
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
@skipIfWindows
|
||||
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
|
||||
def test_runInTerminal(self):
|
||||
if not self.isTestSupported():
|
||||
return
|
||||
"""
|
||||
Tests the "runInTerminal" reverse request. It makes sure that the IDE can
|
||||
launch the inferior with the correct environment variables and arguments.
|
||||
@@ -77,7 +58,7 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
|
||||
# We verify we actually stopped inside the loop
|
||||
counter = int(self.dap_server.get_local_variable_value("counter"))
|
||||
self.assertGreater(counter, 0)
|
||||
self.assertEqual(counter, 1)
|
||||
|
||||
# We verify we were able to set the launch arguments
|
||||
argc = int(self.dap_server.get_local_variable_value("argc"))
|
||||
@@ -90,10 +71,10 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
env = self.dap_server.request_evaluate("foo")["body"]["result"]
|
||||
self.assertIn("bar", env)
|
||||
|
||||
self.continue_to_exit()
|
||||
|
||||
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
|
||||
def test_runInTerminalWithObjectEnv(self):
|
||||
if not self.isTestSupported():
|
||||
return
|
||||
"""
|
||||
Tests the "runInTerminal" reverse request. It makes sure that the IDE can
|
||||
launch the inferior with the correct environment variables using an object.
|
||||
@@ -113,11 +94,11 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
self.assertIn("FOO", request_envs)
|
||||
self.assertEqual("BAR", request_envs["FOO"])
|
||||
|
||||
self.continue_to_exit()
|
||||
|
||||
@skipIfWindows
|
||||
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
|
||||
def test_runInTerminalInvalidTarget(self):
|
||||
if not self.isTestSupported():
|
||||
return
|
||||
self.build_and_create_debug_adapter()
|
||||
response = self.launch(
|
||||
"INVALIDPROGRAM",
|
||||
@@ -135,8 +116,6 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
@skipIfWindows
|
||||
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
|
||||
def test_missingArgInRunInTerminalLauncher(self):
|
||||
if not self.isTestSupported():
|
||||
return
|
||||
proc = subprocess.run(
|
||||
[self.lldbDAPExec, "--launch-target", "INVALIDPROGRAM"],
|
||||
capture_output=True,
|
||||
@@ -150,8 +129,6 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
@skipIfWindows
|
||||
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
|
||||
def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self):
|
||||
if not self.isTestSupported():
|
||||
return
|
||||
comm_file = os.path.join(self.getBuildDir(), "comm-file")
|
||||
os.mkfifo(comm_file)
|
||||
|
||||
@@ -167,9 +144,9 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
|
||||
self.readPidMessage(comm_file)
|
||||
self.sendDidAttachMessage(comm_file)
|
||||
self.assertIn("No such file or directory", self.readErrorMessage(comm_file))
|
||||
self.read_pid_message(comm_file)
|
||||
self.send_did_attach_message(comm_file)
|
||||
self.assertIn("No such file or directory", self.read_error_message(comm_file))
|
||||
|
||||
_, stderr = proc.communicate()
|
||||
self.assertIn("No such file or directory", stderr)
|
||||
@@ -177,8 +154,6 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
@skipIfWindows
|
||||
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
|
||||
def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self):
|
||||
if not self.isTestSupported():
|
||||
return
|
||||
comm_file = os.path.join(self.getBuildDir(), "comm-file")
|
||||
os.mkfifo(comm_file)
|
||||
|
||||
@@ -195,8 +170,8 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
|
||||
self.readPidMessage(comm_file)
|
||||
self.sendDidAttachMessage(comm_file)
|
||||
self.read_pid_message(comm_file)
|
||||
self.send_did_attach_message(comm_file)
|
||||
|
||||
stdout, _ = proc.communicate()
|
||||
self.assertIn("foo", stdout)
|
||||
@@ -204,8 +179,6 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
@skipIfWindows
|
||||
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
|
||||
def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self):
|
||||
if not self.isTestSupported():
|
||||
return
|
||||
comm_file = os.path.join(self.getBuildDir(), "comm-file")
|
||||
os.mkfifo(comm_file)
|
||||
|
||||
@@ -216,8 +189,8 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
env={**os.environ, "FOO": "BAR"},
|
||||
)
|
||||
|
||||
self.readPidMessage(comm_file)
|
||||
self.sendDidAttachMessage(comm_file)
|
||||
self.read_pid_message(comm_file)
|
||||
self.send_did_attach_message(comm_file)
|
||||
|
||||
stdout, _ = proc.communicate()
|
||||
self.assertIn("FOO=BAR", stdout)
|
||||
@@ -225,8 +198,6 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
@skipIfWindows
|
||||
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
|
||||
def test_NonAttachedRunInTerminalLauncher(self):
|
||||
if not self.isTestSupported():
|
||||
return
|
||||
comm_file = os.path.join(self.getBuildDir(), "comm-file")
|
||||
os.mkfifo(comm_file)
|
||||
|
||||
@@ -244,7 +215,7 @@ class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
|
||||
env={**os.environ, "LLDB_DAP_RIT_TIMEOUT_IN_MS": "1000"},
|
||||
)
|
||||
|
||||
self.readPidMessage(comm_file)
|
||||
self.read_pid_message(comm_file)
|
||||
|
||||
_, stderr = proc.communicate()
|
||||
self.assertIn("Timed out trying to get messages from the debug adapter", stderr)
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const char *foo = getenv("FOO");
|
||||
for (int counter = 1;; counter++) {
|
||||
sleep(1); // breakpoint
|
||||
}
|
||||
return 0;
|
||||
int counter = 1;
|
||||
|
||||
return 0; // breakpoint
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user