133c0f93fSPavel Labathfrom lldbsuite.test.gdbclientutils import *
29a4379c3SMichał Górnyfrom lldbsuite.test.decorators import *
333c0f93fSPavel Labathfrom lldbsuite.test.lldbgdbclient import GDBPlatformClientTestBase
49a4379c3SMichał Górny
5c240d2bbSMichał Górnyclass TestGDBRemotePlatformFile(GDBPlatformClientTestBase):
68bbef4f9SMichał Górny
79929cfbcSMichał Górny    def test_file(self):
89929cfbcSMichał Górny        """Test mock operations on a remote file"""
98bbef4f9SMichał Górny
108bbef4f9SMichał Górny        class Responder(MockGDBServerResponder):
118bbef4f9SMichał Górny            def vFile(self, packet):
129929cfbcSMichał Górny                if packet.startswith("vFile:open:"):
138bbef4f9SMichał Górny                    return "F10"
149929cfbcSMichał Górny                elif packet.startswith("vFile:pread:"):
159929cfbcSMichał Górny                    return "Fd;frobnicator"
169929cfbcSMichał Górny                elif packet.startswith("vFile:pwrite:"):
179929cfbcSMichał Górny                    return "Fa"
189929cfbcSMichał Górny                elif packet.startswith("vFile:close:"):
199929cfbcSMichał Górny                    return "F0"
203d3017d3SMichał Górny                return "F-1,58"
218bbef4f9SMichał Górny
228bbef4f9SMichał Górny        self.server.responder = Responder()
238bbef4f9SMichał Górny
249929cfbcSMichał Górny        self.match("platform file open /some/file.txt -v 0755",
259929cfbcSMichał Górny                   [r"File Descriptor = 16"])
269929cfbcSMichał Górny        self.match("platform file read 16 -o 11 -c 13",
279929cfbcSMichał Górny                   [r"Return = 11\nData = \"frobnicator\""])
289929cfbcSMichał Górny        self.match("platform file write 16 -o 11 -d teststring",
299929cfbcSMichał Górny                   [r"Return = 10"])
309929cfbcSMichał Górny        self.match("platform file close 16",
319929cfbcSMichał Górny                   [r"file 16 closed."])
328bbef4f9SMichał Górny        self.assertPacketLogContains([
332c6d90d7SMichał Górny            "vFile:open:2f736f6d652f66696c652e747874,00000202,000001ed",
349929cfbcSMichał Górny            "vFile:pread:10,d,b",
359929cfbcSMichał Górny            "vFile:pwrite:10,b,teststring",
369929cfbcSMichał Górny            "vFile:close:10",
379929cfbcSMichał Górny            ])
389929cfbcSMichał Górny
399929cfbcSMichał Górny    def test_file_fail(self):
409929cfbcSMichał Górny        """Test mocked failures of remote operations"""
419929cfbcSMichał Górny
429929cfbcSMichał Górny        class Responder(MockGDBServerResponder):
439929cfbcSMichał Górny            def vFile(self, packet):
443d3017d3SMichał Górny                # use ENOSYS as this constant differs between GDB Remote
453d3017d3SMichał Górny                # Protocol and Linux, so we can test the translation
463d3017d3SMichał Górny                return "F-1,58"
479929cfbcSMichał Górny
489929cfbcSMichał Górny        self.server.responder = Responder()
499929cfbcSMichał Górny
509929cfbcSMichał Górny        self.match("platform file open /some/file.txt -v 0755",
513d3017d3SMichał Górny                   [r"error: Function not implemented"],
529929cfbcSMichał Górny                   error=True)
539929cfbcSMichał Górny        self.match("platform file read 16 -o 11 -c 13",
543d3017d3SMichał Górny                   [r"error: Function not implemented"],
5539a2449eSMichał Górny                   error=True)
569929cfbcSMichał Górny        self.match("platform file write 16 -o 11 -d teststring",
573d3017d3SMichał Górny                   [r"error: Function not implemented"],
5839a2449eSMichał Górny                   error=True)
599929cfbcSMichał Górny        self.match("platform file close 16",
603d3017d3SMichał Górny                   [r"error: Function not implemented"],
619929cfbcSMichał Górny                   error=True)
629929cfbcSMichał Górny        self.assertPacketLogContains([
632c6d90d7SMichał Górny            "vFile:open:2f736f6d652f66696c652e747874,00000202,000001ed",
649929cfbcSMichał Górny            "vFile:pread:10,d,b",
659929cfbcSMichał Górny            "vFile:pwrite:10,b,teststring",
669929cfbcSMichał Górny            "vFile:close:10",
678bbef4f9SMichał Górny            ])
6821e2d7ceSMichał Górny
6921e2d7ceSMichał Górny    def test_file_size(self):
7021e2d7ceSMichał Górny        """Test 'platform get-size'"""
7121e2d7ceSMichał Górny
7221e2d7ceSMichał Górny        class Responder(MockGDBServerResponder):
7321e2d7ceSMichał Górny            def vFile(self, packet):
7421e2d7ceSMichał Górny                return "F1000"
7521e2d7ceSMichał Górny
7621e2d7ceSMichał Górny        self.server.responder = Responder()
7721e2d7ceSMichał Górny
7821e2d7ceSMichał Górny        self.match("platform get-size /some/file.txt",
7921e2d7ceSMichał Górny                   [r"File size of /some/file\.txt \(remote\): 4096"])
8021e2d7ceSMichał Górny        self.assertPacketLogContains([
8121e2d7ceSMichał Górny            "vFile:size:2f736f6d652f66696c652e747874",
8221e2d7ceSMichał Górny            ])
8321e2d7ceSMichał Górny
8421e2d7ceSMichał Górny    def test_file_size_fallback(self):
8521e2d7ceSMichał Górny        """Test 'platform get-size fallback to vFile:fstat'"""
8621e2d7ceSMichał Górny
8721e2d7ceSMichał Górny        class Responder(MockGDBServerResponder):
8821e2d7ceSMichał Górny            def vFile(self, packet):
8921e2d7ceSMichał Górny                if packet.startswith("vFile:open:"):
9021e2d7ceSMichał Górny                    return "F5"
9121e2d7ceSMichał Górny                elif packet.startswith("vFile:fstat:"):
9221e2d7ceSMichał Górny                    return "F40;" + 28 * "\0" + "\0\0\0\0\0\1\2\3" + 28 * "\0"
9321e2d7ceSMichał Górny                if packet.startswith("vFile:close:"):
9421e2d7ceSMichał Górny                    return "F0"
9521e2d7ceSMichał Górny                return ""
9621e2d7ceSMichał Górny
9721e2d7ceSMichał Górny        self.server.responder = Responder()
9821e2d7ceSMichał Górny
9921e2d7ceSMichał Górny        self.match("platform get-size /some/file.txt",
10021e2d7ceSMichał Górny                   [r"File size of /some/file\.txt \(remote\): 66051"])
10121e2d7ceSMichał Górny        self.assertPacketLogContains([
10221e2d7ceSMichał Górny            "vFile:size:2f736f6d652f66696c652e747874",
10321e2d7ceSMichał Górny            "vFile:open:2f736f6d652f66696c652e747874,00000000,00000000",
10421e2d7ceSMichał Górny            "vFile:fstat:5",
10521e2d7ceSMichał Górny            "vFile:close:5",
10621e2d7ceSMichał Górny            ])
107dbb0c14dSMichał Górny
108*8ccfcab3SPavel Labath        self.runCmd("platform disconnect")
109*8ccfcab3SPavel Labath
110*8ccfcab3SPavel Labath        # For a new onnection, we should attempt vFile:size once again.
111*8ccfcab3SPavel Labath        server2 = MockGDBServer(self.server_socket_class())
112*8ccfcab3SPavel Labath        server2.responder = Responder()
113*8ccfcab3SPavel Labath        server2.start()
114*8ccfcab3SPavel Labath        self.addTearDownHook(lambda:server2.stop())
115*8ccfcab3SPavel Labath        self.runCmd("platform connect " + server2.get_connect_url())
116*8ccfcab3SPavel Labath        self.match("platform get-size /other/file.txt",
117*8ccfcab3SPavel Labath                   [r"File size of /other/file\.txt \(remote\): 66051"])
118*8ccfcab3SPavel Labath
119*8ccfcab3SPavel Labath        self.assertPacketLogContains([
120*8ccfcab3SPavel Labath            "vFile:size:2f6f746865722f66696c652e747874",
121*8ccfcab3SPavel Labath            "vFile:open:2f6f746865722f66696c652e747874,00000000,00000000",
122*8ccfcab3SPavel Labath            "vFile:fstat:5",
123*8ccfcab3SPavel Labath            "vFile:close:5",
124*8ccfcab3SPavel Labath            ],
125*8ccfcab3SPavel Labath            log=server2.responder.packetLog)
126*8ccfcab3SPavel Labath
1279a4379c3SMichał Górny    @skipIfWindows
128dbb0c14dSMichał Górny    def test_file_permissions(self):
129dbb0c14dSMichał Górny        """Test 'platform get-permissions'"""
130dbb0c14dSMichał Górny
131dbb0c14dSMichał Górny        class Responder(MockGDBServerResponder):
132dbb0c14dSMichał Górny            def vFile(self, packet):
133dbb0c14dSMichał Górny                return "F1a4"
134dbb0c14dSMichał Górny
135dbb0c14dSMichał Górny        self.server.responder = Responder()
136dbb0c14dSMichał Górny
137dbb0c14dSMichał Górny        self.match("platform get-permissions /some/file.txt",
138dbb0c14dSMichał Górny                   [r"File permissions of /some/file\.txt \(remote\): 0o0644"])
139dbb0c14dSMichał Górny        self.assertPacketLogContains([
140dbb0c14dSMichał Górny            "vFile:mode:2f736f6d652f66696c652e747874",
141dbb0c14dSMichał Górny            ])
142dbb0c14dSMichał Górny
1439a4379c3SMichał Górny    @skipIfWindows
144501eaf88SMichał Górny    def test_file_permissions_fallback(self):
145501eaf88SMichał Górny        """Test 'platform get-permissions' fallback to fstat"""
146501eaf88SMichał Górny
147501eaf88SMichał Górny        class Responder(MockGDBServerResponder):
148501eaf88SMichał Górny            def vFile(self, packet):
149501eaf88SMichał Górny                if packet.startswith("vFile:open:"):
150501eaf88SMichał Górny                    return "F5"
151501eaf88SMichał Górny                elif packet.startswith("vFile:fstat:"):
152501eaf88SMichał Górny                    return "F40;" + 8 * "\0" + "\0\0\1\xA4" + 52 * "\0"
153501eaf88SMichał Górny                if packet.startswith("vFile:close:"):
154501eaf88SMichał Górny                    return "F0"
155501eaf88SMichał Górny                return ""
156501eaf88SMichał Górny
157501eaf88SMichał Górny        self.server.responder = Responder()
158501eaf88SMichał Górny
159501eaf88SMichał Górny        try:
160501eaf88SMichał Górny            self.match("platform get-permissions /some/file.txt",
161501eaf88SMichał Górny                       [r"File permissions of /some/file\.txt \(remote\): 0o0644"])
162501eaf88SMichał Górny            self.assertPacketLogContains([
163501eaf88SMichał Górny                "vFile:mode:2f736f6d652f66696c652e747874",
164501eaf88SMichał Górny                "vFile:open:2f736f6d652f66696c652e747874,00000000,00000000",
165501eaf88SMichał Górny                "vFile:fstat:5",
166501eaf88SMichał Górny                "vFile:close:5",
167501eaf88SMichał Górny                ])
168501eaf88SMichał Górny        finally:
169501eaf88SMichał Górny            self.dbg.GetSelectedPlatform().DisconnectRemote()
170501eaf88SMichał Górny
171dbb0c14dSMichał Górny    def test_file_exists(self):
172dbb0c14dSMichał Górny        """Test 'platform file-exists'"""
173dbb0c14dSMichał Górny
174dbb0c14dSMichał Górny        class Responder(MockGDBServerResponder):
175dbb0c14dSMichał Górny            def vFile(self, packet):
176dbb0c14dSMichał Górny                return "F,1"
177dbb0c14dSMichał Górny
178dbb0c14dSMichał Górny        self.server.responder = Responder()
179dbb0c14dSMichał Górny
180dbb0c14dSMichał Górny        self.match("platform file-exists /some/file.txt",
181dbb0c14dSMichał Górny                   [r"File /some/file\.txt \(remote\) exists"])
182dbb0c14dSMichał Górny        self.assertPacketLogContains([
183dbb0c14dSMichał Górny            "vFile:exists:2f736f6d652f66696c652e747874",
184dbb0c14dSMichał Górny            ])
185dbb0c14dSMichał Górny
186dbb0c14dSMichał Górny    def test_file_exists_not(self):
187dbb0c14dSMichał Górny        """Test 'platform file-exists' with non-existing file"""
188dbb0c14dSMichał Górny
189dbb0c14dSMichał Górny        class Responder(MockGDBServerResponder):
190dbb0c14dSMichał Górny            def vFile(self, packet):
191dbb0c14dSMichał Górny                return "F,0"
192dbb0c14dSMichał Górny
193dbb0c14dSMichał Górny        self.server.responder = Responder()
194dbb0c14dSMichał Górny
195dbb0c14dSMichał Górny        self.match("platform file-exists /some/file.txt",
196dbb0c14dSMichał Górny                   [r"File /some/file\.txt \(remote\) does not exist"])
197dbb0c14dSMichał Górny        self.assertPacketLogContains([
198dbb0c14dSMichał Górny            "vFile:exists:2f736f6d652f66696c652e747874",
199dbb0c14dSMichał Górny            ])
200501eaf88SMichał Górny
201501eaf88SMichał Górny    def test_file_exists_fallback(self):
202501eaf88SMichał Górny        """Test 'platform file-exists' fallback to open"""
203501eaf88SMichał Górny
204501eaf88SMichał Górny        class Responder(MockGDBServerResponder):
205501eaf88SMichał Górny            def vFile(self, packet):
206501eaf88SMichał Górny                if packet.startswith("vFile:open:"):
207501eaf88SMichał Górny                    return "F5"
208501eaf88SMichał Górny                if packet.startswith("vFile:close:"):
209501eaf88SMichał Górny                    return "F0"
210501eaf88SMichał Górny                return ""
211501eaf88SMichał Górny
212501eaf88SMichał Górny        self.server.responder = Responder()
213501eaf88SMichał Górny
214501eaf88SMichał Górny        self.match("platform file-exists /some/file.txt",
215501eaf88SMichał Górny                   [r"File /some/file\.txt \(remote\) exists"])
216501eaf88SMichał Górny        self.assertPacketLogContains([
217501eaf88SMichał Górny            "vFile:exists:2f736f6d652f66696c652e747874",
218501eaf88SMichał Górny            "vFile:open:2f736f6d652f66696c652e747874,00000000,00000000",
219501eaf88SMichał Górny            "vFile:close:5",
220501eaf88SMichał Górny            ])
221501eaf88SMichał Górny
222501eaf88SMichał Górny    def test_file_exists_not_fallback(self):
223501eaf88SMichał Górny        """Test 'platform file-exists' fallback to open with non-existing file"""
224501eaf88SMichał Górny
225501eaf88SMichał Górny        class Responder(MockGDBServerResponder):
226501eaf88SMichał Górny            def vFile(self, packet):
227501eaf88SMichał Górny                if packet.startswith("vFile:open:"):
228501eaf88SMichał Górny                    return "F-1,2"
229501eaf88SMichał Górny                return ""
230501eaf88SMichał Górny
231501eaf88SMichał Górny        self.server.responder = Responder()
232501eaf88SMichał Górny
233501eaf88SMichał Górny        self.match("platform file-exists /some/file.txt",
234501eaf88SMichał Górny                   [r"File /some/file\.txt \(remote\) does not exist"])
235501eaf88SMichał Górny        self.assertPacketLogContains([
236501eaf88SMichał Górny            "vFile:exists:2f736f6d652f66696c652e747874",
237501eaf88SMichał Górny            "vFile:open:2f736f6d652f66696c652e747874,00000000,00000000",
238501eaf88SMichał Górny            ])
239