xref: /aosp_15_r20/external/toolchain-utils/compiler_wrapper/kernel_bug_test.go (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
1*760c253cSXin Li// Copyright 2021 The ChromiumOS Authors
2*760c253cSXin Li// Use of this source code is governed by a BSD-style license that can be
3*760c253cSXin Li// found in the LICENSE file.
4*760c253cSXin Lipackage main
5*760c253cSXin Li
6*760c253cSXin Liimport (
7*760c253cSXin Li	"errors"
8*760c253cSXin Li	"io"
9*760c253cSXin Li	"testing"
10*760c253cSXin Li)
11*760c253cSXin Li
12*760c253cSXin Lifunc getErrorIndicatingKernelBug() error {
13*760c253cSXin Li	return errors.New("waitid: errno 512")
14*760c253cSXin Li}
15*760c253cSXin Li
16*760c253cSXin Lifunc TestWrapperRetriesCompilationsOnApparentKernelBugsSurfacedInGo(t *testing.T) {
17*760c253cSXin Li	withTestContext(t, func(ctx *testContext) {
18*760c253cSXin Li		ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
19*760c253cSXin Li			switch {
20*760c253cSXin Li			case ctx.cmdCount < kernelBugRetryLimit:
21*760c253cSXin Li				return getErrorIndicatingKernelBug()
22*760c253cSXin Li
23*760c253cSXin Li			case ctx.cmdCount == kernelBugRetryLimit:
24*760c253cSXin Li				return nil
25*760c253cSXin Li
26*760c253cSXin Li			default:
27*760c253cSXin Li				t.Fatalf("unexpected command: %#v", cmd)
28*760c253cSXin Li				return nil
29*760c253cSXin Li			}
30*760c253cSXin Li		}
31*760c253cSXin Li		ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
32*760c253cSXin Li		if ctx.cmdCount != kernelBugRetryLimit {
33*760c253cSXin Li			t.Errorf("expected %d retries. Got: %d", kernelBugRetryLimit, ctx.cmdCount)
34*760c253cSXin Li		}
35*760c253cSXin Li	})
36*760c253cSXin Li}
37*760c253cSXin Li
38*760c253cSXin Lifunc TestWrapperRetriesCompilationsOnApparentKernelBugsSurfacedInGCC(t *testing.T) {
39*760c253cSXin Li	withTestContext(t, func(ctx *testContext) {
40*760c253cSXin Li		ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
41*760c253cSXin Li			if ctx.cmdCount >= kernelBugRetryLimit {
42*760c253cSXin Li				return nil
43*760c253cSXin Li			}
44*760c253cSXin Li			_, err := io.WriteString(stderr, "fatal error: failed to get exit status: Unknown error 512")
45*760c253cSXin Li			if err != nil {
46*760c253cSXin Li				t.Fatalf("Failed writing to stdout: %v", err)
47*760c253cSXin Li			}
48*760c253cSXin Li			return newExitCodeError(1)
49*760c253cSXin Li		}
50*760c253cSXin Li		ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
51*760c253cSXin Li		if ctx.cmdCount != kernelBugRetryLimit {
52*760c253cSXin Li			t.Errorf("expected %d retries. Got: %d", kernelBugRetryLimit, ctx.cmdCount)
53*760c253cSXin Li		}
54*760c253cSXin Li	})
55*760c253cSXin Li}
56*760c253cSXin Li
57*760c253cSXin Lifunc TestWrapperOnlyRetriesCompilationAFiniteNumberOfTimes(t *testing.T) {
58*760c253cSXin Li	withTestContext(t, func(ctx *testContext) {
59*760c253cSXin Li		kernelBugErr := getErrorIndicatingKernelBug()
60*760c253cSXin Li		ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
61*760c253cSXin Li			if ctx.cmdCount > kernelBugRetryLimit {
62*760c253cSXin Li				t.Fatal("command count exceeded kernel bug retry limit; infinite loop?")
63*760c253cSXin Li			}
64*760c253cSXin Li			return kernelBugErr
65*760c253cSXin Li		}
66*760c253cSXin Li		stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
67*760c253cSXin Li		if err := verifyInternalError(stderr); err != nil {
68*760c253cSXin Li			t.Errorf("Internal error wasn't reported: %v", err)
69*760c253cSXin Li		}
70*760c253cSXin Li		if ctx.cmdCount != kernelBugRetryLimit {
71*760c253cSXin Li			t.Errorf("expected %d retries. Got: %d", kernelBugRetryLimit, ctx.cmdCount)
72*760c253cSXin Li		}
73*760c253cSXin Li	})
74*760c253cSXin Li}
75