1"""
2Test lldb-vscode logpoints feature.
3"""
4
5
6import unittest2
7import vscode
8import shutil
9from lldbsuite.test.decorators import *
10from lldbsuite.test.lldbtest import *
11from lldbsuite.test import lldbutil
12import lldbvscode_testcase
13import os
14
15
16class TestVSCode_logpoints(lldbvscode_testcase.VSCodeTestCaseBase):
17
18    mydir = TestBase.compute_mydir(__file__)
19
20    def setUp(self):
21        lldbvscode_testcase.VSCodeTestCaseBase.setUp(self)
22
23        self.main_basename = 'main-copy.cpp'
24        self.main_path = os.path.realpath(self.getBuildArtifact(self.main_basename))
25
26    @skipIfWindows
27    @skipIfRemote
28    def test_logmessage_basic(self):
29        '''Tests breakpoint logmessage basic functionality.'''
30        before_loop_line = line_number('main.cpp', '// before loop')
31        loop_line = line_number('main.cpp', '// break loop')
32        after_loop_line = line_number('main.cpp', '// after loop')
33
34        program = self.getBuildArtifact("a.out")
35        self.build_and_launch(program)
36
37        # Set a breakpoint at a line before loop
38        before_loop_breakpoint_ids = self.set_source_breakpoints(
39            self.main_path,
40            [before_loop_line])
41        self.assertEquals(len(before_loop_breakpoint_ids), 1, "expect one breakpoint")
42
43        self.vscode.request_continue()
44
45        # Verify we hit the breakpoint before loop line
46        self.verify_breakpoint_hit(before_loop_breakpoint_ids)
47
48        # Swallow old console output
49        self.get_console()
50
51        # Set two breakpoints:
52        # 1. First at the loop line with logMessage
53        # 2. Second guard breakpoint at a line after loop
54        logMessage_prefix = "This is log message for { -- "
55        # Trailing newline is needed for splitlines()
56        logMessage = logMessage_prefix + "{i + 3}\n"
57        [loop_breakpoint_id, post_loop_breakpoint_id] = self.set_source_breakpoints(
58            self.main_path,
59            [loop_line, after_loop_line],
60            [{'logMessage': logMessage}, {}]
61        )
62
63        # Continue to trigger the breakpoint with log messages
64        self.vscode.request_continue()
65
66        # Verify we hit the breakpoint after loop line
67        self.verify_breakpoint_hit([post_loop_breakpoint_id])
68
69        output = self.get_console()
70        lines = output.splitlines()
71        logMessage_output = []
72        for line in lines:
73            if line.startswith(logMessage_prefix):
74                logMessage_output.append(line)
75
76        # Verify logMessage count
77        loop_count = 10
78        self.assertEqual(len(logMessage_output), loop_count)
79
80        # Verify log message match
81        for idx, logMessage_line in enumerate(logMessage_output):
82            result = idx + 3
83            self.assertEqual(logMessage_line, logMessage_prefix + str(result))
84
85
86    @skipIfWindows
87    @skipIfRemote
88    def test_logmessage_advanced(self):
89        '''Tests breakpoint logmessage functionality for complex expression.'''
90        before_loop_line = line_number('main.cpp', '// before loop')
91        loop_line = line_number('main.cpp', '// break loop')
92        after_loop_line = line_number('main.cpp', '// after loop')
93
94        program = self.getBuildArtifact("a.out")
95        self.build_and_launch(program)
96
97        # Set a breakpoint at a line before loop
98        before_loop_breakpoint_ids = self.set_source_breakpoints(
99            self.main_path,
100            [before_loop_line])
101        self.assertEquals(len(before_loop_breakpoint_ids), 1, "expect one breakpoint")
102
103        self.vscode.request_continue()
104
105        # Verify we hit the breakpoint before loop line
106        self.verify_breakpoint_hit(before_loop_breakpoint_ids)
107
108        # Swallow old console output
109        self.get_console()
110
111        # Set two breakpoints:
112        # 1. First at the loop line with logMessage
113        # 2. Second guard breakpoint at a line after loop
114        logMessage_prefix = "This is log message for { -- "
115        # Trailing newline is needed for splitlines()
116        logMessage = logMessage_prefix + "{int y = 0; if (i % 3 == 0) { y = i + 3;} else {y = i * 3;} y}\n"
117        [loop_breakpoint_id, post_loop_breakpoint_id] = self.set_source_breakpoints(
118            self.main_path,
119            [loop_line, after_loop_line],
120            [{'logMessage': logMessage}, {}]
121        )
122
123        # Continue to trigger the breakpoint with log messages
124        self.vscode.request_continue()
125
126        # Verify we hit the breakpoint after loop line
127        self.verify_breakpoint_hit([post_loop_breakpoint_id])
128
129        output = self.get_console()
130        lines = output.splitlines()
131        logMessage_output = []
132        for line in lines:
133            if line.startswith(logMessage_prefix):
134                logMessage_output.append(line)
135
136        # Verify logMessage count
137        loop_count = 10
138        self.assertEqual(len(logMessage_output), loop_count)
139
140        # Verify log message match
141        for idx, logMessage_line in enumerate(logMessage_output):
142            result = idx + 3 if idx % 3 == 0 else idx * 3
143            self.assertEqual(logMessage_line, logMessage_prefix + str(result))
144