1from lldbsuite.test.gdbclientutils import * 2from lldbsuite.test.decorators import * 3from lldbsuite.test.lldbgdbclient import GDBPlatformClientTestBase 4 5class TestGDBRemotePlatformFile(GDBPlatformClientTestBase): 6 7 mydir = GDBPlatformClientTestBase.compute_mydir(__file__) 8 9 def test_file(self): 10 """Test mock operations on a remote file""" 11 12 class Responder(MockGDBServerResponder): 13 def vFile(self, packet): 14 if packet.startswith("vFile:open:"): 15 return "F10" 16 elif packet.startswith("vFile:pread:"): 17 return "Fd;frobnicator" 18 elif packet.startswith("vFile:pwrite:"): 19 return "Fa" 20 elif packet.startswith("vFile:close:"): 21 return "F0" 22 return "F-1,58" 23 24 self.server.responder = Responder() 25 26 self.match("platform file open /some/file.txt -v 0755", 27 [r"File Descriptor = 16"]) 28 self.match("platform file read 16 -o 11 -c 13", 29 [r"Return = 11\nData = \"frobnicator\""]) 30 self.match("platform file write 16 -o 11 -d teststring", 31 [r"Return = 10"]) 32 self.match("platform file close 16", 33 [r"file 16 closed."]) 34 self.assertPacketLogContains([ 35 "vFile:open:2f736f6d652f66696c652e747874,00000202,000001ed", 36 "vFile:pread:10,d,b", 37 "vFile:pwrite:10,b,teststring", 38 "vFile:close:10", 39 ]) 40 41 def test_file_fail(self): 42 """Test mocked failures of remote operations""" 43 44 class Responder(MockGDBServerResponder): 45 def vFile(self, packet): 46 # use ENOSYS as this constant differs between GDB Remote 47 # Protocol and Linux, so we can test the translation 48 return "F-1,58" 49 50 self.server.responder = Responder() 51 52 self.match("platform file open /some/file.txt -v 0755", 53 [r"error: Function not implemented"], 54 error=True) 55 self.match("platform file read 16 -o 11 -c 13", 56 [r"error: Function not implemented"], 57 error=True) 58 self.match("platform file write 16 -o 11 -d teststring", 59 [r"error: Function not implemented"], 60 error=True) 61 self.match("platform file close 16", 62 [r"error: Function not implemented"], 63 error=True) 64 self.assertPacketLogContains([ 65 "vFile:open:2f736f6d652f66696c652e747874,00000202,000001ed", 66 "vFile:pread:10,d,b", 67 "vFile:pwrite:10,b,teststring", 68 "vFile:close:10", 69 ]) 70 71 def test_file_size(self): 72 """Test 'platform get-size'""" 73 74 class Responder(MockGDBServerResponder): 75 def vFile(self, packet): 76 return "F1000" 77 78 self.server.responder = Responder() 79 80 self.match("platform get-size /some/file.txt", 81 [r"File size of /some/file\.txt \(remote\): 4096"]) 82 self.assertPacketLogContains([ 83 "vFile:size:2f736f6d652f66696c652e747874", 84 ]) 85 86 def test_file_size_fallback(self): 87 """Test 'platform get-size fallback to vFile:fstat'""" 88 89 class Responder(MockGDBServerResponder): 90 def vFile(self, packet): 91 if packet.startswith("vFile:open:"): 92 return "F5" 93 elif packet.startswith("vFile:fstat:"): 94 return "F40;" + 28 * "\0" + "\0\0\0\0\0\1\2\3" + 28 * "\0" 95 if packet.startswith("vFile:close:"): 96 return "F0" 97 return "" 98 99 self.server.responder = Responder() 100 101 self.match("platform get-size /some/file.txt", 102 [r"File size of /some/file\.txt \(remote\): 66051"]) 103 self.assertPacketLogContains([ 104 "vFile:size:2f736f6d652f66696c652e747874", 105 "vFile:open:2f736f6d652f66696c652e747874,00000000,00000000", 106 "vFile:fstat:5", 107 "vFile:close:5", 108 ]) 109 110 @skipIfWindows 111 def test_file_permissions(self): 112 """Test 'platform get-permissions'""" 113 114 class Responder(MockGDBServerResponder): 115 def vFile(self, packet): 116 return "F1a4" 117 118 self.server.responder = Responder() 119 120 self.match("platform get-permissions /some/file.txt", 121 [r"File permissions of /some/file\.txt \(remote\): 0o0644"]) 122 self.assertPacketLogContains([ 123 "vFile:mode:2f736f6d652f66696c652e747874", 124 ]) 125 126 @skipIfWindows 127 def test_file_permissions_fallback(self): 128 """Test 'platform get-permissions' fallback to fstat""" 129 130 class Responder(MockGDBServerResponder): 131 def vFile(self, packet): 132 if packet.startswith("vFile:open:"): 133 return "F5" 134 elif packet.startswith("vFile:fstat:"): 135 return "F40;" + 8 * "\0" + "\0\0\1\xA4" + 52 * "\0" 136 if packet.startswith("vFile:close:"): 137 return "F0" 138 return "" 139 140 self.server.responder = Responder() 141 142 try: 143 self.match("platform get-permissions /some/file.txt", 144 [r"File permissions of /some/file\.txt \(remote\): 0o0644"]) 145 self.assertPacketLogContains([ 146 "vFile:mode:2f736f6d652f66696c652e747874", 147 "vFile:open:2f736f6d652f66696c652e747874,00000000,00000000", 148 "vFile:fstat:5", 149 "vFile:close:5", 150 ]) 151 finally: 152 self.dbg.GetSelectedPlatform().DisconnectRemote() 153 154 def test_file_exists(self): 155 """Test 'platform file-exists'""" 156 157 class Responder(MockGDBServerResponder): 158 def vFile(self, packet): 159 return "F,1" 160 161 self.server.responder = Responder() 162 163 self.match("platform file-exists /some/file.txt", 164 [r"File /some/file\.txt \(remote\) exists"]) 165 self.assertPacketLogContains([ 166 "vFile:exists:2f736f6d652f66696c652e747874", 167 ]) 168 169 def test_file_exists_not(self): 170 """Test 'platform file-exists' with non-existing file""" 171 172 class Responder(MockGDBServerResponder): 173 def vFile(self, packet): 174 return "F,0" 175 176 self.server.responder = Responder() 177 178 self.match("platform file-exists /some/file.txt", 179 [r"File /some/file\.txt \(remote\) does not exist"]) 180 self.assertPacketLogContains([ 181 "vFile:exists:2f736f6d652f66696c652e747874", 182 ]) 183 184 def test_file_exists_fallback(self): 185 """Test 'platform file-exists' fallback to open""" 186 187 class Responder(MockGDBServerResponder): 188 def vFile(self, packet): 189 if packet.startswith("vFile:open:"): 190 return "F5" 191 if packet.startswith("vFile:close:"): 192 return "F0" 193 return "" 194 195 self.server.responder = Responder() 196 197 self.match("platform file-exists /some/file.txt", 198 [r"File /some/file\.txt \(remote\) exists"]) 199 self.assertPacketLogContains([ 200 "vFile:exists:2f736f6d652f66696c652e747874", 201 "vFile:open:2f736f6d652f66696c652e747874,00000000,00000000", 202 "vFile:close:5", 203 ]) 204 205 def test_file_exists_not_fallback(self): 206 """Test 'platform file-exists' fallback to open with non-existing file""" 207 208 class Responder(MockGDBServerResponder): 209 def vFile(self, packet): 210 if packet.startswith("vFile:open:"): 211 return "F-1,2" 212 return "" 213 214 self.server.responder = Responder() 215 216 self.match("platform file-exists /some/file.txt", 217 [r"File /some/file\.txt \(remote\) does not exist"]) 218 self.assertPacketLogContains([ 219 "vFile:exists:2f736f6d652f66696c652e747874", 220 "vFile:open:2f736f6d652f66696c652e747874,00000000,00000000", 221 ]) 222