1import os
2
3import infra.basetest
4
5
6class TestMicroPython(infra.basetest.BRTest):
7    config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + \
8        f"""
9        BR2_PACKAGE_MICROPYTHON=y
10        BR2_PACKAGE_MICROPYTHON_LIB=y
11        BR2_ROOTFS_OVERLAY="{infra.filepath("tests/package/test_micropython/rootfs-overlay")}"
12        BR2_TARGET_ROOTFS_CPIO=y
13        # BR2_TARGET_ROOTFS_TAR is not set
14        """
15
16    def run_upy_code(self, python_code, opts=""):
17        cmd = f'micropython {opts} -c "{python_code}"'
18        output, ret = self.emulator.run(cmd)
19        self.assertEqual(ret, 0, f"could not run '{cmd}', returnd {ret}: '{output}'")
20        return output
21
22    def test_run(self):
23        cpio_file = os.path.join(self.builddir, "images", "rootfs.cpio")
24        self.emulator.boot(arch="armv5",
25                           kernel="builtin",
26                           options=["-initrd", cpio_file])
27        self.emulator.login()
28
29        # The micropython binary can execute.
30        self.assertRunOk("micropython -h")
31
32        # Query interpreter version and implementation.
33        py_code = "import sys ; "
34        py_code += "print('Version:', sys.version) ; "
35        py_code += "print('Implementation:', sys.implementation)"
36        self.run_upy_code(py_code)
37
38        # Check implementation is 'micropython'.
39        py_code = "import sys ; print(sys.implementation.name)"
40        output = self.run_upy_code(py_code)
41        self.assertEqual(output[0], "micropython")
42
43        # Check micropython optimization are correctly reported.
44        py_code = "import micropython ; print(micropython.opt_level())"
45        for opt_level in range(4):
46            output = self.run_upy_code(py_code, f"-O{opt_level}")
47            self.assertEqual(
48                int(output[0]),
49                opt_level,
50                f"Running '{py_code}' at -O{opt_level} returned '{output}'"
51            )
52
53        # Check micropython can return a non-zero exit code.
54        expected_code = 123
55        py_code = "import sys ; "
56        py_code += f"sys.exit({expected_code})"
57        cmd = f'micropython -c "{py_code}"'
58        _, exit_code = self.emulator.run(cmd)
59        self.assertEqual(exit_code, expected_code)
60
61        # Check micropython computes correctly.
62        input_value = 1234
63        expected_output = str(sum(range(input_value)))
64        py_code = f"print(sum(range(({input_value}))))"
65        output = self.run_upy_code(py_code)
66        self.assertEqual(output[0], expected_output)
67
68        # Check a small script can execute.
69        self.assertRunOk("/root/mandel.py", timeout=10)
70
71        # Check we can use a micropython-lib module.
72        msg = "Hello Buildroot!"
73        filename = "file.txt"
74        gz_filename = f"{filename}.gz"
75        self.assertRunOk(f"echo '{msg}' > {filename}")
76        self.assertRunOk(f"gzip {filename}")
77        out, ret = self.emulator.run(f"/root/zcat.py {gz_filename}")
78        self.assertEqual(ret, 0)
79        self.assertEqual(out[0], msg)
80