Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d5fb280

Browse files
EliahKaganclaude
andcommitted
Add a test that required submodules are initialized
This adds the new test, `test_required_submodule_is_initialized`, to `test_fixture_health.py`. For the gitdb and smmap submodules, the test asserts that the working tree directory exists and contains a `.git` marker (file or directory). The failure message reminds the developer to run `git submodule update --init --recursive`. This is a regression test for a different contract than the preexisting `test_fixture_dir_is_trusted_by_git` in `test_fixture_health.py`. That test verifies git's willingness to operate in each fixture directory (the `safe.directory` / dubious-ownership contract). This one verifies that the directories are populated at all. When the gitdb and smmap submodules aren't populated, the rest of the suite fails in ways that don't name the cause: a cascade of failures across `test_docs.py`, `test_repo.py`, and `test_submodule.py` -- tests that need submodule content but don't set out to check for it. That cascade was the failure mode of #1713 on the Arch Linux build, where `init-tests-after-clone.sh` had stopped running `git submodule update` on CI. Wherever the submodules are actually missing, this test reports the missing path directly instead. The test skips when the source tree is not a git clone (no `.git` at `REPO_ROOT`). This is to accommodate setups that run pytest from an extracted release tarball and prepare submodules in a separately-pointed tree via `GIT_PYTHON_TEST_GIT_REPO_BASE` (e.g. OpenIndiana's package build). In such setups, `git submodule update` cannot operate on the source tree, and the submodule paths checked here would never be populated there, but the test suite still works because `rorepo` points elsewhere. Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
1 parent fa0d9bc commit d5fb280

1 file changed

Lines changed: 58 additions & 18 deletions

File tree

test/test_fixture_health.py

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,15 @@
33

44
"""Verify that fixture directories are usable by git.
55
6-
If a directory the test suite relies on is rejected by git for "dubious
7-
ownership" -- because the directory's owner doesn't match the running user
8-
and there is no ``safe.directory`` entry overriding the check -- three
9-
submodule-related tests fail in confusing ways. The checks here name the
10-
root cause clearly so a misconfigured environment is recognizable from the
11-
test output.
6+
If a fixture directory is missing, isn't an initialized git repository,
7+
or is rejected by git for "dubious ownership", dependent tests
8+
elsewhere in the suite fail in opaque ways. The checks here name the
9+
preconditions directly so a misconfigured environment is recognizable
10+
from the test output rather than from a cascade of unrelated-seeming
11+
failures.
1212
13-
The rejection is most often a CI-workflow problem (the workflow's
14-
``safe.directory`` list doesn't cover the path); on a developer's own
15-
clone, it usually reflects an ownership mismatch (sudo clone, restored
16-
backup, container mount, networked filesystem) rather than a config gap.
17-
18-
These tests do not exercise GitPython's production code. They verify the
19-
conditions under which production code is exercised are valid.
20-
21-
A check is skipped, rather than failed, if a fixture directory is missing or
22-
has no ``.git`` marker, since that condition is more naturally diagnosed as
23-
"``init-tests-after-clone.sh`` hasn't been run" than as a problem with
24-
``safe.directory``.
13+
These tests do not exercise GitPython's production code. They verify
14+
the conditions under which production code is exercised are valid.
2515
"""
2616

2717
import subprocess
@@ -45,6 +35,19 @@
4535
),
4636
]
4737

38+
# Submodule working trees that must be present and initialized for the
39+
# test suite to operate normally: gitdb at `git/ext/gitdb`, and smmap
40+
# nested inside gitdb at `git/ext/gitdb/gitdb/ext/smmap`. The paths
41+
# below are anchored at REPO_ROOT (the GitPython source tree), not at
42+
# any rorepo redirection target.
43+
SUBMODULE_DIRS = [
44+
pytest.param(REPO_ROOT / "git" / "ext" / "gitdb", id="gitdb"),
45+
pytest.param(
46+
REPO_ROOT / "git" / "ext" / "gitdb" / "gitdb" / "ext" / "smmap",
47+
id="smmap",
48+
),
49+
]
50+
4851

4952
@pytest.mark.parametrize("fixture_dir", FIXTURE_DIRS)
5053
def test_fixture_dir_is_trusted_by_git(fixture_dir: Path) -> None:
@@ -89,3 +92,40 @@ def test_fixture_dir_is_trusted_by_git(fixture_dir: Path) -> None:
8992
"This usually means the directory is not an initialized git "
9093
"repository (its `.git` marker may be stale or pointing elsewhere)."
9194
)
95+
96+
97+
@pytest.mark.parametrize("submodule_dir", SUBMODULE_DIRS)
98+
def test_required_submodule_is_initialized(submodule_dir: Path) -> None:
99+
"""The submodule's working tree is present and initialized.
100+
101+
Failure means the source tree is a git clone but the submodule's
102+
working tree hasn't been populated. Skipped when the source tree
103+
itself isn't a git clone (e.g. an extracted release tarball), since
104+
``git submodule update`` cannot operate there; setups that handle
105+
submodules in a separately-prepared tree (via
106+
``GIT_PYTHON_TEST_GIT_REPO_BASE``) are exempted from this check.
107+
"""
108+
if not (REPO_ROOT / ".git").exists():
109+
pytest.skip(
110+
"Source tree is not a git clone (no .git in REPO_ROOT); submodules "
111+
"cannot be initialized via `git submodule update` here. Setups "
112+
"that prepare submodules in a separately-pointed tree (via "
113+
"GIT_PYTHON_TEST_GIT_REPO_BASE) are exempted from this check."
114+
)
115+
# The assertion messages below recommend `git submodule update --init
116+
# --recursive` rather than `init-tests-after-clone.sh`, even though the
117+
# latter is the documented entry point for first-time test setup. Two
118+
# reasons: the script performs `git reset --hard` operations that can
119+
# destroy local work, and #1713 showed the script itself can carry
120+
# submodule-init regressions, in which case recommending it would lead
121+
# developers in a circle. The direct git command is a safe minimal fix
122+
# for this test's specific failure mode and bypasses any such regression.
123+
assert submodule_dir.is_dir(), (
124+
f"Submodule working tree missing: {submodule_dir}.\n"
125+
"Run `git submodule update --init --recursive` from the repo root."
126+
)
127+
assert (submodule_dir / ".git").exists(), (
128+
f"Submodule directory exists but has no .git marker: {submodule_dir}.\n"
129+
"The submodule hasn't been initialized. "
130+
"Run `git submodule update --init --recursive` from the repo root."
131+
)

0 commit comments

Comments
 (0)