1import os
2
3import infra.basetest
4
5
6class TestPythonBase(infra.basetest.BRTest):
7    config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + \
8        """
9        BR2_TARGET_ROOTFS_CPIO=y
10        # BR2_TARGET_ROOTFS_TAR is not set
11        """
12    interpreter = "python"
13
14    def login(self):
15        cpio_file = os.path.join(self.builddir, "images", "rootfs.cpio")
16        self.emulator.boot(arch="armv5",
17                           kernel="builtin",
18                           options=["-initrd", cpio_file])
19        self.emulator.login()
20
21    def version_test(self, version, timeout=-1):
22        cmd = self.interpreter + " --version 2>&1 | grep '^{}'".format(version)
23        self.assertRunOk(cmd, timeout)
24
25    def math_floor_test(self, timeout=-1):
26        cmd = self.interpreter + " -c 'import math; math.floor(12.3)'"
27        self.assertRunOk(cmd, timeout)
28
29    def libc_time_test(self, timeout=-1):
30        cmd = self.interpreter + " -c '"
31        cmd += "import ctypes;"
32        cmd += "libc = ctypes.cdll.LoadLibrary(\"libc.so.6\");"
33        cmd += "print(libc.time(None))'"
34        self.assertRunOk(cmd, timeout)
35
36    def zlib_test(self, timeout=-1):
37        cmd = self.interpreter + " -c 'import zlib'"
38        _, exit_code = self.emulator.run(cmd, timeout)
39        self.assertEqual(exit_code, 1)
40
41
42class TestPython3Pyc(TestPythonBase):
43    config = TestPythonBase.config + \
44        """
45        BR2_PACKAGE_PYTHON3=y
46        """
47
48    def test_run(self):
49        self.login()
50        self.version_test("Python 3")
51        self.math_floor_test()
52        self.libc_time_test()
53        self.zlib_test()
54
55
56class TestPython3Py(TestPythonBase):
57    config = TestPythonBase.config + \
58        """
59        BR2_PACKAGE_PYTHON3=y
60        BR2_PACKAGE_PYTHON3_PY_ONLY=y
61        """
62
63    def test_run(self):
64        self.login()
65        self.version_test("Python 3")
66        self.math_floor_test()
67        self.libc_time_test()
68        self.zlib_test()
69
70
71class TestPython3PyPyc(TestPythonBase):
72    config = TestPythonBase.config + \
73        """
74        BR2_PACKAGE_PYTHON3=y
75        BR2_PACKAGE_PYTHON3_PY_PYC=y
76        """
77
78    def test_run(self):
79        self.login()
80        self.version_test("Python 3")
81        self.math_floor_test()
82        self.libc_time_test()
83        self.zlib_test()
84
85
86class TestPythonPackageBase(TestPythonBase):
87    """Common class to test a python package.
88
89    Build an image containing the scripts listed in sample_scripts, start the
90    emulator, login to it and for each sample script in the image run the python
91    interpreter passing the name of the script and check the status code is 0.
92
93    Each test case that inherits from this class must have:
94    __test__ = True  - to let nose2 know that it is a test case
95    config           - defconfig fragment with the packages to run the test
96    It also can have:
97    sample_scripts   - list of scripts to add to the image and run on the target
98    timeout          - timeout to the script to run when the default from the
99                       test infra is not enough
100    When custom commands need be issued on the target the method
101    run_sample_scripts can be overridden.
102    """
103
104    __test__ = False
105    config_sample_scripts = \
106        """
107        BR2_ROOTFS_POST_BUILD_SCRIPT="{}"
108        BR2_ROOTFS_POST_SCRIPT_ARGS="{}"
109        """.format(infra.filepath("tests/package/copy-sample-script-to-target.sh"),
110                   "{sample_scripts}")
111    sample_scripts = None
112    timeout = -1
113
114    def __init__(self, names):
115        """Add the scripts to the target in build time."""
116        super(TestPythonPackageBase, self).__init__(names)
117        if self.sample_scripts:
118            scripts = [infra.filepath(s) for s in self.sample_scripts]
119            self.config += self.config_sample_scripts.format(sample_scripts=" ".join(scripts))
120
121    def check_sample_scripts_exist(self):
122        """Check the scripts were really added to the image."""
123        scripts = [os.path.basename(s) for s in self.sample_scripts]
124        cmd = "md5sum " + " ".join(scripts)
125        _, exit_code = self.emulator.run(cmd)
126        self.assertEqual(exit_code, 0)
127
128    def run_sample_scripts(self):
129        """Run each script previously added to the image."""
130        for script in self.sample_scripts:
131            cmd = self.interpreter + " " + os.path.basename(script)
132            self.assertRunOk(cmd, timeout=self.timeout)
133
134    def test_run(self):
135        self.login()
136        self.check_sample_scripts_exist()
137        self.run_sample_scripts()
138