Skip to content

Commit b83d31d

Browse files
authored
Merge pull request #18 from entireio/changes
Expand on integration tests
2 parents 1c117e3 + 5c60d93 commit b83d31d

6 files changed

Lines changed: 772 additions & 0 deletions

File tree

internal/planner/planner_test.go

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,165 @@ func TestBuildPlansDelete(t *testing.T) {
426426
}
427427
}
428428

429+
// TestBuildPlansPrunePreservesUnrelatedBranchesUnderFilter is a regression
430+
// guard for the prune-scoping rule in planner.go: --prune deletes orphan
431+
// target branches only when the user has not narrowed the source ref set
432+
// with --branch or --map. With either filter present, branches that exist
433+
// only on the target are out of scope and must be preserved.
434+
func TestBuildPlansPrunePreservesUnrelatedBranchesUnderFilter(t *testing.T) {
435+
t.Parallel()
436+
437+
mainHash := plumbing.NewHash("1111111111111111111111111111111111111111")
438+
releaseHash := plumbing.NewHash("2222222222222222222222222222222222222222")
439+
440+
mainRef := plumbing.NewBranchReferenceName("main")
441+
stableRef := plumbing.NewBranchReferenceName("stable")
442+
releaseRef := plumbing.NewBranchReferenceName("release")
443+
444+
sourceRefs := map[plumbing.ReferenceName]plumbing.Hash{
445+
mainRef: mainHash,
446+
}
447+
448+
tests := []struct {
449+
name string
450+
cfg PlanConfig
451+
targetRefs map[plumbing.ReferenceName]plumbing.Hash
452+
wantManaged plumbing.ReferenceName
453+
preservedRef plumbing.ReferenceName
454+
}{
455+
{
456+
name: "branch filter --branch main --prune",
457+
cfg: PlanConfig{
458+
Branches: []string{"main"},
459+
Prune: true,
460+
},
461+
targetRefs: map[plumbing.ReferenceName]plumbing.Hash{
462+
mainRef: mainHash,
463+
releaseRef: releaseHash,
464+
},
465+
wantManaged: mainRef,
466+
preservedRef: releaseRef,
467+
},
468+
{
469+
name: "rename mapping --map main:stable --prune",
470+
cfg: PlanConfig{
471+
Mappings: []RefMapping{{Source: "main", Target: "stable"}},
472+
Prune: true,
473+
},
474+
targetRefs: map[plumbing.ReferenceName]plumbing.Hash{
475+
stableRef: mainHash,
476+
releaseRef: releaseHash,
477+
},
478+
wantManaged: stableRef,
479+
preservedRef: releaseRef,
480+
},
481+
}
482+
483+
for _, tt := range tests {
484+
t.Run(tt.name, func(t *testing.T) {
485+
t.Parallel()
486+
487+
desired, managed, err := BuildDesiredRefs(sourceRefs, tt.cfg)
488+
if err != nil {
489+
t.Fatalf("BuildDesiredRefs: %v", err)
490+
}
491+
492+
plans, err := BuildPlans(nil, desired, tt.targetRefs, managed, tt.cfg)
493+
if err != nil {
494+
t.Fatalf("BuildPlans: %v", err)
495+
}
496+
497+
for _, p := range plans {
498+
if p.TargetRef == tt.preservedRef {
499+
t.Fatalf("unrelated target branch %s emitted plan %+v; --prune must preserve it under filtered scope", tt.preservedRef, p)
500+
}
501+
if p.Action == ActionDelete && p.TargetRef != tt.preservedRef {
502+
t.Fatalf("unexpected delete plan for %s: %+v", p.TargetRef, p)
503+
}
504+
}
505+
506+
if _, ok := managed[tt.preservedRef]; ok {
507+
t.Fatalf("managed map leaked unrelated target ref %s under filtered prune scope", tt.preservedRef)
508+
}
509+
if _, ok := managed[tt.wantManaged]; !ok {
510+
t.Fatalf("expected managed scope to include %s, got %+v", tt.wantManaged, managed)
511+
}
512+
})
513+
}
514+
}
515+
516+
// TestBuildReplicationPlansPrunePreservesUnrelatedBranchesUnderFilter is the
517+
// replicate-mode counterpart to the sync test above. The prune-scoping rule
518+
// must hold whether the operation is sync or replicate.
519+
func TestBuildReplicationPlansPrunePreservesUnrelatedBranchesUnderFilter(t *testing.T) {
520+
t.Parallel()
521+
522+
mainHash := plumbing.NewHash("1111111111111111111111111111111111111111")
523+
releaseHash := plumbing.NewHash("2222222222222222222222222222222222222222")
524+
525+
mainRef := plumbing.NewBranchReferenceName("main")
526+
stableRef := plumbing.NewBranchReferenceName("stable")
527+
releaseRef := plumbing.NewBranchReferenceName("release")
528+
529+
sourceRefs := map[plumbing.ReferenceName]plumbing.Hash{
530+
mainRef: mainHash,
531+
}
532+
533+
tests := []struct {
534+
name string
535+
cfg PlanConfig
536+
targetRefs map[plumbing.ReferenceName]plumbing.Hash
537+
preservedRef plumbing.ReferenceName
538+
}{
539+
{
540+
name: "branch filter --branch main --prune",
541+
cfg: PlanConfig{
542+
Branches: []string{"main"},
543+
Prune: true,
544+
},
545+
targetRefs: map[plumbing.ReferenceName]plumbing.Hash{
546+
mainRef: mainHash,
547+
releaseRef: releaseHash,
548+
},
549+
preservedRef: releaseRef,
550+
},
551+
{
552+
name: "rename mapping --map main:stable --prune",
553+
cfg: PlanConfig{
554+
Mappings: []RefMapping{{Source: "main", Target: "stable"}},
555+
Prune: true,
556+
},
557+
targetRefs: map[plumbing.ReferenceName]plumbing.Hash{
558+
stableRef: mainHash,
559+
releaseRef: releaseHash,
560+
},
561+
preservedRef: releaseRef,
562+
},
563+
}
564+
565+
for _, tt := range tests {
566+
t.Run(tt.name, func(t *testing.T) {
567+
t.Parallel()
568+
569+
desired, managed, err := BuildDesiredRefs(sourceRefs, tt.cfg)
570+
if err != nil {
571+
t.Fatalf("BuildDesiredRefs: %v", err)
572+
}
573+
574+
plans, err := BuildReplicationPlans(desired, tt.targetRefs, managed, tt.cfg)
575+
if err != nil {
576+
t.Fatalf("BuildReplicationPlans: %v", err)
577+
}
578+
579+
for _, p := range plans {
580+
if p.TargetRef == tt.preservedRef {
581+
t.Fatalf("unrelated target branch %s emitted plan %+v; --prune must preserve it under filtered scope", tt.preservedRef, p)
582+
}
583+
}
584+
})
585+
}
586+
}
587+
429588
func TestBuildPlansTagBlock(t *testing.T) {
430589
repo, err := git.Init(memory.NewStorage(), nil)
431590
if err != nil {

0 commit comments

Comments
 (0)