Skip to content

Commit 4d1ad66

Browse files
committed
flag build failures
1 parent b500f69 commit 4d1ad66

6 files changed

Lines changed: 136 additions & 4 deletions

File tree

.ci/magician/cmd/test_terraform_vcr.go

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,12 @@ func execTestTerraformVCR(prNumber, mmCommitSha, buildID, projectID, buildStep,
237237
return nil
238238
}
239239

240+
if hasBuildFailures, err := handleBuildFailures(prNumber, buildID, buildStatusTargetURL, mmCommitSha, replayingResult, vcr.Replaying, gh); err != nil {
241+
return fmt.Errorf("error handling build failures: %w", err)
242+
} else if hasBuildFailures {
243+
return nil
244+
}
245+
240246
var servicesArr []string
241247
for s := range services {
242248
servicesArr = append(servicesArr, s)
@@ -297,6 +303,12 @@ func execTestTerraformVCR(prNumber, mmCommitSha, buildID, projectID, buildStep,
297303
return nil
298304
}
299305

306+
if hasBuildFailures, err := handleBuildFailures(prNumber, buildID, buildStatusTargetURL, mmCommitSha, recordingResult, vcr.Recording, gh); err != nil {
307+
return fmt.Errorf("error handling build failures: %w", err)
308+
} else if hasBuildFailures {
309+
return nil
310+
}
311+
300312
replayingAfterRecordingResult := vcr.Result{}
301313
var replayingAfterRecordingErr error
302314
if len(recordingResult.PassedTests) > 0 {
@@ -397,10 +409,11 @@ func notRunTests(gaDiff, betaDiff string, result vcr.Result) ([]string, []string
397409

398410
func subtestResult(original vcr.Result) vcr.Result {
399411
return vcr.Result{
400-
PassedTests: excludeCompoundTests(original.PassedTests, original.PassedSubtests),
401-
FailedTests: excludeCompoundTests(original.FailedTests, original.FailedSubtests),
402-
SkippedTests: excludeCompoundTests(original.SkippedTests, original.SkippedSubtests),
403-
Panics: original.Panics,
412+
PassedTests: excludeCompoundTests(original.PassedTests, original.PassedSubtests),
413+
FailedTests: excludeCompoundTests(original.FailedTests, original.FailedSubtests),
414+
SkippedTests: excludeCompoundTests(original.SkippedTests, original.SkippedSubtests),
415+
Panics: original.Panics,
416+
BuildFailures: original.BuildFailures,
404417
}
405418
}
406419

@@ -508,6 +521,26 @@ View the [build log](https://storage.cloud.google.com/ci-vcr-logs/beta/refs/head
508521
return false, nil
509522
}
510523

524+
func handleBuildFailures(prNumber, buildID, buildStatusTargetURL, mmCommitSha string, result vcr.Result, mode vcr.Mode, gh GithubClient) (bool, error) {
525+
if len(result.BuildFailures) > 0 {
526+
comment := color("red", fmt.Sprintf("The provider failed to build during VCR tests in %s mode\n", mode.Upper()))
527+
comment += "The following packages failed to build:\n"
528+
for _, pkg := range result.BuildFailures {
529+
comment += fmt.Sprintf("- `%s`\n", pkg)
530+
}
531+
comment += fmt.Sprintf(`Please fix the compilation errors to complete your PR.
532+
View the [build log](https://storage.cloud.google.com/ci-vcr-logs/beta/refs/heads/auto-pr-%s/artifacts/%s/build-log/%s_test.log)`, prNumber, buildID, mode.Lower())
533+
if err := gh.PostComment(prNumber, comment); err != nil {
534+
return true, fmt.Errorf("error posting comment: %v", err)
535+
}
536+
if err := gh.PostBuildStatus(prNumber, "VCR-test", "failure", buildStatusTargetURL, mmCommitSha); err != nil {
537+
return true, fmt.Errorf("error posting failure status: %v", err)
538+
}
539+
return true, nil
540+
}
541+
return false, nil
542+
}
543+
511544
func init() {
512545
rootCmd.AddCommand(testTerraformVCRCmd)
513546
}

.ci/magician/cmd/test_terraform_vcr_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,3 +579,42 @@ func TestRecordReplay(t *testing.T) {
579579
})
580580
}
581581
}
582+
583+
func TestHandleBuildFailures(t *testing.T) {
584+
gh := &mockGithub{
585+
calledMethods: make(map[string][][]any),
586+
}
587+
result := vcr.Result{
588+
BuildFailures: []string{"package1", "package2"},
589+
}
590+
591+
handled, err := handleBuildFailures("123", "build-456", "http://target", "sha789", result, vcr.Replaying, gh)
592+
593+
assert.NoError(t, err)
594+
assert.True(t, handled)
595+
596+
assert.Len(t, gh.calledMethods["PostComment"], 1)
597+
assert.Equal(t, "123", gh.calledMethods["PostComment"][0][0])
598+
comment := gh.calledMethods["PostComment"][0][1].(string)
599+
assert.Contains(t, comment, "package1")
600+
assert.Contains(t, comment, "package2")
601+
602+
assert.Len(t, gh.calledMethods["PostBuildStatus"], 1)
603+
assert.Equal(t, "123", gh.calledMethods["PostBuildStatus"][0][0])
604+
assert.Equal(t, "VCR-test", gh.calledMethods["PostBuildStatus"][0][1])
605+
assert.Equal(t, "failure", gh.calledMethods["PostBuildStatus"][0][2])
606+
}
607+
608+
func TestHandleBuildFailures_NoFailures(t *testing.T) {
609+
gh := &mockGithub{
610+
calledMethods: make(map[string][][]any),
611+
}
612+
result := vcr.Result{}
613+
614+
handled, err := handleBuildFailures("123", "build-456", "http://target", "sha789", result, vcr.Replaying, gh)
615+
616+
assert.NoError(t, err)
617+
assert.False(t, handled)
618+
assert.Len(t, gh.calledMethods["PostComment"], 0)
619+
assert.Len(t, gh.calledMethods["PostBuildStatus"], 0)
620+
}

.ci/magician/cmd/vcr_cassette_update.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ func execVCRCassetteUpdate(buildID, today string, rnr ExecRunner, ctlr *source.C
169169
return fmt.Errorf("provider crashed while running the VCR tests in REPLAYING mode: %v", replayingResult.Panics)
170170
}
171171

172+
if len(replayingResult.BuildFailures) != 0 {
173+
return fmt.Errorf("provider failed to build during VCR tests in REPLAYING mode: %v", replayingResult.BuildFailures)
174+
}
175+
172176
if len(replayingResult.FailedTests) != 0 {
173177
fmt.Println("running tests in RECORDING mode now")
174178

@@ -217,6 +221,10 @@ func execVCRCassetteUpdate(buildID, today string, rnr ExecRunner, ctlr *source.C
217221
if len(recordingResult.Panics) != 0 {
218222
return fmt.Errorf("provider crashed while running the VCR tests in RECORDING mode: %v", recordingResult.Panics)
219223
}
224+
225+
if len(recordingResult.BuildFailures) != 0 {
226+
return fmt.Errorf("provider failed to build during VCR tests in RECORDING mode: %v", recordingResult.BuildFailures)
227+
}
220228
}
221229
return nil
222230
}

.ci/magician/cmd/vcr_cassette_update_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,3 +433,31 @@ func TestExecVCRCassetteUpdate(t *testing.T) {
433433
})
434434
}
435435
}
436+
437+
func TestExecVCRCassetteUpdate_BuildFailure(t *testing.T) {
438+
rnr := &mockRunner{
439+
calledMethods: make(map[string][]ParameterList),
440+
cwd: "/mock/dir/magic-modules/.ci/magician",
441+
dirStack: list.New(),
442+
cmdResults: map[string]string{
443+
"gopath/src/github.com/hashicorp/terraform-provider-google-beta go [test -p 16 -parallel 32 -v -run=TestAcc -timeout 360m -ldflags=-X=github.com/hashicorp/terraform-provider-google-beta/version.ProviderVersion=acc -vet=off] map[ACCTEST_PARALLELISM:32 GOOGLE_APPLICATION_CREDENTIALS:/mock/dir/magic-modules/.ci/magician/sa_key.json GOOGLE_CREDENTIALS:sa_key GOOGLE_TEST_DIRECTORY: SA_KEY:sa_key TF_ACC:1 TF_ACC_REFRESH_AFTER_APPLY:1 TF_LOG:DEBUG TF_LOG_CORE:WARN TF_LOG_PATH_MASK:/mock/dir/magic-modules/.ci/magician/testlogs/replaying/beta/%s.log TF_LOG_SDK_FRAMEWORK:INFO TF_SCHEMA_PANIC_ON_ERROR:1 VCR_MODE:REPLAYING VCR_PATH:/mock/dir/magic-modules/.ci/magician/cassettes/beta]": "FAIL\tgithub.com/hashicorp/terraform-provider-google-beta/google-beta/services/corebilling [build failed]",
444+
},
445+
}
446+
447+
ctlr := source.NewController("gopath", "hashicorp", "token", rnr)
448+
vt, err := vcr.NewTester(map[string]string{
449+
"SA_KEY": "sa_key",
450+
}, "ci-vcr-cassettes", "", rnr, false)
451+
if err != nil {
452+
t.Fatalf("Failed to create new tester: %v", err)
453+
}
454+
455+
err = execVCRCassetteUpdate("buildID", "2024-07-08", rnr, ctlr, vt)
456+
if err == nil {
457+
t.Fatalf("execVCRCassetteUpdate expected to return error on build failure, got nil")
458+
}
459+
460+
if !strings.Contains(err.Error(), "provider failed to build during VCR tests in REPLAYING mode") {
461+
t.Errorf("Unexpected error message: %v", err)
462+
}
463+
}

.ci/magician/vcr/tester.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type Result struct {
2424
SkippedSubtests []string
2525
FailedSubtests []string
2626
Panics []string
27+
BuildFailures []string
2728
}
2829

2930
type Mode int
@@ -82,6 +83,8 @@ var subtestResultsExpression = regexp.MustCompile(`(?m:^ --- (PASS|FAIL|SKIP)
8283

8384
var testPanicExpression = regexp.MustCompile(`(?m:^panic: .*)`)
8485

86+
var buildFailedExpression = regexp.MustCompile(`(?m:^FAIL\s+(\S+)\s+\[build failed\])`)
87+
8588
var safeToLog = map[string]bool{
8689
"ACCTEST_PARALLELISM": true,
8790
"COMMIT_SHA": true,
@@ -726,6 +729,16 @@ func collectResult(output string) Result {
726729
results := make(map[string][]string, 4)
727730
results["PANIC"] = testPanicExpression.FindAllString(output, -1)
728731
sort.Strings(results["PANIC"])
732+
733+
buildFailuresMatches := buildFailedExpression.FindAllStringSubmatch(output, -1)
734+
var buildFailures []string
735+
for _, submatches := range buildFailuresMatches {
736+
if len(submatches) == 2 {
737+
buildFailures = append(buildFailures, submatches[1])
738+
}
739+
}
740+
sort.Strings(buildFailures)
741+
729742
subtestResults := make(map[string][]string, 3)
730743
for _, kind := range []string{"FAIL", "PASS", "SKIP"} {
731744
for test := range resultSets[kind] {
@@ -745,5 +758,6 @@ func collectResult(output string) Result {
745758
PassedSubtests: subtestResults["PASS"],
746759
SkippedSubtests: subtestResults["SKIP"],
747760
Panics: results["PANIC"],
761+
BuildFailures: buildFailures,
748762
}
749763
}

.ci/magician/vcr/tester_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ func TestCollectResults(t *testing.T) {
4949
FailedSubtests: []string{"TestAccServiceOneResourceTwo__test_two"},
5050
},
5151
},
52+
{
53+
name: "build failure",
54+
output: `FAIL github.com/hashicorp/terraform-provider-google-beta/google-beta/services/corebilling [build failed]
55+
--- PASS: TestAccServiceTwoResourceOne (100.00s)
56+
`,
57+
expected: Result{
58+
PassedTests: []string{"TestAccServiceTwoResourceOne"},
59+
BuildFailures: []string{"github.com/hashicorp/terraform-provider-google-beta/google-beta/services/corebilling"},
60+
},
61+
},
5262
} {
5363
if diff := cmp.Diff(test.expected, collectResult(test.output)); diff != "" {
5464
t.Errorf("collectResult(%q) got unexpected diff (-want +got):\n%s", test.output, diff)

0 commit comments

Comments
 (0)