mirror of
https://github.com/micropython/micropython.git
synced 2025-12-15 17:30:14 +01:00
tests/ports/qemu: Add arch flags MPY import checks test.
This commit introduces a test file (along with its necessary data) to test MPY files pass/reject cases, due to either mismatching architecture flag requirements or unneeded "no-flags" values set. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit is contained in:
128
tests/ports/qemu/mpy_arch_flags_test.py
Normal file
128
tests/ports/qemu/mpy_arch_flags_test.py
Normal file
@@ -0,0 +1,128 @@
|
||||
try:
|
||||
import sys, io, vfs
|
||||
|
||||
sys.implementation._mpy
|
||||
io.IOBase
|
||||
except (ImportError, AttributeError):
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
sys_implementation_mpy = sys.implementation._mpy
|
||||
arch = (sys_implementation_mpy >> 10) & 0x0F
|
||||
|
||||
# RV32-only for now.
|
||||
if arch != 11:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
class UserFile(io.IOBase):
|
||||
def __init__(self, data):
|
||||
self.data = memoryview(data)
|
||||
self.pos = 0
|
||||
|
||||
def readinto(self, buf):
|
||||
n = min(len(buf), len(self.data) - self.pos)
|
||||
buf[:n] = self.data[self.pos : self.pos + n]
|
||||
self.pos += n
|
||||
return n
|
||||
|
||||
def ioctl(self, req, arg):
|
||||
if req == 4: # MP_STREAM_CLOSE
|
||||
return 0
|
||||
return -1
|
||||
|
||||
|
||||
class UserFS:
|
||||
def __init__(self, files):
|
||||
self.files = files
|
||||
|
||||
def mount(self, readonly, mksfs):
|
||||
pass
|
||||
|
||||
def umount(self):
|
||||
pass
|
||||
|
||||
def stat(self, path):
|
||||
if path in self.files:
|
||||
return (32768, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
raise OSError
|
||||
|
||||
def open(self, path, mode):
|
||||
return UserFile(self.files[path])
|
||||
|
||||
|
||||
def mp_encode_uint(val):
|
||||
encoded = [val & 0x7F]
|
||||
val >>= 7
|
||||
while val != 0:
|
||||
encoded.insert(0, 0x80 | (val & 0x7F))
|
||||
val >>= 7
|
||||
return bytes(encoded)
|
||||
|
||||
|
||||
def add_flags(module, flags):
|
||||
output = bytearray()
|
||||
output.extend(module[:4])
|
||||
output[2] |= 0x40
|
||||
output.extend(mp_encode_uint(flags))
|
||||
output.extend(module[4:])
|
||||
return output
|
||||
|
||||
|
||||
arch_flags = sys_implementation_mpy >> 16
|
||||
can_test_partial_flags = arch_flags not in [1 << i for i in range(16)]
|
||||
|
||||
# To recreate this string run:
|
||||
# echo "hello=1" | mpy-cross -s module.py - | python -c 'import sys; print(sys.stdin.buffer.read())'
|
||||
MPY_FILE_BASE = b"M\x06\x00\x1f\x03\x00\x12module.py\x00\x0f\nhello\x00@\x00\x02\x01\x81\x16\x02Qc"
|
||||
|
||||
user_files = {
|
||||
"/matching_flags.mpy": add_flags(MPY_FILE_BASE, arch_flags),
|
||||
"/invalid_flags.mpy": add_flags(MPY_FILE_BASE, (~arch_flags & 0xFFFF)),
|
||||
"/explicit_no_flags.mpy": add_flags(MPY_FILE_BASE, 0),
|
||||
}
|
||||
if can_test_partial_flags:
|
||||
user_files["/partial_flags_more.mpy"] = add_flags(
|
||||
MPY_FILE_BASE, (arch_flags | (arch_flags << 1)) & 0xFFFF
|
||||
)
|
||||
user_files["/partial_flags_less.mpy"] = add_flags(
|
||||
MPY_FILE_BASE, (arch_flags >> 1) & arch_flags
|
||||
)
|
||||
|
||||
vfs.mount(UserFS(user_files), "/userfs")
|
||||
sys.path.append("/userfs")
|
||||
|
||||
import matching_flags
|
||||
|
||||
if not hasattr(matching_flags, "hello"):
|
||||
print("Improper matching_flags import")
|
||||
|
||||
import explicit_no_flags
|
||||
|
||||
if not hasattr(explicit_no_flags, "hello"):
|
||||
print("Improper explicit_no_flags import")
|
||||
|
||||
try:
|
||||
import invalid_flags
|
||||
|
||||
print("Unexpected invalid_flags import")
|
||||
except ValueError as e:
|
||||
if str(e) != "incompatible .mpy file":
|
||||
print("Unexpected invalid_flags import error:", str(e))
|
||||
|
||||
if can_test_partial_flags:
|
||||
import partial_flags_less
|
||||
|
||||
if not hasattr(partial_flags_less, "hello"):
|
||||
print("Improper partial_flags_less import")
|
||||
|
||||
try:
|
||||
import partial_flags_more
|
||||
|
||||
print("Unexpected partial_flags_more import")
|
||||
except ValueError as e:
|
||||
if str(e) != "incompatible .mpy file":
|
||||
print("Unexpected partial_flags_more import error:", str(e))
|
||||
|
||||
print("OK")
|
||||
1
tests/ports/qemu/mpy_arch_flags_test.py.exp
Normal file
1
tests/ports/qemu/mpy_arch_flags_test.py.exp
Normal file
@@ -0,0 +1 @@
|
||||
OK
|
||||
Reference in New Issue
Block a user