| 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, |
| ]) |
| return self._clone_location |
| |
| def install(self): |
| subprocess.run(['pip3', 'install', self._clone_location]) |
| |
| 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) |