Commit ec0f0757 authored by Phil Dawson's avatar Phil Dawson

testutils: move repo.py into buildstream.plugintestutils

This needs to be exposed as part of the plugin author facing API so
that plugin authors can define custom repo types which will can be
passed to the set of tests which iterate over multiple source types.

Part of the work towards #944
parent 92c9a047
......@@ -15,7 +15,9 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
from collections import OrderedDict
from .repo import Repo
from .runcli import cli, cli_integration, cli_remote_execution
# To make use of these test utilities it is necessary to have pytest
......@@ -28,3 +30,64 @@ except ImportError:
msg = "Could not import pytest:\n" \
"To use the {} module, you must have pytest installed.".format(module_name)
raise ImportError(msg)
ALL_REPO_KINDS = OrderedDict()
def create_repo(kind, directory, subdir='repo'):
"""Convenience method for creating a Repo
Args:
kind (str): The kind of repo to create (a source plugin basename). This
must have previously been registered using
`register_repo_kind`
directory (str): The path where the repo will keep a cache
Returns:
(Repo): A new Repo object
"""
try:
constructor = ALL_REPO_KINDS[kind]
except KeyError as e:
raise AssertionError("Unsupported repo kind {}".format(kind)) from e
return constructor(directory, subdir=subdir)
def register_repo_kind(kind, cls):
"""Register a new repo kind.
Registering a repo kind will allow the use of the `create_repo`
method for that kind and include that repo kind in ALL_REPO_KINDS
In addition, repo_kinds registred prior to
`sourcetests_collection_hook` being called will be automatically
used to test the basic behaviour of their associated source
plugins using the tests in `plugintestutils._sourcetests`.
Args:
kind (str): The kind of repo to create (a source plugin basename)
cls (cls) : A class derived from Repo.
"""
ALL_REPO_KINDS[kind] = cls
def sourcetests_collection_hook(session):
""" Used to hook the templated source plugin tests into a pyest test suite.
This should be called via the `pytest_sessionstart
hook <https://docs.pytest.org/en/latest/reference.html#collection-hooks>`_.
The tests in the _sourcetests package will be collected as part of
whichever test package this hook is called from.
Args:
session (pytest.Session): The current pytest session
"""
SOURCE_TESTS_PATH = os.path.dirname(_sourcetests.__file__)
# Add the location of the source tests to the session's
# python_files config. Without this, pytest may filter out these
# tests during collection.
session.config.addinivalue_line("python_files", os.path.join(SOURCE_TESTS_PATH, "/**.py"))
session.config.args.append(SOURCE_TESTS_PATH)
#
# Copyright (C) 2016-2018 Codethink Limited
# Copyright (C) 2019 Bloomberg Finance LP
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
"""
Repo - Utility class for testing source plugins
===============================================
"""
import os
import shutil
# Repo()
#
# Abstract class providing scaffolding for
# generating data to be used with various sources
#
# Args:
# directory (str): The base temp directory for the test
# subdir (str): The subdir for the repo, in case there is more than one
#
class Repo():
"""Repo()
Abstract class providing scaffolding for generating data to be
used with various sources. Subclasses of Repo may be registered to
run through the suite of generic source plugin tests provided in
buildstream.plugintestutils.
Args:
directory (str): The base temp directory for the test
subdir (str): The subdir for the repo, in case there is more than one
"""
def __init__(self, directory, subdir='repo'):
# The working directory for the repo object
......@@ -24,44 +49,40 @@ class Repo():
os.makedirs(self.repo, exist_ok=True)
# create():
#
# Create a repository in self.directory and add the initial content
#
# Args:
# directory: A directory with content to commit
#
# Returns:
# (smth): A new ref corresponding to this commit, which can
# be passed as the ref in the Repo.source_config() API.
#
def create(self, directory):
pass
# source_config()
#
# Args:
# ref (smth): An optional abstract ref object, usually a string.
#
# Returns:
# (dict): A configuration which can be serialized as a
# source when generating an element file on the fly
#
"""Create a repository in self.directory and add the initial content
Args:
directory: A directory with content to commit
Returns:
(smth): A new ref corresponding to this commit, which can
be passed as the ref in the Repo.source_config() API.
"""
raise NotImplementedError("create method has not been implemeted")
def source_config(self, ref=None):
pass
# copy_directory():
#
# Copies the content of src to the directory dest
#
# Like shutil.copytree(), except dest is expected
# to exist.
#
# Args:
# src (str): The source directory
# dest (str): The destination directory
#
"""
Args:
ref (smth): An optional abstract ref object, usually a string.
Returns:
(dict): A configuration which can be serialized as a
source when generating an element file on the fly
"""
raise NotImplementedError("source_config method has not been implemeted")
def copy_directory(self, src, dest):
""" Copies the content of src to the directory dest
Like shutil.copytree(), except dest is expected
to exist.
Args:
src (str): The source directory
dest (str): The destination directory
"""
for filename in os.listdir(src):
src_path = os.path.join(src, filename)
dest_path = os.path.join(dest, filename)
......@@ -70,17 +91,15 @@ class Repo():
else:
shutil.copy2(src_path, dest_path)
# copy():
#
# Creates a copy of this repository in the specified
# destination.
#
# Args:
# dest (str): The destination directory
#
# Returns:
# (Repo): A Repo object for the new repository.
def copy(self, dest):
"""Creates a copy of this repository in the specified destination.
Args:
dest (str): The destination directory
Returns:
(Repo): A Repo object for the new repository.
"""
subdir = self.repo[len(self.directory):].lstrip(os.sep)
new_dir = os.path.join(dest, subdir)
os.makedirs(new_dir, exist_ok=True)
......
......@@ -6,7 +6,7 @@ import shutil
import pytest
from tests.testutils import create_repo
from buildstream.plugintestutils import create_repo
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream._exceptions import ErrorDomain
from buildstream import _yaml
......
......@@ -7,8 +7,8 @@ import pytest
from buildstream import _yaml
from buildstream._exceptions import ErrorDomain, LoadErrorReason
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from tests.testutils import generate_junction, create_repo
from buildstream.plugintestutils import create_repo
from tests.testutils import generate_junction
# Project directory
......
......@@ -9,7 +9,7 @@ import pytest
from buildstream import _yaml
from buildstream._exceptions import ErrorDomain, LoadErrorReason
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from tests.testutils import create_repo
from buildstream.plugintestutils import create_repo
from tests.testutils.site import HAVE_GIT
......
......@@ -8,9 +8,8 @@ import itertools
import pytest
from tests.testutils import create_repo
from buildstream import _yaml
from buildstream.plugintestutils import create_repo
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream._exceptions import ErrorDomain
......
......@@ -3,10 +3,9 @@
import os
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream.plugintestutils import create_repo
from buildstream import _yaml
from tests.testutils import create_repo
def prepare_junction_project(cli, tmpdir):
main_project = tmpdir.join("main")
......
......@@ -4,8 +4,8 @@
import os
import pytest
from tests.testutils import create_repo, generate_junction, yaml_file_get_provenance
from tests.testutils import generate_junction, yaml_file_get_provenance
from buildstream.plugintestutils import create_repo
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream import _yaml
from buildstream._exceptions import ErrorDomain, LoadErrorReason
......
......@@ -6,7 +6,7 @@ import re
import pytest
from tests.testutils import create_repo
from buildstream.plugintestutils import create_repo
from buildstream import _yaml
from buildstream._exceptions import ErrorDomain
......
......@@ -4,9 +4,8 @@
import os
import pytest
from tests.testutils import create_repo
from buildstream import _yaml
from buildstream.plugintestutils import create_repo
from buildstream.plugintestutils import cli # pylint: disable=unused-import
......
......@@ -4,7 +4,7 @@
import os
import pytest
from tests.testutils import create_repo
from buildstream.plugintestutils import create_repo
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream import _yaml
......
......@@ -4,12 +4,12 @@
import stat
import os
import pytest
from tests.testutils import create_repo, generate_junction, yaml_file_get_provenance
from buildstream.plugintestutils import create_repo
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream._exceptions import ErrorDomain, LoadErrorReason
from buildstream import _yaml
from tests.testutils import generate_junction, yaml_file_get_provenance
from . import configure_project
# Project directory
......
......@@ -34,9 +34,9 @@ import subprocess
import pytest
from tests.testutils import create_repo, ALL_REPO_KINDS, wait_for_cache_granularity
from tests.testutils import create_artifact_share, create_element_size
from tests.testutils import create_artifact_share, create_element_size, wait_for_cache_granularity
from buildstream.plugintestutils import create_repo, ALL_REPO_KINDS
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream import _yaml
from buildstream._exceptions import ErrorDomain, LoadErrorReason
......
......@@ -3,7 +3,7 @@ import pytest
from buildstream import _yaml
from buildstream.plugintestutils import cli_integration as cli
from tests.testutils import create_repo
from buildstream.plugintestutils import create_repo
from tests.testutils.site import HAVE_SANDBOX
......
......@@ -28,8 +28,8 @@ from buildstream._context import Context
from buildstream._project import Project
from buildstream import _yaml
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from tests.testutils import create_artifact_share, create_repo
from buildstream.plugintestutils import create_repo
from tests.testutils import create_artifact_share
DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project")
......
......@@ -28,8 +28,9 @@ from buildstream._exceptions import ErrorDomain
from buildstream._project import Project
from buildstream import _yaml
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream.plugintestutils import create_repo
from tests.testutils import create_artifact_share, create_repo
from tests.testutils import create_artifact_share
DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project")
......
import os
from buildstream.plugintestutils import register_repo_kind
from tests.testutils.repo.git import Git
from tests.testutils.repo.bzr import Bzr
from tests.testutils.repo.ostree import OSTree
from tests.testutils.repo.tar import Tar
from tests.testutils.repo.zip import Zip
register_repo_kind('git', Git)
register_repo_kind('bzr', Bzr)
register_repo_kind('ostree', OSTree)
register_repo_kind('tar', Tar)
register_repo_kind('zip', Zip)
def list_dir_contents(srcdir):
contents = set()
......
......@@ -7,7 +7,7 @@ import pytest
from buildstream import _yaml
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from tests.testutils import create_repo
from buildstream.plugintestutils import create_repo
from tests.testutils.site import HAVE_BZR
DATA_DIR = os.path.join(
......
......@@ -22,8 +22,7 @@
import os
import pytest
from tests.testutils import create_repo, ALL_REPO_KINDS
from buildstream.plugintestutils import create_repo, ALL_REPO_KINDS
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream import _yaml
......
......@@ -22,7 +22,8 @@
import os
import pytest
from tests.testutils import create_repo, ALL_REPO_KINDS, generate_junction
from tests.testutils import generate_junction
from buildstream.plugintestutils import create_repo, ALL_REPO_KINDS
from tests.frontend import configure_project
from buildstream.plugintestutils import cli # pylint: disable=unused-import
......
......@@ -22,8 +22,9 @@
import os
import pytest
from tests.testutils import create_repo, ALL_REPO_KINDS, generate_junction
from tests.testutils import generate_junction
from buildstream.plugintestutils import create_repo, ALL_REPO_KINDS
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream import _yaml
from buildstream._exceptions import ErrorDomain
......
......@@ -22,9 +22,9 @@
import os
import pytest
from tests.testutils import create_repo, ALL_REPO_KINDS
from tests.testutils.site import HAVE_SANDBOX
from buildstream.plugintestutils import create_repo, ALL_REPO_KINDS
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream import _yaml
......
......@@ -22,9 +22,10 @@
import os
import pytest
from tests.testutils import create_repo, ALL_REPO_KINDS, generate_junction
from tests.testutils import generate_junction
from tests.frontend import configure_project
from buildstream.plugintestutils import create_repo, ALL_REPO_KINDS
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream import _yaml
from buildstream._exceptions import ErrorDomain
......
......@@ -22,8 +22,9 @@
import os
import pytest
from tests.testutils import create_repo, ALL_REPO_KINDS, generate_junction
from tests.testutils import generate_junction
from buildstream.plugintestutils import create_repo, ALL_REPO_KINDS
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream import _yaml
......
......@@ -23,8 +23,7 @@ import os
import shutil
import pytest
from tests.testutils import create_repo, ALL_REPO_KINDS
from buildstream.plugintestutils import create_repo, ALL_REPO_KINDS
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream import _yaml
......
......@@ -33,8 +33,8 @@ from buildstream._exceptions import ErrorDomain
from buildstream import _yaml
from buildstream.plugin import CoreWarnings
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from buildstream.plugintestutils import create_repo
from tests.testutils import create_repo
from tests.testutils.site import HAVE_GIT, HAVE_OLD_GIT
DATA_DIR = os.path.join(
......
......@@ -7,7 +7,7 @@ import pytest
from buildstream import _yaml
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from tests.testutils import create_repo
from buildstream.plugintestutils import create_repo
from tests.testutils.site import HAVE_GIT
DATA_DIR = os.path.join(
......
......@@ -26,8 +26,7 @@ import pytest
from buildstream._exceptions import ErrorDomain
from buildstream import _yaml
from buildstream.plugintestutils import cli # pylint: disable=unused-import
from tests.testutils import create_repo
from buildstream.plugintestutils import create_repo
DATA_DIR = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
......
......@@ -23,7 +23,6 @@
# William Salmon <will.salmon@codethink.co.uk>
#
from .repo import create_repo, ALL_REPO_KINDS
from .artifactshare import create_artifact_share
from .element_generators import create_element_size, update_element_size
from .junction import generate_junction
......
......@@ -2,8 +2,7 @@ import os
from buildstream import _yaml
from buildstream import utils
from .repo import create_repo
from buildstream.plugintestutils import create_repo
# create_element_size()
......
from buildstream import _yaml
from .repo import create_repo
from buildstream.plugintestutils import create_repo
# generate_junction()
......
from collections import OrderedDict
from .git import Git
from .bzr import Bzr
from .ostree import OSTree
from .tar import Tar
from .zip import Zip
ALL_REPO_KINDS = OrderedDict()
ALL_REPO_KINDS['git'] = Git
ALL_REPO_KINDS['bzr'] = Bzr
ALL_REPO_KINDS['ostree'] = OSTree
ALL_REPO_KINDS['tar'] = Tar
ALL_REPO_KINDS['zip'] = Zip
# create_repo()
#
# Convenience for creating a Repo
#
# Args:
# kind (str): The kind of repo to create (a source plugin basename)
# directory (str): The path where the repo will keep a cache
#
def create_repo(kind, directory, subdir='repo'):
try:
constructor = ALL_REPO_KINDS[kind]
except KeyError as e:
raise AssertionError("Unsupported repo kind {}".format(kind)) from e
return constructor(directory, subdir=subdir)
......@@ -2,7 +2,7 @@ import os
import subprocess
import pytest
from .repo import Repo
from buildstream.plugintestutils import Repo
from .. import site
......
......@@ -4,7 +4,7 @@ import subprocess
import pytest
from .repo import Repo
from buildstream.plugintestutils import Repo
from .. import site
......
......@@ -2,7 +2,7 @@ import subprocess
import pytest
from .repo import Repo
from buildstream.plugintestutils import Repo
from .. import site
......
......@@ -3,7 +3,7 @@ import tarfile
from buildstream.utils import sha256sum
from .repo import Repo
from buildstream.plugintestutils import Repo
class Tar(Repo):
......
......@@ -3,7 +3,7 @@ import zipfile
from buildstream.utils import sha256sum
from .repo import Repo
from buildstream.plugintestutils import Repo
class Zip(Repo):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment