You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildstream.apache.org by be...@apache.org on 2022/01/18 20:43:31 UTC

[buildstream] branch bschubert/standard-source-tests-v2 created (now 9370d1a)

This is an automated email from the ASF dual-hosted git repository.

benschubert pushed a change to branch bschubert/standard-source-tests-v2
in repository https://gitbox.apache.org/repos/asf/buildstream.git.


      at 9370d1a  tests: Replace all usages of 'create_repo' that hardcode the kind

This branch includes the following new commits:

     new 667fe33  workspace.py: Remove assumption on specific kinds to testing multiple
     new 51ddca1  workspace.py: Move bzr specific test to the bzr source
     new 9370d1a  tests: Replace all usages of 'create_repo' that hardcode the kind

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[buildstream] 02/03: workspace.py: Move bzr specific test to the bzr source

Posted by be...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

benschubert pushed a commit to branch bschubert/standard-source-tests-v2
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit 51ddca1aeab4ef56b29d254b063d184128c5b605
Author: Benjamin Schubert <co...@benschubert.me>
AuthorDate: Sat Jan 15 13:50:47 2022 +0000

    workspace.py: Move bzr specific test to the bzr source
---
 tests/frontend/workspace.py | 17 -----------------
 tests/sources/bzr.py        | 30 +++++++++++++++++++++++++++++-
 2 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/tests/frontend/workspace.py b/tests/frontend/workspace.py
index 1a7c879..669df9e 100644
--- a/tests/frontend/workspace.py
+++ b/tests/frontend/workspace.py
@@ -169,23 +169,6 @@ def open_workspace(
 
 
 @pytest.mark.datafiles(DATA_DIR)
-def test_open_bzr_customize(cli, tmpdir, datafiles):
-    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "bzr")
-
-    # Check that the .bzr dir exists
-    bzrdir = os.path.join(workspace, ".bzr")
-    assert os.path.isdir(bzrdir)
-
-    # Check that the correct origin branch is set
-    element_config = _yaml.load(os.path.join(project, "elements", element_name), shortname=None)
-    source_config = element_config.get_sequence("sources").mapping_at(0)
-    output = subprocess.check_output(["bzr", "info"], cwd=workspace)
-    stripped_url = source_config.get_str("url").lstrip("file:///")
-    expected_output_str = "checkout of branch: /{}/{}".format(stripped_url, source_config.get_str("track"))
-    assert expected_output_str in str(output)
-
-
-@pytest.mark.datafiles(DATA_DIR)
 def test_open_multi(cli, tmpdir, datafiles):
     workspace_object = WorkspaceCreator(cli, tmpdir, datafiles)
     workspaces = workspace_object.open_workspaces(repo_kinds)
diff --git a/tests/sources/bzr.py b/tests/sources/bzr.py
index f0dad8f..3ba4229 100644
--- a/tests/sources/bzr.py
+++ b/tests/sources/bzr.py
@@ -2,17 +2,20 @@
 # pylint: disable=redefined-outer-name
 
 import os
+import subprocess
+
 import pytest
 
+from buildstream import _yaml
 from buildstream.testing import cli  # pylint: disable=unused-import
 from buildstream.testing import create_repo
 from buildstream.testing import generate_element
 from buildstream.testing._utils.site import HAVE_BZR
 
+pytestmark = pytest.mark.skipif(HAVE_BZR is False, reason="bzr is not available")
 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "bzr")
 
 
-@pytest.mark.skipif(HAVE_BZR is False, reason="bzr is not available")
 @pytest.mark.datafiles(os.path.join(DATA_DIR))
 def test_fetch_checkout(cli, tmpdir, datafiles):
     project = str(datafiles)
@@ -38,3 +41,28 @@ def test_fetch_checkout(cli, tmpdir, datafiles):
         text = f.read()
 
     assert text == "test\n"
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_open_bzr_customize(cli, tmpdir, datafiles):
+    project = str(datafiles)
+    repo = create_repo("bzr", str(tmpdir))
+    ref = repo.create(os.path.join(project, "basic"))
+
+    element = {"kind": "import", "sources": [repo.source_config(ref=ref)]}
+    generate_element(project, "target.bst", element)
+
+    workspace = os.path.join(datafiles, "bzr-workspace")
+    result = cli.run(cwd=project, project=project, args=["workspace", "open", "--directory", workspace, "target.bst"])
+    result.assert_success()
+
+    # Check that the .bzr dir exists
+    assert os.path.isdir(os.path.join(workspace, ".bzr"))
+
+    # Check that the correct origin branch is set
+    element_config = _yaml.load(os.path.join(project, "target.bst"), shortname=None)
+    source_config = element_config.get_sequence("sources").mapping_at(0)
+    output = subprocess.check_output(["bzr", "info"], cwd=workspace)
+    stripped_url = source_config.get_str("url").lstrip("file:///")
+    expected_output_str = "checkout of branch: /{}/{}".format(stripped_url, source_config.get_str("track"))
+    assert expected_output_str in str(output)

[buildstream] 01/03: workspace.py: Remove assumption on specific kinds to testing multiple

Posted by be...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

benschubert pushed a commit to branch bschubert/standard-source-tests-v2
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit 667fe33482bb0c646a80aacc13d1315c9acad355
Author: Benjamin Schubert <co...@benschubert.me>
AuthorDate: Sat Jan 15 15:56:21 2022 +0000

    workspace.py: Remove assumption on specific kinds to testing multiple
    
    This makes the test more explicit in testing that it can actually open
    multiple different projects at the same time, and removes the need of
    actually using multiple kinds
---
 tests/frontend/workspace.py | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/tests/frontend/workspace.py b/tests/frontend/workspace.py
index 66e195c..1a7c879 100644
--- a/tests/frontend/workspace.py
+++ b/tests/frontend/workspace.py
@@ -30,6 +30,7 @@ import os
 import stat
 import shutil
 import subprocess
+import tempfile
 
 import pytest
 
@@ -74,8 +75,19 @@ class WorkspaceCreator:
 
         # Create our repo object of the given source type with
         # the bin files, and then collect the initial ref.
-        repo = create_repo(kind, str(self.tmpdir))
-        ref = repo.create(self.bin_files_path)
+        # And ensure we store it in a suffix-specific directory, to avoid clashes
+        # if using multiple times the same kind element here.
+        repo = create_repo(kind, str(self.tmpdir), "repo-for-{}".format(element_name))
+
+        with tempfile.TemporaryDirectory() as tempdir:
+            dst_repo = os.path.join(tempdir, "repo")
+            shutil.copytree(self.bin_files_path, dst_repo)
+            # Touch a file with the element name in, to allow validating that this
+            # is the correct repo
+            # pylint: disable=consider-using-with
+            open(os.path.join(dst_repo, element_name), "a", encoding="utf-8").close()
+
+            ref = repo.create(os.path.join(tempdir, "repo"))
 
         # Write out our test target
         element = {"kind": "import", "sources": [repo.source_config(ref=ref)]}
@@ -175,20 +187,13 @@ def test_open_bzr_customize(cli, tmpdir, datafiles):
 
 @pytest.mark.datafiles(DATA_DIR)
 def test_open_multi(cli, tmpdir, datafiles):
-
     workspace_object = WorkspaceCreator(cli, tmpdir, datafiles)
     workspaces = workspace_object.open_workspaces(repo_kinds)
 
     for (elname, workspace), kind in zip(workspaces, repo_kinds):
         assert kind in elname
         workspace_lsdir = os.listdir(workspace)
-        if kind == "git":
-            assert ".git" in workspace_lsdir
-        elif kind == "bzr":
-            assert ".bzr" in workspace_lsdir
-        else:
-            assert ".git" not in workspace_lsdir
-            assert ".bzr" not in workspace_lsdir
+        assert elname in workspace_lsdir
 
 
 @pytest.mark.skipif(os.geteuid() == 0, reason="root may have CAP_DAC_OVERRIDE and ignore permissions")

[buildstream] 03/03: tests: Replace all usages of 'create_repo' that hardcode the kind

Posted by be...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

benschubert pushed a commit to branch bschubert/standard-source-tests-v2
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit 9370d1a03d9fa03489bacfc2cb2a6588ecc471db
Author: Benjamin Schubert <co...@benschubert.me>
AuthorDate: Thu Jan 13 08:20:48 2022 +0000

    tests: Replace all usages of 'create_repo' that hardcode the kind
    
    This makes it use the kind directly and removes one layer of
    abstraction.
    
    This also helps us in getting away from the ALL_REPO_KINDS variable,
    which is necessary to untangle generic source tests
---
 tests/elements/filter.py                   | 13 ++---
 tests/format/include.py                    |  9 ++--
 tests/format/junctions.py                  | 11 +++--
 tests/frontend/buildcheckout.py            |  4 +-
 tests/frontend/cross_junction_workspace.py |  8 +--
 tests/frontend/default_target.py           |  8 +--
 tests/frontend/logging.py                  |  8 +--
 tests/frontend/mirror.py                   | 24 ++++-----
 tests/frontend/order.py                    |  5 +-
 tests/frontend/pull.py                     |  4 +-
 tests/frontend/track.py                    | 16 +++---
 tests/frontend/workspace.py                |  5 +-
 tests/remoteexecution/junction.py          |  7 ++-
 tests/sourcecache/fetch.py                 |  4 +-
 tests/sourcecache/push.py                  | 13 ++---
 tests/sources/bzr.py                       |  8 +--
 tests/sources/git.py                       | 79 +++++++++++++++---------------
 tests/sources/no_fetch_cached.py           |  5 +-
 tests/testutils/element_generators.py      |  5 +-
 tests/testutils/junction.py                |  5 +-
 20 files changed, 133 insertions(+), 108 deletions(-)

diff --git a/tests/elements/filter.py b/tests/elements/filter.py
index 443f64d..39c9431 100644
--- a/tests/elements/filter.py
+++ b/tests/elements/filter.py
@@ -6,11 +6,12 @@ import shutil
 
 import pytest
 
-from buildstream.testing import create_repo
 from buildstream.testing import cli  # pylint: disable=unused-import
 from buildstream.exceptions import ErrorDomain
 from buildstream import _yaml
 
+from tests.testutils.repo.git import Git
+
 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "filter",)
 
 
@@ -189,7 +190,7 @@ def test_filter_workspace_reset(datafiles, cli, tmpdir):
 
 @pytest.mark.datafiles(os.path.join(DATA_DIR, "basic"))
 def test_filter_track(datafiles, cli, tmpdir):
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(os.path.join(str(datafiles), "files"))
     elements_dir = os.path.join(str(tmpdir), "elements")
     project = str(tmpdir)
@@ -235,7 +236,7 @@ def test_filter_track(datafiles, cli, tmpdir):
 
 @pytest.mark.datafiles(os.path.join(DATA_DIR, "basic"))
 def test_filter_track_excepted(datafiles, cli, tmpdir):
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(str(datafiles), "files"))
     elements_dir = os.path.join(str(tmpdir), "elements")
     project = str(tmpdir)
@@ -280,7 +281,7 @@ def test_filter_track_excepted(datafiles, cli, tmpdir):
 
 @pytest.mark.datafiles(os.path.join(DATA_DIR, "basic"))
 def test_filter_track_multi_to_one(datafiles, cli, tmpdir):
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(os.path.join(str(datafiles), "files"))
     elements_dir = os.path.join(str(tmpdir), "elements")
     project = str(tmpdir)
@@ -326,7 +327,7 @@ def test_filter_track_multi_to_one(datafiles, cli, tmpdir):
 
 @pytest.mark.datafiles(os.path.join(DATA_DIR, "basic"))
 def test_filter_track_multi(datafiles, cli, tmpdir):
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(os.path.join(str(datafiles), "files"))
     elements_dir = os.path.join(str(tmpdir), "elements")
     project = str(tmpdir)
@@ -387,7 +388,7 @@ def test_filter_track_multi(datafiles, cli, tmpdir):
 
 @pytest.mark.datafiles(os.path.join(DATA_DIR, "basic"))
 def test_filter_track_multi_exclude(datafiles, cli, tmpdir):
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(os.path.join(str(datafiles), "files"))
     elements_dir = os.path.join(str(tmpdir), "elements")
     project = str(tmpdir)
diff --git a/tests/format/include.py b/tests/format/include.py
index 11659d4..b782374 100644
--- a/tests/format/include.py
+++ b/tests/format/include.py
@@ -3,12 +3,15 @@
 
 import os
 import textwrap
+
 import pytest
+
 from buildstream import _yaml
 from buildstream.exceptions import ErrorDomain, LoadErrorReason
 from buildstream.testing import cli  # pylint: disable=unused-import
-from buildstream.testing import create_repo
+
 from tests.testutils import generate_junction
+from tests.testutils.repo.git import Git
 
 
 # Project directory
@@ -109,7 +112,7 @@ def test_junction_element_partial_project_project(cli, tmpdir, datafiles):
     subproject_path = os.path.join(project, "subproject")
     junction_path = os.path.join(project, "junction.bst")
 
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
 
     ref = repo.create(subproject_path)
 
@@ -133,7 +136,7 @@ def test_junction_element_not_partial_project_file(cli, tmpdir, datafiles):
     subproject_path = os.path.join(project, "subproject")
     junction_path = os.path.join(project, "junction.bst")
 
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
 
     ref = repo.create(subproject_path)
 
diff --git a/tests/format/junctions.py b/tests/format/junctions.py
index 5c65a55..f701c2d 100644
--- a/tests/format/junctions.py
+++ b/tests/format/junctions.py
@@ -8,7 +8,8 @@ import pytest
 from buildstream import _yaml
 from buildstream.exceptions import ErrorDomain, LoadErrorReason
 from buildstream.testing import cli  # pylint: disable=unused-import
-from buildstream.testing import create_repo
+
+from tests.testutils.repo.tar import Tar
 
 
 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "junctions",)
@@ -260,7 +261,7 @@ def test_tar_show(cli, tmpdir, datafiles):
     project = os.path.join(str(datafiles), "use-repo")
 
     # Create the repo from 'baserepo' subdir
-    repo = create_repo("tar", str(tmpdir))
+    repo = Tar(str(tmpdir))
     ref = repo.create(os.path.join(project, "baserepo"))
 
     # Write out junction element with tar source
@@ -279,7 +280,7 @@ def test_tar_build(cli, tmpdir, datafiles):
     checkoutdir = os.path.join(str(tmpdir), "checkout")
 
     # Create the repo from 'baserepo' subdir
-    repo = create_repo("tar", str(tmpdir))
+    repo = Tar(str(tmpdir))
     ref = repo.create(os.path.join(project, "baserepo"))
 
     # Write out junction element with tar source
@@ -304,7 +305,7 @@ def test_tar_missing_project_conf(cli, tmpdir, datafiles):
     os.remove(datafiles / "use-repo" / "baserepo" / "project.conf")
 
     # Create the repo from 'base' subdir
-    repo = create_repo("tar", str(tmpdir))
+    repo = Tar(str(tmpdir))
     ref = repo.create(os.path.join(project, "baserepo"))
 
     # Write out junction element with tar source
@@ -324,7 +325,7 @@ def test_build_tar_cross_junction_names(cli, tmpdir, datafiles):
     checkoutdir = os.path.join(str(tmpdir), "checkout")
 
     # Create the repo from 'base' subdir
-    repo = create_repo("tar", str(tmpdir))
+    repo = Tar(str(tmpdir))
     ref = repo.create(os.path.join(project, "baserepo"))
 
     # Write out junction element with tar source
diff --git a/tests/frontend/buildcheckout.py b/tests/frontend/buildcheckout.py
index b25e313..5e52ab9 100644
--- a/tests/frontend/buildcheckout.py
+++ b/tests/frontend/buildcheckout.py
@@ -9,13 +9,13 @@ import re
 import pytest
 
 from buildstream.testing import cli  # pylint: disable=unused-import
-from buildstream.testing import create_repo
 from buildstream.testing._utils.site import CASD_SEPARATE_USER
 from buildstream import _yaml
 from buildstream.exceptions import ErrorDomain, LoadErrorReason
 from buildstream import utils
 
 from tests.testutils import generate_junction, create_artifact_share
+from tests.testutils.repo.git import Git
 
 from . import configure_project
 
@@ -1035,7 +1035,7 @@ def test_partial_artifact_checkout_fetch(cli, datafiles, tmpdir):
     project = str(datafiles)
     checkout_dir = os.path.join(str(tmpdir), "checkout")
 
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(str(datafiles), "files"))
     element_dir = os.path.join(str(tmpdir), "elements")
     project = str(tmpdir)
diff --git a/tests/frontend/cross_junction_workspace.py b/tests/frontend/cross_junction_workspace.py
index 0972f94..47c848c 100644
--- a/tests/frontend/cross_junction_workspace.py
+++ b/tests/frontend/cross_junction_workspace.py
@@ -2,10 +2,12 @@
 # pylint: disable=redefined-outer-name
 
 import os
+
 from buildstream.testing import cli  # pylint: disable=unused-import
-from buildstream.testing import create_repo
 from buildstream import _yaml
 
+from tests.testutils.repo.git import Git
+
 
 def prepare_junction_project(cli, tmpdir):
     main_project = tmpdir.join("main")
@@ -23,7 +25,7 @@ def prepare_junction_project(cli, tmpdir):
 
     import_repo_dir = tmpdir.join("import_repo")
     os.makedirs(str(import_repo_dir))
-    import_repo = create_repo("git", str(import_repo_dir))
+    import_repo = Git(str(import_repo_dir))
     import_ref = import_repo.create(str(import_dir))
 
     _yaml.roundtrip_dump(
@@ -32,7 +34,7 @@ def prepare_junction_project(cli, tmpdir):
 
     sub_repo_dir = tmpdir.join("sub_repo")
     os.makedirs(str(sub_repo_dir))
-    sub_repo = create_repo("git", str(sub_repo_dir))
+    sub_repo = Git(str(sub_repo_dir))
     sub_ref = sub_repo.create(str(sub_project))
 
     _yaml.roundtrip_dump(
diff --git a/tests/frontend/default_target.py b/tests/frontend/default_target.py
index a10133d..cff81cd 100644
--- a/tests/frontend/default_target.py
+++ b/tests/frontend/default_target.py
@@ -6,8 +6,10 @@ import os
 import pytest
 
 from buildstream import _yaml
-from buildstream.testing import cli, create_repo  # pylint: disable=unused-import
+from buildstream.testing import cli  # pylint: disable=unused-import
+
 from tests.testutils import create_artifact_share
+from tests.testutils.repo.git import Git
 
 # project directory
 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "default-target",)
@@ -99,7 +101,7 @@ def test_default_target_track(cli, tmpdir, datafiles):
     target = "track-fetch-test.bst"
 
     # First, create an element with trackable sources
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(project)
     element_conf = {"kind": "import", "sources": [repo.source_config()]}
     _yaml.roundtrip_dump(element_conf, os.path.join(project, "elements", target))
@@ -129,7 +131,7 @@ def test_default_target_fetch(cli, tmpdir, datafiles):
     target = "track-fetch-test.bst"
 
     # First, create an element with trackable sources
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(project)
     element_conf = {"kind": "import", "sources": [repo.source_config(ref=ref)]}
     _yaml.roundtrip_dump(element_conf, os.path.join(project, "elements", target))
diff --git a/tests/frontend/logging.py b/tests/frontend/logging.py
index 6cbbee7..b8ad4b5 100644
--- a/tests/frontend/logging.py
+++ b/tests/frontend/logging.py
@@ -6,12 +6,12 @@ import re
 
 import pytest
 
-from buildstream.testing import create_repo
-
 from buildstream import _yaml
 from buildstream.exceptions import ErrorDomain
 from buildstream.testing import cli  # pylint: disable=unused-import
 
+from tests.testutils.repo.git import Git
+
 # Project directory
 DATA_DIR = os.path.dirname(os.path.realpath(__file__))
 
@@ -26,7 +26,7 @@ def test_default_logging(cli, tmpdir, datafiles):
     # Create our repo object of the given source type with
     # the bin files, and then collect the initial ref.
     #
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(bin_files_path)
 
     # Write out our test target
@@ -55,7 +55,7 @@ def test_custom_logging(cli, tmpdir, datafiles):
     # Create our repo object of the given source type with
     # the bin files, and then collect the initial ref.
     #
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(bin_files_path)
 
     # Write out our test target
diff --git a/tests/frontend/mirror.py b/tests/frontend/mirror.py
index db5d6bf..a38652a 100644
--- a/tests/frontend/mirror.py
+++ b/tests/frontend/mirror.py
@@ -5,9 +5,11 @@ import os
 import pytest
 
 from buildstream import _yaml
-from buildstream.testing import create_repo
 from buildstream.testing import cli  # pylint: disable=unused-import
 
+from tests.testutils.repo.git import Git
+from tests.testutils.repo.tar import Tar
+
 
 # Project directory
 TOP_DIR = os.path.dirname(os.path.realpath(__file__))
@@ -67,7 +69,7 @@ def test_mirror_fetch_ref_storage(cli, tmpdir, datafiles, ref_storage, mirror):
     element_dir = os.path.join(project_dir, "elements")
 
     # Create repo objects of the upstream and mirror
-    upstream_repo = create_repo("tar", upstream_repodir)
+    upstream_repo = Tar(upstream_repodir)
     upstream_repo.create(bin_files_path)
     mirror_repo = upstream_repo.copy(mirror_repodir)
     upstream_ref = upstream_repo.create(dev_files_path)
@@ -247,15 +249,15 @@ def test_mirror_git_submodule_fetch(cli, tmpdir, datafiles):
     dev_files_path = os.path.join(str(datafiles), "files", "dev-files", "usr")
     mirror_dir = os.path.join(str(datafiles), "mirror")
 
-    defined_subrepo = create_repo("git", str(tmpdir), "defined_subrepo")
+    defined_subrepo = Git(str(tmpdir), "defined_subrepo")
     defined_subrepo.create(bin_files_path)
     defined_subrepo.copy(mirror_dir)
     defined_subrepo.add_file(foo_file)
 
-    found_subrepo = create_repo("git", str(tmpdir), "found_subrepo")
+    found_subrepo = Git(str(tmpdir), "found_subrepo")
     found_subrepo.create(dev_files_path)
 
-    main_repo = create_repo("git", str(tmpdir))
+    main_repo = Git(str(tmpdir))
     main_mirror_ref = main_repo.create(bin_files_path)
     main_repo.add_submodule("defined", "file://" + defined_subrepo.repo)
     main_repo.add_submodule("found", "file://" + found_subrepo.repo)
@@ -320,12 +322,12 @@ def test_mirror_fallback_git_only_submodules(cli, tmpdir, datafiles):
 
     upstream_bin_repodir = os.path.join(str(tmpdir), "bin-upstream")
     mirror_bin_repodir = os.path.join(str(tmpdir), "bin-mirror")
-    upstream_bin_repo = create_repo("git", upstream_bin_repodir)
+    upstream_bin_repo = Git(upstream_bin_repodir)
     upstream_bin_repo.create(bin_files_path)
     mirror_bin_repo = upstream_bin_repo.copy(mirror_bin_repodir)
 
     dev_repodir = os.path.join(str(tmpdir), "dev-upstream")
-    dev_repo = create_repo("git", dev_repodir)
+    dev_repo = Git(dev_repodir)
     dev_repo.create(dev_files_path)
 
     main_files = os.path.join(str(tmpdir), "main-files")
@@ -333,7 +335,7 @@ def test_mirror_fallback_git_only_submodules(cli, tmpdir, datafiles):
     with open(os.path.join(main_files, "README"), "w", encoding="utf-8") as f:
         f.write("TEST\n")
     main_repodir = os.path.join(str(tmpdir), "main-upstream")
-    main_repo = create_repo("git", main_repodir)
+    main_repo = Git(main_repodir)
     main_repo.create(main_files)
 
     upstream_url = "file://{}".format(upstream_bin_repo.repo)
@@ -399,11 +401,11 @@ def test_mirror_fallback_git_with_submodules(cli, tmpdir, datafiles):
     dev_files_path = os.path.join(str(datafiles), "files", "dev-files", "usr")
 
     bin_repodir = os.path.join(str(tmpdir), "bin-repo")
-    bin_repo = create_repo("git", bin_repodir)
+    bin_repo = Git(bin_repodir)
     bin_repo.create(bin_files_path)
 
     dev_repodir = os.path.join(str(tmpdir), "dev-repo")
-    dev_repo = create_repo("git", dev_repodir)
+    dev_repo = Git(dev_repodir)
     dev_repo.create(dev_files_path)
 
     main_files = os.path.join(str(tmpdir), "main-files")
@@ -411,7 +413,7 @@ def test_mirror_fallback_git_with_submodules(cli, tmpdir, datafiles):
     with open(os.path.join(main_files, "README"), "w", encoding="utf-8") as f:
         f.write("TEST\n")
     upstream_main_repodir = os.path.join(str(tmpdir), "main-upstream")
-    upstream_main_repo = create_repo("git", upstream_main_repodir)
+    upstream_main_repo = Git(upstream_main_repodir)
     upstream_main_repo.create(main_files)
 
     upstream_main_repo.add_submodule("bin", url="file://{}".format(bin_repo.repo))
diff --git a/tests/frontend/order.py b/tests/frontend/order.py
index b57f373..cee6889 100644
--- a/tests/frontend/order.py
+++ b/tests/frontend/order.py
@@ -4,10 +4,11 @@
 import os
 
 import pytest
-from buildstream.testing import create_repo
 from buildstream.testing import cli  # pylint: disable=unused-import
 from buildstream import _yaml
 
+from tests.testutils.repo.git import Git
+
 # Project directory
 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project",)
 
@@ -24,7 +25,7 @@ DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project",)
 def create_element(project, name, dependencies):
     dev_files_path = os.path.join(project, "files", "dev-files")
     element_path = os.path.join(project, "elements")
-    repo = create_repo("git", project, "{}-repo".format(name))
+    repo = Git(project, "{}-repo".format(name))
     ref = repo.create(dev_files_path)
 
     element = {"kind": "import", "sources": [repo.source_config(ref=ref)], "depends": dependencies}
diff --git a/tests/frontend/pull.py b/tests/frontend/pull.py
index 93168cb..40b3e8d 100644
--- a/tests/frontend/pull.py
+++ b/tests/frontend/pull.py
@@ -7,7 +7,6 @@ import stat
 import pytest
 from buildstream import utils, _yaml
 from buildstream.testing import cli  # pylint: disable=unused-import
-from buildstream.testing import create_repo
 from tests.testutils import (
     create_artifact_share,
     create_split_share,
@@ -15,6 +14,7 @@ from tests.testutils import (
     assert_shared,
     assert_not_shared,
 )
+from tests.testutils.repo.git import Git
 
 
 # Project directory
@@ -326,7 +326,7 @@ def test_pull_missing_blob_split_share(cli, tmpdir, datafiles):
 @pytest.mark.datafiles(DATA_DIR)
 def test_pull_missing_local_blob(cli, tmpdir, datafiles):
     project = os.path.join(datafiles.dirname, datafiles.basename)
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(str(datafiles), "files"))
     element_dir = os.path.join(str(tmpdir), "elements")
     project = str(tmpdir)
diff --git a/tests/frontend/track.py b/tests/frontend/track.py
index 3ed9f50..fd1e040 100644
--- a/tests/frontend/track.py
+++ b/tests/frontend/track.py
@@ -6,12 +6,14 @@ import os
 import re
 import pytest
 
-from buildstream.testing import create_repo, generate_project
+from buildstream.testing import generate_project
 from buildstream.testing import cli  # pylint: disable=unused-import
 from buildstream.testing._utils.site import have_subsecond_mtime
 from buildstream.exceptions import ErrorDomain, LoadErrorReason
 from buildstream import _yaml
 from tests.testutils import generate_junction
+from tests.testutils.repo.git import Git
+from tests.testutils.repo.tar import Tar
 from . import configure_project
 
 # Project directory
@@ -38,7 +40,7 @@ def test_track_single(cli, tmpdir, datafiles):
     # Create our repo object of the given source type with
     # the dev files, and then collect the initial ref.
     #
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(dev_files_path)
 
     # Write out our test targets
@@ -78,7 +80,7 @@ def test_track_optional(cli, tmpdir, datafiles, ref_storage):
     # Create our repo object of the given source type with
     # the dev files, and then collect the initial ref.
     #
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(dev_files_path)
 
     # Now create an optional test branch and add a commit to that,
@@ -175,7 +177,7 @@ def test_track_cross_junction(cli, tmpdir, datafiles, cross_junction, ref_storag
     # Create our repo object of the given source type with
     # the dev files, and then collect the initial ref.
     #
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(dev_files_path)
 
     # Generate two elements using the git source, one in
@@ -344,7 +346,7 @@ def test_track_error_cannot_write_file(cli, tmpdir, datafiles):
 
     configure_project(project, {"ref-storage": "inline"})
 
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(dev_files_path)
 
     element_full_path = os.path.join(element_path, element_name)
@@ -377,7 +379,7 @@ def test_no_needless_overwrite(cli, tmpdir, datafiles):
     # Create our repo object of the given source type with
     # the dev files, and then collect the initial ref.
     #
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(dev_files_path)
 
     # Write out our test target and assert it exists
@@ -464,7 +466,7 @@ def test_track_skip(cli, tmpdir, datafiles):
 
     # Generate a regular import element which will have a workspace open
     #
-    repo = create_repo("tar", str(tmpdir))
+    repo = Tar(str(tmpdir))
     repo.create(dev_files_path)
     generate_element(repo, os.path.join(element_path, element_workspace_name))
 
diff --git a/tests/frontend/workspace.py b/tests/frontend/workspace.py
index 669df9e..8219bad 100644
--- a/tests/frontend/workspace.py
+++ b/tests/frontend/workspace.py
@@ -41,6 +41,7 @@ from buildstream.exceptions import ErrorDomain, LoadErrorReason
 from buildstream._workspaces import BST_WORKSPACE_FORMAT_VERSION
 
 from tests.testutils import create_artifact_share, create_element_size, wait_for_cache_granularity
+from tests.testutils.repo.git import Git
 
 repo_kinds = ALL_REPO_KINDS
 
@@ -695,7 +696,7 @@ def test_buildable_no_ref(cli, tmpdir, datafiles):
     element_path = os.path.join(project, "elements")
 
     # Write out our test target without any source ref
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     element = {"kind": "import", "sources": [repo.source_config()]}
     _yaml.roundtrip_dump(element, os.path.join(element_path, element_name))
 
@@ -872,7 +873,7 @@ def test_list_supported_workspace(cli, tmpdir, datafiles, workspace_cfg, expecte
     # Create our repo object of the given source type with
     # the bin files, and then collect the initial ref.
     #
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(bin_files_path)
 
     # Write out our test target
diff --git a/tests/remoteexecution/junction.py b/tests/remoteexecution/junction.py
index 13565cd..14e2c0a 100644
--- a/tests/remoteexecution/junction.py
+++ b/tests/remoteexecution/junction.py
@@ -18,11 +18,14 @@
 # pylint: disable=redefined-outer-name
 
 import os
+
 import pytest
+
 from buildstream.testing import cli_remote_execution as cli  # pylint: disable=unused-import
-from buildstream.testing import create_repo
 from buildstream import _yaml
+
 from tests.testutils import generate_junction
+from tests.testutils.repo.git import Git
 
 pytestmark = pytest.mark.remoteexecution
 
@@ -51,7 +54,7 @@ def test_junction_build_remote(cli, tmpdir, datafiles):
     junction_path = os.path.join(element_path, "junction.bst")
 
     # We need a repo for real trackable elements
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(amhello_files_path)
 
     # ensure that the correct project directory is also listed in the junction
diff --git a/tests/sourcecache/fetch.py b/tests/sourcecache/fetch.py
index deaaadc..bdfef4f 100644
--- a/tests/sourcecache/fetch.py
+++ b/tests/sourcecache/fetch.py
@@ -27,15 +27,15 @@ from buildstream.exceptions import ErrorDomain
 from buildstream._project import Project
 from buildstream import _yaml
 from buildstream.testing import cli  # pylint: disable=unused-import
-from buildstream.testing import create_repo
 
 from tests.testutils import create_artifact_share, dummy_context
+from tests.testutils.repo.git import Git
 
 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project")
 
 
 def create_test_element(tmpdir, project_dir):
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(os.path.join(project_dir, "files"))
     element_path = os.path.join(project_dir, "elements")
     element_name = "fetch.bst"
diff --git a/tests/sourcecache/push.py b/tests/sourcecache/push.py
index 1d7c9a5..8c81265 100644
--- a/tests/sourcecache/push.py
+++ b/tests/sourcecache/push.py
@@ -28,8 +28,9 @@ from buildstream.exceptions import ErrorDomain
 from buildstream._project import Project
 from buildstream import _yaml
 from buildstream.testing import cli  # pylint: disable=unused-import
-from buildstream.testing import create_repo
+
 from tests.testutils import create_artifact_share, dummy_context
+from tests.testutils.repo.git import Git
 
 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project")
 
@@ -72,7 +73,7 @@ def test_source_push_split(cli, tmpdir, datafiles):
         _yaml.roundtrip_dump(user_config, file=user_config_file)
         cli.configure(user_config)
 
-        repo = create_repo("git", str(tmpdir))
+        repo = Git(str(tmpdir))
         ref = repo.create(os.path.join(project_dir, "files"))
         element_path = os.path.join(project_dir, "elements")
         element_name = "push.bst"
@@ -122,7 +123,7 @@ def test_source_push(cli, tmpdir, datafiles):
         _yaml.roundtrip_dump(user_config, file=user_config_file)
         cli.configure(user_config)
 
-        repo = create_repo("git", str(tmpdir))
+        repo = Git(str(tmpdir))
         ref = repo.create(os.path.join(project_dir, "files"))
         element_path = os.path.join(project_dir, "elements")
         element_name = "push.bst"
@@ -173,7 +174,7 @@ def test_push_pull(cli, datafiles, tmpdir):
         cli.configure(user_config)
 
         # create repo to pull from
-        repo = create_repo("git", str(tmpdir))
+        repo = Git(str(tmpdir))
         ref = repo.create(os.path.join(project_dir, "files"))
         element_path = os.path.join(project_dir, "elements")
         element_name = "push.bst"
@@ -211,7 +212,7 @@ def test_push_fail(cli, tmpdir, datafiles):
         cli.configure(user_config)
 
     # create repo to pull from
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(os.path.join(project_dir, "files"))
     element_path = os.path.join(project_dir, "elements")
     element_name = "push.bst"
@@ -240,7 +241,7 @@ def test_source_push_build_fail(cli, tmpdir, datafiles):
         }
         cli.configure(user_config)
 
-        repo = create_repo("git", str(tmpdir))
+        repo = Git(str(tmpdir))
         ref = repo.create(os.path.join(project_dir, "files"))
         element_path = os.path.join(project_dir, "elements")
 
diff --git a/tests/sources/bzr.py b/tests/sources/bzr.py
index 3ba4229..73d80b1 100644
--- a/tests/sources/bzr.py
+++ b/tests/sources/bzr.py
@@ -8,11 +8,13 @@ import pytest
 
 from buildstream import _yaml
 from buildstream.testing import cli  # pylint: disable=unused-import
-from buildstream.testing import create_repo
 from buildstream.testing import generate_element
 from buildstream.testing._utils.site import HAVE_BZR
 
+from tests.testutils.repo.bzr import Bzr
+
 pytestmark = pytest.mark.skipif(HAVE_BZR is False, reason="bzr is not available")
+
 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "bzr")
 
 
@@ -21,7 +23,7 @@ def test_fetch_checkout(cli, tmpdir, datafiles):
     project = str(datafiles)
     checkoutdir = os.path.join(str(tmpdir), "checkout")
 
-    repo = create_repo("bzr", str(tmpdir))
+    repo = Bzr(str(tmpdir))
     ref = repo.create(os.path.join(project, "basic"))
 
     # Write out our test target
@@ -46,7 +48,7 @@ def test_fetch_checkout(cli, tmpdir, datafiles):
 @pytest.mark.datafiles(DATA_DIR)
 def test_open_bzr_customize(cli, tmpdir, datafiles):
     project = str(datafiles)
-    repo = create_repo("bzr", str(tmpdir))
+    repo = Bzr(str(tmpdir))
     ref = repo.create(os.path.join(project, "basic"))
 
     element = {"kind": "import", "sources": [repo.source_config(ref=ref)]}
diff --git a/tests/sources/git.py b/tests/sources/git.py
index fd0af4c..3c68722 100644
--- a/tests/sources/git.py
+++ b/tests/sources/git.py
@@ -33,9 +33,10 @@ from buildstream.exceptions import ErrorDomain
 from buildstream.plugin import CoreWarnings
 from buildstream.testing import cli  # pylint: disable=unused-import
 from buildstream.testing import generate_project, generate_element, load_yaml
-from buildstream.testing import create_repo
 from buildstream.testing._utils.site import HAVE_GIT, HAVE_OLD_GIT
 
+from tests.testutils.repo.git import Git
+
 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "git",)
 
 
@@ -45,7 +46,7 @@ def test_fetch_bad_ref(cli, tmpdir, datafiles):
     project = str(datafiles)
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Write out our test target with a bad ref
@@ -66,7 +67,7 @@ def test_fetch_shallow(cli, tmpdir, datafiles):
     workspacedir = os.path.join(str(tmpdir), "workspace")
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
     first_commit = repo.latest_commit()
     repo.add_commit()
@@ -93,11 +94,11 @@ def test_submodule_fetch_checkout(cli, tmpdir, datafiles):
     checkoutdir = os.path.join(str(tmpdir), "checkout")
 
     # Create the submodule first from the 'subrepofiles' subdir
-    subrepo = create_repo("git", str(tmpdir), "subrepo")
+    subrepo = Git(str(tmpdir), "subrepo")
     subrepo.create(os.path.join(project, "subrepofiles"))
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Add a submodule pointing to the one we created
@@ -127,15 +128,15 @@ def test_recursive_submodule_fetch_checkout(cli, tmpdir, datafiles):
     checkoutdir = os.path.join(str(tmpdir), "checkout")
 
     # Create a submodule from the 'othersubrepofiles' subdir
-    subsubrepo = create_repo("git", str(tmpdir), "subsubrepo")
+    subsubrepo = Git(str(tmpdir), "subsubrepo")
     subsubrepo.create(os.path.join(project, "othersubrepofiles"))
 
     # Create another submodule from the 'subrepofiles' subdir
-    subrepo = create_repo("git", str(tmpdir), "subrepo")
+    subrepo = Git(str(tmpdir), "subrepo")
     subrepo.create(os.path.join(project, "subrepofiles"))
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Configure submodules
@@ -167,11 +168,11 @@ def test_submodule_fetch_source_enable_explicit(cli, tmpdir, datafiles):
     checkoutdir = os.path.join(str(tmpdir), "checkout")
 
     # Create the submodule first from the 'subrepofiles' subdir
-    subrepo = create_repo("git", str(tmpdir), "subrepo")
+    subrepo = Git(str(tmpdir), "subrepo")
     subrepo.create(os.path.join(project, "subrepofiles"))
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Add a submodule pointing to the one we created
@@ -201,11 +202,11 @@ def test_submodule_fetch_source_disable(cli, tmpdir, datafiles):
     checkoutdir = os.path.join(str(tmpdir), "checkout")
 
     # Create the submodule first from the 'subrepofiles' subdir
-    subrepo = create_repo("git", str(tmpdir), "subrepo")
+    subrepo = Git(str(tmpdir), "subrepo")
     subrepo.create(os.path.join(project, "subrepofiles"))
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Add a submodule pointing to the one we created
@@ -235,11 +236,11 @@ def test_submodule_fetch_submodule_does_override(cli, tmpdir, datafiles):
     checkoutdir = os.path.join(str(tmpdir), "checkout")
 
     # Create the submodule first from the 'subrepofiles' subdir
-    subrepo = create_repo("git", str(tmpdir), "subrepo")
+    subrepo = Git(str(tmpdir), "subrepo")
     subrepo.create(os.path.join(project, "subrepofiles"))
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Add a submodule pointing to the one we created
@@ -269,15 +270,15 @@ def test_submodule_fetch_submodule_individual_checkout(cli, tmpdir, datafiles):
     checkoutdir = os.path.join(str(tmpdir), "checkout")
 
     # Create the submodule first from the 'subrepofiles' subdir
-    subrepo = create_repo("git", str(tmpdir), "subrepo")
+    subrepo = Git(str(tmpdir), "subrepo")
     subrepo.create(os.path.join(project, "subrepofiles"))
 
     # Create another submodule from the 'othersubrepofiles' subdir
-    other_subrepo = create_repo("git", str(tmpdir), "othersubrepo")
+    other_subrepo = Git(str(tmpdir), "othersubrepo")
     other_subrepo.create(os.path.join(project, "othersubrepofiles"))
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Add a submodule pointing to the one we created
@@ -309,15 +310,15 @@ def test_submodule_fetch_submodule_individual_checkout_explicit(cli, tmpdir, dat
     checkoutdir = os.path.join(str(tmpdir), "checkout")
 
     # Create the submodule first from the 'subrepofiles' subdir
-    subrepo = create_repo("git", str(tmpdir), "subrepo")
+    subrepo = Git(str(tmpdir), "subrepo")
     subrepo.create(os.path.join(project, "subrepofiles"))
 
     # Create another submodule from the 'othersubrepofiles' subdir
-    other_subrepo = create_repo("git", str(tmpdir), "othersubrepo")
+    other_subrepo = Git(str(tmpdir), "othersubrepo")
     other_subrepo.create(os.path.join(project, "othersubrepofiles"))
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Add a submodule pointing to the one we created
@@ -349,11 +350,11 @@ def test_submodule_fetch_project_override(cli, tmpdir, datafiles):
     checkoutdir = os.path.join(str(tmpdir), "checkout")
 
     # Create the submodule first from the 'subrepofiles' subdir
-    subrepo = create_repo("git", str(tmpdir), "subrepo")
+    subrepo = Git(str(tmpdir), "subrepo")
     subrepo.create(os.path.join(project, "subrepofiles"))
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Add a submodule pointing to the one we created
@@ -382,7 +383,7 @@ def test_submodule_track_ignore_inconsistent(cli, tmpdir, datafiles):
     project = str(datafiles)
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(os.path.join(project, "repofiles"))
 
     # Write out our test target
@@ -418,7 +419,7 @@ def test_submodule_track_no_ref_or_track(cli, tmpdir, datafiles):
     project = str(datafiles)
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Write out our test target
@@ -444,7 +445,7 @@ def test_ref_not_in_track(cli, tmpdir, datafiles, fail):
         generate_project(project, config={"fatal-warnings": [CoreWarnings.REF_NOT_IN_TRACK]})
 
     # Create the repo from 'repofiles', create a branch without latest commit
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(os.path.join(project, "repofiles"))
 
     gitsource = repo.source_config(ref=ref)
@@ -478,11 +479,11 @@ def test_unlisted_submodule(cli, tmpdir, datafiles, fail):
         generate_project(project, config={"fatal-warnings": ["git:unlisted-submodule"]})
 
     # Create the submodule first from the 'subrepofiles' subdir
-    subrepo = create_repo("git", str(tmpdir), "subrepo")
+    subrepo = Git(str(tmpdir), "subrepo")
     subrepo.create(os.path.join(project, "subrepofiles"))
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Add a submodule pointing to the one we created
@@ -536,11 +537,11 @@ def test_track_unlisted_submodule(cli, tmpdir, datafiles, fail):
         generate_project(project, config={"fatal-warnings": ["git:unlisted-submodule"]})
 
     # Create the submodule first from the 'subrepofiles' subdir
-    subrepo = create_repo("git", str(tmpdir), "subrepo")
+    subrepo = Git(str(tmpdir), "subrepo")
     subrepo.create(os.path.join(project, "subrepofiles"))
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(os.path.join(project, "repofiles"))
 
     # Add a submodule pointing to the one we created, but use
@@ -590,7 +591,7 @@ def test_invalid_submodule(cli, tmpdir, datafiles, fail):
         generate_project(project, config={"fatal-warnings": ["git:invalid-submodule"]})
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(os.path.join(project, "repofiles"))
 
     # Create the source without any submodules, and add
@@ -643,11 +644,11 @@ def test_track_invalid_submodule(cli, tmpdir, datafiles, fail):
         generate_project(project, config={"fatal-warnings": ["git:invalid-submodule"]})
 
     # Create the submodule first from the 'subrepofiles' subdir
-    subrepo = create_repo("git", str(tmpdir), "subrepo")
+    subrepo = Git(str(tmpdir), "subrepo")
     subrepo.create(os.path.join(project, "subrepofiles"))
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
 
     # Add a submodule pointing to the one we created
@@ -694,7 +695,7 @@ def test_track_fetch(cli, tmpdir, datafiles, ref_format, tag, extra_commit):
     project = str(datafiles)
 
     # Create the repo from 'repofiles' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(os.path.join(project, "repofiles"))
     if tag:
         repo.add_tag("tag")
@@ -746,7 +747,7 @@ def test_git_describe(cli, tmpdir, datafiles, ref_storage, tag_type):
     with open(file0, "w", encoding="utf-8") as f:
         f.write("test\n")
 
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
 
     def tag(name):
         if tag_type == "annotated":
@@ -856,7 +857,7 @@ def test_git_describe_head_is_tagged(cli, tmpdir, datafiles, ref_storage, tag_ty
     with open(file0, "w", encoding="utf-8") as f:
         f.write("test\n")
 
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
 
     def tag(name):
         if tag_type == "annotated":
@@ -963,7 +964,7 @@ def test_git_describe_relevant_history(cli, tmpdir, datafiles):
     with open(file0, "w", encoding="utf-8") as f:
         f.write("test\n")
 
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     repo.create(repofiles)
 
     file1 = os.path.join(str(tmpdir), "file1")
@@ -1036,7 +1037,7 @@ def test_default_do_not_track_tags(cli, tmpdir, datafiles):
     with open(file0, "w", encoding="utf-8") as f:
         f.write("test\n")
 
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
 
     repo.create(repofiles)
     repo.add_tag("tag")
@@ -1076,7 +1077,7 @@ def test_overwrite_rogue_tag_multiple_remotes(cli, tmpdir, datafiles):
     with open(file0, "w", encoding="utf-8") as f:
         f.write("test\n")
 
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
 
     top_commit = repo.create(repofiles)
 
@@ -1122,7 +1123,7 @@ def test_overwrite_rogue_tag_multiple_remotes(cli, tmpdir, datafiles):
 
     otherpath = os.path.join(str(tmpdir), "other_path")
     shutil.copytree(repo.repo, os.path.join(otherpath, "repo"))
-    create_repo("git", otherpath)
+    Git(otherpath)
 
     repodir, reponame = os.path.split(repo.repo)
 
diff --git a/tests/sources/no_fetch_cached.py b/tests/sources/no_fetch_cached.py
index 4984f53..ece0ca3 100644
--- a/tests/sources/no_fetch_cached.py
+++ b/tests/sources/no_fetch_cached.py
@@ -5,10 +5,11 @@ import os
 import pytest
 
 from buildstream.testing import cli  # pylint: disable=unused-import
-from buildstream.testing import create_repo
 from buildstream.testing import generate_element
 from buildstream.testing._utils.site import HAVE_GIT
 
+from tests.testutils.repo.git import Git
+
 DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "no-fetch-cached")
 
 
@@ -22,7 +23,7 @@ def test_no_fetch_cached(cli, tmpdir, datafiles):
     project = str(datafiles)
 
     # Create the repo from 'files' subdir
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     ref = repo.create(os.path.join(project, "files"))
 
     # Write out test target with a cached and a non-cached source
diff --git a/tests/testutils/element_generators.py b/tests/testutils/element_generators.py
index 6da465a..8d457b7 100644
--- a/tests/testutils/element_generators.py
+++ b/tests/testutils/element_generators.py
@@ -2,7 +2,8 @@ import os
 
 from buildstream import _yaml
 from buildstream import utils
-from buildstream.testing import create_repo
+
+from tests.testutils.repo.git import Git
 
 
 # create_element_size()
@@ -29,7 +30,7 @@ def create_element_size(name, project_dir, elements_path, dependencies, size):
 
     # Create a git repo
     repodir = os.path.join(project_dir, "repos")
-    repo = create_repo("git", repodir, subdir=name)
+    repo = Git(repodir, subdir=name)
 
     with utils._tempdir(dir=project_dir) as tmp:
 
diff --git a/tests/testutils/junction.py b/tests/testutils/junction.py
index 4889fdb..2f44bce 100644
--- a/tests/testutils/junction.py
+++ b/tests/testutils/junction.py
@@ -1,5 +1,6 @@
 from buildstream import _yaml
-from buildstream.testing import create_repo
+
+from tests.testutils.repo.git import Git
 
 
 # generate_junction()
@@ -19,7 +20,7 @@ def generate_junction(tmpdir, subproject_path, junction_path, *, store_ref=True,
     # Create a repo to hold the subproject and generate
     # a junction element for it
     #
-    repo = create_repo("git", str(tmpdir))
+    repo = Git(str(tmpdir))
     source_ref = ref = repo.create(subproject_path)
     if not store_ref:
         source_ref = None