1"""Test that the 'add-dsym', aka 'target symbols add', command informs the user about success or failure."""
2
3import os, time
4import unittest2
5import lldb
6import pexpect
7from lldbtest import *
8
9@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
10class AddDsymCommandCase(TestBase):
11
12    mydir = os.path.join("warnings", "uuid")
13
14    def setUp(self):
15        TestBase.setUp(self)
16        self.template = 'main.cpp.template'
17        self.source = 'main.cpp'
18        self.teardown_hook_added = False
19
20    def test_add_dsym_command_with_error(self):
21        """Test that the 'add-dsym' command informs the user about failures."""
22
23        # Call the program generator to produce main.cpp, version 1.
24        self.generate_main_cpp(version=1)
25        self.buildDsym(clean=True)
26
27        # Insert some delay and then call the program generator to produce main.cpp, version 2.
28        time.sleep(5)
29        self.generate_main_cpp(version=101)
30        # Now call make again, but this time don't generate the dSYM.
31        self.buildDwarf(clean=False)
32
33        self.exe_name = 'a.out'
34        self.do_add_dsym_with_error(self.exe_name)
35
36    def test_add_dsym_command_with_success(self):
37        """Test that the 'add-dsym' command informs the user about success."""
38
39        # Call the program generator to produce main.cpp, version 1.
40        self.generate_main_cpp(version=1)
41        self.buildDsym(clean=True)
42
43        self.exe_name = 'a.out'
44        self.do_add_dsym_with_success(self.exe_name)
45
46    def test_add_dsym_with_dSYM_bundle(self):
47        """Test that the 'add-dsym' command informs the user about success."""
48
49        # Call the program generator to produce main.cpp, version 1.
50        self.generate_main_cpp(version=1)
51        self.buildDsym(clean=True)
52
53        self.exe_name = 'a.out'
54        self.do_add_dsym_with_dSYM_bundle(self.exe_name)
55
56
57    def generate_main_cpp(self, version=0):
58        """Generate main.cpp from main.cpp.template."""
59        temp = os.path.join(os.getcwd(), self.template)
60        with open(temp, 'r') as f:
61            content = f.read()
62
63        new_content = content.replace('%ADD_EXTRA_CODE%',
64                                      'printf("This is version %d\\n");' % version)
65        src = os.path.join(os.getcwd(), self.source)
66        with open(src, 'w') as f:
67            f.write(new_content)
68
69        # The main.cpp has been generated, add a teardown hook to remove it.
70        if not self.teardown_hook_added:
71            self.addTearDownHook(lambda: os.remove(src))
72            self.teardown_hook_added = True
73
74    def do_add_dsym_with_error(self, exe_name):
75        """Test that the 'add-dsym' command informs the user about failures."""
76        self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET)
77
78        wrong_path = os.path.join("%s.dSYM" % exe_name, "Contents")
79        self.expect("add-dsym " + wrong_path, error=True,
80            substrs = ['invalid module path'])
81
82        right_path = os.path.join("%s.dSYM" % exe_name, "Contents", "Resources", "DWARF", exe_name)
83        self.expect("add-dsym " + right_path, error=True,
84            substrs = ['symbol file', 'does not match'])
85
86    def do_add_dsym_with_success(self, exe_name):
87        """Test that the 'add-dsym' command informs the user about success."""
88        self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET)
89
90        # This time, the UUID should match and we expect some feedback from lldb.
91        right_path = os.path.join("%s.dSYM" % exe_name, "Contents", "Resources", "DWARF", exe_name)
92        self.expect("add-dsym " + right_path,
93            substrs = ['symbol file', 'has been added to'])
94
95    def do_add_dsym_with_dSYM_bundle(self, exe_name):
96        """Test that the 'add-dsym' command informs the user about success when loading files in bundles."""
97        self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET)
98
99        # This time, the UUID should be found inside the bundle
100        right_path = "%s.dSYM" % exe_name
101        self.expect("add-dsym " + right_path,
102            substrs = ['symbol file', 'has been added to'])
103
104
105if __name__ == '__main__':
106    import atexit
107    lldb.SBDebugger.Initialize()
108    atexit.register(lambda: lldb.SBDebugger.Terminate())
109    unittest2.main()
110