From 44a1146915b62b2289cf564d2661d659fdb6eec7 Mon Sep 17 00:00:00 2001 From: Amrit Ghimire Date: Fri, 7 Jan 2022 11:13:04 +0545 Subject: [PATCH] test: fix test failure in case of different default branch (#6857) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: fix test failure in case of different default branch When the git config has set global `init.defaultBranch` different than master, a few test cases were failing. Currently, the test case is assuming the default branch to be set as master. This commit will introduce **initial_branch** option to git init call which will ensure *master* branch is used as default for out test cases. Set default git branch to main for test CI Since main is going to be new default branch, it will let the test case handle the scenario where default branch is set other than master. Introduce isolation for git configuration Co-authored-by: Saugat Pachhai (सौगात) --- .github/workflows/tests.yaml | 4 ---- dvc/testing/tmp_dir.py | 29 ++++++------------------ tests/basic_env.py | 23 ++++--------------- tests/conftest.py | 40 ++++++++++++++++++++++++++++++++- tests/dir_helpers.py | 3 --- tests/func/metrics/test_diff.py | 5 ++--- tests/func/params/test_diff.py | 5 ++--- tests/func/test_diff.py | 5 ++--- tests/func/test_import.py | 9 +++----- tests/unit/fs/test_ssh.py | 9 ++++++-- 10 files changed, 66 insertions(+), 66 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 09ce22c60..7b1e37b63 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -67,10 +67,6 @@ jobs: run: | pip install --upgrade pip setuptools wheel pip install -e ".[dev]" - - name: setup git - run: | - git config --global user.email "dvctester@example.com" - git config --global user.name "DVC Tester" - name: run tests timeout-minutes: 40 run: >- diff --git a/dvc/testing/tmp_dir.py b/dvc/testing/tmp_dir.py index 4cfcbd926..e79bec160 100644 --- a/dvc/testing/tmp_dir.py +++ b/dvc/testing/tmp_dir.py @@ -51,8 +51,6 @@ import sys from contextlib import contextmanager from functools import partialmethod -from funcy import lmap, retry - from dvc.utils import serialize from dvc.utils.fs import makedirs @@ -62,7 +60,7 @@ class TmpDir(pathlib.Path): @property def fs_path(self): - return str(self) + return os.fspath(self) @property def url(self): @@ -98,18 +96,18 @@ class TmpDir(pathlib.Path): assert not scm or not hasattr(self, "scm") assert not dvc or not hasattr(self, "dvc") - str_path = os.fspath(self) - if scm: - git_init(str_path) + Git.init(self.fs_path).close() if dvc: self.dvc = Repo.init( - str_path, + self.fs_path, no_scm=not scm and not hasattr(self, "scm"), subdir=subdir, ) if scm: - self.scm = self.dvc.scm if hasattr(self, "dvc") else Git(str_path) + self.scm = ( + self.dvc.scm if hasattr(self, "dvc") else Git(self.fs_path) + ) if dvc and hasattr(self, "scm"): self.scm.commit("init dvc") @@ -264,7 +262,7 @@ class TmpDir(pathlib.Path): def _coerce_filenames(filenames): if isinstance(filenames, (str, bytes, pathlib.PurePath)): filenames = [filenames] - return lmap(os.fspath, filenames) + return list(map(os.fspath, filenames)) class WindowsTmpDir(TmpDir, pathlib.PureWindowsPath): @@ -273,16 +271,3 @@ class WindowsTmpDir(TmpDir, pathlib.PureWindowsPath): class PosixTmpDir(TmpDir, pathlib.PurePosixPath): pass - - -def git_init(path): - from git import Repo - from git.exc import GitCommandNotFound - - # NOTE: handles EAGAIN error on BSD systems (osx in our case). - # Otherwise when running tests you might get this exception: - # - # GitCommandNotFound: Cmd('git') not found due to: - # OSError('[Errno 35] Resource temporarily unavailable') - git = retry(5, GitCommandNotFound)(Repo.init)(path) - git.close() diff --git a/tests/basic_env.py b/tests/basic_env.py index f5e246a02..536a8261c 100644 --- a/tests/basic_env.py +++ b/tests/basic_env.py @@ -6,8 +6,6 @@ from unittest import TestCase import pytest import shortuuid -from git import Repo -from git.exc import GitCommandNotFound from dvc.repo import Repo as DvcRepo from dvc.utils.fs import remove @@ -116,24 +114,11 @@ class TestGitFixture(TestDirFixture): N_RETRIES = 5 def setUp(self): - super().setUp() - # NOTE: handles EAGAIN error on BSD systems (osx in our case). - # Otherwise when running tests you might get this exception: - # - # GitCommandNotFound: Cmd('git') not found due to: - # OSError('[Errno 35] Resource temporarily unavailable') - retries = self.N_RETRIES - while True: - try: - self.git = Repo.init() - break - except GitCommandNotFound: - retries -= 1 - if not retries: - raise + from scmrepo.git import Git - self.git.index.add([self.CODE]) - self.git.index.commit("add code") + super().setUp() + self.git = Git.init(".") + self.git.add_commit(self.CODE, message="add code") def tearDown(self): self.git.close() diff --git a/tests/conftest.py b/tests/conftest.py index f3ce802cb..9a168ade0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,5 @@ import os +import sys from contextlib import suppress import pytest @@ -161,7 +162,7 @@ def pytest_configure(config): enabled_remotes.add(remote_name) -@pytest.fixture() +@pytest.fixture def custom_template(tmp_dir, dvc): try: import importlib_resources @@ -185,3 +186,40 @@ scriptify_fixture = pytest.fixture(lambda: scriptify, name="scriptify") @pytest.fixture(autouse=True) def mocked_webbrowser_open(mocker): mocker.patch("webbrowser.open") + + +@pytest.fixture(autouse=True) +def isolate(tmp_path_factory, monkeypatch) -> None: + path = tmp_path_factory.mktemp("mock") + home_dir = path / "home" + home_dir.mkdir() + + if sys.platform == "win32": + home_drive, home_path = os.path.splitdrive(home_dir) + monkeypatch.setenv("USERPROFILE", str(home_dir)) + monkeypatch.setenv("HOMEDRIVE", home_drive) + monkeypatch.setenv("HOMEPATH", home_path) + + for env_var, sub_path in ( + ("APPDATA", "Roaming"), + ("LOCALAPPDATA", "Local"), + ): + path = home_dir / "AppData" / sub_path + path.mkdir(parents=True) + monkeypatch.setenv(env_var, os.fspath(path)) + else: + monkeypatch.setenv("HOME", str(home_dir)) + + monkeypatch.setenv("GIT_CONFIG_NOSYSTEM", "1") + contents = b""" +[user] +name=DVC Tester +email=dvctester@example.com +[init] +defaultBranch=master +""" + (home_dir / ".gitconfig").write_bytes(contents) + + import pygit2 + + pygit2.settings.search_path[pygit2.GIT_CONFIG_LEVEL_GLOBAL] = str(home_dir) diff --git a/tests/dir_helpers.py b/tests/dir_helpers.py index b1da1b3d4..e0943c7db 100644 --- a/tests/dir_helpers.py +++ b/tests/dir_helpers.py @@ -52,19 +52,16 @@ from textwrap import dedent import pytest from dvc.logger import disable_other_loggers -from dvc.testing.tmp_dir import git_init __all__ = [ "run_copy", "run_head", "erepo_dir", "git_dir", - "git_init", "git_upstream", "git_downstream", ] - # see https://github.com/iterative/dvc/issues/3167 disable_other_loggers() diff --git a/tests/func/metrics/test_diff.py b/tests/func/metrics/test_diff.py index 40efcf88e..6df35ba0b 100644 --- a/tests/func/metrics/test_diff.py +++ b/tests/func/metrics/test_diff.py @@ -148,10 +148,9 @@ def test_no_commits(tmp_dir): from scmrepo.git import Git from dvc.repo import Repo - from tests.dir_helpers import git_init - git_init(".") - assert Git().no_commits + git = Git.init(tmp_dir.fs_path) + assert git.no_commits assert Repo.init().metrics.diff() == {} diff --git a/tests/func/params/test_diff.py b/tests/func/params/test_diff.py index f8afbaf5d..836e46893 100644 --- a/tests/func/params/test_diff.py +++ b/tests/func/params/test_diff.py @@ -129,10 +129,9 @@ def test_no_commits(tmp_dir): from scmrepo.git import Git from dvc.repo import Repo - from tests.dir_helpers import git_init - git_init(".") - assert Git().no_commits + git = Git.init(tmp_dir.fs_path) + assert git.no_commits assert Repo.init().params.diff() == {} diff --git a/tests/func/test_diff.py b/tests/func/test_diff.py index 0fad45162..976facc46 100644 --- a/tests/func/test_diff.py +++ b/tests/func/test_diff.py @@ -293,10 +293,9 @@ def test_no_commits(tmp_dir): from scmrepo.git import Git from dvc.repo import Repo - from tests.dir_helpers import git_init - git_init(".") - assert Git().no_commits + git = Git.init(tmp_dir.fs_path) + assert git.no_commits assert Repo.init().diff() == {} diff --git a/tests/func/test_import.py b/tests/func/test_import.py index d4d19c621..0bc6f8b5b 100644 --- a/tests/func/test_import.py +++ b/tests/func/test_import.py @@ -4,6 +4,7 @@ from unittest.mock import patch import pytest from funcy import first +from scmrepo.git import Git from dvc.config import NoRemoteError from dvc.dvcfile import Dvcfile @@ -268,9 +269,7 @@ def test_pull_wildcard_imported_directory_stage(tmp_dir, dvc, erepo_dir): def test_push_wildcard_from_bare_git_repo( tmp_dir, make_tmp_dir, erepo_dir, local_cloud ): - import git - - git.Repo.init(os.fspath(tmp_dir), bare=True) + Git.init(tmp_dir.fs_path, bare=True).close() erepo_dir.add_remote(config=local_cloud.config) with erepo_dir.chdir(): @@ -381,9 +380,7 @@ def test_pull_no_rev_lock(erepo_dir, tmp_dir, dvc): def test_import_from_bare_git_repo( tmp_dir, make_tmp_dir, erepo_dir, local_cloud ): - import git - - git.Repo.init(os.fspath(tmp_dir), bare=True) + Git.init(tmp_dir.fs_path, bare=True).close() erepo_dir.add_remote(config=local_cloud.config) with erepo_dir.chdir(): diff --git a/tests/unit/fs/test_ssh.py b/tests/unit/fs/test_ssh.py index 60712e9b1..ff071091e 100644 --- a/tests/unit/fs/test_ssh.py +++ b/tests/unit/fs/test_ssh.py @@ -122,7 +122,7 @@ def test_ssh_port(mock_file, config, expected_port): ), ( {"host": "example.com"}, - [os.path.expanduser("~/.ssh/not_default.key")], + ["~/.ssh/not_default.key"], ), ( { @@ -141,7 +141,12 @@ def test_ssh_port(mock_file, config, expected_port): ) def test_ssh_keyfile(mock_file, config, expected_keyfile): fs = SSHFileSystem(**config) - assert fs.fs_args.get("client_keys") == expected_keyfile + expected_keyfiles = ( + [os.path.expanduser(path) for path in expected_keyfile] + if expected_keyfile + else expected_keyfile + ) + assert fs.fs_args.get("client_keys") == expected_keyfiles mock_ssh_multi_key_config = """