diff options
| author | Alessandro Gatti <a.gatti@frob.it> | 2025-09-25 01:10:50 +0200 |
|---|---|---|
| committer | Alessandro Gatti <a.gatti@frob.it> | 2025-10-24 19:13:15 +0200 |
| commit | a080585ffdc628ab14d70a1489e31ede485e9a88 (patch) | |
| tree | e3acfcb8f1aa6eff8646fadc19b9f35f38e77740 | |
| parent | 849c67bcdc9f848a674554f3e03ef850a8f70692 (diff) | |
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>
| -rw-r--r-- | tests/ports/qemu/mpy_arch_flags_test.py | 128 | ||||
| -rw-r--r-- | tests/ports/qemu/mpy_arch_flags_test.py.exp | 1 |
2 files changed, 129 insertions, 0 deletions
diff --git a/tests/ports/qemu/mpy_arch_flags_test.py b/tests/ports/qemu/mpy_arch_flags_test.py new file mode 100644 index 000000000..c07d92d53 --- /dev/null +++ b/tests/ports/qemu/mpy_arch_flags_test.py @@ -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") diff --git a/tests/ports/qemu/mpy_arch_flags_test.py.exp b/tests/ports/qemu/mpy_arch_flags_test.py.exp new file mode 100644 index 000000000..d86bac9de --- /dev/null +++ b/tests/ports/qemu/mpy_arch_flags_test.py.exp @@ -0,0 +1 @@ +OK |
