xref: /llvm-project/lldb/test/API/tools/lldb-server/TestGdbRemotePlatformFile.py (revision b62ba7f5b1caf99a3cbbe06d0e1c788c2dc85416)
19929cfbcSMichał Górny# lldb test suite imports
29929cfbcSMichał Górnyfrom lldbsuite.test.decorators import *
39929cfbcSMichał Górnyfrom lldbsuite.test.lldbtest import TestBase
4346f2b76SDmitry Vasilyevfrom lldbsuite.test import lldbutil
59929cfbcSMichał Górny
69929cfbcSMichał Górny# gdb-remote-specific imports
79929cfbcSMichał Górnyimport lldbgdbserverutils
89929cfbcSMichał Górnyfrom gdbremote_testcase import GdbRemoteTestCaseBase
99929cfbcSMichał Górny
109929cfbcSMichał Górnyimport binascii
11a1097d31SMichał Górnyimport os
129929cfbcSMichał Górnyimport stat
13a1097d31SMichał Górnyimport struct
14a1097d31SMichał Górnyimport typing
15a1097d31SMichał Górny
16a1097d31SMichał Górny
17a1097d31SMichał Górnyclass GDBStat(typing.NamedTuple):
18a1097d31SMichał Górny    st_dev: int
19a1097d31SMichał Górny    st_ino: int
20a1097d31SMichał Górny    st_mode: int
21a1097d31SMichał Górny    st_nlink: int
22a1097d31SMichał Górny    st_uid: int
23a1097d31SMichał Górny    st_gid: int
24a1097d31SMichał Górny    st_rdev: int
25a1097d31SMichał Górny    st_size: int
26a1097d31SMichał Górny    st_blksize: int
27a1097d31SMichał Górny    st_blocks: int
28a1097d31SMichał Górny    st_atime: int
29a1097d31SMichał Górny    st_mtime: int
30a1097d31SMichał Górny    st_ctime: int
31a1097d31SMichał Górny
32a1097d31SMichał Górny
33a1097d31SMichał Górnydef uint32_or_zero(x):
34d3292c4bSMichał Górny    return x if x < 2**32 and x >= 0 else 0
35a1097d31SMichał Górny
36a1097d31SMichał Górny
37a1097d31SMichał Górnydef uint32_or_max(x):
38d3292c4bSMichał Górny    return x if x < 2**32 and x >= 0 else 2**32 - 1
39a1097d31SMichał Górny
40a1097d31SMichał Górny
41a1097d31SMichał Górnydef uint32_trunc(x):
42a1097d31SMichał Górny    return x & (2**32 - 1)
439929cfbcSMichał Górny
449929cfbcSMichał Górny
459929cfbcSMichał Górnyclass TestGdbRemotePlatformFile(GdbRemoteTestCaseBase):
4627b238afSMichał Górny    @skipIfWindows
4752d89d26SMichał Górny    @add_test_categories(["llgs"])
489929cfbcSMichał Górny    def test_platform_file_rdonly(self):
499929cfbcSMichał Górny        self.vFile_test(read=True)
509929cfbcSMichał Górny
5127b238afSMichał Górny    @skipIfWindows
5252d89d26SMichał Górny    @add_test_categories(["llgs"])
539929cfbcSMichał Górny    def test_platform_file_wronly(self):
549929cfbcSMichał Górny        self.vFile_test(write=True)
559929cfbcSMichał Górny
5627b238afSMichał Górny    @skipIfWindows
5752d89d26SMichał Górny    @add_test_categories(["llgs"])
589929cfbcSMichał Górny    def test_platform_file_rdwr(self):
599929cfbcSMichał Górny        self.vFile_test(read=True, write=True)
609929cfbcSMichał Górny
6127b238afSMichał Górny    @skipIfWindows
6252d89d26SMichał Górny    @add_test_categories(["llgs"])
639929cfbcSMichał Górny    def test_platform_file_wronly_append(self):
649929cfbcSMichał Górny        self.vFile_test(write=True, append=True)
659929cfbcSMichał Górny
6627b238afSMichał Górny    @skipIfWindows
6752d89d26SMichał Górny    @add_test_categories(["llgs"])
689929cfbcSMichał Górny    def test_platform_file_rdwr_append(self):
699929cfbcSMichał Górny        self.vFile_test(read=True, write=True, append=True)
709929cfbcSMichał Górny
7127b238afSMichał Górny    @skipIfWindows
7252d89d26SMichał Górny    @add_test_categories(["llgs"])
739929cfbcSMichał Górny    def test_platform_file_wronly_trunc(self):
749929cfbcSMichał Górny        self.vFile_test(write=True, trunc=True)
759929cfbcSMichał Górny
7627b238afSMichał Górny    @skipIfWindows
7752d89d26SMichał Górny    @add_test_categories(["llgs"])
789929cfbcSMichał Górny    def test_platform_file_rdwr_trunc(self):
799929cfbcSMichał Górny        self.vFile_test(read=True, write=True, trunc=True)
809929cfbcSMichał Górny
8127b238afSMichał Górny    @skipIfWindows
8252d89d26SMichał Górny    @add_test_categories(["llgs"])
839929cfbcSMichał Górny    def test_platform_file_wronly_creat(self):
849929cfbcSMichał Górny        self.vFile_test(write=True, creat=True)
859929cfbcSMichał Górny
8627b238afSMichał Górny    @skipIfWindows
8752d89d26SMichał Górny    @add_test_categories(["llgs"])
889929cfbcSMichał Górny    def test_platform_file_wronly_creat_excl(self):
899929cfbcSMichał Górny        self.vFile_test(write=True, creat=True, excl=True)
909929cfbcSMichał Górny
9127b238afSMichał Górny    @skipIfWindows
9252d89d26SMichał Górny    @add_test_categories(["llgs"])
939929cfbcSMichał Górny    def test_platform_file_wronly_fail(self):
949929cfbcSMichał Górny        server = self.connect_to_debug_monitor()
959929cfbcSMichał Górny        self.assertIsNotNone(server)
969929cfbcSMichał Górny
978872c9d1SMichał Górny        temp_path = self.getBuildArtifact("test")
989929cfbcSMichał Górny        self.assertFalse(os.path.exists(temp_path))
999929cfbcSMichał Górny
1009929cfbcSMichał Górny        # attempt to open the file without O_CREAT
1019929cfbcSMichał Górny        self.do_handshake()
1029929cfbcSMichał Górny        self.test_sequence.add_log_lines(
1032238dcc3SJonas Devlieghere            [
1042238dcc3SJonas Devlieghere                "read packet: $vFile:open:%s,1,0#00"
1052238dcc3SJonas Devlieghere                % (binascii.b2a_hex(temp_path.encode()).decode(),),
1062238dcc3SJonas Devlieghere                {"direction": "send", "regex": r"^\$F-1,[0-9a-fA-F]+#[0-9a-fA-F]{2}$"},
1072238dcc3SJonas Devlieghere            ],
1082238dcc3SJonas Devlieghere            True,
1092238dcc3SJonas Devlieghere        )
1109929cfbcSMichał Górny        self.expect_gdbremote_sequence()
1119929cfbcSMichał Górny
11227b238afSMichał Górny    @skipIfWindows
11352d89d26SMichał Górny    @add_test_categories(["llgs"])
1149929cfbcSMichał Górny    def test_platform_file_wronly_creat_excl_fail(self):
1159929cfbcSMichał Górny        server = self.connect_to_debug_monitor()
1169929cfbcSMichał Górny        self.assertIsNotNone(server)
1179929cfbcSMichał Górny
1188872c9d1SMichał Górny        temp_file = self.getBuildArtifact("test")
1198872c9d1SMichał Górny        with open(temp_file, "wb"):
1208872c9d1SMichał Górny            pass
121346f2b76SDmitry Vasilyev        temp_file = lldbutil.install_to_target(self, temp_file)
1228872c9d1SMichał Górny
1239929cfbcSMichał Górny        # attempt to open the file with O_CREAT|O_EXCL
1249929cfbcSMichał Górny        self.do_handshake()
1259929cfbcSMichał Górny        self.test_sequence.add_log_lines(
1262238dcc3SJonas Devlieghere            [
1272238dcc3SJonas Devlieghere                "read packet: $vFile:open:%s,a01,0#00"
1282238dcc3SJonas Devlieghere                % (binascii.b2a_hex(temp_file.encode()).decode(),),
1292238dcc3SJonas Devlieghere                {"direction": "send", "regex": r"^\$F-1,[0-9a-fA-F]+#[0-9a-fA-F]{2}$"},
1302238dcc3SJonas Devlieghere            ],
1312238dcc3SJonas Devlieghere            True,
1322238dcc3SJonas Devlieghere        )
1339929cfbcSMichał Górny        self.expect_gdbremote_sequence()
1349929cfbcSMichał Górny
1358872c9d1SMichał Górny    @skipIfWindows
1368872c9d1SMichał Górny    @add_test_categories(["llgs"])
1378872c9d1SMichał Górny    def test_platform_file_size(self):
1388872c9d1SMichał Górny        server = self.connect_to_debug_monitor()
1398872c9d1SMichał Górny        self.assertIsNotNone(server)
1408872c9d1SMichał Górny
1418872c9d1SMichał Górny        temp_path = self.getBuildArtifact("test")
1428872c9d1SMichał Górny        test_data = b"test data of some length"
1438872c9d1SMichał Górny        with open(temp_path, "wb") as temp_file:
1448872c9d1SMichał Górny            temp_file.write(test_data)
145346f2b76SDmitry Vasilyev        temp_path = lldbutil.install_to_target(self, temp_path)
1468872c9d1SMichał Górny
1478872c9d1SMichał Górny        self.do_handshake()
1488872c9d1SMichał Górny        self.test_sequence.add_log_lines(
1492238dcc3SJonas Devlieghere            [
1502238dcc3SJonas Devlieghere                "read packet: $vFile:size:%s#00"
1512238dcc3SJonas Devlieghere                % (binascii.b2a_hex(temp_path.encode()).decode(),),
1522238dcc3SJonas Devlieghere                {
1532238dcc3SJonas Devlieghere                    "direction": "send",
1548872c9d1SMichał Górny                    "regex": r"^\$F([0-9a-fA-F]+)+#[0-9a-fA-F]{2}$",
1552238dcc3SJonas Devlieghere                    "capture": {1: "size"},
1562238dcc3SJonas Devlieghere                },
1572238dcc3SJonas Devlieghere            ],
1582238dcc3SJonas Devlieghere            True,
1592238dcc3SJonas Devlieghere        )
1608872c9d1SMichał Górny        context = self.expect_gdbremote_sequence()
1618872c9d1SMichał Górny        self.assertEqual(int(context["size"], 16), len(test_data))
1628872c9d1SMichał Górny
1638872c9d1SMichał Górny    @skipIfWindows
1648872c9d1SMichał Górny    @add_test_categories(["llgs"])
1658872c9d1SMichał Górny    def test_platform_file_mode(self):
1668872c9d1SMichał Górny        server = self.connect_to_debug_monitor()
1678872c9d1SMichał Górny        self.assertIsNotNone(server)
1688872c9d1SMichał Górny
1698872c9d1SMichał Górny        temp_path = self.getBuildArtifact("test")
1708872c9d1SMichał Górny        test_mode = 0o751
1718872c9d1SMichał Górny
1728872c9d1SMichał Górny        with open(temp_path, "wb") as temp_file:
173346f2b76SDmitry Vasilyev            if lldbplatformutil.getHostPlatform() == "windows":
174346f2b76SDmitry Vasilyev                test_mode = 0o700
175346f2b76SDmitry Vasilyev            else:
1768872c9d1SMichał Górny                os.chmod(temp_file.fileno(), test_mode)
177346f2b76SDmitry Vasilyev        temp_path = lldbutil.install_to_target(self, temp_path)
1788872c9d1SMichał Górny
1798872c9d1SMichał Górny        self.do_handshake()
1808872c9d1SMichał Górny        self.test_sequence.add_log_lines(
1812238dcc3SJonas Devlieghere            [
1822238dcc3SJonas Devlieghere                "read packet: $vFile:mode:%s#00"
1832238dcc3SJonas Devlieghere                % (binascii.b2a_hex(temp_path.encode()).decode(),),
1842238dcc3SJonas Devlieghere                {
1852238dcc3SJonas Devlieghere                    "direction": "send",
1868872c9d1SMichał Górny                    "regex": r"^\$F([0-9a-fA-F]+)+#[0-9a-fA-F]{2}$",
1872238dcc3SJonas Devlieghere                    "capture": {1: "mode"},
1882238dcc3SJonas Devlieghere                },
1892238dcc3SJonas Devlieghere            ],
1902238dcc3SJonas Devlieghere            True,
1912238dcc3SJonas Devlieghere        )
1928872c9d1SMichał Górny        context = self.expect_gdbremote_sequence()
1938872c9d1SMichał Górny        self.assertEqual(int(context["mode"], 16), test_mode)
1948872c9d1SMichał Górny
1958872c9d1SMichał Górny    @skipIfWindows
1968872c9d1SMichał Górny    @add_test_categories(["llgs"])
197dbb0c14dSMichał Górny    def test_platform_file_mode_fail(self):
198dbb0c14dSMichał Górny        server = self.connect_to_debug_monitor()
199dbb0c14dSMichał Górny        self.assertIsNotNone(server)
200dbb0c14dSMichał Górny
201dbb0c14dSMichał Górny        temp_path = self.getBuildArtifact("nonexist")
202dbb0c14dSMichał Górny
203dbb0c14dSMichał Górny        self.do_handshake()
204dbb0c14dSMichał Górny        self.test_sequence.add_log_lines(
2052238dcc3SJonas Devlieghere            [
2062238dcc3SJonas Devlieghere                "read packet: $vFile:mode:%s#00"
2072238dcc3SJonas Devlieghere                % (binascii.b2a_hex(temp_path.encode()).decode(),),
2082238dcc3SJonas Devlieghere                {"direction": "send", "regex": r"^\$F-1,0*2+#[0-9a-fA-F]{2}$"},
2092238dcc3SJonas Devlieghere            ],
2102238dcc3SJonas Devlieghere            True,
2112238dcc3SJonas Devlieghere        )
212dbb0c14dSMichał Górny        self.expect_gdbremote_sequence()
213dbb0c14dSMichał Górny
214dbb0c14dSMichał Górny    @skipIfWindows
215dbb0c14dSMichał Górny    @add_test_categories(["llgs"])
2168872c9d1SMichał Górny    def test_platform_file_exists(self):
2178872c9d1SMichał Górny        server = self.connect_to_debug_monitor()
2188872c9d1SMichał Górny        self.assertIsNotNone(server)
2198872c9d1SMichał Górny
2208872c9d1SMichał Górny        temp_path = self.getBuildArtifact("test")
2218872c9d1SMichał Górny        with open(temp_path, "wb"):
2228872c9d1SMichał Górny            pass
223346f2b76SDmitry Vasilyev        temp_path = lldbutil.install_to_target(self, temp_path)
2248872c9d1SMichał Górny
2258872c9d1SMichał Górny        self.do_handshake()
2268872c9d1SMichał Górny        self.test_sequence.add_log_lines(
2272238dcc3SJonas Devlieghere            [
2282238dcc3SJonas Devlieghere                "read packet: $vFile:exists:%s#00"
2292238dcc3SJonas Devlieghere                % (binascii.b2a_hex(temp_path.encode()).decode(),),
2302238dcc3SJonas Devlieghere                "send packet: $F,1#00",
2312238dcc3SJonas Devlieghere            ],
2322238dcc3SJonas Devlieghere            True,
2332238dcc3SJonas Devlieghere        )
2348872c9d1SMichał Górny        self.expect_gdbremote_sequence()
2358872c9d1SMichał Górny
2368872c9d1SMichał Górny    @skipIfWindows
2378872c9d1SMichał Górny    @add_test_categories(["llgs"])
2388872c9d1SMichał Górny    def test_platform_file_exists_not(self):
2398872c9d1SMichał Górny        server = self.connect_to_debug_monitor()
2408872c9d1SMichał Górny        self.assertIsNotNone(server)
2418872c9d1SMichał Górny
2428872c9d1SMichał Górny        test_path = self.getBuildArtifact("nonexist")
2438872c9d1SMichał Górny        self.do_handshake()
2448872c9d1SMichał Górny        self.test_sequence.add_log_lines(
2452238dcc3SJonas Devlieghere            [
2462238dcc3SJonas Devlieghere                "read packet: $vFile:exists:%s#00"
2472238dcc3SJonas Devlieghere                % (binascii.b2a_hex(test_path.encode()).decode(),),
2482238dcc3SJonas Devlieghere                "send packet: $F,0#00",
2492238dcc3SJonas Devlieghere            ],
2502238dcc3SJonas Devlieghere            True,
2512238dcc3SJonas Devlieghere        )
2528872c9d1SMichał Górny        self.expect_gdbremote_sequence()
2538872c9d1SMichał Górny
254a1097d31SMichał Górny    @skipIfWindows
255346f2b76SDmitry Vasilyev    # FIXME: lldb.remote_platform.Install() cannot copy opened temp file on Windows.
256346f2b76SDmitry Vasilyev    # It is possible to use tempfile.NamedTemporaryFile(..., delete=False) and
257346f2b76SDmitry Vasilyev    # delete the temp file manually at the end.
258346f2b76SDmitry Vasilyev    @skipIf(hostoslist=["windows"])
259a1097d31SMichał Górny    @add_test_categories(["llgs"])
260a1097d31SMichał Górny    def test_platform_file_fstat(self):
261a1097d31SMichał Górny        server = self.connect_to_debug_monitor()
262a1097d31SMichał Górny        self.assertIsNotNone(server)
263a1097d31SMichał Górny
264a1097d31SMichał Górny        with tempfile.NamedTemporaryFile() as temp_file:
265a1097d31SMichał Górny            temp_file.write(b"some test data for stat")
266a1097d31SMichał Górny            temp_file.flush()
267346f2b76SDmitry Vasilyev            temp_path = lldbutil.install_to_target(self, temp_file.name)
268a1097d31SMichał Górny
269a1097d31SMichał Górny            self.do_handshake()
270a1097d31SMichał Górny            self.test_sequence.add_log_lines(
2712238dcc3SJonas Devlieghere                [
2722238dcc3SJonas Devlieghere                    "read packet: $vFile:open:%s,0,0#00"
273346f2b76SDmitry Vasilyev                    % (binascii.b2a_hex(temp_path.encode()).decode(),),
2742238dcc3SJonas Devlieghere                    {
2752238dcc3SJonas Devlieghere                        "direction": "send",
276a1097d31SMichał Górny                        "regex": r"^\$F([0-9a-fA-F]+)#[0-9a-fA-F]{2}$",
2772238dcc3SJonas Devlieghere                        "capture": {1: "fd"},
2782238dcc3SJonas Devlieghere                    },
2792238dcc3SJonas Devlieghere                ],
2802238dcc3SJonas Devlieghere                True,
2812238dcc3SJonas Devlieghere            )
282a1097d31SMichał Górny
283a1097d31SMichał Górny            context = self.expect_gdbremote_sequence()
284a1097d31SMichał Górny            self.assertIsNotNone(context)
285a1097d31SMichał Górny            fd = int(context["fd"], 16)
286a1097d31SMichał Górny
287a1097d31SMichał Górny            self.reset_test_sequence()
288a1097d31SMichał Górny            self.test_sequence.add_log_lines(
2892238dcc3SJonas Devlieghere                [
2902238dcc3SJonas Devlieghere                    "read packet: $vFile:fstat:%x#00" % (fd,),
2912238dcc3SJonas Devlieghere                    {
2922238dcc3SJonas Devlieghere                        "direction": "send",
293a1097d31SMichał Górny                        "regex": r"^\$F([0-9a-fA-F]+);(.*)#[0-9a-fA-F]{2}$",
2942238dcc3SJonas Devlieghere                        "capture": {1: "size", 2: "data"},
2952238dcc3SJonas Devlieghere                    },
2962238dcc3SJonas Devlieghere                ],
2972238dcc3SJonas Devlieghere                True,
2982238dcc3SJonas Devlieghere            )
299a1097d31SMichał Górny            context = self.expect_gdbremote_sequence()
300a1097d31SMichał Górny            self.assertEqual(int(context["size"], 16), 64)
301a1097d31SMichał Górny            # NB: we're using .encode() as a hack because the test suite
302a1097d31SMichał Górny            # is wrongly using (unicode) str instead of bytes
303a1097d31SMichał Górny            gdb_stat = GDBStat(
3042238dcc3SJonas Devlieghere                *struct.unpack(
3052238dcc3SJonas Devlieghere                    ">IIIIIIIQQQIII",
3062238dcc3SJonas Devlieghere                    self.decode_gdbremote_binary(context["data"]).encode("iso-8859-1"),
3072238dcc3SJonas Devlieghere                )
3082238dcc3SJonas Devlieghere            )
309a1097d31SMichał Górny            sys_stat = os.fstat(temp_file.fileno())
310a1097d31SMichał Górny
311a1097d31SMichał Górny            self.assertEqual(gdb_stat.st_mode, uint32_trunc(sys_stat.st_mode))
312a1097d31SMichał Górny            self.assertEqual(gdb_stat.st_nlink, uint32_or_max(sys_stat.st_nlink))
313a1097d31SMichał Górny            self.assertEqual(gdb_stat.st_rdev, uint32_or_zero(sys_stat.st_rdev))
314a1097d31SMichał Górny            self.assertEqual(gdb_stat.st_size, sys_stat.st_size)
315*b62ba7f5SDmitry Vasilyev            if not lldb.remote_platform:
316*b62ba7f5SDmitry Vasilyev                self.assertEqual(gdb_stat.st_dev, uint32_or_zero(sys_stat.st_dev))
317*b62ba7f5SDmitry Vasilyev                self.assertEqual(gdb_stat.st_ino, uint32_or_zero(sys_stat.st_ino))
318*b62ba7f5SDmitry Vasilyev                self.assertEqual(gdb_stat.st_uid, uint32_or_zero(sys_stat.st_uid))
319*b62ba7f5SDmitry Vasilyev                self.assertEqual(gdb_stat.st_gid, uint32_or_zero(sys_stat.st_gid))
320a1097d31SMichał Górny                self.assertEqual(gdb_stat.st_blksize, sys_stat.st_blksize)
321a1097d31SMichał Górny                self.assertEqual(gdb_stat.st_blocks, sys_stat.st_blocks)
322*b62ba7f5SDmitry Vasilyev                self.assertEqual(
323*b62ba7f5SDmitry Vasilyev                    gdb_stat.st_atime, uint32_or_zero(int(sys_stat.st_atime))
324*b62ba7f5SDmitry Vasilyev                )
325*b62ba7f5SDmitry Vasilyev                self.assertEqual(
326*b62ba7f5SDmitry Vasilyev                    gdb_stat.st_mtime, uint32_or_zero(int(sys_stat.st_mtime))
327*b62ba7f5SDmitry Vasilyev                )
328*b62ba7f5SDmitry Vasilyev                self.assertEqual(
329*b62ba7f5SDmitry Vasilyev                    gdb_stat.st_ctime, uint32_or_zero(int(sys_stat.st_ctime))
330*b62ba7f5SDmitry Vasilyev                )
331a1097d31SMichał Górny
332a1097d31SMichał Górny            self.reset_test_sequence()
333a1097d31SMichał Górny            self.test_sequence.add_log_lines(
3342238dcc3SJonas Devlieghere                ["read packet: $vFile:close:%x#00" % (fd,), "send packet: $F0#00"], True
3352238dcc3SJonas Devlieghere            )
336a1097d31SMichał Górny            self.expect_gdbremote_sequence()
337a1097d31SMichał Górny
3389929cfbcSMichał Górny    def expect_error(self):
3399929cfbcSMichał Górny        self.test_sequence.add_log_lines(
3402238dcc3SJonas Devlieghere            [{"direction": "send", "regex": r"^\$F-1,[0-9a-fA-F]+#[0-9a-fA-F]{2}$"}],
3412238dcc3SJonas Devlieghere            True,
3422238dcc3SJonas Devlieghere        )
3439929cfbcSMichał Górny        self.expect_gdbremote_sequence()
3449929cfbcSMichał Górny
3452238dcc3SJonas Devlieghere    def vFile_test(
3462238dcc3SJonas Devlieghere        self,
3472238dcc3SJonas Devlieghere        read=False,
3482238dcc3SJonas Devlieghere        write=False,
3492238dcc3SJonas Devlieghere        append=False,
3502238dcc3SJonas Devlieghere        trunc=False,
3512238dcc3SJonas Devlieghere        creat=False,
3522238dcc3SJonas Devlieghere        excl=False,
3532238dcc3SJonas Devlieghere    ):
3549929cfbcSMichał Górny        if read and write:
3559929cfbcSMichał Górny            mode = 2
3569929cfbcSMichał Górny        elif write:
3579929cfbcSMichał Górny            mode = 1
3589929cfbcSMichał Górny        else:  # read
3599929cfbcSMichał Górny            mode = 0
3609929cfbcSMichał Górny        if append:
3619929cfbcSMichał Górny            mode |= 8
3629929cfbcSMichał Górny        if creat:
3639929cfbcSMichał Górny            mode |= 0x200
3649929cfbcSMichał Górny        if trunc:
3659929cfbcSMichał Górny            mode |= 0x400
3669929cfbcSMichał Górny        if excl:
3679929cfbcSMichał Górny            mode |= 0x800
3689929cfbcSMichał Górny
3694c830b5fSMichał Górny        old_umask = os.umask(0o22)
370d6bf9dcbSMichał Górny        try:
3719929cfbcSMichał Górny            server = self.connect_to_debug_monitor()
372d6bf9dcbSMichał Górny        finally:
373d6bf9dcbSMichał Górny            os.umask(old_umask)
3749929cfbcSMichał Górny        self.assertIsNotNone(server)
3759929cfbcSMichał Górny
3769929cfbcSMichał Górny        # create a temporary file with some data
3778872c9d1SMichał Górny        temp_path = self.getBuildArtifact("test")
3782238dcc3SJonas Devlieghere        test_data = "some test data longer than 16 bytes\n"
3799929cfbcSMichał Górny
3809929cfbcSMichał Górny        if creat:
3819929cfbcSMichał Górny            self.assertFalse(os.path.exists(temp_path))
382346f2b76SDmitry Vasilyev            if lldb.remote_platform:
383346f2b76SDmitry Vasilyev                temp_path = lldbutil.append_to_process_working_directory(self, "test")
3849929cfbcSMichał Górny        else:
3858872c9d1SMichał Górny            with open(temp_path, "wb") as temp_file:
3869929cfbcSMichał Górny                temp_file.write(test_data.encode())
387346f2b76SDmitry Vasilyev            temp_path = lldbutil.install_to_target(self, temp_path)
3889929cfbcSMichał Górny
3899929cfbcSMichał Górny        # open the file for reading
3909929cfbcSMichał Górny        self.do_handshake()
3919929cfbcSMichał Górny        self.test_sequence.add_log_lines(
3922238dcc3SJonas Devlieghere            [
3932238dcc3SJonas Devlieghere                "read packet: $vFile:open:%s,%x,1a0#00"
3942238dcc3SJonas Devlieghere                % (binascii.b2a_hex(temp_path.encode()).decode(), mode),
3952238dcc3SJonas Devlieghere                {
3962238dcc3SJonas Devlieghere                    "direction": "send",
3979929cfbcSMichał Górny                    "regex": r"^\$F([0-9a-fA-F]+)#[0-9a-fA-F]{2}$",
3982238dcc3SJonas Devlieghere                    "capture": {1: "fd"},
3992238dcc3SJonas Devlieghere                },
4002238dcc3SJonas Devlieghere            ],
4012238dcc3SJonas Devlieghere            True,
4022238dcc3SJonas Devlieghere        )
4039929cfbcSMichał Górny
4049929cfbcSMichał Górny        context = self.expect_gdbremote_sequence()
4059929cfbcSMichał Górny        self.assertIsNotNone(context)
4069929cfbcSMichał Górny        fd = int(context["fd"], 16)
4079929cfbcSMichał Górny
4089929cfbcSMichał Górny        # read data from the file
4099929cfbcSMichał Górny        self.reset_test_sequence()
4109929cfbcSMichał Górny        self.test_sequence.add_log_lines(
4112238dcc3SJonas Devlieghere            ["read packet: $vFile:pread:%x,11,10#00" % (fd,)], True
4122238dcc3SJonas Devlieghere        )
4139929cfbcSMichał Górny        if read:
4149929cfbcSMichał Górny            self.test_sequence.add_log_lines(
4152238dcc3SJonas Devlieghere                [
4162238dcc3SJonas Devlieghere                    {
4172238dcc3SJonas Devlieghere                        "direction": "send",
4189929cfbcSMichał Górny                        "regex": r"^\$F([0-9a-fA-F]+);(.*)#[0-9a-fA-F]{2}$",
4192238dcc3SJonas Devlieghere                        "capture": {1: "size", 2: "data"},
4202238dcc3SJonas Devlieghere                    }
4212238dcc3SJonas Devlieghere                ],
4222238dcc3SJonas Devlieghere                True,
4232238dcc3SJonas Devlieghere            )
4249929cfbcSMichał Górny            context = self.expect_gdbremote_sequence()
4259929cfbcSMichał Górny            self.assertIsNotNone(context)
4269929cfbcSMichał Górny            if trunc:
4279929cfbcSMichał Górny                self.assertEqual(context["size"], "0")
4289929cfbcSMichał Górny                self.assertEqual(context["data"], "")
4299929cfbcSMichał Górny            else:
4309929cfbcSMichał Górny                self.assertEqual(context["size"], "11")  # hex
4319929cfbcSMichał Górny                self.assertEqual(context["data"], test_data[0x10 : 0x10 + 0x11])
4329929cfbcSMichał Górny        else:
4339929cfbcSMichał Górny            self.expect_error()
4349929cfbcSMichał Górny
4359929cfbcSMichał Górny        # another offset
4369929cfbcSMichał Górny        if read and not trunc:
4379929cfbcSMichał Górny            self.reset_test_sequence()
4389929cfbcSMichał Górny            self.test_sequence.add_log_lines(
4392238dcc3SJonas Devlieghere                [
4402238dcc3SJonas Devlieghere                    "read packet: $vFile:pread:%x,6,3#00" % (fd,),
4412238dcc3SJonas Devlieghere                    {
4422238dcc3SJonas Devlieghere                        "direction": "send",
4439929cfbcSMichał Górny                        "regex": r"^\$F([0-9a-fA-F]+);(.+)#[0-9a-fA-F]{2}$",
4442238dcc3SJonas Devlieghere                        "capture": {1: "size", 2: "data"},
4452238dcc3SJonas Devlieghere                    },
4462238dcc3SJonas Devlieghere                ],
4472238dcc3SJonas Devlieghere                True,
4482238dcc3SJonas Devlieghere            )
4499929cfbcSMichał Górny            context = self.expect_gdbremote_sequence()
4509929cfbcSMichał Górny            self.assertIsNotNone(context)
4519929cfbcSMichał Górny            self.assertEqual(context["size"], "6")  # hex
4529929cfbcSMichał Górny            self.assertEqual(context["data"], test_data[3 : 3 + 6])
4539929cfbcSMichał Górny
4549929cfbcSMichał Górny        # write data to the file
4559929cfbcSMichał Górny        self.reset_test_sequence()
4569929cfbcSMichał Górny        self.test_sequence.add_log_lines(
4572238dcc3SJonas Devlieghere            ["read packet: $vFile:pwrite:%x,6,somedata#00" % (fd,)], True
4582238dcc3SJonas Devlieghere        )
4599929cfbcSMichał Górny        if write:
4602238dcc3SJonas Devlieghere            self.test_sequence.add_log_lines(["send packet: $F8#00"], True)
4619929cfbcSMichał Górny            self.expect_gdbremote_sequence()
4629929cfbcSMichał Górny        else:
4639929cfbcSMichał Górny            self.expect_error()
4649929cfbcSMichał Górny
4659929cfbcSMichał Górny        # close the file
4669929cfbcSMichał Górny        self.reset_test_sequence()
4679929cfbcSMichał Górny        self.test_sequence.add_log_lines(
4682238dcc3SJonas Devlieghere            ["read packet: $vFile:close:%x#00" % (fd,), "send packet: $F0#00"], True
4692238dcc3SJonas Devlieghere        )
4709929cfbcSMichał Górny        self.expect_gdbremote_sequence()
4719929cfbcSMichał Górny
4729929cfbcSMichał Górny        if write:
4739929cfbcSMichał Górny            # check if the data was actually written
474346f2b76SDmitry Vasilyev            if lldb.remote_platform:
475346f2b76SDmitry Vasilyev                local_path = self.getBuildArtifact("file_from_target")
476346f2b76SDmitry Vasilyev                error = lldb.remote_platform.Get(
477346f2b76SDmitry Vasilyev                    lldb.SBFileSpec(temp_path, False), lldb.SBFileSpec(local_path, True)
478346f2b76SDmitry Vasilyev                )
479346f2b76SDmitry Vasilyev                self.assertTrue(
480346f2b76SDmitry Vasilyev                    error.Success(),
481346f2b76SDmitry Vasilyev                    "Reading file {0} failed: {1}".format(temp_path, error),
482346f2b76SDmitry Vasilyev                )
483346f2b76SDmitry Vasilyev                temp_path = local_path
484346f2b76SDmitry Vasilyev
4858872c9d1SMichał Górny            with open(temp_path, "rb") as temp_file:
486346f2b76SDmitry Vasilyev                if creat and lldbplatformutil.getHostPlatform() != "windows":
4872238dcc3SJonas Devlieghere                    self.assertEqual(
4882238dcc3SJonas Devlieghere                        os.fstat(temp_file.fileno()).st_mode & 0o7777, 0o640
4892238dcc3SJonas Devlieghere                    )
4909929cfbcSMichał Górny                data = test_data.encode()
4919929cfbcSMichał Górny                if trunc or creat:
4929929cfbcSMichał Górny                    data = b"\0" * 6 + b"somedata"
4939929cfbcSMichał Górny                elif append:
4949929cfbcSMichał Górny                    data += b"somedata"
4959929cfbcSMichał Górny                else:
4969929cfbcSMichał Górny                    data = data[:6] + b"somedata" + data[6 + 8 :]
4979929cfbcSMichał Górny                self.assertEqual(temp_file.read(), data)
498