Skip to content

Commit d766f3a

Browse files
committed
fixup! feat: Add preflight checks framework
Remove unnecessary copying of slice
1 parent ec20c1e commit d766f3a

File tree

2 files changed

+91
-50
lines changed

2 files changed

+91
-50
lines changed

pkg/webhook/preflight/preflight.go

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ func (h *WebhookHandler) Handle(ctx context.Context, req admission.Request) admi
7272
return admission.Allowed("")
7373
}
7474

75+
resultsOrderedByCheckerAndCheck := run(ctx, h.client, cluster, h.checkers)
76+
77+
// Summarize the results.
7578
resp := admission.Response{
7679
AdmissionResponse: admissionv1.AdmissionResponse{
7780
Allowed: true,
@@ -80,26 +83,24 @@ func (h *WebhookHandler) Handle(ctx context.Context, req admission.Request) admi
8083
},
8184
},
8285
}
83-
84-
results := run(ctx, h.client, cluster, h.checkers)
85-
86-
// Summarize the results.
8786
internalError := false
88-
for _, result := range results {
89-
if result.Error {
90-
internalError = true
91-
}
92-
if !result.Allowed {
93-
resp.Allowed = false
94-
}
95-
for _, cause := range result.Causes {
96-
resp.Result.Details.Causes = append(resp.Result.Details.Causes, metav1.StatusCause{
97-
Type: metav1.CauseType(fmt.Sprintf("FailedPreflight%s", result.Name)),
98-
Message: cause.Message,
99-
Field: cause.Field,
100-
})
87+
for _, results := range resultsOrderedByCheckerAndCheck {
88+
for _, result := range results {
89+
if result.Error {
90+
internalError = true
91+
}
92+
if !result.Allowed {
93+
resp.Allowed = false
94+
}
95+
for _, cause := range result.Causes {
96+
resp.Result.Details.Causes = append(resp.Result.Details.Causes, metav1.StatusCause{
97+
Type: metav1.CauseType(fmt.Sprintf("FailedPreflight%s", result.Name)),
98+
Message: cause.Message,
99+
Field: cause.Field,
100+
})
101+
}
102+
resp.Warnings = append(resp.Warnings, result.Warnings...)
101103
}
102-
resp.Warnings = append(resp.Warnings, result.Warnings...)
103104
}
104105

105106
switch {
@@ -118,7 +119,13 @@ func (h *WebhookHandler) Handle(ctx context.Context, req admission.Request) admi
118119
return resp
119120
}
120121

121-
func run(ctx context.Context, client ctrlclient.Client, cluster *clusterv1.Cluster, checkers []Checker) []CheckResult {
122+
// run runs all checks for the cluster, concurrently, and returns the results ordered by checker and check.
123+
// Checker are initialized concurrently, and checks runs concurrently as well.
124+
func run(ctx context.Context,
125+
client ctrlclient.Client,
126+
cluster *clusterv1.Cluster,
127+
checkers []Checker,
128+
) [][]CheckResult {
122129
resultsOrderedByCheckerAndCheck := make([][]CheckResult, len(checkers))
123130

124131
checkersWG := sync.WaitGroup{}
@@ -139,14 +146,11 @@ func run(ctx context.Context, client ctrlclient.Client, cluster *clusterv1.Clust
139146
}
140147
checksWG.Wait()
141148
resultsOrderedByCheckerAndCheck[i] = resultsOrderedByCheck
149+
142150
checkersWG.Done()
143151
}(ctx, client, cluster, checker, i)
144152
}
145153
checkersWG.Wait()
146154

147-
results := []CheckResult{}
148-
for _, resultsByCheck := range resultsOrderedByCheckerAndCheck {
149-
results = append(results, resultsByCheck...)
150-
}
151-
return results
155+
return resultsOrderedByCheckerAndCheck
152156
}

pkg/webhook/preflight/preflight_test.go

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,11 @@ func TestRun_SingleCheckerSingleCheck(t *testing.T) {
530530
},
531531
},
532532
}
533-
results := run(ctx, nil, nil, []Checker{checker})
533+
resultsOrderedByCheckerAndCheck := run(ctx, nil, nil, []Checker{checker})
534+
if len(resultsOrderedByCheckerAndCheck) != 1 {
535+
t.Fatalf("expected results for 1 checker, got %d", len(resultsOrderedByCheckerAndCheck))
536+
}
537+
results := resultsOrderedByCheckerAndCheck[0]
534538
if len(results) != 1 {
535539
t.Fatalf("expected 1 result, got %d", len(results))
536540
}
@@ -560,15 +564,19 @@ func TestRun_MultipleCheckersMultipleChecks(t *testing.T) {
560564
},
561565
},
562566
}
563-
results := run(ctx, nil, nil, []Checker{checker1, checker2})
564-
if len(results) != 3 {
565-
t.Fatalf("expected 3 results, got %d", len(results))
567+
resultsOrderedByCheckerAndCheck := run(ctx, nil, nil, []Checker{checker1, checker2})
568+
if len(resultsOrderedByCheckerAndCheck) != 2 {
569+
t.Fatalf("expected results for 2 checkers, got %d", len(resultsOrderedByCheckerAndCheck))
566570
}
567-
names := []string{results[0].Name, results[1].Name, results[2].Name}
571+
568572
expected := []string{"c1-check1", "c1-check2", "c2-check1"}
569-
for i, name := range expected {
570-
if names[i] != name {
571-
t.Errorf("expected result %d to have name %q, got %q", i, name, names[i])
573+
expectedIdx := 0
574+
for _, results := range resultsOrderedByCheckerAndCheck {
575+
for _, result := range results {
576+
if result.Name != expected[expectedIdx] {
577+
t.Errorf("expected result %d to be %q, got %q", expectedIdx, expected[expectedIdx], result.Name)
578+
}
579+
expectedIdx++
572580
}
573581
}
574582
}
@@ -595,7 +603,9 @@ func TestRun_ChecksRunInParallel(t *testing.T) {
595603
},
596604
},
597605
}
598-
results := run(ctx, nil, nil, []Checker{checker})
606+
resultsOrderedByCheckerAndCheck := run(ctx, nil, nil, []Checker{checker})
607+
608+
results := resultsOrderedByCheckerAndCheck[0]
599609
if len(results) != 2 {
600610
t.Fatalf("expected 2 results, got %d", len(results))
601611
}
@@ -670,7 +680,10 @@ func TestRun_ContextCancellation(t *testing.T) {
670680
cancel()
671681
}()
672682

673-
results := run(ctx, nil, nil, []Checker{checker})
683+
resultsOrderedByCheckerAndCheck := run(ctx, nil, nil, []Checker{checker})
684+
if len(resultsOrderedByCheckerAndCheck) != 1 {
685+
t.Fatalf("expected results for 1 checker, got %d", len(resultsOrderedByCheckerAndCheck))
686+
}
674687

675688
select {
676689
case <-completed:
@@ -679,6 +692,7 @@ func TestRun_ContextCancellation(t *testing.T) {
679692
// This is expected - the check was cancelled
680693
}
681694

695+
results := resultsOrderedByCheckerAndCheck[0]
682696
if len(results) != 1 {
683697
t.Fatalf("expected 1 result, got %d", len(results))
684698
}
@@ -717,18 +731,21 @@ func TestRun_OrderOfResults(t *testing.T) {
717731
},
718732
}
719733

720-
results := run(ctx, nil, nil, []Checker{checker1, checker2})
721-
722-
if len(results) != 4 {
723-
t.Fatalf("expected 4 results, got %d", len(results))
734+
resultsOrderedByCheckerAndCheck := run(ctx, nil, nil, []Checker{checker1, checker2})
735+
if len(resultsOrderedByCheckerAndCheck) != 2 {
736+
t.Fatalf("expected results for 2 checkers, got %d", len(resultsOrderedByCheckerAndCheck))
724737
}
725738

726739
// The order should be all checks from checker1 followed by all checks from checker2,
727740
// regardless of their completion time
728741
expected := []string{"c1-check1", "c1-check2", "c2-check1", "c2-check2"}
729-
for i, name := range expected {
730-
if results[i].Name != name {
731-
t.Errorf("result[%d]: expected %q, got %q", i, name, results[i].Name)
742+
expectedIdx := 0
743+
for _, results := range resultsOrderedByCheckerAndCheck {
744+
for _, result := range results {
745+
if result.Name != expected[expectedIdx] {
746+
t.Errorf("expected result %d to be %q, got %q", expectedIdx, expected[expectedIdx], result.Name)
747+
}
748+
expectedIdx++
732749
}
733750
}
734751
}
@@ -761,11 +778,16 @@ func TestRun_LargeNumberOfCheckersAndChecks(t *testing.T) {
761778
}
762779

763780
start := time.Now()
764-
results := run(ctx, nil, nil, checkers)
781+
resultsOrderedByCheckerAndCheck := run(ctx, nil, nil, checkers)
765782
duration := time.Since(start)
766783

767-
if len(results) != expectedTotal {
768-
t.Errorf("expected %d results, got %d", expectedTotal, len(results))
784+
resultTotal := 0
785+
for _, results := range resultsOrderedByCheckerAndCheck {
786+
resultTotal += len(results)
787+
}
788+
789+
if resultTotal != expectedTotal {
790+
t.Errorf("expected %d results, got %d", expectedTotal, resultTotal)
769791
}
770792

771793
t.Logf("Completed %d checks in %v", expectedTotal, duration)
@@ -799,8 +821,13 @@ func TestRun_ErrorHandlingInChecks(t *testing.T) {
799821
},
800822
}
801823

802-
results := run(ctx, nil, nil, []Checker{checker})
824+
resultsOrderedByCheckerAndCheck := run(ctx, nil, nil, []Checker{checker})
825+
826+
if len(resultsOrderedByCheckerAndCheck) != 1 {
827+
t.Fatalf("expected results for 1 checker, got %d", len(resultsOrderedByCheckerAndCheck))
828+
}
803829

830+
results := resultsOrderedByCheckerAndCheck[0]
804831
if len(results) != 2 {
805832
t.Fatalf("expected 2 results, got %d", len(results))
806833
}
@@ -840,13 +867,23 @@ func TestRun_ZeroChecksFromChecker(t *testing.T) {
840867
},
841868
}
842869

843-
results := run(ctx, nil, nil, []Checker{emptyChecker, normalChecker})
870+
resultsOrderedByCheckerAndCheck := run(ctx, nil, nil, []Checker{emptyChecker, normalChecker})
844871

845-
if len(results) != 1 {
846-
t.Fatalf("expected 1 result, got %d", len(results))
872+
if len(resultsOrderedByCheckerAndCheck) != 2 {
873+
t.Fatalf("expected results for 2 checkers, got %d", len(resultsOrderedByCheckerAndCheck))
874+
}
875+
876+
emptyResults := resultsOrderedByCheckerAndCheck[0] // We expect no results from the empty checker
877+
if len(emptyResults) != 0 {
878+
t.Fatalf("expected 0 results from empty checker, got %d", len(emptyResults))
879+
}
880+
881+
normalResults := resultsOrderedByCheckerAndCheck[1] // We expect results from the normal checker
882+
if len(normalResults) != 1 {
883+
t.Fatalf("expected 1 result, got %d", len(normalResults))
847884
}
848885

849-
if results[0].Name != "check1" {
850-
t.Errorf("expected result from normal checker, got %s", results[0].Name)
886+
if normalResults[0].Name != "check1" {
887+
t.Errorf("expected result from normal checker, got %s", normalResults[0].Name)
851888
}
852889
}

0 commit comments

Comments
 (0)