xref: /llvm-project/lldb/test/API/functionalities/module_cache/simple_exe/TestModuleCacheSimple.py (revision 1eeeab82c6eb185f5139e633a59c2dbcb15616e4)
1da816ca0SGreg Clayton"""Test the LLDB module cache funcionality."""
2da816ca0SGreg Clayton
3da816ca0SGreg Claytonimport glob
4da816ca0SGreg Claytonimport lldb
5da816ca0SGreg Claytonfrom lldbsuite.test.decorators import *
6da816ca0SGreg Claytonfrom lldbsuite.test.lldbtest import *
7da816ca0SGreg Claytonfrom lldbsuite.test import lldbutil
8da816ca0SGreg Claytonimport os
9da816ca0SGreg Claytonimport time
10da816ca0SGreg Clayton
11da816ca0SGreg Clayton
12da816ca0SGreg Claytonclass ModuleCacheTestcaseSimple(TestBase):
13da816ca0SGreg Clayton    def setUp(self):
14da816ca0SGreg Clayton        # Call super's setUp().
15da816ca0SGreg Clayton        TestBase.setUp(self)
16da816ca0SGreg Clayton        # Find the line number in a(int) to break at.
172238dcc3SJonas Devlieghere        self.cache_dir = os.path.join(self.getBuildDir(), "lldb-module-cache")
18da816ca0SGreg Clayton        # Set the lldb module cache directory to a directory inside the build
19da816ca0SGreg Clayton        # artifacts directory so no other tests are interfered with.
202238dcc3SJonas Devlieghere        self.runCmd(
212238dcc3SJonas Devlieghere            'settings set symbols.lldb-index-cache-path "%s"' % (self.cache_dir)
222238dcc3SJonas Devlieghere        )
232238dcc3SJonas Devlieghere        self.runCmd("settings set symbols.enable-lldb-index-cache true")
24da816ca0SGreg Clayton        self.build()
25da816ca0SGreg Clayton
26da816ca0SGreg Clayton    def get_module_cache_files(self, basename):
272238dcc3SJonas Devlieghere        module_file_glob = os.path.join(
282238dcc3SJonas Devlieghere            self.cache_dir, "llvmcache-*%s*-symtab-*" % (basename)
292238dcc3SJonas Devlieghere        )
30da816ca0SGreg Clayton        return glob.glob(module_file_glob)
31da816ca0SGreg Clayton
32da816ca0SGreg Clayton    # Doesn't depend on any specific debug information.
33da816ca0SGreg Clayton    @no_debug_info_test
34a2154b19SGreg Clayton    @skipIfWindows
35da816ca0SGreg Clayton    def test(self):
36da816ca0SGreg Clayton        """
37da816ca0SGreg Clayton        Test module cache functionality for a simple object file.
38da816ca0SGreg Clayton
39da816ca0SGreg Clayton        This will test that if we enable the module cache, we have a
40da816ca0SGreg Clayton        corresponding index cache entry for the symbol table for the
41da816ca0SGreg Clayton        executable. It also removes the executable, rebuilds so that the
42da816ca0SGreg Clayton        modification time of the binary gets updated, and then creates a new
43da816ca0SGreg Clayton        target and should cause the cache to get updated so the cache file
44da816ca0SGreg Clayton        should get an updated modification time.
45da816ca0SGreg Clayton        """
46da816ca0SGreg Clayton        exe = self.getBuildArtifact("a.out")
47da816ca0SGreg Clayton
487240436cSGabriel Ravier        # Create a module with no dependencies.
49da816ca0SGreg Clayton        target = self.createTestTarget(load_dependent_modules=False)
50da816ca0SGreg Clayton
51da816ca0SGreg Clayton        # Get the executable module and get the number of symbols to make
52da816ca0SGreg Clayton        # sure the symbol table gets parsed and cached. The module cache is
53da816ca0SGreg Clayton        # enabled in the setUp() function.
54da816ca0SGreg Clayton        main_module = target.GetModuleAtIndex(0)
55da816ca0SGreg Clayton        self.assertTrue(main_module.IsValid())
56da816ca0SGreg Clayton        # Make sure the symbol table gets loaded and cached
57da816ca0SGreg Clayton        main_module.GetNumSymbols()
58da816ca0SGreg Clayton        cache_files = self.get_module_cache_files("a.out")
592238dcc3SJonas Devlieghere        self.assertEqual(
602238dcc3SJonas Devlieghere            len(cache_files), 1, "make sure there is only one cache file for 'a.out'"
612238dcc3SJonas Devlieghere        )
62da816ca0SGreg Clayton        symtab_cache_path = cache_files[0]
63da816ca0SGreg Clayton        exe_mtime_1 = os.path.getmtime(exe)
64da816ca0SGreg Clayton        symtab_mtime_1 = os.path.getmtime(symtab_cache_path)
65da816ca0SGreg Clayton        # Now remove the executable and sleep for a few seconds to make sure we
66da816ca0SGreg Clayton        # get a different creation and modification time for the file since some
67da816ca0SGreg Clayton        # OSs store the modification time in seconds since Jan 1, 1970.
68da816ca0SGreg Clayton        os.remove(exe)
69*1eeeab82SJordan Rupprecht        self.assertFalse(
70*1eeeab82SJordan Rupprecht            os.path.exists(exe), "make sure we were able to remove the executable"
712238dcc3SJonas Devlieghere        )
72da816ca0SGreg Clayton        time.sleep(2)
73da816ca0SGreg Clayton        # Now rebuild the binary so it has a different content which should
74da816ca0SGreg Clayton        # update the UUID to make the cache miss when it tries to load the
75da816ca0SGreg Clayton        # symbol table from the binary at the same path.
762238dcc3SJonas Devlieghere        self.build(dictionary={"CFLAGS_EXTRAS": "-DEXTRA_FUNCTION"})
77*1eeeab82SJordan Rupprecht        self.assertTrue(
78*1eeeab82SJordan Rupprecht            os.path.exists(exe), "make sure executable exists after rebuild"
792238dcc3SJonas Devlieghere        )
80da816ca0SGreg Clayton        # Make sure the modification time has changed or this test will fail.
81da816ca0SGreg Clayton        exe_mtime_2 = os.path.getmtime(exe)
82da816ca0SGreg Clayton        self.assertNotEqual(
83da816ca0SGreg Clayton            exe_mtime_1,
84da816ca0SGreg Clayton            exe_mtime_2,
852238dcc3SJonas Devlieghere            "make sure the modification time of the executable has changed",
862238dcc3SJonas Devlieghere        )
87da816ca0SGreg Clayton        # Make sure the module cache still has an out of date cache with the
88da816ca0SGreg Clayton        # same old modification time.
892238dcc3SJonas Devlieghere        self.assertEqual(
902238dcc3SJonas Devlieghere            symtab_mtime_1,
91da816ca0SGreg Clayton            os.path.getmtime(symtab_cache_path),
922238dcc3SJonas Devlieghere            "check that the 'symtab' cache file modification time doesn't match the executable modification time after rebuild",
932238dcc3SJonas Devlieghere        )
94da816ca0SGreg Clayton        # Create a new target and get the symbols again, and make sure the cache
95da816ca0SGreg Clayton        # gets updated for the symbol table cache
96da816ca0SGreg Clayton        target = self.createTestTarget(load_dependent_modules=False)
97da816ca0SGreg Clayton        main_module = target.GetModuleAtIndex(0)
98da816ca0SGreg Clayton        self.assertTrue(main_module.IsValid())
99da816ca0SGreg Clayton        main_module.GetNumSymbols()
100*1eeeab82SJordan Rupprecht        self.assertTrue(
1012238dcc3SJonas Devlieghere            os.path.exists(symtab_cache_path),
1022238dcc3SJonas Devlieghere            'make sure "symtab" cache files exists after cache is updated',
1032238dcc3SJonas Devlieghere        )
104da816ca0SGreg Clayton        symtab_mtime_2 = os.path.getmtime(symtab_cache_path)
105da816ca0SGreg Clayton        self.assertNotEqual(
106da816ca0SGreg Clayton            symtab_mtime_1,
107da816ca0SGreg Clayton            symtab_mtime_2,
1082238dcc3SJonas Devlieghere            'make sure modification time of "symtab-..." changed',
1092238dcc3SJonas Devlieghere        )
110