1"""
2Test lldb-vscode setBreakpoints request
3"""
4
5
6import unittest2
7import vscode
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11import lldbvscode_testcase
12import os
13
14
15class TestVSCode_stackTrace(lldbvscode_testcase.VSCodeTestCaseBase):
16
17    mydir = TestBase.compute_mydir(__file__)
18    name_key_path = ['name']
19    source_key_path = ['source', 'path']
20    line_key_path = ['line']
21
22    def verify_stackFrames(self, start_idx, stackFrames):
23        frame_idx = start_idx
24        for stackFrame in stackFrames:
25            # Don't care about frame above main
26            if frame_idx > 20:
27                return
28            self.verify_stackFrame(frame_idx, stackFrame)
29            frame_idx += 1
30
31    def verify_stackFrame(self, frame_idx, stackFrame):
32        frame_name = self.get_dict_value(stackFrame, self.name_key_path)
33        frame_source = self.get_dict_value(stackFrame, self.source_key_path)
34        frame_line = self.get_dict_value(stackFrame, self.line_key_path)
35        if frame_idx == 0:
36            expected_line = self.recurse_end
37            expected_name = 'recurse'
38        elif frame_idx < 20:
39            expected_line = self.recurse_call
40            expected_name = 'recurse'
41        else:
42            expected_line = self.recurse_invocation
43            expected_name = 'main'
44        self.assertEquals(frame_name, expected_name,
45                        'frame #%i name "%s" == "%s"' % (
46                            frame_idx, frame_name, expected_name))
47        self.assertEquals(frame_source, self.source_path,
48                        'frame #%i source "%s" == "%s"' % (
49                            frame_idx, frame_source, self.source_path))
50        self.assertEquals(frame_line, expected_line,
51                        'frame #%i line %i == %i' % (frame_idx, frame_line,
52                                                     expected_line))
53
54    @skipIfWindows
55    def test_stackTrace(self):
56        '''
57            Tests the 'stackTrace' packet and all its variants.
58        '''
59        program = self.getBuildArtifact("a.out")
60        self.build_and_launch(program)
61        source = 'main.c'
62        self.source_path = os.path.join(os.getcwd(), source)
63        self.recurse_end = line_number(source, 'recurse end')
64        self.recurse_call = line_number(source, 'recurse call')
65        self.recurse_invocation = line_number(source, 'recurse invocation')
66
67        lines = [self.recurse_end]
68
69        # Set breakoint at a point of deepest recuusion
70        breakpoint_ids = self.set_source_breakpoints(source, lines)
71        self.assertEquals(len(breakpoint_ids), len(lines),
72                        "expect correct number of breakpoints")
73
74        self.continue_to_breakpoints(breakpoint_ids)
75        startFrame = 0
76        # Verify we get all stack frames with no arguments
77        (stackFrames, totalFrames) = self.get_stackFrames_and_totalFramesCount()
78        frameCount = len(stackFrames)
79        self.assertTrue(frameCount >= 20,
80                        'verify we get at least 20 frames for all frames')
81        self.assertEquals(totalFrames, frameCount,
82                        'verify we get correct value for totalFrames count')
83        self.verify_stackFrames(startFrame, stackFrames)
84
85        # Verify all stack frames by specifying startFrame = 0 and levels not
86        # specified
87        stackFrames = self.get_stackFrames(startFrame=startFrame)
88        self.assertEquals(frameCount, len(stackFrames),
89                        ('verify same number of frames with startFrame=%i') % (
90                            startFrame))
91        self.verify_stackFrames(startFrame, stackFrames)
92
93        # Verify all stack frames by specifying startFrame = 0 and levels = 0
94        levels = 0
95        stackFrames = self.get_stackFrames(startFrame=startFrame,
96                                           levels=levels)
97        self.assertEquals(frameCount, len(stackFrames),
98                        ('verify same number of frames with startFrame=%i and'
99                         ' levels=%i') % (startFrame, levels))
100        self.verify_stackFrames(startFrame, stackFrames)
101
102        # Get only the first stack frame by sepcifying startFrame = 0 and
103        # levels = 1
104        levels = 1
105        stackFrames = self.get_stackFrames(startFrame=startFrame,
106                                           levels=levels)
107        self.assertEquals(levels, len(stackFrames),
108                        ('verify one frame with startFrame=%i and'
109                         ' levels=%i') % (startFrame, levels))
110        self.verify_stackFrames(startFrame, stackFrames)
111
112        # Get only the first 3 stack frames by sepcifying startFrame = 0 and
113        # levels = 3
114        levels = 3
115        stackFrames = self.get_stackFrames(startFrame=startFrame,
116                                           levels=levels)
117        self.assertEquals(levels, len(stackFrames),
118                        ('verify %i frames with startFrame=%i and'
119                         ' levels=%i') % (levels, startFrame, levels))
120        self.verify_stackFrames(startFrame, stackFrames)
121
122        # Get only the first 15 stack frames by sepcifying startFrame = 5 and
123        # levels = 16
124        startFrame = 5
125        levels = 16
126        stackFrames = self.get_stackFrames(startFrame=startFrame,
127                                           levels=levels)
128        self.assertEquals(levels, len(stackFrames),
129                        ('verify %i frames with startFrame=%i and'
130                         ' levels=%i') % (levels, startFrame, levels))
131        self.verify_stackFrames(startFrame, stackFrames)
132
133        # Verify we cap things correctly when we ask for too many frames
134        startFrame = 5
135        levels = 1000
136        (stackFrames, totalFrames) = self.get_stackFrames_and_totalFramesCount(
137                                            startFrame=startFrame,
138                                            levels=levels)
139        self.assertEquals(len(stackFrames), frameCount - startFrame,
140                        ('verify less than 1000 frames with startFrame=%i and'
141                         ' levels=%i') % (startFrame, levels))
142        self.assertEquals(totalFrames, frameCount,
143                        'verify we get correct value for totalFrames count '
144                        'when requested frames not from 0 index')
145        self.verify_stackFrames(startFrame, stackFrames)
146
147        # Verify level=0 works with non-zerp start frame
148        startFrame = 5
149        levels = 0
150        stackFrames = self.get_stackFrames(startFrame=startFrame,
151                                           levels=levels)
152        self.assertEquals(len(stackFrames), frameCount - startFrame,
153                        ('verify less than 1000 frames with startFrame=%i and'
154                         ' levels=%i') % (startFrame, levels))
155        self.verify_stackFrames(startFrame, stackFrames)
156
157        # Verify we get not frames when startFrame is too high
158        startFrame = 1000
159        levels = 1
160        stackFrames = self.get_stackFrames(startFrame=startFrame,
161                                           levels=levels)
162        self.assertEquals(0, len(stackFrames),
163                        'verify zero frames with startFrame out of bounds')
164