| // Copyright 2021 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| package main |
| |
| import ( |
| "errors" |
| "io" |
| "testing" |
| ) |
| |
| func getErrorIndicatingKernelBug() error { |
| return errors.New("waitid: errno 512") |
| } |
| |
| func TestWrapperRetriesCompilationsOnApparentKernelBugsSurfacedInGo(t *testing.T) { |
| withTestContext(t, func(ctx *testContext) { |
| ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error { |
| switch { |
| case ctx.cmdCount < kernelBugRetryLimit: |
| return getErrorIndicatingKernelBug() |
| |
| case ctx.cmdCount == kernelBugRetryLimit: |
| return nil |
| |
| default: |
| t.Fatalf("unexpected command: %#v", cmd) |
| return nil |
| } |
| } |
| ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc))) |
| if ctx.cmdCount != kernelBugRetryLimit { |
| t.Errorf("expected %d retries. Got: %d", kernelBugRetryLimit, ctx.cmdCount) |
| } |
| }) |
| } |
| |
| func TestWrapperRetriesCompilationsOnApparentKernelBugsSurfacedInGCC(t *testing.T) { |
| withTestContext(t, func(ctx *testContext) { |
| ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error { |
| if ctx.cmdCount >= kernelBugRetryLimit { |
| return nil |
| } |
| _, err := io.WriteString(stderr, "fatal error: failed to get exit status: Unknown error 512") |
| if err != nil { |
| t.Fatalf("Failed writing to stdout: %v", err) |
| } |
| return newExitCodeError(1) |
| } |
| ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc))) |
| if ctx.cmdCount != kernelBugRetryLimit { |
| t.Errorf("expected %d retries. Got: %d", kernelBugRetryLimit, ctx.cmdCount) |
| } |
| }) |
| } |
| |
| func TestWrapperOnlyRetriesCompilationAFiniteNumberOfTimes(t *testing.T) { |
| withTestContext(t, func(ctx *testContext) { |
| kernelBugErr := getErrorIndicatingKernelBug() |
| ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error { |
| if ctx.cmdCount > kernelBugRetryLimit { |
| t.Fatal("command count exceeded kernel bug retry limit; infinite loop?") |
| } |
| return kernelBugErr |
| } |
| stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc))) |
| if err := verifyInternalError(stderr); err != nil { |
| t.Errorf("Internal error wasn't reported: %v", err) |
| } |
| if ctx.cmdCount != kernelBugRetryLimit { |
| t.Errorf("expected %d retries. Got: %d", kernelBugRetryLimit, ctx.cmdCount) |
| } |
| }) |
| } |