1 # lldb test suite imports
2 from lldbsuite
.test
.decorators
import *
3 from lldbsuite
.test
.lldbtest
import TestBase
4 from lldbsuite
.test
import lldbutil
6 # gdb-remote-specific imports
7 import lldbgdbserverutils
8 from gdbremote_testcase
import GdbRemoteTestCaseBase
17 class GDBStat(typing
.NamedTuple
):
33 def uint32_or_zero(x
):
34 return x
if x
< 2**32 and x
>= 0 else 0
38 return x
if x
< 2**32 and x
>= 0 else 2**32 - 1
42 return x
& (2**32 - 1)
45 class TestGdbRemotePlatformFile(GdbRemoteTestCaseBase
):
47 @add_test_categories(["llgs"])
48 def test_platform_file_rdonly(self
):
49 self
.vFile_test(read
=True)
52 @add_test_categories(["llgs"])
53 def test_platform_file_wronly(self
):
54 self
.vFile_test(write
=True)
57 @add_test_categories(["llgs"])
58 def test_platform_file_rdwr(self
):
59 self
.vFile_test(read
=True, write
=True)
62 @add_test_categories(["llgs"])
63 def test_platform_file_wronly_append(self
):
64 self
.vFile_test(write
=True, append
=True)
67 @add_test_categories(["llgs"])
68 def test_platform_file_rdwr_append(self
):
69 self
.vFile_test(read
=True, write
=True, append
=True)
72 @add_test_categories(["llgs"])
73 def test_platform_file_wronly_trunc(self
):
74 self
.vFile_test(write
=True, trunc
=True)
77 @add_test_categories(["llgs"])
78 def test_platform_file_rdwr_trunc(self
):
79 self
.vFile_test(read
=True, write
=True, trunc
=True)
82 @add_test_categories(["llgs"])
83 def test_platform_file_wronly_creat(self
):
84 self
.vFile_test(write
=True, creat
=True)
87 @add_test_categories(["llgs"])
88 def test_platform_file_wronly_creat_excl(self
):
89 self
.vFile_test(write
=True, creat
=True, excl
=True)
92 @add_test_categories(["llgs"])
93 def test_platform_file_wronly_fail(self
):
94 server
= self
.connect_to_debug_monitor()
95 self
.assertIsNotNone(server
)
97 temp_path
= self
.getBuildArtifact("test")
98 self
.assertFalse(os
.path
.exists(temp_path
))
100 # attempt to open the file without O_CREAT
102 self
.test_sequence
.add_log_lines(
104 "read packet: $vFile:open:%s,1,0#00"
105 % (binascii
.b2a_hex(temp_path
.encode()).decode(),),
106 {"direction": "send", "regex": r
"^\$F-1,[0-9a-fA-F]+#[0-9a-fA-F]{2}$"},
110 self
.expect_gdbremote_sequence()
113 @add_test_categories(["llgs"])
114 def test_platform_file_wronly_creat_excl_fail(self
):
115 server
= self
.connect_to_debug_monitor()
116 self
.assertIsNotNone(server
)
118 temp_file
= self
.getBuildArtifact("test")
119 with
open(temp_file
, "wb"):
121 temp_file
= lldbutil
.install_to_target(self
, temp_file
)
123 # attempt to open the file with O_CREAT|O_EXCL
125 self
.test_sequence
.add_log_lines(
127 "read packet: $vFile:open:%s,a01,0#00"
128 % (binascii
.b2a_hex(temp_file
.encode()).decode(),),
129 {"direction": "send", "regex": r
"^\$F-1,[0-9a-fA-F]+#[0-9a-fA-F]{2}$"},
133 self
.expect_gdbremote_sequence()
136 @add_test_categories(["llgs"])
137 def test_platform_file_size(self
):
138 server
= self
.connect_to_debug_monitor()
139 self
.assertIsNotNone(server
)
141 temp_path
= self
.getBuildArtifact("test")
142 test_data
= b
"test data of some length"
143 with
open(temp_path
, "wb") as temp_file
:
144 temp_file
.write(test_data
)
145 temp_path
= lldbutil
.install_to_target(self
, temp_path
)
148 self
.test_sequence
.add_log_lines(
150 "read packet: $vFile:size:%s#00"
151 % (binascii
.b2a_hex(temp_path
.encode()).decode(),),
154 "regex": r
"^\$F([0-9a-fA-F]+)+#[0-9a-fA-F]{2}$",
155 "capture": {1: "size"},
160 context
= self
.expect_gdbremote_sequence()
161 self
.assertEqual(int(context
["size"], 16), len(test_data
))
164 @add_test_categories(["llgs"])
165 def test_platform_file_mode(self
):
166 server
= self
.connect_to_debug_monitor()
167 self
.assertIsNotNone(server
)
169 temp_path
= self
.getBuildArtifact("test")
172 with
open(temp_path
, "wb") as temp_file
:
173 if lldbplatformutil
.getHostPlatform() == "windows":
176 os
.chmod(temp_file
.fileno(), test_mode
)
177 temp_path
= lldbutil
.install_to_target(self
, temp_path
)
180 self
.test_sequence
.add_log_lines(
182 "read packet: $vFile:mode:%s#00"
183 % (binascii
.b2a_hex(temp_path
.encode()).decode(),),
186 "regex": r
"^\$F([0-9a-fA-F]+)+#[0-9a-fA-F]{2}$",
187 "capture": {1: "mode"},
192 context
= self
.expect_gdbremote_sequence()
193 self
.assertEqual(int(context
["mode"], 16), test_mode
)
196 @add_test_categories(["llgs"])
197 def test_platform_file_mode_fail(self
):
198 server
= self
.connect_to_debug_monitor()
199 self
.assertIsNotNone(server
)
201 temp_path
= self
.getBuildArtifact("nonexist")
204 self
.test_sequence
.add_log_lines(
206 "read packet: $vFile:mode:%s#00"
207 % (binascii
.b2a_hex(temp_path
.encode()).decode(),),
208 {"direction": "send", "regex": r
"^\$F-1,0*2+#[0-9a-fA-F]{2}$"},
212 self
.expect_gdbremote_sequence()
215 @add_test_categories(["llgs"])
216 def test_platform_file_exists(self
):
217 server
= self
.connect_to_debug_monitor()
218 self
.assertIsNotNone(server
)
220 temp_path
= self
.getBuildArtifact("test")
221 with
open(temp_path
, "wb"):
223 temp_path
= lldbutil
.install_to_target(self
, temp_path
)
226 self
.test_sequence
.add_log_lines(
228 "read packet: $vFile:exists:%s#00"
229 % (binascii
.b2a_hex(temp_path
.encode()).decode(),),
230 "send packet: $F,1#00",
234 self
.expect_gdbremote_sequence()
237 @add_test_categories(["llgs"])
238 def test_platform_file_exists_not(self
):
239 server
= self
.connect_to_debug_monitor()
240 self
.assertIsNotNone(server
)
242 test_path
= self
.getBuildArtifact("nonexist")
244 self
.test_sequence
.add_log_lines(
246 "read packet: $vFile:exists:%s#00"
247 % (binascii
.b2a_hex(test_path
.encode()).decode(),),
248 "send packet: $F,0#00",
252 self
.expect_gdbremote_sequence()
255 # FIXME: lldb.remote_platform.Install() cannot copy opened temp file on Windows.
256 # It is possible to use tempfile.NamedTemporaryFile(..., delete=False) and
257 # delete the temp file manually at the end.
258 @skipIf(hostoslist
=["windows"])
259 @add_test_categories(["llgs"])
260 def test_platform_file_fstat(self
):
261 server
= self
.connect_to_debug_monitor()
262 self
.assertIsNotNone(server
)
264 with tempfile
.NamedTemporaryFile() as temp_file
:
265 temp_file
.write(b
"some test data for stat")
267 temp_path
= lldbutil
.install_to_target(self
, temp_file
.name
)
270 self
.test_sequence
.add_log_lines(
272 "read packet: $vFile:open:%s,0,0#00"
273 % (binascii
.b2a_hex(temp_path
.encode()).decode(),),
276 "regex": r
"^\$F([0-9a-fA-F]+)#[0-9a-fA-F]{2}$",
277 "capture": {1: "fd"},
283 context
= self
.expect_gdbremote_sequence()
284 self
.assertIsNotNone(context
)
285 fd
= int(context
["fd"], 16)
287 self
.reset_test_sequence()
288 self
.test_sequence
.add_log_lines(
290 "read packet: $vFile:fstat:%x#00" % (fd
,),
293 "regex": r
"^\$F([0-9a-fA-F]+);(.*)#[0-9a-fA-F]{2}$",
294 "capture": {1: "size", 2: "data"},
299 context
= self
.expect_gdbremote_sequence()
300 self
.assertEqual(int(context
["size"], 16), 64)
301 # NB: we're using .encode() as a hack because the test suite
302 # is wrongly using (unicode) str instead of bytes
306 self
.decode_gdbremote_binary(context
["data"]).encode("iso-8859-1"),
309 sys_stat
= os
.fstat(temp_file
.fileno())
311 self
.assertEqual(gdb_stat
.st_mode
, uint32_trunc(sys_stat
.st_mode
))
312 self
.assertEqual(gdb_stat
.st_nlink
, uint32_or_max(sys_stat
.st_nlink
))
313 self
.assertEqual(gdb_stat
.st_rdev
, uint32_or_zero(sys_stat
.st_rdev
))
314 self
.assertEqual(gdb_stat
.st_size
, sys_stat
.st_size
)
315 if not lldb
.remote_platform
:
316 self
.assertEqual(gdb_stat
.st_dev
, uint32_or_zero(sys_stat
.st_dev
))
317 self
.assertEqual(gdb_stat
.st_ino
, uint32_or_zero(sys_stat
.st_ino
))
318 self
.assertEqual(gdb_stat
.st_uid
, uint32_or_zero(sys_stat
.st_uid
))
319 self
.assertEqual(gdb_stat
.st_gid
, uint32_or_zero(sys_stat
.st_gid
))
320 self
.assertEqual(gdb_stat
.st_blksize
, sys_stat
.st_blksize
)
321 self
.assertEqual(gdb_stat
.st_blocks
, sys_stat
.st_blocks
)
323 gdb_stat
.st_atime
, uint32_or_zero(int(sys_stat
.st_atime
))
326 gdb_stat
.st_mtime
, uint32_or_zero(int(sys_stat
.st_mtime
))
329 gdb_stat
.st_ctime
, uint32_or_zero(int(sys_stat
.st_ctime
))
332 self
.reset_test_sequence()
333 self
.test_sequence
.add_log_lines(
334 ["read packet: $vFile:close:%x#00" % (fd
,), "send packet: $F0#00"], True
336 self
.expect_gdbremote_sequence()
338 def expect_error(self
):
339 self
.test_sequence
.add_log_lines(
340 [{"direction": "send", "regex": r
"^\$F-1,[0-9a-fA-F]+#[0-9a-fA-F]{2}$"}],
343 self
.expect_gdbremote_sequence()
369 old_umask
= os
.umask(0o22)
371 server
= self
.connect_to_debug_monitor()
374 self
.assertIsNotNone(server
)
376 # create a temporary file with some data
377 temp_path
= self
.getBuildArtifact("test")
378 test_data
= "some test data longer than 16 bytes\n"
381 self
.assertFalse(os
.path
.exists(temp_path
))
382 if lldb
.remote_platform
:
383 temp_path
= lldbutil
.append_to_process_working_directory(self
, "test")
385 with
open(temp_path
, "wb") as temp_file
:
386 temp_file
.write(test_data
.encode())
387 temp_path
= lldbutil
.install_to_target(self
, temp_path
)
389 # open the file for reading
391 self
.test_sequence
.add_log_lines(
393 "read packet: $vFile:open:%s,%x,1a0#00"
394 % (binascii
.b2a_hex(temp_path
.encode()).decode(), mode
),
397 "regex": r
"^\$F([0-9a-fA-F]+)#[0-9a-fA-F]{2}$",
398 "capture": {1: "fd"},
404 context
= self
.expect_gdbremote_sequence()
405 self
.assertIsNotNone(context
)
406 fd
= int(context
["fd"], 16)
408 # read data from the file
409 self
.reset_test_sequence()
410 self
.test_sequence
.add_log_lines(
411 ["read packet: $vFile:pread:%x,11,10#00" % (fd
,)], True
414 self
.test_sequence
.add_log_lines(
418 "regex": r
"^\$F([0-9a-fA-F]+);(.*)#[0-9a-fA-F]{2}$",
419 "capture": {1: "size", 2: "data"},
424 context
= self
.expect_gdbremote_sequence()
425 self
.assertIsNotNone(context
)
427 self
.assertEqual(context
["size"], "0")
428 self
.assertEqual(context
["data"], "")
430 self
.assertEqual(context
["size"], "11") # hex
431 self
.assertEqual(context
["data"], test_data
[0x10 : 0x10 + 0x11])
436 if read
and not trunc
:
437 self
.reset_test_sequence()
438 self
.test_sequence
.add_log_lines(
440 "read packet: $vFile:pread:%x,6,3#00" % (fd
,),
443 "regex": r
"^\$F([0-9a-fA-F]+);(.+)#[0-9a-fA-F]{2}$",
444 "capture": {1: "size", 2: "data"},
449 context
= self
.expect_gdbremote_sequence()
450 self
.assertIsNotNone(context
)
451 self
.assertEqual(context
["size"], "6") # hex
452 self
.assertEqual(context
["data"], test_data
[3 : 3 + 6])
454 # write data to the file
455 self
.reset_test_sequence()
456 self
.test_sequence
.add_log_lines(
457 ["read packet: $vFile:pwrite:%x,6,somedata#00" % (fd
,)], True
460 self
.test_sequence
.add_log_lines(["send packet: $F8#00"], True)
461 self
.expect_gdbremote_sequence()
466 self
.reset_test_sequence()
467 self
.test_sequence
.add_log_lines(
468 ["read packet: $vFile:close:%x#00" % (fd
,), "send packet: $F0#00"], True
470 self
.expect_gdbremote_sequence()
473 # check if the data was actually written
474 if lldb
.remote_platform
:
475 local_path
= self
.getBuildArtifact("file_from_target")
476 error
= lldb
.remote_platform
.Get(
477 lldb
.SBFileSpec(temp_path
, False), lldb
.SBFileSpec(local_path
, True)
481 "Reading file {0} failed: {1}".format(temp_path
, error
),
483 temp_path
= local_path
485 with
open(temp_path
, "rb") as temp_file
:
486 if creat
and lldbplatformutil
.getHostPlatform() != "windows":
488 os
.fstat(temp_file
.fileno()).st_mode
& 0o7777, 0o640
490 data
= test_data
.encode()
492 data
= b
"\0" * 6 + b
"somedata"
496 data
= data
[:6] + b
"somedata" + data
[6 + 8 :]
497 self
.assertEqual(temp_file
.read(), data
)