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