This one snuck into the previous patch. The test program needs updating if it's ever going to work on Windows.
271 lines
9.7 KiB
Python
271 lines
9.7 KiB
Python
"""
|
|
Test lldb-dap logpoints feature.
|
|
"""
|
|
|
|
|
|
import dap_server
|
|
import shutil
|
|
from lldbsuite.test.decorators import *
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test import lldbutil
|
|
import lldbdap_testcase
|
|
import os
|
|
|
|
|
|
class TestDAP_logpoints(lldbdap_testcase.DAPTestCaseBase):
|
|
def setUp(self):
|
|
lldbdap_testcase.DAPTestCaseBase.setUp(self)
|
|
|
|
self.main_basename = "main-copy.cpp"
|
|
self.main_path = os.path.realpath(self.getBuildArtifact(self.main_basename))
|
|
|
|
@skipIfWindows
|
|
def test_logmessage_basic(self):
|
|
"""Tests breakpoint logmessage basic functionality."""
|
|
before_loop_line = line_number("main.cpp", "// before loop")
|
|
loop_line = line_number("main.cpp", "// break loop")
|
|
after_loop_line = line_number("main.cpp", "// after loop")
|
|
|
|
program = self.getBuildArtifact("a.out")
|
|
self.build_and_launch(program)
|
|
|
|
# Set a breakpoint at a line before loop
|
|
before_loop_breakpoint_ids = self.set_source_breakpoints(
|
|
self.main_path, [before_loop_line]
|
|
)
|
|
self.assertEqual(len(before_loop_breakpoint_ids), 1, "expect one breakpoint")
|
|
|
|
self.dap_server.request_continue()
|
|
|
|
# Verify we hit the breakpoint before loop line
|
|
self.verify_breakpoint_hit(before_loop_breakpoint_ids)
|
|
|
|
# Swallow old console output
|
|
self.get_console()
|
|
|
|
# Set two breakpoints:
|
|
# 1. First at the loop line with logMessage
|
|
# 2. Second guard breakpoint at a line after loop
|
|
logMessage_prefix = "This is log message for { -- "
|
|
logMessage = logMessage_prefix + "{i + 3}, {message}"
|
|
[loop_breakpoint_id, post_loop_breakpoint_id] = self.set_source_breakpoints(
|
|
self.main_path,
|
|
[loop_line, after_loop_line],
|
|
[{"logMessage": logMessage}, {}],
|
|
)
|
|
|
|
# Continue to trigger the breakpoint with log messages
|
|
self.dap_server.request_continue()
|
|
|
|
# Verify we hit the breakpoint after loop line
|
|
self.verify_breakpoint_hit([post_loop_breakpoint_id])
|
|
|
|
output = self.get_console()
|
|
lines = output.splitlines()
|
|
logMessage_output = []
|
|
for line in lines:
|
|
if line.startswith(logMessage_prefix):
|
|
logMessage_output.append(line)
|
|
|
|
# Verify logMessage count
|
|
loop_count = 10
|
|
self.assertEqual(len(logMessage_output), loop_count)
|
|
|
|
message_addr_pattern = r"\b0x[0-9A-Fa-f]+\b"
|
|
message_content = '"Hello from main!"'
|
|
# Verify log message match
|
|
for idx, logMessage_line in enumerate(logMessage_output):
|
|
result = idx + 3
|
|
reg_str = (
|
|
f"{logMessage_prefix}{result}, {message_addr_pattern} {message_content}"
|
|
)
|
|
self.assertRegex(logMessage_line, reg_str)
|
|
|
|
@skipIfWindows
|
|
def test_logmessage_advanced(self):
|
|
"""Tests breakpoint logmessage functionality for complex expression."""
|
|
before_loop_line = line_number("main.cpp", "// before loop")
|
|
loop_line = line_number("main.cpp", "// break loop")
|
|
after_loop_line = line_number("main.cpp", "// after loop")
|
|
|
|
program = self.getBuildArtifact("a.out")
|
|
self.build_and_launch(program)
|
|
|
|
# Set a breakpoint at a line before loop
|
|
before_loop_breakpoint_ids = self.set_source_breakpoints(
|
|
self.main_path, [before_loop_line]
|
|
)
|
|
self.assertEqual(len(before_loop_breakpoint_ids), 1, "expect one breakpoint")
|
|
|
|
self.dap_server.request_continue()
|
|
|
|
# Verify we hit the breakpoint before loop line
|
|
self.verify_breakpoint_hit(before_loop_breakpoint_ids)
|
|
|
|
# Swallow old console output
|
|
self.get_console()
|
|
|
|
# Set two breakpoints:
|
|
# 1. First at the loop line with logMessage
|
|
# 2. Second guard breakpoint at a line after loop
|
|
logMessage_prefix = "This is log message for { -- "
|
|
logMessage = (
|
|
logMessage_prefix
|
|
+ "{int y = 0; if (i % 3 == 0) { y = i + 3;} else {y = i * 3;} y}"
|
|
)
|
|
[loop_breakpoint_id, post_loop_breakpoint_id] = self.set_source_breakpoints(
|
|
self.main_path,
|
|
[loop_line, after_loop_line],
|
|
[{"logMessage": logMessage}, {}],
|
|
)
|
|
|
|
# Continue to trigger the breakpoint with log messages
|
|
self.dap_server.request_continue()
|
|
|
|
# Verify we hit the breakpoint after loop line
|
|
self.verify_breakpoint_hit([post_loop_breakpoint_id])
|
|
|
|
output = self.get_console()
|
|
lines = output.splitlines()
|
|
logMessage_output = []
|
|
for line in lines:
|
|
if line.startswith(logMessage_prefix):
|
|
logMessage_output.append(line)
|
|
|
|
# Verify logMessage count
|
|
loop_count = 10
|
|
self.assertEqual(len(logMessage_output), loop_count)
|
|
|
|
# Verify log message match
|
|
for idx, logMessage_line in enumerate(logMessage_output):
|
|
result = idx + 3 if idx % 3 == 0 else idx * 3
|
|
self.assertEqual(logMessage_line, logMessage_prefix + str(result))
|
|
|
|
@skipIfWindows
|
|
def test_logmessage_format(self):
|
|
"""
|
|
Tests breakpoint logmessage functionality with format.
|
|
"""
|
|
before_loop_line = line_number("main.cpp", "// before loop")
|
|
loop_line = line_number("main.cpp", "// break loop")
|
|
after_loop_line = line_number("main.cpp", "// after loop")
|
|
|
|
program = self.getBuildArtifact("a.out")
|
|
self.build_and_launch(program)
|
|
|
|
# Set a breakpoint at a line before loop
|
|
before_loop_breakpoint_ids = self.set_source_breakpoints(
|
|
self.main_path, [before_loop_line]
|
|
)
|
|
self.assertEqual(len(before_loop_breakpoint_ids), 1, "expect one breakpoint")
|
|
|
|
self.dap_server.request_continue()
|
|
|
|
# Verify we hit the breakpoint before loop line
|
|
self.verify_breakpoint_hit(before_loop_breakpoint_ids)
|
|
|
|
# Swallow old console output
|
|
self.get_console()
|
|
|
|
# Set two breakpoints:
|
|
# 1. First at the loop line with logMessage
|
|
# 2. Second guard breakpoint at a line after loop
|
|
logMessage_prefix = "This is log message for -- "
|
|
logMessage_with_format = "part1\tpart2\bpart3\x64part4"
|
|
logMessage_with_format_raw = r"part1\tpart2\bpart3\x64part4"
|
|
logMessage = logMessage_prefix + logMessage_with_format_raw + "{i - 1}"
|
|
[loop_breakpoint_id, post_loop_breakpoint_id] = self.set_source_breakpoints(
|
|
self.main_path,
|
|
[loop_line, after_loop_line],
|
|
[{"logMessage": logMessage}, {}],
|
|
)
|
|
|
|
# Continue to trigger the breakpoint with log messages
|
|
self.dap_server.request_continue()
|
|
|
|
# Verify we hit the breakpoint after loop line
|
|
self.verify_breakpoint_hit([post_loop_breakpoint_id])
|
|
|
|
output = self.get_console()
|
|
lines = output.splitlines()
|
|
logMessage_output = []
|
|
for line in lines:
|
|
if line.startswith(logMessage_prefix):
|
|
logMessage_output.append(line)
|
|
|
|
# Verify logMessage count
|
|
loop_count = 10
|
|
self.assertEqual(len(logMessage_output), loop_count)
|
|
|
|
# Verify log message match
|
|
for idx, logMessage_line in enumerate(logMessage_output):
|
|
result = idx - 1
|
|
self.assertEqual(
|
|
logMessage_line,
|
|
logMessage_prefix + logMessage_with_format + str(result),
|
|
)
|
|
|
|
@skipIfWindows
|
|
def test_logmessage_format_failure(self):
|
|
"""
|
|
Tests breakpoint logmessage format with parsing failure.
|
|
"""
|
|
before_loop_line = line_number("main.cpp", "// before loop")
|
|
loop_line = line_number("main.cpp", "// break loop")
|
|
after_loop_line = line_number("main.cpp", "// after loop")
|
|
|
|
program = self.getBuildArtifact("a.out")
|
|
self.build_and_launch(program)
|
|
|
|
# Set a breakpoint at a line before loop
|
|
before_loop_breakpoint_ids = self.set_source_breakpoints(
|
|
self.main_path, [before_loop_line]
|
|
)
|
|
self.assertEqual(len(before_loop_breakpoint_ids), 1, "expect one breakpoint")
|
|
|
|
self.dap_server.request_continue()
|
|
|
|
# Verify we hit the breakpoint before loop line
|
|
self.verify_breakpoint_hit(before_loop_breakpoint_ids)
|
|
|
|
# Swallow old console output
|
|
self.get_console()
|
|
|
|
# Set two breakpoints:
|
|
# 1. First at the loop line with logMessage
|
|
# 2. Second guard breakpoint at a line after loop
|
|
logMessage_prefix = "This is log message for -- "
|
|
# log message missing hex number.
|
|
logMessage_with_format_raw = r"part1\x"
|
|
logMessage = logMessage_prefix + logMessage_with_format_raw
|
|
[loop_breakpoint_id, post_loop_breakpoint_id] = self.set_source_breakpoints(
|
|
self.main_path,
|
|
[loop_line, after_loop_line],
|
|
[{"logMessage": logMessage}, {}],
|
|
)
|
|
|
|
# Continue to trigger the breakpoint with log messages
|
|
self.dap_server.request_continue()
|
|
|
|
# Verify we hit logpoint breakpoint if it's format has error.
|
|
self.verify_breakpoint_hit([loop_breakpoint_id])
|
|
|
|
output = self.get_console()
|
|
lines = output.splitlines()
|
|
|
|
failure_prefix = "Log message has error:"
|
|
logMessage_output = []
|
|
logMessage_failure_output = []
|
|
for line in lines:
|
|
if line.startswith(logMessage_prefix):
|
|
logMessage_output.append(line)
|
|
elif line.startswith(failure_prefix):
|
|
logMessage_failure_output.append(line)
|
|
|
|
# Verify logMessage failure message
|
|
self.assertEqual(len(logMessage_failure_output), 1)
|
|
self.assertEqual(
|
|
logMessage_failure_output[0].strip(),
|
|
failure_prefix + " missing hex number following '\\x'",
|
|
)
|