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
|
import glob
import os
import subprocess
import sys
import pytest
# An ExternalPluginRepo represents a git repository containing a plugin
# with tests that we wish to use as part of our test suite.
#
# Args:
# name (str): The name of the repository. This is used for impormational purposes
# url (str): The location from which therepository can be cloned
# ref (str): A known git ref that we wish to test against
# test_match_patterns (list[str]): A list of shell style globs which may be
# used to specify a subset of test files from the repository to run.
# These must be specified relative to the root of the repository.
class ExternalPluginRepo:
def __init__(self, name, url, ref, test_match_patterns=None):
self.name = name
self.url = url
self.ref = ref
if test_match_patterns is None:
test_match_patterns = ["tests"]
self._test_match_patterns = test_match_patterns
self._clone_location = None
def clone(self, location):
self._clone_location = os.path.join(location, self.name)
subprocess.run(
["git", "clone", "--single-branch", "--branch", self.ref, "--depth", "1", self.url, self._clone_location,],
check=True,
)
return self._clone_location
def install(self):
subprocess.run(["pip3", "install", self._clone_location], check=True)
def test(self, args):
test_files = self._match_test_patterns()
return pytest.main(args + test_files)
def _match_test_patterns(self):
match_list = []
for pattern in self._test_match_patterns:
abs_pattern = os.path.join(self._clone_location, pattern)
print("matching pattern: ", abs_pattern)
matches = glob.glob(abs_pattern)
match_list.extend(matches)
if not match_list:
raise ValueError("No matches found for patterns {}".format(self._test_match_patterns))
return match_list
def run_repo_tests(repo, tempdir, args):
print("Cloning repo {} to {}...".format(repo.name, tempdir))
repo.clone(tempdir)
print("Installing {}...".format(repo.name))
repo.install()
print("Testing {}...".format(repo.name))
return repo.test(args)
if __name__ == "__main__":
# Args:
# tmpdir: The directory in which this script will clone external
# repositories and use pytest's tmpdir.
# pytest_args: any remaining arguments to this script will be passed
# directly to it's pytest invocations
_, tmpdir, *pytest_args = sys.argv
ALL_EXTERNAL_PLUGINS = []
exit_code = 0
for plugin in ALL_EXTERNAL_PLUGINS:
exit_code = run_repo_tests(plugin, tmpdir, pytest_args)
if exit_code != 0:
sys.exit(exit_code)
|