Skip to content

Commit a080585

Browse files
committed
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 <[email protected]>
1 parent 849c67b commit a080585

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
try:
2+
import sys, io, vfs
3+
4+
sys.implementation._mpy
5+
io.IOBase
6+
except (ImportError, AttributeError):
7+
print("SKIP")
8+
raise SystemExit
9+
10+
sys_implementation_mpy = sys.implementation._mpy
11+
arch = (sys_implementation_mpy >> 10) & 0x0F
12+
13+
# RV32-only for now.
14+
if arch != 11:
15+
print("SKIP")
16+
raise SystemExit
17+
18+
19+
class UserFile(io.IOBase):
20+
def __init__(self, data):
21+
self.data = memoryview(data)
22+
self.pos = 0
23+
24+
def readinto(self, buf):
25+
n = min(len(buf), len(self.data) - self.pos)
26+
buf[:n] = self.data[self.pos : self.pos + n]
27+
self.pos += n
28+
return n
29+
30+
def ioctl(self, req, arg):
31+
if req == 4: # MP_STREAM_CLOSE
32+
return 0
33+
return -1
34+
35+
36+
class UserFS:
37+
def __init__(self, files):
38+
self.files = files
39+
40+
def mount(self, readonly, mksfs):
41+
pass
42+
43+
def umount(self):
44+
pass
45+
46+
def stat(self, path):
47+
if path in self.files:
48+
return (32768, 0, 0, 0, 0, 0, 0, 0, 0, 0)
49+
raise OSError
50+
51+
def open(self, path, mode):
52+
return UserFile(self.files[path])
53+
54+
55+
def mp_encode_uint(val):
56+
encoded = [val & 0x7F]
57+
val >>= 7
58+
while val != 0:
59+
encoded.insert(0, 0x80 | (val & 0x7F))
60+
val >>= 7
61+
return bytes(encoded)
62+
63+
64+
def add_flags(module, flags):
65+
output = bytearray()
66+
output.extend(module[:4])
67+
output[2] |= 0x40
68+
output.extend(mp_encode_uint(flags))
69+
output.extend(module[4:])
70+
return output
71+
72+
73+
arch_flags = sys_implementation_mpy >> 16
74+
can_test_partial_flags = arch_flags not in [1 << i for i in range(16)]
75+
76+
# To recreate this string run:
77+
# echo "hello=1" | mpy-cross -s module.py - | python -c 'import sys; print(sys.stdin.buffer.read())'
78+
MPY_FILE_BASE = b"M\x06\x00\x1f\x03\x00\x12module.py\x00\x0f\nhello\x00@\x00\x02\x01\x81\x16\x02Qc"
79+
80+
user_files = {
81+
"/matching_flags.mpy": add_flags(MPY_FILE_BASE, arch_flags),
82+
"/invalid_flags.mpy": add_flags(MPY_FILE_BASE, (~arch_flags & 0xFFFF)),
83+
"/explicit_no_flags.mpy": add_flags(MPY_FILE_BASE, 0),
84+
}
85+
if can_test_partial_flags:
86+
user_files["/partial_flags_more.mpy"] = add_flags(
87+
MPY_FILE_BASE, (arch_flags | (arch_flags << 1)) & 0xFFFF
88+
)
89+
user_files["/partial_flags_less.mpy"] = add_flags(
90+
MPY_FILE_BASE, (arch_flags >> 1) & arch_flags
91+
)
92+
93+
vfs.mount(UserFS(user_files), "/userfs")
94+
sys.path.append("/userfs")
95+
96+
import matching_flags
97+
98+
if not hasattr(matching_flags, "hello"):
99+
print("Improper matching_flags import")
100+
101+
import explicit_no_flags
102+
103+
if not hasattr(explicit_no_flags, "hello"):
104+
print("Improper explicit_no_flags import")
105+
106+
try:
107+
import invalid_flags
108+
109+
print("Unexpected invalid_flags import")
110+
except ValueError as e:
111+
if str(e) != "incompatible .mpy file":
112+
print("Unexpected invalid_flags import error:", str(e))
113+
114+
if can_test_partial_flags:
115+
import partial_flags_less
116+
117+
if not hasattr(partial_flags_less, "hello"):
118+
print("Improper partial_flags_less import")
119+
120+
try:
121+
import partial_flags_more
122+
123+
print("Unexpected partial_flags_more import")
124+
except ValueError as e:
125+
if str(e) != "incompatible .mpy file":
126+
print("Unexpected partial_flags_more import error:", str(e))
127+
128+
print("OK")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
OK

0 commit comments

Comments
 (0)