1from __future__ import print_function 2 3# lldb test suite imports 4from lldbsuite.test.decorators import * 5from lldbsuite.test.lldbtest import TestBase 6 7# gdb-remote-specific imports 8import lldbgdbserverutils 9from gdbremote_testcase import GdbRemoteTestCaseBase 10 11import binascii 12import stat 13 14 15class TestGdbRemotePlatformFile(GdbRemoteTestCaseBase): 16 17 mydir = TestBase.compute_mydir(__file__) 18 19 @skipIfWindows 20 @add_test_categories(["llgs"]) 21 def test_platform_file_rdonly(self): 22 self.vFile_test(read=True) 23 24 @skipIfWindows 25 @add_test_categories(["llgs"]) 26 def test_platform_file_wronly(self): 27 self.vFile_test(write=True) 28 29 @skipIfWindows 30 @add_test_categories(["llgs"]) 31 def test_platform_file_rdwr(self): 32 self.vFile_test(read=True, write=True) 33 34 @skipIfWindows 35 @add_test_categories(["llgs"]) 36 def test_platform_file_wronly_append(self): 37 self.vFile_test(write=True, append=True) 38 39 @skipIfWindows 40 @add_test_categories(["llgs"]) 41 def test_platform_file_rdwr_append(self): 42 self.vFile_test(read=True, write=True, append=True) 43 44 @skipIfWindows 45 @add_test_categories(["llgs"]) 46 def test_platform_file_wronly_trunc(self): 47 self.vFile_test(write=True, trunc=True) 48 49 @skipIfWindows 50 @add_test_categories(["llgs"]) 51 def test_platform_file_rdwr_trunc(self): 52 self.vFile_test(read=True, write=True, trunc=True) 53 54 @skipIfWindows 55 @add_test_categories(["llgs"]) 56 def test_platform_file_wronly_creat(self): 57 self.vFile_test(write=True, creat=True) 58 59 @skipIfWindows 60 @add_test_categories(["llgs"]) 61 def test_platform_file_wronly_creat_excl(self): 62 self.vFile_test(write=True, creat=True, excl=True) 63 64 @skipIfWindows 65 @add_test_categories(["llgs"]) 66 def test_platform_file_wronly_fail(self): 67 server = self.connect_to_debug_monitor() 68 self.assertIsNotNone(server) 69 70 temp_path = self.getBuildArtifact("test") 71 self.assertFalse(os.path.exists(temp_path)) 72 73 # attempt to open the file without O_CREAT 74 self.do_handshake() 75 self.test_sequence.add_log_lines( 76 ["read packet: $vFile:open:%s,1,0#00" % ( 77 binascii.b2a_hex(temp_path.encode()).decode(),), 78 {"direction": "send", 79 "regex": r"^\$F-1,[0-9a-fA-F]+#[0-9a-fA-F]{2}$"}], 80 True) 81 self.expect_gdbremote_sequence() 82 83 @skipIfWindows 84 @add_test_categories(["llgs"]) 85 def test_platform_file_wronly_creat_excl_fail(self): 86 server = self.connect_to_debug_monitor() 87 self.assertIsNotNone(server) 88 89 temp_file = self.getBuildArtifact("test") 90 with open(temp_file, "wb"): 91 pass 92 93 # attempt to open the file with O_CREAT|O_EXCL 94 self.do_handshake() 95 self.test_sequence.add_log_lines( 96 ["read packet: $vFile:open:%s,a01,0#00" % ( 97 binascii.b2a_hex(temp_file.encode()).decode(),), 98 {"direction": "send", 99 "regex": r"^\$F-1,[0-9a-fA-F]+#[0-9a-fA-F]{2}$"}], 100 True) 101 self.expect_gdbremote_sequence() 102 103 @skipIfWindows 104 @add_test_categories(["llgs"]) 105 def test_platform_file_size(self): 106 server = self.connect_to_debug_monitor() 107 self.assertIsNotNone(server) 108 109 temp_path = self.getBuildArtifact("test") 110 test_data = b"test data of some length" 111 with open(temp_path, "wb") as temp_file: 112 temp_file.write(test_data) 113 114 self.do_handshake() 115 self.test_sequence.add_log_lines( 116 ["read packet: $vFile:size:%s#00" % ( 117 binascii.b2a_hex(temp_path.encode()).decode(),), 118 {"direction": "send", 119 "regex": r"^\$F([0-9a-fA-F]+)+#[0-9a-fA-F]{2}$", 120 "capture": {1: "size"}}], 121 True) 122 context = self.expect_gdbremote_sequence() 123 self.assertEqual(int(context["size"], 16), len(test_data)) 124 125 @skipIfWindows 126 @add_test_categories(["llgs"]) 127 def test_platform_file_mode(self): 128 server = self.connect_to_debug_monitor() 129 self.assertIsNotNone(server) 130 131 temp_path = self.getBuildArtifact("test") 132 test_mode = 0o751 133 134 with open(temp_path, "wb") as temp_file: 135 os.chmod(temp_file.fileno(), test_mode) 136 137 self.do_handshake() 138 self.test_sequence.add_log_lines( 139 ["read packet: $vFile:mode:%s#00" % ( 140 binascii.b2a_hex(temp_path.encode()).decode(),), 141 {"direction": "send", 142 "regex": r"^\$F([0-9a-fA-F]+)+#[0-9a-fA-F]{2}$", 143 "capture": {1: "mode"}}], 144 True) 145 context = self.expect_gdbremote_sequence() 146 self.assertEqual(int(context["mode"], 16), test_mode) 147 148 @skipIfWindows 149 @add_test_categories(["llgs"]) 150 def test_platform_file_exists(self): 151 server = self.connect_to_debug_monitor() 152 self.assertIsNotNone(server) 153 154 temp_path = self.getBuildArtifact("test") 155 with open(temp_path, "wb"): 156 pass 157 158 self.do_handshake() 159 self.test_sequence.add_log_lines( 160 ["read packet: $vFile:exists:%s#00" % ( 161 binascii.b2a_hex(temp_path.encode()).decode(),), 162 "send packet: $F,1#00"], 163 True) 164 self.expect_gdbremote_sequence() 165 166 @skipIfWindows 167 @add_test_categories(["llgs"]) 168 def test_platform_file_exists_not(self): 169 server = self.connect_to_debug_monitor() 170 self.assertIsNotNone(server) 171 172 test_path = self.getBuildArtifact("nonexist") 173 self.do_handshake() 174 self.test_sequence.add_log_lines( 175 ["read packet: $vFile:exists:%s#00" % ( 176 binascii.b2a_hex(test_path.encode()).decode(),), 177 "send packet: $F,0#00"], 178 True) 179 self.expect_gdbremote_sequence() 180 181 def expect_error(self): 182 self.test_sequence.add_log_lines( 183 [{"direction": "send", 184 "regex": r"^\$F-1,[0-9a-fA-F]+#[0-9a-fA-F]{2}$"}], 185 True) 186 self.expect_gdbremote_sequence() 187 188 def vFile_test(self, read=False, write=False, append=False, trunc=False, 189 creat=False, excl=False): 190 if read and write: 191 mode = 2 192 elif write: 193 mode = 1 194 else: # read 195 mode = 0 196 if append: 197 mode |= 8 198 if creat: 199 mode |= 0x200 200 if trunc: 201 mode |= 0x400 202 if excl: 203 mode |= 0x800 204 205 old_umask = os.umask(0o22) 206 try: 207 server = self.connect_to_debug_monitor() 208 finally: 209 os.umask(old_umask) 210 self.assertIsNotNone(server) 211 212 # create a temporary file with some data 213 temp_path = self.getBuildArtifact("test") 214 test_data = 'some test data longer than 16 bytes\n' 215 216 if creat: 217 self.assertFalse(os.path.exists(temp_path)) 218 else: 219 with open(temp_path, "wb") as temp_file: 220 temp_file.write(test_data.encode()) 221 222 # open the file for reading 223 self.do_handshake() 224 self.test_sequence.add_log_lines( 225 ["read packet: $vFile:open:%s,%x,1a0#00" % ( 226 binascii.b2a_hex(temp_path.encode()).decode(), 227 mode), 228 {"direction": "send", 229 "regex": r"^\$F([0-9a-fA-F]+)#[0-9a-fA-F]{2}$", 230 "capture": {1: "fd"}}], 231 True) 232 233 context = self.expect_gdbremote_sequence() 234 self.assertIsNotNone(context) 235 fd = int(context["fd"], 16) 236 237 # read data from the file 238 self.reset_test_sequence() 239 self.test_sequence.add_log_lines( 240 ["read packet: $vFile:pread:%x,11,10#00" % (fd,)], 241 True) 242 if read: 243 self.test_sequence.add_log_lines( 244 [{"direction": "send", 245 "regex": r"^\$F([0-9a-fA-F]+);(.*)#[0-9a-fA-F]{2}$", 246 "capture": {1: "size", 2: "data"}}], 247 True) 248 context = self.expect_gdbremote_sequence() 249 self.assertIsNotNone(context) 250 if trunc: 251 self.assertEqual(context["size"], "0") 252 self.assertEqual(context["data"], "") 253 else: 254 self.assertEqual(context["size"], "11") # hex 255 self.assertEqual(context["data"], test_data[0x10:0x10 + 0x11]) 256 else: 257 self.expect_error() 258 259 # another offset 260 if read and not trunc: 261 self.reset_test_sequence() 262 self.test_sequence.add_log_lines( 263 ["read packet: $vFile:pread:%x,6,3#00" % (fd,), 264 {"direction": "send", 265 "regex": r"^\$F([0-9a-fA-F]+);(.+)#[0-9a-fA-F]{2}$", 266 "capture": {1: "size", 2: "data"}}], 267 True) 268 context = self.expect_gdbremote_sequence() 269 self.assertIsNotNone(context) 270 self.assertEqual(context["size"], "6") # hex 271 self.assertEqual(context["data"], test_data[3:3 + 6]) 272 273 # write data to the file 274 self.reset_test_sequence() 275 self.test_sequence.add_log_lines( 276 ["read packet: $vFile:pwrite:%x,6,somedata#00" % (fd,)], 277 True) 278 if write: 279 self.test_sequence.add_log_lines( 280 ["send packet: $F8#00"], 281 True) 282 self.expect_gdbremote_sequence() 283 else: 284 self.expect_error() 285 286 # close the file 287 self.reset_test_sequence() 288 self.test_sequence.add_log_lines( 289 ["read packet: $vFile:close:%x#00" % (fd,), 290 "send packet: $F0#00"], 291 True) 292 self.expect_gdbremote_sequence() 293 294 if write: 295 # check if the data was actually written 296 with open(temp_path, "rb") as temp_file: 297 if creat: 298 self.assertEqual(os.fstat(temp_file.fileno()).st_mode & 0o7777, 299 0o640) 300 data = test_data.encode() 301 if trunc or creat: 302 data = b"\0" * 6 + b"somedata" 303 elif append: 304 data += b"somedata" 305 else: 306 data = data[:6] + b"somedata" + data[6 + 8:] 307 self.assertEqual(temp_file.read(), data) 308