diff --git a/tests/import/mpy_native.py b/tests/import/mpy_native.py new file mode 100644 index 0000000000..e03d14e2ed --- /dev/null +++ b/tests/import/mpy_native.py @@ -0,0 +1,93 @@ +# test importing of .mpy files with native code (x64 only) + +import sys, uio + +try: + uio.IOBase + import uos + uos.mount +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +if not (sys.platform == 'linux' and sys.maxsize > 2 ** 32): + print("SKIP") + raise SystemExit + + +class UserFile(uio.IOBase): + def __init__(self, data): + self.data = data + self.pos = 0 + def read(self): + return self.data + def readinto(self, buf): + n = 0 + while n < len(buf) and self.pos < len(self.data): + buf[n] = self.data[self.pos] + n += 1 + self.pos += 1 + return n + def ioctl(self, req, arg): + return 0 + + +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]) + + +# these are the test .mpy files +user_files = { + # bad architecture + '/mod0.mpy': b'M\x04\xff\x00\x10', + + # test loading of viper and asm + '/mod1.mpy': ( + b'M\x04\x0b\x1f\x20' # header + + b'\x38' # n bytes, bytecode + b'\x01\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\xff' # prelude + b'\x11' # LOAD_CONST_NONE + b'\x5b' # RETURN_VALUE + + b'\x02m\x02m\x00\x02' # simple_name, source_file, n_obj, n_raw_code + + b'\x22' # n bytes, viper code + b'\x00\x00\x00\x00\x00\x00' # dummy machine code + b'\x00\x00' # qstr0 + b'\x01\x0c\x0aprint' # n_qstr, qstr0 + b'\x00\x00\x00' # scope_flags, n_obj, n_raw_code + + b'\x23' # n bytes, asm code + b'\x00\x00\x00\x00\x00\x00\x00\x00' # dummy machine code + b'\x00\x00\x00' # scope_flags, n_pos_args, type_sig + ), +} + +# create and mount a user filesystem +uos.mount(UserFS(user_files), '/userfs') +sys.path.append('/userfs') + +# import .mpy files from the user filesystem +for i in range(len(user_files)): + mod = 'mod%u' % i + try: + __import__(mod) + print(mod, 'OK') + except ValueError as er: + print(mod, 'ValueError', er) + +# unmount and undo path addition +uos.umount('/userfs') +sys.path.pop() diff --git a/tests/import/mpy_native.py.exp b/tests/import/mpy_native.py.exp new file mode 100644 index 0000000000..b73812094a --- /dev/null +++ b/tests/import/mpy_native.py.exp @@ -0,0 +1,2 @@ +mod0 ValueError incompatible .mpy arch +mod1 OK