19262cd52e254fb261334254a80a1b316d59b555cJohnny Chen"""Test that the 'add-dsym', aka 'target symbols add', command informs the user about success or failure."""
29262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
39262cd52e254fb261334254a80a1b316d59b555cJohnny Chenimport os, time
49262cd52e254fb261334254a80a1b316d59b555cJohnny Chenimport unittest2
59262cd52e254fb261334254a80a1b316d59b555cJohnny Chenimport lldb
69262cd52e254fb261334254a80a1b316d59b555cJohnny Chenimport pexpect
79262cd52e254fb261334254a80a1b316d59b555cJohnny Chenfrom lldbtest import *
89262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
99262cd52e254fb261334254a80a1b316d59b555cJohnny Chen@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
109262cd52e254fb261334254a80a1b316d59b555cJohnny Chenclass AddDsymCommandCase(TestBase):
119262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
129262cd52e254fb261334254a80a1b316d59b555cJohnny Chen    mydir = os.path.join("warnings", "uuid")
139262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
149262cd52e254fb261334254a80a1b316d59b555cJohnny Chen    def setUp(self):
159262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        TestBase.setUp(self)
169262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.template = 'main.cpp.template'
179262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.source = 'main.cpp'
189262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.teardown_hook_added = False
199262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
209262cd52e254fb261334254a80a1b316d59b555cJohnny Chen    def test_add_dsym_command_with_error(self):
219262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        """Test that the 'add-dsym' command informs the user about failures."""
229262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
239262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        # Call the program generator to produce main.cpp, version 1.
249262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.generate_main_cpp(version=1)
259262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.buildDsym(clean=True)
269262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
279262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        # Insert some delay and then call the program generator to produce main.cpp, version 2.
289262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        time.sleep(5)
299262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.generate_main_cpp(version=101)
309262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        # Now call make again, but this time don't generate the dSYM.
319262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.buildDwarf(clean=False)
329262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
339262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.exe_name = 'a.out'
349262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.do_add_dsym_with_error(self.exe_name)
359262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
369262cd52e254fb261334254a80a1b316d59b555cJohnny Chen    def test_add_dsym_command_with_success(self):
379262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        """Test that the 'add-dsym' command informs the user about success."""
389262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
399262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        # Call the program generator to produce main.cpp, version 1.
409262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.generate_main_cpp(version=1)
419262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.buildDsym(clean=True)
429262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
439262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.exe_name = 'a.out'
449262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.do_add_dsym_with_success(self.exe_name)
459262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
46a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas    def test_add_dsym_with_dSYM_bundle(self):
47a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        """Test that the 'add-dsym' command informs the user about success."""
48a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas
49a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        # Call the program generator to produce main.cpp, version 1.
50a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        self.generate_main_cpp(version=1)
51a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        self.buildDsym(clean=True)
52a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas
53a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        self.exe_name = 'a.out'
54a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        self.do_add_dsym_with_dSYM_bundle(self.exe_name)
55a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas
56a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas
579262cd52e254fb261334254a80a1b316d59b555cJohnny Chen    def generate_main_cpp(self, version=0):
589262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        """Generate main.cpp from main.cpp.template."""
599262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        temp = os.path.join(os.getcwd(), self.template)
609262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        with open(temp, 'r') as f:
619262cd52e254fb261334254a80a1b316d59b555cJohnny Chen            content = f.read()
629262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
639262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        new_content = content.replace('%ADD_EXTRA_CODE%',
649262cd52e254fb261334254a80a1b316d59b555cJohnny Chen                                      'printf("This is version %d\\n");' % version)
659262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        src = os.path.join(os.getcwd(), self.source)
669262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        with open(src, 'w') as f:
679262cd52e254fb261334254a80a1b316d59b555cJohnny Chen            f.write(new_content)
689262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
699262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        # The main.cpp has been generated, add a teardown hook to remove it.
709262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        if not self.teardown_hook_added:
719262cd52e254fb261334254a80a1b316d59b555cJohnny Chen            self.addTearDownHook(lambda: os.remove(src))
729262cd52e254fb261334254a80a1b316d59b555cJohnny Chen            self.teardown_hook_added = True
739262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
749262cd52e254fb261334254a80a1b316d59b555cJohnny Chen    def do_add_dsym_with_error(self, exe_name):
759262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        """Test that the 'add-dsym' command informs the user about failures."""
769262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET)
779262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
78a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        wrong_path = os.path.join("%s.dSYM" % exe_name, "Contents")
799262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.expect("add-dsym " + wrong_path, error=True,
80a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas            substrs = ['invalid module path'])
819262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
82a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        right_path = os.path.join("%s.dSYM" % exe_name, "Contents", "Resources", "DWARF", exe_name)
839262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.expect("add-dsym " + right_path, error=True,
84c92fded462447b410694cd1927432231d33f2a42Greg Clayton            substrs = ['symbol file', 'does not match'])
859262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
869262cd52e254fb261334254a80a1b316d59b555cJohnny Chen    def do_add_dsym_with_success(self, exe_name):
879262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        """Test that the 'add-dsym' command informs the user about success."""
889262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET)
899262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
909262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        # This time, the UUID should match and we expect some feedback from lldb.
919262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        right_path = os.path.join("%s.dSYM" % exe_name, "Contents", "Resources", "DWARF", exe_name)
929262cd52e254fb261334254a80a1b316d59b555cJohnny Chen        self.expect("add-dsym " + right_path,
93c92fded462447b410694cd1927432231d33f2a42Greg Clayton            substrs = ['symbol file', 'has been added to'])
949262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
95a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas    def do_add_dsym_with_dSYM_bundle(self, exe_name):
96a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        """Test that the 'add-dsym' command informs the user about success when loading files in bundles."""
97a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET)
98a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas
99a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        # This time, the UUID should be found inside the bundle
100a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        right_path = "%s.dSYM" % exe_name
101a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas        self.expect("add-dsym " + right_path,
102c92fded462447b410694cd1927432231d33f2a42Greg Clayton            substrs = ['symbol file', 'has been added to'])
103a50897992b19bbd242ac4d7204095e9d5c4de756Filipe Cabecinhas
1049262cd52e254fb261334254a80a1b316d59b555cJohnny Chen
1059262cd52e254fb261334254a80a1b316d59b555cJohnny Chenif __name__ == '__main__':
1069262cd52e254fb261334254a80a1b316d59b555cJohnny Chen    import atexit
1079262cd52e254fb261334254a80a1b316d59b555cJohnny Chen    lldb.SBDebugger.Initialize()
1089262cd52e254fb261334254a80a1b316d59b555cJohnny Chen    atexit.register(lambda: lldb.SBDebugger.Terminate())
1099262cd52e254fb261334254a80a1b316d59b555cJohnny Chen    unittest2.main()
110