xref: /llvm-project/lldb/test/API/commands/platform/sdk/TestPlatformSDK.py (revision 0fc578664809d9f808d24a91e50a68d6bfa22118)
1dd2054d3SJonas Devlieghereimport lldb
2dd2054d3SJonas Devlieghere
3dd2054d3SJonas Devliegherefrom lldbsuite.test.decorators import *
4dd2054d3SJonas Devliegherefrom lldbsuite.test.lldbtest import *
5dd2054d3SJonas Devliegherefrom lldbsuite.test import lldbutil
63ca7b2d0SPavel Labathfrom lldbgdbserverutils import get_debugserver_exe
7dd2054d3SJonas Devlieghere
8dd2054d3SJonas Devlieghereimport os
9dd2054d3SJonas Devlieghereimport platform
10dd2054d3SJonas Devlieghereimport shutil
11dd2054d3SJonas Devlieghereimport time
12dd2054d3SJonas Devlieghereimport socket
13dd2054d3SJonas Devlieghere
14dd2054d3SJonas Devlieghere
15dd2054d3SJonas Devlieghereclass PlatformSDKTestCase(TestBase):
16dd2054d3SJonas Devlieghere    NO_DEBUG_INFO_TESTCASE = True
17dd2054d3SJonas Devlieghere
18dd2054d3SJonas Devlieghere    # The port used by debugserver.
19dd2054d3SJonas Devlieghere    PORT = 54637
20dd2054d3SJonas Devlieghere
21dd2054d3SJonas Devlieghere    # The number of attempts.
22dd2054d3SJonas Devlieghere    ATTEMPTS = 10
23dd2054d3SJonas Devlieghere
24dd2054d3SJonas Devlieghere    # Time given to the binary to launch and to debugserver to attach to it for
25dd2054d3SJonas Devlieghere    # every attempt. We'll wait a maximum of 10 times 2 seconds while the
26dd2054d3SJonas Devlieghere    # inferior will wait 10 times 10 seconds.
27dd2054d3SJonas Devlieghere    TIMEOUT = 2
28dd2054d3SJonas Devlieghere
29dd2054d3SJonas Devlieghere    def no_debugserver(self):
303ca7b2d0SPavel Labath        if get_debugserver_exe() is None:
312238dcc3SJonas Devlieghere            return "no debugserver"
32dd2054d3SJonas Devlieghere        return None
33dd2054d3SJonas Devlieghere
34dd2054d3SJonas Devlieghere    def port_not_available(self):
35dd2054d3SJonas Devlieghere        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
362238dcc3SJonas Devlieghere        if s.connect_ex(("127.0.0.1", self.PORT)) == 0:
372238dcc3SJonas Devlieghere            return "{} not available".format(self.PORT)
38dd2054d3SJonas Devlieghere        return None
39dd2054d3SJonas Devlieghere
40dd2054d3SJonas Devlieghere    @no_debug_info_test
41dd2054d3SJonas Devlieghere    @skipUnlessDarwin
42*0fc57866SJordan Rupprecht    @skipTestIfFn(no_debugserver)
43*0fc57866SJordan Rupprecht    @skipTestIfFn(port_not_available)
4466b829acSJonas Devlieghere    @skipIfRemote
45dd2054d3SJonas Devlieghere    def test_macos_sdk(self):
46dd2054d3SJonas Devlieghere        self.build()
47dd2054d3SJonas Devlieghere
482238dcc3SJonas Devlieghere        exe = self.getBuildArtifact("a.out")
492238dcc3SJonas Devlieghere        token = self.getBuildArtifact("token")
50dd2054d3SJonas Devlieghere
51dd2054d3SJonas Devlieghere        # Remove the old token.
52dd2054d3SJonas Devlieghere        try:
53dd2054d3SJonas Devlieghere            os.remove(token)
54dd2054d3SJonas Devlieghere        except:
55dd2054d3SJonas Devlieghere            pass
56dd2054d3SJonas Devlieghere
57dd2054d3SJonas Devlieghere        # Create a fake 'SDK' directory.
582238dcc3SJonas Devlieghere        test_home = os.path.join(self.getBuildDir(), "fake_home.noindex")
598ee35c55SJason Molenda        test_home = os.path.realpath(test_home)
60dd2054d3SJonas Devlieghere        macos_version = platform.mac_ver()[0]
612238dcc3SJonas Devlieghere        sdk_dir = os.path.join(
622238dcc3SJonas Devlieghere            test_home,
632238dcc3SJonas Devlieghere            "Library",
642238dcc3SJonas Devlieghere            "Developer",
652238dcc3SJonas Devlieghere            "Xcode",
662238dcc3SJonas Devlieghere            "macOS DeviceSupport",
672238dcc3SJonas Devlieghere            macos_version,
682238dcc3SJonas Devlieghere        )
692238dcc3SJonas Devlieghere        symbols_dir = os.path.join(sdk_dir, "Symbols")
70dd2054d3SJonas Devlieghere        lldbutil.mkdir_p(symbols_dir)
71dd2054d3SJonas Devlieghere
72dd2054d3SJonas Devlieghere        # Save the current home directory and restore it afterwards.
732238dcc3SJonas Devlieghere        old_home = os.getenv("HOME")
74dd2054d3SJonas Devlieghere
75dd2054d3SJonas Devlieghere        def cleanup():
76dd2054d3SJonas Devlieghere            if not old_home:
772238dcc3SJonas Devlieghere                del os.environ["HOME"]
78dd2054d3SJonas Devlieghere            else:
792238dcc3SJonas Devlieghere                os.environ["HOME"] = old_home
80dd2054d3SJonas Devlieghere
81dd2054d3SJonas Devlieghere        self.addTearDownHook(cleanup)
822238dcc3SJonas Devlieghere        os.environ["HOME"] = test_home
83dd2054d3SJonas Devlieghere
84dd2054d3SJonas Devlieghere        # Launch our test binary.
85dd2054d3SJonas Devlieghere        inferior = self.spawnSubprocess(exe, [token])
86dd2054d3SJonas Devlieghere        pid = inferior.pid
87dd2054d3SJonas Devlieghere
88dd2054d3SJonas Devlieghere        # Wait for the binary to launch.
89dd2054d3SJonas Devlieghere        lldbutil.wait_for_file_on_target(self, token)
90dd2054d3SJonas Devlieghere
91dd2054d3SJonas Devlieghere        # Move the binary into the 'SDK'.
922238dcc3SJonas Devlieghere        rel_exe_path = os.path.relpath(os.path.realpath(exe), "/")
93dd2054d3SJonas Devlieghere        exe_sdk_path = os.path.join(symbols_dir, rel_exe_path)
94dd2054d3SJonas Devlieghere        lldbutil.mkdir_p(os.path.dirname(exe_sdk_path))
95dd2054d3SJonas Devlieghere        shutil.move(exe, exe_sdk_path)
96dd2054d3SJonas Devlieghere
97dd2054d3SJonas Devlieghere        # Attach to it with debugserver.
983ca7b2d0SPavel Labath        debugserver = get_debugserver_exe()
992238dcc3SJonas Devlieghere        debugserver_args = ["localhost:{}".format(self.PORT), "--attach={}".format(pid)]
100dd2054d3SJonas Devlieghere        self.spawnSubprocess(debugserver, debugserver_args)
101dd2054d3SJonas Devlieghere
102dd2054d3SJonas Devlieghere        # Select the platform.
1032238dcc3SJonas Devlieghere        self.expect("platform select remote-macosx", substrs=[sdk_dir])
104dd2054d3SJonas Devlieghere
105dd2054d3SJonas Devlieghere        # Connect to debugserver
106dd2054d3SJonas Devlieghere        interpreter = self.dbg.GetCommandInterpreter()
107dd2054d3SJonas Devlieghere        connected = False
108dd2054d3SJonas Devlieghere        for i in range(self.ATTEMPTS):
109dd2054d3SJonas Devlieghere            result = lldb.SBCommandReturnObject()
1102238dcc3SJonas Devlieghere            interpreter.HandleCommand("gdb-remote {}".format(self.PORT), result)
111dd2054d3SJonas Devlieghere            connected = result.Succeeded()
112dd2054d3SJonas Devlieghere            if connected:
113dd2054d3SJonas Devlieghere                break
114dd2054d3SJonas Devlieghere            time.sleep(self.TIMEOUT)
115dd2054d3SJonas Devlieghere
116dd2054d3SJonas Devlieghere        self.assertTrue(connected, "could not connect to debugserver")
117dd2054d3SJonas Devlieghere
118dd2054d3SJonas Devlieghere        # Make sure the image was loaded from the 'SDK'.
1192238dcc3SJonas Devlieghere        self.expect("image list", substrs=[exe_sdk_path])
120