1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
7 import arvados_fuse.command
12 import multiprocessing
21 from . import run_test_server
31 def wrap_static_test_method(modName, clsName, funcName, args, kwargs):
32 class Test(unittest.TestCase):
33 def runTest(self, *args, **kwargs):
34 getattr(getattr(sys.modules[modName], clsName), funcName)(self, *args, **kwargs)
35 Test().runTest(*args, **kwargs)
38 # To avoid Python's threading+multiprocessing=deadlock problems, we
39 # use a single global pool with maxtasksperchild=None for the entire
45 _pool = multiprocessing.Pool(processes=1, maxtasksperchild=None)
49 class IntegrationTest(unittest.TestCase):
50 def pool_test(self, *args, **kwargs):
51 """Run a static method as a unit test, in a different process.
53 If called by method 'foobar', the static method '_foobar' of
54 the same class will be called in the other process.
56 modName = inspect.getmodule(self).__name__
57 clsName = self.__class__.__name__
58 funcName = inspect.currentframe().f_back.f_code.co_name
60 wrap_static_test_method,
61 (modName, clsName, '_'+funcName, args, kwargs))
66 run_test_server.run_keep(blob_signing=True, num_servers=2)
69 def tearDownClass(cls):
70 run_test_server.stop_keep(num_servers=2)
73 self.mnt = tempfile.mkdtemp()
74 run_test_server.authorize_with('active')
78 run_test_server.reset()
82 """Decorator. Sets up a FUSE mount at self.mnt with the given args."""
84 @functools.wraps(func)
85 def wrapper(self, *args, **kwargs):
88 with arvados_fuse.command.Mount(
89 arvados_fuse.command.ArgumentParser().parse_args(
90 argv + ['--foreground',
91 '--unmount-timeout=60',
92 self.mnt])) as self.mount:
93 return func(self, *args, **kwargs)
95 if self.mount and self.mount.llfuse_thread.is_alive():
96 # pytest uses exit status 2 when test collection failed.
97 # A UnitTest failing in setup/teardown counts as a
98 # collection failure, so pytest will exit with status 2
99 # no matter what status you specify here. run-tests.sh
100 # looks for this status, so specify 2 just to keep
101 # everything as consistent as possible.
102 # TODO: If we refactor these tests so they're not built
103 # on unittest, consider using a dedicated, non-pytest
104 # exit code like TEMPFAIL.
105 pytest.exit("llfuse thread outlived test - aborting test suite to avoid deadlock", 2)