1"""
2Test lldb-vscode setBreakpoints request
3"""
4
5from __future__ import print_function
6
7import unittest2
8import vscode
9from lldbsuite.test.decorators import *
10from lldbsuite.test.lldbtest import *
11from lldbsuite.test import lldbutil
12import lldbvscode_testcase
13import re
14
15class TestVSCode_module(lldbvscode_testcase.VSCodeTestCaseBase):
16
17    mydir = TestBase.compute_mydir(__file__)
18
19    def run_test(self, symbol_basename, expect_debug_info_size):
20        program_basename = "a.out.stripped"
21        program = self.getBuildArtifact(program_basename)
22        self.build_and_launch(program)
23        functions = ['foo']
24        breakpoint_ids = self.set_function_breakpoints(functions)
25        self.assertEquals(len(breakpoint_ids), len(functions), 'expect one breakpoint')
26        self.continue_to_breakpoints(breakpoint_ids)
27        active_modules = self.vscode.get_active_modules()
28        program_module = active_modules[program_basename]
29        self.assertIn(program_basename, active_modules, '%s module is in active modules' % (program_basename))
30        self.assertIn('name', program_module, 'make sure name is in module')
31        self.assertEqual(program_basename, program_module['name'])
32        self.assertIn('path', program_module, 'make sure path is in module')
33        self.assertEqual(program, program_module['path'])
34        self.assertTrue('symbolFilePath' not in program_module, 'Make sure a.out.stripped has no debug info')
35        self.assertEqual('Symbols not found.', program_module['symbolStatus'])
36        symbols_path = self.getBuildArtifact(symbol_basename)
37        self.vscode.request_evaluate('`%s' % ('target symbols add -s "%s" "%s"' % (program, symbols_path)))
38
39        def checkSymbolsLoaded():
40            active_modules = self.vscode.get_active_modules()
41            program_module = active_modules[program_basename]
42            return 'Symbols loaded.' == program_module['symbolStatus']
43
44        def checkSymbolsLoadedWithSize():
45            active_modules = self.vscode.get_active_modules()
46            program_module = active_modules[program_basename]
47            symbolsStatus = program_module['symbolStatus']
48            symbol_regex = re.compile(r"Symbols loaded. \([0-9]+(\.[0-9]*)?[KMG]?B\)")
49            return symbol_regex.match(program_module['symbolStatus'])
50
51        if expect_debug_info_size:
52            self.waitUntil(checkSymbolsLoadedWithSize)
53        else:
54            self.waitUntil(checkSymbolsLoaded)
55        active_modules = self.vscode.get_active_modules()
56        program_module = active_modules[program_basename]
57        self.assertEqual(program_basename, program_module['name'])
58        self.assertEqual(program, program_module['path'])
59        self.assertIn('symbolFilePath', program_module)
60        self.assertIn(symbols_path, program_module['symbolFilePath'])
61        self.assertIn('addressRange', program_module)
62
63    @skipIfWindows
64    @skipUnlessDarwin
65    @skipIfRemote
66    #TODO: Update the Makefile so that this test runs on Linux
67    def test_module_event(self):
68        '''
69            Mac or linux.
70
71            On mac, if we load a.out as our symbol file, we will use DWARF with .o files and we will
72            have debug symbols, but we won't see any debug info size because all of the DWARF
73            sections are in .o files.
74
75            On other platforms, we expect a.out to have debug info, so we will expect a size.
76            expect_debug_info_size = platform.system() != 'Darwin'
77            return self.run_test("a.out", expect_debug_info_size)
78        '''
79        expect_debug_info_size = platform.system() != 'Darwin'
80        return self.run_test("a.out", expect_debug_info_size)
81
82    @skipIfWindows
83    @skipUnlessDarwin
84    @skipIfRemote
85    def test_module_event_dsym(self):
86        '''
87            Darwin only test with dSYM file.
88
89            On mac, if we load a.out.dSYM as our symbol file, we will have debug symbols and we
90            will have DWARF sections added to the module, so we will expect a size.
91            return self.run_test("a.out.dSYM", True)
92        '''
93        return self.run_test("a.out.dSYM", True)
94
95    @skipIfWindows
96    @skipUnlessDarwin
97    @skipIfRemote
98    def test_compile_units(self):
99        program = self.getBuildArtifact("a.out")
100        self.build_and_launch(program)
101        source = "main.cpp"
102        main_source_path = self.getSourcePath(source)
103        breakpoint1_line = line_number(source, '// breakpoint 1')
104        lines = [breakpoint1_line]
105        breakpoint_ids = self.set_source_breakpoints(source, lines)
106        self.continue_to_breakpoints(breakpoint_ids)
107        moduleId = self.vscode.get_active_modules()['a.out']['id']
108        response = self.vscode.request_getCompileUnits(moduleId)
109        self.assertTrue(response['body'])
110        self.assertTrue(len(response['body']['compileUnits']) == 1,
111                        'Only one source file should exist')
112        self.assertTrue(response['body']['compileUnits'][0]['compileUnitPath'] == main_source_path,
113                        'Real path to main.cpp matches')
114
115