While debugging the tests for #155000 I found it helpful to have both sides of the simulated gdb-rsp traffic rather than just the responses so I've extended the packetLog in MockGDBServerResponder to record traffic in both directions. Tests have been updated accordingly
288 lines
9.4 KiB
Python
288 lines
9.4 KiB
Python
from lldbsuite.test.gdbclientutils import *
|
|
from lldbsuite.test.decorators import *
|
|
from lldbsuite.test.lldbgdbclient import GDBPlatformClientTestBase
|
|
|
|
|
|
class TestGDBRemotePlatformFile(GDBPlatformClientTestBase):
|
|
def test_file(self):
|
|
"""Test mock operations on a remote file"""
|
|
|
|
class Responder(MockGDBServerResponder):
|
|
def vFile(self, packet):
|
|
if packet.startswith("vFile:open:"):
|
|
return "F10"
|
|
elif packet.startswith("vFile:pread:"):
|
|
return "Fd;frobnicator"
|
|
elif packet.startswith("vFile:pwrite:"):
|
|
return "Fa"
|
|
elif packet.startswith("vFile:close:"):
|
|
return "F0"
|
|
return "F-1,58"
|
|
|
|
self.server.responder = Responder()
|
|
|
|
self.match(
|
|
"platform file open /some/file.txt -v 0755", [r"File Descriptor = 16"]
|
|
)
|
|
self.match(
|
|
"platform file read 16 -o 11 -c 13",
|
|
[r"Return = 11\nData = \"frobnicator\""],
|
|
)
|
|
self.match("platform file write 16 -o 11 -d teststring", [r"Return = 10"])
|
|
self.match("platform file close 16", [r"file 16 closed."])
|
|
self.assertPacketLogReceived(
|
|
[
|
|
"vFile:open:2f736f6d652f66696c652e747874,00000202,000001ed",
|
|
"vFile:pread:10,d,b",
|
|
"vFile:pwrite:10,b,teststring",
|
|
"vFile:close:10",
|
|
]
|
|
)
|
|
|
|
def test_file_fail(self):
|
|
"""Test mocked failures of remote operations"""
|
|
|
|
class Responder(MockGDBServerResponder):
|
|
def vFile(self, packet):
|
|
# use ENOSYS as this constant differs between GDB Remote
|
|
# Protocol and Linux, so we can test the translation
|
|
return "F-1,58"
|
|
|
|
self.server.responder = Responder()
|
|
enosys_regex = r"error: (Function not implemented|function not supported)"
|
|
self.match(
|
|
"platform file open /some/file.txt -v 0755",
|
|
[enosys_regex],
|
|
error=True,
|
|
)
|
|
self.match(
|
|
"platform file read 16 -o 11 -c 13",
|
|
[enosys_regex],
|
|
error=True,
|
|
)
|
|
self.match(
|
|
"platform file write 16 -o 11 -d teststring",
|
|
[enosys_regex],
|
|
error=True,
|
|
)
|
|
self.match("platform file close 16", [enosys_regex], error=True)
|
|
self.assertPacketLogReceived(
|
|
[
|
|
"vFile:open:2f736f6d652f66696c652e747874,00000202,000001ed",
|
|
"vFile:pread:10,d,b",
|
|
"vFile:pwrite:10,b,teststring",
|
|
"vFile:close:10",
|
|
]
|
|
)
|
|
|
|
def test_file_size(self):
|
|
"""Test 'platform get-size'"""
|
|
|
|
class Responder(MockGDBServerResponder):
|
|
def vFile(self, packet):
|
|
return "F1000"
|
|
|
|
self.server.responder = Responder()
|
|
|
|
self.match(
|
|
"platform get-size /some/file.txt",
|
|
[r"File size of /some/file\.txt \(remote\): 4096"],
|
|
)
|
|
self.assertPacketLogReceived(
|
|
[
|
|
"vFile:size:2f736f6d652f66696c652e747874",
|
|
]
|
|
)
|
|
|
|
def test_file_size_fallback(self):
|
|
"""Test 'platform get-size fallback to vFile:fstat'"""
|
|
|
|
class Responder(MockGDBServerResponder):
|
|
def vFile(self, packet):
|
|
if packet.startswith("vFile:open:"):
|
|
return "F5"
|
|
elif packet.startswith("vFile:fstat:"):
|
|
return "F40;" + 28 * "\0" + "\0\0\0\0\0\1\2\3" + 28 * "\0"
|
|
if packet.startswith("vFile:close:"):
|
|
return "F0"
|
|
return ""
|
|
|
|
self.server.responder = Responder()
|
|
|
|
self.match(
|
|
"platform get-size /some/file.txt",
|
|
[r"File size of /some/file\.txt \(remote\): 66051"],
|
|
)
|
|
self.assertPacketLogReceived(
|
|
[
|
|
"vFile:size:2f736f6d652f66696c652e747874",
|
|
"vFile:open:2f736f6d652f66696c652e747874,00000000,00000000",
|
|
"vFile:fstat:5",
|
|
"vFile:close:5",
|
|
]
|
|
)
|
|
|
|
self.runCmd("platform disconnect")
|
|
|
|
# For a new onnection, we should attempt vFile:size once again.
|
|
server2 = MockGDBServer(self.server_socket_class())
|
|
server2.responder = Responder()
|
|
server2.start()
|
|
self.addTearDownHook(lambda: server2.stop())
|
|
self.runCmd("platform connect " + server2.get_connect_url())
|
|
self.match(
|
|
"platform get-size /other/file.txt",
|
|
[r"File size of /other/file\.txt \(remote\): 66051"],
|
|
)
|
|
|
|
self.assertPacketLogReceived(
|
|
[
|
|
"vFile:size:2f6f746865722f66696c652e747874",
|
|
"vFile:open:2f6f746865722f66696c652e747874,00000000,00000000",
|
|
"vFile:fstat:5",
|
|
"vFile:close:5",
|
|
],
|
|
log=server2.responder.packetLog,
|
|
)
|
|
|
|
@expectedFailureAll(
|
|
hostoslist=["windows"], bugnumber="github.com/llvm/llvm-project/issues/92255"
|
|
)
|
|
def test_file_permissions(self):
|
|
"""Test 'platform get-permissions'"""
|
|
|
|
class Responder(MockGDBServerResponder):
|
|
def vFile(self, packet):
|
|
return "F1a4"
|
|
|
|
self.server.responder = Responder()
|
|
|
|
self.match(
|
|
"platform get-permissions /some/file.txt",
|
|
[r"File permissions of /some/file\.txt \(remote\): 0o0644"],
|
|
)
|
|
self.assertPacketLogReceived(
|
|
[
|
|
"vFile:mode:2f736f6d652f66696c652e747874",
|
|
]
|
|
)
|
|
|
|
@expectedFailureAll(
|
|
hostoslist=["windows"], bugnumber="github.com/llvm/llvm-project/issues/92255"
|
|
)
|
|
def test_file_permissions_fallback(self):
|
|
"""Test 'platform get-permissions' fallback to fstat"""
|
|
|
|
class Responder(MockGDBServerResponder):
|
|
def vFile(self, packet):
|
|
if packet.startswith("vFile:open:"):
|
|
return "F5"
|
|
elif packet.startswith("vFile:fstat:"):
|
|
return "F40;" + 8 * "\0" + "\0\0\1\xA4" + 52 * "\0"
|
|
if packet.startswith("vFile:close:"):
|
|
return "F0"
|
|
return ""
|
|
|
|
self.server.responder = Responder()
|
|
|
|
try:
|
|
self.match(
|
|
"platform get-permissions /some/file.txt",
|
|
[r"File permissions of /some/file\.txt \(remote\): 0o0644"],
|
|
)
|
|
self.assertPacketLogReceived(
|
|
[
|
|
"vFile:mode:2f736f6d652f66696c652e747874",
|
|
"vFile:open:2f736f6d652f66696c652e747874,00000000,00000000",
|
|
"vFile:fstat:5",
|
|
"vFile:close:5",
|
|
]
|
|
)
|
|
finally:
|
|
self.dbg.GetSelectedPlatform().DisconnectRemote()
|
|
|
|
def test_file_exists(self):
|
|
"""Test 'platform file-exists'"""
|
|
|
|
class Responder(MockGDBServerResponder):
|
|
def vFile(self, packet):
|
|
return "F,1"
|
|
|
|
self.server.responder = Responder()
|
|
|
|
self.match(
|
|
"platform file-exists /some/file.txt",
|
|
[r"File /some/file\.txt \(remote\) exists"],
|
|
)
|
|
self.assertPacketLogReceived(
|
|
[
|
|
"vFile:exists:2f736f6d652f66696c652e747874",
|
|
]
|
|
)
|
|
|
|
def test_file_exists_not(self):
|
|
"""Test 'platform file-exists' with non-existing file"""
|
|
|
|
class Responder(MockGDBServerResponder):
|
|
def vFile(self, packet):
|
|
return "F,0"
|
|
|
|
self.server.responder = Responder()
|
|
|
|
self.match(
|
|
"platform file-exists /some/file.txt",
|
|
[r"File /some/file\.txt \(remote\) does not exist"],
|
|
)
|
|
self.assertPacketLogReceived(
|
|
[
|
|
"vFile:exists:2f736f6d652f66696c652e747874",
|
|
]
|
|
)
|
|
|
|
def test_file_exists_fallback(self):
|
|
"""Test 'platform file-exists' fallback to open"""
|
|
|
|
class Responder(MockGDBServerResponder):
|
|
def vFile(self, packet):
|
|
if packet.startswith("vFile:open:"):
|
|
return "F5"
|
|
if packet.startswith("vFile:close:"):
|
|
return "F0"
|
|
return ""
|
|
|
|
self.server.responder = Responder()
|
|
|
|
self.match(
|
|
"platform file-exists /some/file.txt",
|
|
[r"File /some/file\.txt \(remote\) exists"],
|
|
)
|
|
self.assertPacketLogReceived(
|
|
[
|
|
"vFile:exists:2f736f6d652f66696c652e747874",
|
|
"vFile:open:2f736f6d652f66696c652e747874,00000000,00000000",
|
|
"vFile:close:5",
|
|
]
|
|
)
|
|
|
|
def test_file_exists_not_fallback(self):
|
|
"""Test 'platform file-exists' fallback to open with non-existing file"""
|
|
|
|
class Responder(MockGDBServerResponder):
|
|
def vFile(self, packet):
|
|
if packet.startswith("vFile:open:"):
|
|
return "F-1,2"
|
|
return ""
|
|
|
|
self.server.responder = Responder()
|
|
|
|
self.match(
|
|
"platform file-exists /some/file.txt",
|
|
[r"File /some/file\.txt \(remote\) does not exist"],
|
|
)
|
|
self.assertPacketLogReceived(
|
|
[
|
|
"vFile:exists:2f736f6d652f66696c652e747874",
|
|
"vFile:open:2f736f6d652f66696c652e747874,00000000,00000000",
|
|
]
|
|
)
|