You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
7.0 KiB
261 lines
7.0 KiB
// Copyright 2022 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 (
|
|
"bytes"
|
|
"io"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestBuildWithAutoCrashDoesNothingIfCrashIsNotRequested(t *testing.T) {
|
|
withTestContext(t, func(ctx *testContext) {
|
|
neverAutoCrash := buildWithAutocrashPredicates{
|
|
allowInConfigure: true,
|
|
shouldAutocrash: func(env, *config, *command, compilerExecInfo) bool {
|
|
return false
|
|
},
|
|
}
|
|
|
|
exitCode, err := buildWithAutocrashImpl(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc), neverAutoCrash)
|
|
if err != nil {
|
|
t.Fatalf("unexpectedly failed with %v", err)
|
|
}
|
|
ctx.must(exitCode)
|
|
if ctx.cmdCount != 1 {
|
|
t.Errorf("expected 1 call. Got: %d", ctx.cmdCount)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestBuildWithAutoCrashSkipsAutocrashLogicIfInConfigureAndConfigureChecksDisabled(t *testing.T) {
|
|
withTestContext(t, func(ctx *testContext) {
|
|
alwaysAutocrash := buildWithAutocrashPredicates{
|
|
allowInConfigure: false,
|
|
shouldAutocrash: func(env, *config, *command, compilerExecInfo) bool {
|
|
return true
|
|
},
|
|
}
|
|
|
|
ctx.env = append(ctx.env, "EBUILD_PHASE=configure")
|
|
exitCode, err := buildWithAutocrashImpl(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc), alwaysAutocrash)
|
|
if err != nil {
|
|
t.Fatalf("unexpectedly failed with %v", err)
|
|
}
|
|
ctx.must(exitCode)
|
|
if ctx.cmdCount != 1 {
|
|
t.Errorf("expected 1 call. Got: %d", ctx.cmdCount)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestBuildWithAutoCrashRerunsIfPredicateRequestsCrash(t *testing.T) {
|
|
withTestContext(t, func(ctx *testContext) {
|
|
autocrashPostCmd := buildWithAutocrashPredicates{
|
|
allowInConfigure: true,
|
|
shouldAutocrash: func(env, *config, *command, compilerExecInfo) bool {
|
|
return true
|
|
},
|
|
}
|
|
|
|
ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
|
|
hasDash := false
|
|
for _, arg := range cmd.Args {
|
|
if arg == "-" {
|
|
hasDash = true
|
|
break
|
|
}
|
|
}
|
|
|
|
switch ctx.cmdCount {
|
|
case 1:
|
|
if hasDash {
|
|
t.Error("Got `-` on command 1; didn't want that.")
|
|
}
|
|
return nil
|
|
case 2:
|
|
if !hasDash {
|
|
t.Error("Didn't get `-` on command 2; wanted that.")
|
|
} else {
|
|
input := stdin.(*bytes.Buffer)
|
|
if s := input.String(); !strings.Contains(s, autocrashProgramLine) {
|
|
t.Errorf("Input was %q; expected %q to be in it", s, autocrashProgramLine)
|
|
}
|
|
}
|
|
return nil
|
|
default:
|
|
t.Fatalf("Unexpected command count: %d", ctx.cmdCount)
|
|
panic("Unreachable")
|
|
}
|
|
}
|
|
|
|
exitCode, err := buildWithAutocrashImpl(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc), autocrashPostCmd)
|
|
if err != nil {
|
|
t.Fatalf("unexpectedly failed with %v", err)
|
|
}
|
|
ctx.must(exitCode)
|
|
|
|
if ctx.cmdCount != 2 {
|
|
t.Errorf("expected 2 calls. Got: %d", ctx.cmdCount)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestBuildWithAutoCrashAddsDashAndWritesToStdinIfInputFileIsNotStdin(t *testing.T) {
|
|
withTestContext(t, func(ctx *testContext) {
|
|
autocrashPostCmd := buildWithAutocrashPredicates{
|
|
allowInConfigure: true,
|
|
shouldAutocrash: func(env, *config, *command, compilerExecInfo) bool {
|
|
return true
|
|
},
|
|
}
|
|
|
|
ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
|
|
numDashes := 0
|
|
for _, arg := range cmd.Args {
|
|
if arg == "-" {
|
|
numDashes++
|
|
}
|
|
}
|
|
|
|
switch ctx.cmdCount {
|
|
case 1:
|
|
if numDashes != 0 {
|
|
t.Errorf("Got %d dashes on command 1; want 0", numDashes)
|
|
}
|
|
return nil
|
|
case 2:
|
|
if numDashes != 1 {
|
|
t.Errorf("Got %d dashes on command 2; want 1", numDashes)
|
|
}
|
|
|
|
input := stdin.(*bytes.Buffer).String()
|
|
stdinHasAutocrashLine := strings.Contains(input, autocrashProgramLine)
|
|
if !stdinHasAutocrashLine {
|
|
t.Error("Got no autocrash line on the second command; wanted that")
|
|
}
|
|
return nil
|
|
default:
|
|
t.Fatalf("Unexpected command count: %d", ctx.cmdCount)
|
|
panic("Unreachable")
|
|
}
|
|
}
|
|
|
|
exitCode, err := buildWithAutocrashImpl(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc), autocrashPostCmd)
|
|
if err != nil {
|
|
t.Fatalf("unexpectedly failed with %v", err)
|
|
}
|
|
ctx.must(exitCode)
|
|
|
|
if ctx.cmdCount != 2 {
|
|
t.Errorf("expected 2 calls. Got: %d", ctx.cmdCount)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestBuildWithAutoCrashAppendsToStdinIfStdinIsTheOnlyInputFile(t *testing.T) {
|
|
withTestContext(t, func(ctx *testContext) {
|
|
autocrashPostCmd := buildWithAutocrashPredicates{
|
|
allowInConfigure: true,
|
|
shouldAutocrash: func(env, *config, *command, compilerExecInfo) bool {
|
|
return true
|
|
},
|
|
}
|
|
|
|
ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
|
|
numDashes := 0
|
|
for _, arg := range cmd.Args {
|
|
if arg == "-" {
|
|
numDashes++
|
|
}
|
|
}
|
|
|
|
if numDashes != 1 {
|
|
t.Errorf("Got %d dashes on command %d (args: %#v); want 1", numDashes, ctx.cmdCount, cmd.Args)
|
|
}
|
|
|
|
input := stdin.(*bytes.Buffer).String()
|
|
stdinHasAutocrashLine := strings.Contains(input, autocrashProgramLine)
|
|
|
|
switch ctx.cmdCount {
|
|
case 1:
|
|
if stdinHasAutocrashLine {
|
|
t.Error("Got autocrash line on the first command; did not want that")
|
|
}
|
|
return nil
|
|
case 2:
|
|
if !stdinHasAutocrashLine {
|
|
t.Error("Got no autocrash line on the second command; wanted that")
|
|
}
|
|
return nil
|
|
default:
|
|
t.Fatalf("Unexpected command count: %d", ctx.cmdCount)
|
|
panic("Unreachable")
|
|
}
|
|
}
|
|
|
|
exitCode, err := buildWithAutocrashImpl(ctx, ctx.cfg, ctx.newCommand(clangX86_64, "-x", "c", "-"), autocrashPostCmd)
|
|
if err != nil {
|
|
t.Fatalf("unexpectedly failed with %v", err)
|
|
}
|
|
ctx.must(exitCode)
|
|
|
|
if ctx.cmdCount != 2 {
|
|
t.Errorf("expected 2 calls. Got: %d", ctx.cmdCount)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestCrashBuildFiltersObjectFileOptionOnCrashes(t *testing.T) {
|
|
withTestContext(t, func(ctx *testContext) {
|
|
autocrashPostCmd := buildWithAutocrashPredicates{
|
|
allowInConfigure: true,
|
|
shouldAutocrash: func(env, *config, *command, compilerExecInfo) bool {
|
|
return true
|
|
},
|
|
}
|
|
|
|
const outputFileName = "/path/to/foo.o"
|
|
|
|
ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
|
|
cmdOutputArg := (*string)(nil)
|
|
for i, e := range cmd.Args {
|
|
if e == "-o" {
|
|
// Assume something follows. If not, we'll crash and the
|
|
// test will fail.
|
|
cmdOutputArg = &cmd.Args[i+1]
|
|
}
|
|
}
|
|
|
|
switch ctx.cmdCount {
|
|
case 1:
|
|
if cmdOutputArg == nil || *cmdOutputArg != outputFileName {
|
|
t.Errorf("Got command args %q; want `-o %q` in them", cmd.Args, outputFileName)
|
|
}
|
|
return nil
|
|
case 2:
|
|
if cmdOutputArg != nil {
|
|
t.Errorf("Got command args %q; want no mention of `-o %q` in them", cmd.Args, outputFileName)
|
|
}
|
|
return nil
|
|
default:
|
|
t.Fatalf("Unexpected command count: %d", ctx.cmdCount)
|
|
panic("Unreachable")
|
|
}
|
|
}
|
|
|
|
exitCode, err := buildWithAutocrashImpl(ctx, ctx.cfg, ctx.newCommand(clangX86_64, "-o", outputFileName, mainCc), autocrashPostCmd)
|
|
if err != nil {
|
|
t.Fatalf("unexpectedly failed with %v", err)
|
|
}
|
|
ctx.must(exitCode)
|
|
|
|
if ctx.cmdCount != 2 {
|
|
t.Errorf("expected 2 calls. Got: %d", ctx.cmdCount)
|
|
}
|
|
})
|
|
}
|