Skip to content
File

Blob: src/workerd/server/tests/python/import_tests.bzl

4.6 KB
1load("@bazel_skylib//rules:write_file.bzl", "write_file")
2load("//:build/python_metadata.bzl", "BUNDLE_VERSION_INFO", "PYTHON_IMPORTS_TO_TEST")
3load("//src/workerd/server/tests/python:py_wd_test.bzl", "py_wd_test")
4 
5def _generate_import_py_file(imports):
6 res = ""
7 for imp in imports:
8 res += "import " + imp + "\n"
9 
10 res += "from workers import WorkerEntrypoint\n"
11 res += "class Default(WorkerEntrypoint):\n"
12 res += " def test(self):\n"
13 res += " pass"
14 return res
15 
16WD_FILE_TEMPLATE = """
17using Workerd = import "/workerd/workerd.capnp";
18 
19const unitTests :Workerd.Config = (
20 services = [
21 ( name = "python-import-{name}",
22 worker = (
23 modules = [
24 (name = "worker.py", pythonModule = embed "./worker.py"),
25 {requirements}
26 ],
27 compatibilityFlags = [%PYTHON_FEATURE_FLAGS],
28 )
29 ),
30 ]
31);"""
32 
33def _generate_wd_test_file(name, requirements):
34 l = []
35 for req in requirements:
36 l.append('(name = "{}", pythonRequirement = ""),\n'.format(req))
37 requirements = "".join(l)
38 return WD_FILE_TEMPLATE.format(name = name, requirements = requirements)
39 
40def _test(name, directory, wd_test, py_file, python_version, **kwds):
41 py_wd_test(
42 name = name,
43 directory = directory,
44 src = wd_test,
45 python_flags = [python_version],
46 use_snapshot = None,
47 make_snapshot = False,
48 skip_default_data = True,
49 data = [py_file],
50 **kwds
51 )
52 
53# to_test is a dictionary from library name to list of imports
54def _gen_import_tests(to_test, python_version, pkg_skip_versions):
55 for lib in to_test.keys():
56 skip_python_flags = [version for version, packages in pkg_skip_versions.items() if lib in packages]
57 if BUNDLE_VERSION_INFO["development"]["real_pyodide_version"] in skip_python_flags:
58 skip_python_flags.append("development")
59 if lib.endswith("-tests"):
60 # TODO: The pyodide-build-scripts should be updated to not emit these packages. Once
61 # that's done we can remove this check.
62 continue
63 
64 prefix = "import/" + lib
65 worker_py_fname = python_version + "/" + prefix + "/worker.py"
66 wd_test_fname = python_version + "/" + prefix + "/import.wd-test"
67 write_file(
68 name = worker_py_fname + "@rule",
69 out = worker_py_fname,
70 content = [_generate_import_py_file(to_test[lib])],
71 )
72 write_file(
73 name = wd_test_fname + "@rule",
74 out = wd_test_fname,
75 content = [_generate_wd_test_file(lib, [lib])],
76 )
77 
78 _test(
79 name = prefix,
80 directory = lib,
81 wd_test = wd_test_fname,
82 py_file = worker_py_fname,
83 python_version = python_version,
84 skip_python_flags = skip_python_flags,
85 )
86 
87def gen_import_tests(*, pkg_skip_versions = {}):
88 for python_version, info in BUNDLE_VERSION_INFO.items():
89 to_test = PYTHON_IMPORTS_TO_TEST[info["packages"]]
90 _gen_import_tests(to_test, python_version, pkg_skip_versions = pkg_skip_versions)
91 
92def _rotations(lst):
93 result = []
94 cur = lst
95 for i in range(len(lst)):
96 result.append(cur)
97 cur = cur[1:] + [cur[0]]
98 return result
99 
100def _pkg_permutations(lst):
101 return _rotations(lst) + _rotations(reversed(lst))
102 
103def _gen_rust_import_tests(python_version):
104 pyodide_version = BUNDLE_VERSION_INFO[python_version]["real_pyodide_version"]
105 if pyodide_version == "0.26.0a2":
106 pkgs = _rotations(["tiktoken", "pydantic"])
107 else:
108 pkgs = _pkg_permutations(["cryptography", "jiter", "tiktoken", "pydantic"])
109 
110 for res in pkgs:
111 name = "-".join(res)
112 prefix = "import2/" + name
113 worker_py_fname = python_version + "/" + prefix + "/worker.py"
114 wd_test_fname = python_version + "/" + prefix + "/import.wd-test"
115 write_file(
116 name = worker_py_fname + "@rule",
117 out = worker_py_fname,
118 content = [_generate_import_py_file(res)],
119 )
120 write_file(
121 name = wd_test_fname + "@rule",
122 out = wd_test_fname,
123 content = [_generate_wd_test_file(name, res)],
124 )
125 
126 _test(
127 name = prefix,
128 directory = name,
129 wd_test = wd_test_fname,
130 py_file = worker_py_fname,
131 python_version = python_version,
132 )
133 
134def gen_rust_import_tests():
135 for python_version in BUNDLE_VERSION_INFO.keys():
136 _gen_rust_import_tests(python_version)