Skip to content

git: add contract tests for force-push resilience, error recovery, and edge cases#65750

Merged
potiuk merged 1 commit intoapache:mainfrom
Dev-iL:2604/git_tests
Apr 25, 2026
Merged

git: add contract tests for force-push resilience, error recovery, and edge cases#65750
potiuk merged 1 commit intoapache:mainfrom
Dev-iL:2604/git_tests

Conversation

@Dev-iL
Copy link
Copy Markdown
Collaborator

@Dev-iL Dev-iL commented Apr 24, 2026

Summary

Add 12 unit tests to the Git DAG bundle provider, expanding test coverage for force-push resilience, error recovery, and edge cases. The new tests cover previously untested defensive paths.

Context

These tests were motivated by an investigation into repeated recloning behavior observed after force-pushing a tracked tag.

Force-push resilience (6 tests)

Test What it proves
test_refresh_tag_force_pushed_to_unrelated_commit Tag moved to orphan commit is followed
test_refresh_branch_force_pushed_to_unrelated_commit Branch equivalent of the above
test_refresh_tag_moved_forward_and_backward Non-monotonic tag movement across multiple refreshes
test_refresh_after_force_push_does_not_reclone Repo.clone_from is never called during refresh
test_repeated_refreshes_after_force_push_stable Post-force-push state doesn't degrade
test_reinitialize_reuses_repos_after_force_push New bundle object reuses existing repos (processor restart)

Error handling (4 tests)

Test What it proves
test_refresh_survives_upstream_tag_deletion Deleted upstream tags persist locally; refresh succeeds
test_refresh_failure_preserves_previous_checkout Failed fetch leaves working tree intact
test_refresh_versioned_bundle_raises refresh() on versioned bundle raises AirflowException
test_clone_repo_invalid_repository_error_retry Corrupted working repo triggers cleanup + retry

Edge cases (2 tests)

Test What it proves
test_refresh_with_real_submodules_after_ref_change Real submodule (two repos) stays intact through ref change
test_refresh_ambiguous_ref_prefers_branch_over_tag Documents branch-over-tag preference when names collide

Notable finding

git reset --hard fails when the target tree references a different submodule commit than the current checkout, because the existing mysub/.git file triggers git's invalid-path protection (verified on git 2.43). This means refresh() with submodules=True cannot handle upstream submodule reference changes. A fix would require deiniting submodules before the reset. This is a pre-existing limitation, not introduced by this PR.


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude Opus 4.6 and GPT 5.4-Mini following the guidelines
-->


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@boring-cyborg boring-cyborg Bot added area:dev-tools area:providers backport-to-v3-2-test Mark PR with this label to backport to v3-2-test branch provider:git labels Apr 24, 2026
@Dev-iL Dev-iL changed the title Add tests for git bundle force-push resilience, error recovery, and edge cases git: add contract tests to force-push resilience, error recovery, and edge cases Apr 24, 2026
Expand GitDagBundle test coverage with 12 new tests addressing gaps
identified during investigation of repeated recloning after tag force-push.

Force-push resilience:
- Branch force-pushed to unrelated commit follows the new ref
- Tag force-pushed to unrelated commit follows the new ref
- Tag moved forward then backward across multiple refreshes
- Refresh after force-push never triggers Repo.clone_from
- Repeated refreshes after force-push remain stable
- Re-initialization reuses existing repos (no reclone)

Error handling:
- Upstream tag deletion does not break refresh (local copy persists)
- Failed bare-repo fetch preserves previous working tree
- Refresh on versioned bundle raises AirflowException
- Corrupted working repo triggers cleanup and retry

Edge cases:
- Real submodule fixture with ref change and submodule sync
- Ambiguous ref (branch+tag same name) documents branch preference
@Dev-iL Dev-iL changed the title git: add contract tests to force-push resilience, error recovery, and edge cases git: add contract tests for force-push resilience, error recovery, and edge cases Apr 24, 2026
@potiuk potiuk merged commit 19ae9ee into apache:main Apr 25, 2026
88 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

Backport successfully created: v3-2-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

Status Branch Result
v3-2-test PR Link

@Dev-iL Dev-iL deleted the 2604/git_tests branch April 26, 2026 05:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:dev-tools area:providers backport-to-v3-2-test Mark PR with this label to backport to v3-2-test branch provider:git

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants