aboutsummaryrefslogtreecommitdiff
path: root/compiler_wrapper/kernel_bug_test.go
blob: 3c7bccf13627b834f7c3b2a2229684d2c4ebefa5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// 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)
		}
	})
}