1import os 2import os.path 3import lldb 4from lldbsuite.test.lldbtest import * 5from lldbsuite.test.gdbclientutils import * 6 7class GDBRemoteTestBase(TestBase): 8 """ 9 Base class for GDB client tests. 10 11 This class will setup and start a mock GDB server for the test to use. 12 It also provides assertPacketLogContains, which simplifies the checking 13 of packets sent by the client. 14 """ 15 16 NO_DEBUG_INFO_TESTCASE = True 17 server = None 18 server_socket_class = TCPServerSocket 19 20 def setUp(self): 21 TestBase.setUp(self) 22 self.server = MockGDBServer(self.server_socket_class()) 23 self.server.start() 24 25 def tearDown(self): 26 # TestBase.tearDown will kill the process, but we need to kill it early 27 # so its client connection closes and we can stop the server before 28 # finally calling the base tearDown. 29 if self.process() is not None: 30 self.process().Kill() 31 self.server.stop() 32 TestBase.tearDown(self) 33 34 def createTarget(self, yaml_path): 35 """ 36 Create a target by auto-generating the object based on the given yaml 37 instructions. 38 39 This will track the generated object so it can be automatically removed 40 during tearDown. 41 """ 42 yaml_base, ext = os.path.splitext(yaml_path) 43 obj_path = self.getBuildArtifact(yaml_base) 44 self.yaml2obj(yaml_path, obj_path) 45 return self.dbg.CreateTarget(obj_path) 46 47 def connect(self, target): 48 """ 49 Create a process by connecting to the mock GDB server. 50 51 Includes assertions that the process was successfully created. 52 """ 53 listener = self.dbg.GetListener() 54 error = lldb.SBError() 55 process = target.ConnectRemote(listener, 56 self.server.get_connect_url(), "gdb-remote", error) 57 self.assertTrue(error.Success(), error.description) 58 self.assertTrue(process, PROCESS_IS_VALID) 59 return process 60 61 def assertPacketLogContains(self, packets, log=None): 62 """ 63 Assert that the mock server's packet log contains the given packets. 64 65 The packet log includes all packets sent by the client and received 66 by the server. This fuction makes it easy to verify that the client 67 sent the expected packets to the server. 68 69 The check does not require that the packets be consecutive, but does 70 require that they are ordered in the log as they ordered in the arg. 71 """ 72 if log is None: 73 log = self.server.responder.packetLog 74 i = 0 75 j = 0 76 77 while i < len(packets) and j < len(log): 78 if log[j] == packets[i]: 79 i += 1 80 j += 1 81 if i < len(packets): 82 self.fail(u"Did not receive: %s\nLast 10 packets:\n\t%s" % 83 (packets[i], u'\n\t'.join(log))) 84 85 86class GDBPlatformClientTestBase(GDBRemoteTestBase): 87 """ 88 Base class for platform server clients. 89 90 This class extends GDBRemoteTestBase by automatically connecting 91 via "platform connect" in the setUp() method. 92 """ 93 94 def setUp(self): 95 super().setUp() 96 self.runCmd("platform select remote-gdb-server") 97 self.runCmd("platform connect " + self.server.get_connect_url()) 98 self.assertTrue(self.dbg.GetSelectedPlatform().IsConnected()) 99 100 def tearDown(self): 101 self.dbg.GetSelectedPlatform().DisconnectRemote() 102 super().tearDown() 103