forked from RustPython/RustPython
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_snippets.py
144 lines (110 loc) · 4.07 KB
/
test_snippets.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# This is a python unittest class automatically populating with all tests
# in the tests folder.
import sys
import os
import unittest
import glob
import logging
import subprocess
import contextlib
import enum
from pathlib import Path
import shutil
class _TestType(enum.Enum):
functional = 1
logger = logging.getLogger("tests")
ROOT_DIR = ".."
TEST_ROOT = os.path.abspath(os.path.join(ROOT_DIR, "tests"))
TEST_DIRS = {_TestType.functional: os.path.join(TEST_ROOT, "snippets")}
CPYTHON_RUNNER_DIR = os.path.abspath(os.path.join(ROOT_DIR, "py_code_object"))
RUSTPYTHON_RUNNER_DIR = os.path.abspath(os.path.join(ROOT_DIR))
RUSTPYTHON_LIB_DIR = os.path.abspath(os.path.join(ROOT_DIR, "Lib"))
@contextlib.contextmanager
def pushd(path):
old_dir = os.getcwd()
os.chdir(path)
yield
os.chdir(old_dir)
def perform_test(filename, method, test_type):
logger.info("Running %s via %s", filename, method)
if method == "cpython":
run_via_cpython(filename)
elif method == "rustpython":
run_via_rustpython(filename, test_type)
else:
raise NotImplementedError(method)
def run_via_cpython(filename):
""" Simply invoke python itself on the script """
env = os.environ.copy()
subprocess.check_call([sys.executable, filename], env=env)
def run_via_rustpython(filename, test_type):
env = os.environ.copy()
env['RUST_LOG'] = 'info,cargo=error,jobserver=error'
env['RUST_BACKTRACE'] = '1'
env['PYTHONPATH'] = RUSTPYTHON_LIB_DIR
target = "release"
if env.get("CODE_COVERAGE", "false") == "true":
target = "debug"
binary = os.path.abspath(os.path.join(ROOT_DIR, "target", target, "rustpython"))
subprocess.check_call([binary, filename], env=env)
def create_test_function(cls, filename, method, test_type):
""" Create a test function for a single snippet """
core_test_directory, snippet_filename = os.path.split(filename)
test_function_name = "test_{}_".format(method) + os.path.splitext(snippet_filename)[
0
].replace(".", "_").replace("-", "_")
def test_function(self):
perform_test(filename, method, test_type)
if hasattr(cls, test_function_name):
raise ValueError("Duplicate test case {}".format(test_function_name))
setattr(cls, test_function_name, test_function)
def populate(method):
def wrapper(cls):
""" Decorator function which can populate a unittest.TestCase class """
for test_type, filename in get_test_files():
create_test_function(cls, filename, method, test_type)
return cls
return wrapper
def get_test_files():
""" Retrieve test files """
for test_type, test_dir in TEST_DIRS.items():
for filepath in sorted(glob.iglob(os.path.join(test_dir, "*.py"))):
filename = os.path.split(filepath)[1]
if filename.startswith("xfail_"):
continue
yield test_type, os.path.abspath(filepath)
def generate_slices(path):
# loop used to build slices_res.py with cpython
ll = [0, 1, 2, 3]
start = list(range(-7, 7))
end = list(range(-7, 7))
step = list(range(-5, 5))
step.pop(step.index(0))
for i in [start, end, step]:
i.append(None)
slices_res = []
for s in start:
for e in end:
for t in step:
slices_res.append(ll[s:e:t])
path.write_text(
"SLICES_RES={}\nSTART= {}\nEND= {}\nSTEP= {}\nLL={}\n".format(
slices_res, start, end, step, ll
)
)
@populate("cpython")
@populate("rustpython")
class SampleTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Here add resource files
cls.slices_resource_path = Path(TEST_DIRS[_TestType.functional]) / "cpython_generated_slices.py"
if cls.slices_resource_path.exists():
cls.slices_resource_path.unlink()
generate_slices(cls.slices_resource_path)
# cargo stuff
subprocess.check_call(["cargo", "build"])
subprocess.check_call(["cargo", "build", "--release"])
@classmethod
def tearDownClass(cls):
cls.slices_resource_path.unlink()