199451b44SJordan Rupprechtimport lldb
299451b44SJordan Rupprechtimport binascii
399451b44SJordan Rupprechtimport os
4bf3ac994SPavel Labathimport time
599451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
699451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
7*33c0f93fSPavel Labathfrom lldbsuite.test.gdbclientutils import *
8*33c0f93fSPavel Labathfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
999451b44SJordan Rupprecht
1099451b44SJordan Rupprechtdef hexlify(string):
1199451b44SJordan Rupprecht    return binascii.hexlify(string.encode()).decode()
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprechtclass TestPlatformClient(GDBRemoteTestBase):
1499451b44SJordan Rupprecht
1599451b44SJordan Rupprecht    def test_process_list_with_all_users(self):
1699451b44SJordan Rupprecht        """Test connecting to a remote linux platform"""
1799451b44SJordan Rupprecht
1899451b44SJordan Rupprecht        class MyResponder(MockGDBServerResponder):
1999451b44SJordan Rupprecht            def __init__(self):
2099451b44SJordan Rupprecht                MockGDBServerResponder.__init__(self)
2199451b44SJordan Rupprecht                self.currentQsProc = 0
2299451b44SJordan Rupprecht                self.all_users = False
2399451b44SJordan Rupprecht
2499451b44SJordan Rupprecht            def qfProcessInfo(self, packet):
2599451b44SJordan Rupprecht                if "all_users:1" in packet:
2699451b44SJordan Rupprecht                    self.all_users = True
2799451b44SJordan Rupprecht                    name = hexlify("/a/test_process")
2899451b44SJordan Rupprecht                    args = "-".join(map(hexlify,
2999451b44SJordan Rupprecht                                        ["/system/bin/sh", "-c", "/data/local/tmp/lldb-server"]))
3099451b44SJordan Rupprecht                    return "pid:10;ppid:1;uid:2;gid:3;euid:4;egid:5;name:" + name + ";args:" + args + ";"
3199451b44SJordan Rupprecht                else:
3299451b44SJordan Rupprecht                    self.all_users = False
3399451b44SJordan Rupprecht                    return "E04"
3499451b44SJordan Rupprecht
3599451b44SJordan Rupprecht            def qsProcessInfo(self):
3699451b44SJordan Rupprecht                if self.all_users:
3799451b44SJordan Rupprecht                    if self.currentQsProc == 0:
3899451b44SJordan Rupprecht                        self.currentQsProc = 1
3999451b44SJordan Rupprecht                        name = hexlify("/b/another_test_process")
4099451b44SJordan Rupprecht                        # This intentionally has a badly encoded argument
4199451b44SJordan Rupprecht                        args = "X".join(map(hexlify,
4299451b44SJordan Rupprecht                                            ["/system/bin/ls", "--help"]))
4399451b44SJordan Rupprecht                        return "pid:11;ppid:2;uid:3;gid:4;euid:5;egid:6;name:" + name + ";args:" + args + ";"
4499451b44SJordan Rupprecht                    elif self.currentQsProc == 1:
4599451b44SJordan Rupprecht                        self.currentQsProc = 0
4699451b44SJordan Rupprecht                        return "E04"
4799451b44SJordan Rupprecht                else:
4899451b44SJordan Rupprecht                    return "E04"
4999451b44SJordan Rupprecht
5099451b44SJordan Rupprecht        self.server.responder = MyResponder()
5199451b44SJordan Rupprecht
5299451b44SJordan Rupprecht        try:
5399451b44SJordan Rupprecht            self.runCmd("platform select remote-linux")
548fa2394bSMichał Górny            self.runCmd("platform connect " + self.server.get_connect_url())
5599451b44SJordan Rupprecht            self.assertTrue(self.dbg.GetSelectedPlatform().IsConnected())
5699451b44SJordan Rupprecht            self.expect("platform process list -x",
5799451b44SJordan Rupprecht                        substrs=["2 matching processes were found", "test_process", "another_test_process"])
5899451b44SJordan Rupprecht            self.expect("platform process list -xv",
5999451b44SJordan Rupprecht                        substrs=[
6099451b44SJordan Rupprecht                            "PID    PARENT USER       GROUP      EFF USER   EFF GROUP  TRIPLE                         ARGUMENTS",
6199451b44SJordan Rupprecht                            "10     1      2          3          4          5                                         /system/bin/sh -c /data/local/tmp/lldb-server",
6299451b44SJordan Rupprecht                            "11     2      3          4          5          6"])
6399451b44SJordan Rupprecht            self.expect("platform process list -xv", substrs=["/system/bin/ls"], matching=False)
6499451b44SJordan Rupprecht            self.expect("platform process list",
6599451b44SJordan Rupprecht                        error=True,
6699451b44SJordan Rupprecht                        substrs=["error: no processes were found on the \"remote-linux\" platform"])
6799451b44SJordan Rupprecht        finally:
6899451b44SJordan Rupprecht            self.dbg.GetSelectedPlatform().DisconnectRemote()
69bf3ac994SPavel Labath
70bf3ac994SPavel Labath    class TimeoutResponder(MockGDBServerResponder):
71bf3ac994SPavel Labath        """A mock server, which takes a very long time to compute the working
72bf3ac994SPavel Labath        directory."""
73bf3ac994SPavel Labath        def __init__(self):
74bf3ac994SPavel Labath            MockGDBServerResponder.__init__(self)
75bf3ac994SPavel Labath
76bf3ac994SPavel Labath        def qGetWorkingDir(self):
77bf3ac994SPavel Labath            time.sleep(10)
78bf3ac994SPavel Labath            return hexlify("/foo/bar")
79bf3ac994SPavel Labath
80bf3ac994SPavel Labath    def test_no_timeout(self):
81bf3ac994SPavel Labath        """Test that we honor the timeout setting. With a large enough timeout,
82bf3ac994SPavel Labath        we should get the CWD successfully."""
83bf3ac994SPavel Labath
84bf3ac994SPavel Labath        self.server.responder = TestPlatformClient.TimeoutResponder()
85bf3ac994SPavel Labath        self.runCmd("settings set plugin.process.gdb-remote.packet-timeout 30")
86bf3ac994SPavel Labath        plat = lldb.SBPlatform("remote-linux")
87bf3ac994SPavel Labath        try:
888fa2394bSMichał Górny            self.assertSuccess(plat.ConnectRemote(lldb.SBPlatformConnectOptions(
898fa2394bSMichał Górny                self.server.get_connect_url())))
90bf3ac994SPavel Labath            self.assertEqual(plat.GetWorkingDirectory(), "/foo/bar")
91bf3ac994SPavel Labath        finally:
92bf3ac994SPavel Labath            plat.DisconnectRemote()
93bf3ac994SPavel Labath
94bf3ac994SPavel Labath    def test_timeout(self):
95bf3ac994SPavel Labath        """Test that we honor the timeout setting. With a small timeout, CWD
96bf3ac994SPavel Labath        retrieval should fail."""
97bf3ac994SPavel Labath
98bf3ac994SPavel Labath        self.server.responder = TestPlatformClient.TimeoutResponder()
99bf3ac994SPavel Labath        self.runCmd("settings set plugin.process.gdb-remote.packet-timeout 3")
100bf3ac994SPavel Labath        plat = lldb.SBPlatform("remote-linux")
101bf3ac994SPavel Labath        try:
1028fa2394bSMichał Górny            self.assertSuccess(plat.ConnectRemote(lldb.SBPlatformConnectOptions(
1038fa2394bSMichał Górny                self.server.get_connect_url())))
104bf3ac994SPavel Labath            self.assertIsNone(plat.GetWorkingDirectory())
105bf3ac994SPavel Labath        finally:
106bf3ac994SPavel Labath            plat.DisconnectRemote()
107