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