| """ |
| Test lldb-vscode logpoints feature. |
| """ |
| |
| |
| import vscode |
| import shutil |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test import lldbutil |
| import lldbvscode_testcase |
| import os |
| |
| |
| class TestVSCode_logpoints(lldbvscode_testcase.VSCodeTestCaseBase): |
| def setUp(self): |
| lldbvscode_testcase.VSCodeTestCaseBase.setUp(self) |
| |
| self.main_basename = "main-copy.cpp" |
| self.main_path = os.path.realpath(self.getBuildArtifact(self.main_basename)) |
| |
| @skipIfWindows |
| @skipIfRemote |
| 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.assertEquals(len(before_loop_breakpoint_ids), 1, "expect one breakpoint") |
| |
| self.vscode.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}" |
| [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.vscode.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 |
| self.assertEqual(logMessage_line, logMessage_prefix + str(result)) |
| |
| @skipIfWindows |
| @skipIfRemote |
| 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.assertEquals(len(before_loop_breakpoint_ids), 1, "expect one breakpoint") |
| |
| self.vscode.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.vscode.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 |
| @skipIfRemote |
| 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.assertEquals(len(before_loop_breakpoint_ids), 1, "expect one breakpoint") |
| |
| self.vscode.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.vscode.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 |
| @skipIfRemote |
| 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.assertEquals(len(before_loop_breakpoint_ids), 1, "expect one breakpoint") |
| |
| self.vscode.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.vscode.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'", |
| ) |