|
1 | 1 | import importlib.util |
2 | 2 | import inspect |
3 | 3 | import os |
| 4 | +import sys |
4 | 5 |
|
5 | 6 | from drivers import ALSTestDriver |
6 | 7 | from drivers.lsp_python_driver import set_debug_mode, set_wait_factor |
@@ -31,25 +32,69 @@ def run(self): |
31 | 32 |
|
32 | 33 | # If there is a "test.py", evaluate it |
33 | 34 | if os.path.exists(os.path.join(wd, "test.py")): |
34 | | - # Load test.py as a module |
35 | | - python_file = os.path.join(wd, "test.py") |
36 | | - spec = importlib.util.spec_from_file_location("module.name", python_file) |
37 | | - module = importlib.util.module_from_spec(spec) |
38 | | - spec.loader.exec_module(module) |
39 | | - |
40 | | - # Look for functions with the decorator @simple_test and run them |
41 | | - errors = [ |
42 | | - f"no function with @simple_test or @complex_test found in {python_file}" |
| 35 | + # Spawn a separate executable for the test. The reason |
| 36 | + # for this is that we want to be able to remove the |
| 37 | + # test directory after the test is done, but we can't |
| 38 | + # do that under Windows if this Python driver still has |
| 39 | + # a handle on the module file. |
| 40 | + cmd = [ |
| 41 | + sys.executable, |
| 42 | + __file__, |
| 43 | + os.path.join(wd, "test.py"), |
| 44 | + self.env.als, |
| 45 | + self.env.als_home, |
| 46 | + str(self.env.wait_factor), |
43 | 47 | ] |
44 | | - |
45 | | - for _, obj in inspect.getmembers(module): |
46 | | - if inspect.isfunction(obj) and ( |
47 | | - hasattr(obj, "simple_test") or hasattr(obj, "complex_test") |
48 | | - ): |
49 | | - errors = obj(wd) |
50 | | - |
51 | | - if len(errors) > 0: |
52 | | - self.result.log += "\n".join(errors) |
53 | | - raise TestAbortWithFailure("Test returned errors") |
| 48 | + self.shell( |
| 49 | + cmd, |
| 50 | + cwd=wd, |
| 51 | + env={ |
| 52 | + "PYTHONPATH": os.path.dirname(os.path.dirname(__file__)), |
| 53 | + }, |
| 54 | + ignore_environ=False, |
| 55 | + ) |
54 | 56 | else: |
55 | 57 | raise TestAbortWithFailure("No test.py found in %s" % wd) |
| 58 | + |
| 59 | + |
| 60 | +def run_a_module( |
| 61 | + test_py_path: str, als: str, als_home: str, wait_factor: float, debug: bool |
| 62 | +): |
| 63 | + if debug: |
| 64 | + set_debug_mode(True) |
| 65 | + |
| 66 | + set_wait_factor(wait_factor) |
| 67 | + |
| 68 | + wd = os.path.dirname(test_py_path) |
| 69 | + |
| 70 | + # Load test.py as a module |
| 71 | + spec = importlib.util.spec_from_file_location("module.name", test_py_path) |
| 72 | + module = importlib.util.module_from_spec(spec) |
| 73 | + spec.loader.exec_module(module) |
| 74 | + |
| 75 | + # Look for functions with the decorator @simple_test and run them |
| 76 | + errors = [f"no function with @simple_test or @complex_test found in {test_py_path}"] |
| 77 | + |
| 78 | + for _, obj in inspect.getmembers(module): |
| 79 | + if inspect.isfunction(obj) and ( |
| 80 | + hasattr(obj, "simple_test") or hasattr(obj, "complex_test") |
| 81 | + ): |
| 82 | + errors = obj(wd) |
| 83 | + |
| 84 | + if len(errors) > 0: |
| 85 | + print("\n".join(errors)) |
| 86 | + sys.exit(1) |
| 87 | + sys.exit(0) |
| 88 | + |
| 89 | + |
| 90 | +if __name__ == "__main__": |
| 91 | + import argparse |
| 92 | + |
| 93 | + parser = argparse.ArgumentParser(description="Run a Python test driver") |
| 94 | + parser.add_argument("test", help="The test to load") |
| 95 | + parser.add_argument("als", help="The ALS program to run") |
| 96 | + parser.add_argument("als_home", help="The ALS home directory") |
| 97 | + parser.add_argument("wait_factor", type=float, help="The wait factor") |
| 98 | + parser.add_argument("--debug", action="store_true", help="Enable debug mode") |
| 99 | + args = parser.parse_args() |
| 100 | + run_a_module(args.test, args.als, args.als_home, args.wait_factor, args.debug) |
0 commit comments