GoPLS Viewer

Home|gopls/cmd/signature-fuzzer/fuzz-runner/rnr_test.go
1// Copyright 2021 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package main
6
7import (
8    "fmt"
9    "os"
10    "os/exec"
11    "path/filepath"
12    "runtime"
13    "strings"
14    "testing"
15
16    "golang.org/x/tools/internal/testenv"
17)
18
19func canRace(t *testing.Tbool {
20    _err := exec.Command("go""run""-race""./testdata/himom.go").CombinedOutput()
21    return err == nil
22}
23
24// buildRunner builds the fuzz-runner executable, returning its path.
25func buildRunner(t *testing.Tstring {
26    bindir := filepath.Join(t.TempDir(), "bin")
27    err := os.Mkdir(bindiros.ModePerm)
28    if err != nil {
29        t.Fatal(err)
30    }
31    binary := filepath.Join(bindir"runner")
32    if runtime.GOOS == "windows" {
33        binary += ".exe"
34    }
35    cmd := exec.Command("go""build""-o"binary)
36    if err := cmd.Run(); err != nil {
37        t.Fatalf("Building fuzz-runner: %v"err)
38    }
39    return binary
40}
41
42// TestRunner builds the binary, then kicks off a collection of sub-tests that invoke it.
43func TestRunner(t *testing.T) {
44    testenv.NeedsTool(t"go")
45    if runtime.GOOS == "android" {
46        t.Skipf("the dependencies are not available on android")
47    }
48    binaryPath := buildRunner(t)
49
50    // Sub-tests using the binary built above.
51    t.Run("Basic", func(t *testing.T) { testBasic(tbinaryPath) })
52    t.Run("Race", func(t *testing.T) { testRace(tbinaryPath) })
53    t.Run("Minimization1", func(t *testing.T) { testMinimization1(tbinaryPath) })
54    t.Run("Minimization2", func(t *testing.T) { testMinimization2(tbinaryPath) })
55}
56
57func testBasic(t *testing.TbinaryPath string) {
58    t.Parallel()
59    args := []string{"-numit=1""-numfcns=1""-numpkgs=1""-seed=103""-cleancache=0"}
60    c := exec.Command(binaryPathargs...)
61    berr := c.CombinedOutput()
62    t.Logf("%s\n"b)
63    if err != nil {
64        t.Fatalf("error invoking fuzz-runner: %v"err)
65    }
66}
67
68func testRace(t *testing.TbinaryPath string) {
69    t.Parallel()
70    // For this test to work, the current test platform has to support the
71    // race detector. Check to see if that is the case by running a very
72    // simple Go program through it.
73    if !canRace(t) {
74        t.Skip("current platform does not appear to support the race detector")
75    }
76
77    args := []string{"-v=1""-numit=1""-race""-numfcns=3""-numpkgs=3""-seed=987""-cleancache=0"}
78    c := exec.Command(binaryPathargs...)
79    berr := c.CombinedOutput()
80    t.Logf("%s\n"b)
81    if err != nil {
82        t.Fatalf("error invoking fuzz-runner: %v"err)
83    }
84}
85
86func testMinimization1(t *testing.TbinaryPath string) {
87    if binaryPath == "" {
88        t.Skipf("No runner binary")
89    }
90    t.Parallel()
91    // Fire off the runner passing it -emitbad=1, so that the generated code
92    // contains illegal Go code (which will force the build to fail). Verify that
93    // it does fail, that the error reflects the nature of the failure, and that
94    // we can minimize the error down to a single package.
95    args := []string{"-emitbad=1""-badfcnidx=2""-badpkgidx=2",
96        "-forcetmpclean""-cleancache=0",
97        "-numit=1""-numfcns=3""-numpkgs=3""-seed=909"}
98    invocation := fmt.Sprintf("%s %v"binaryPathargs)
99    c := exec.Command(binaryPathargs...)
100    berr := c.CombinedOutput()
101    t.Logf("%s\n"b)
102    if err == nil {
103        t.Fatalf("unexpected pass of fuzz-runner (invocation %q): %v"invocationerr)
104    }
105    result := string(b)
106    if !strings.Contains(result"syntax error") {
107        t.Fatalf("-emitbad=1 did not trigger syntax error (invocation %q): output: %s"invocationresult)
108    }
109    if !strings.Contains(result"package minimization succeeded: found bad pkg 2") {
110        t.Fatalf("failed to minimize package (invocation %q): output: %s"invocationresult)
111    }
112    if !strings.Contains(result"function minimization succeeded: found bad fcn 2") {
113        t.Fatalf("failed to minimize package (invocation %q): output: %s"invocationresult)
114    }
115}
116
117func testMinimization2(t *testing.TbinaryPath string) {
118    if binaryPath == "" {
119        t.Skipf("No runner binary")
120    }
121    t.Parallel()
122    // Fire off the runner passing it -emitbad=2, so that the
123    // generated code forces a runtime error. Verify that it does
124    // fail, and that the error is reflective.
125    args := []string{"-emitbad=2""-badfcnidx=1""-badpkgidx=1",
126        "-forcetmpclean""-cleancache=0",
127        "-numit=1""-numfcns=3""-numpkgs=3""-seed=55909"}
128    invocation := fmt.Sprintf("%s %v"binaryPathargs)
129    c := exec.Command(binaryPathargs...)
130    berr := c.CombinedOutput()
131    t.Logf("%s\n"b)
132    if err == nil {
133        t.Fatalf("unexpected pass of fuzz-runner (invocation %q): %v"invocationerr)
134    }
135    result := string(b)
136    if !strings.Contains(result"Error: fail") || !strings.Contains(result"Checker1.Test1") {
137        t.Fatalf("-emitbad=2 did not trigger runtime error (invocation %q): output: %s"invocationresult)
138    }
139    if !strings.Contains(result"package minimization succeeded: found bad pkg 1") {
140        t.Fatalf("failed to minimize package (invocation %q): output: %s"invocationresult)
141    }
142    if !strings.Contains(result"function minimization succeeded: found bad fcn 1") {
143        t.Fatalf("failed to minimize package (invocation %q): output: %s"invocationresult)
144    }
145}
146
MembersX
testRace.c
testMinimization1.c
testBasic.args
testMinimization1.t
testMinimization2.b
canRace.err
testMinimization1.binaryPath
testMinimization1.b
strings
testMinimization2.invocation
os
testMinimization1
testMinimization2.t
testBasic.t
testRace.args
canRace.t
testBasic.err
testRace.b
canRace
buildRunner.t
buildRunner.bindir
TestRunner.binaryPath
testBasic.binaryPath
testenv
testRace.err
testMinimization2
canRace._
TestRunner
testMinimization1.args
testMinimization1.err
fmt
testMinimization1.invocation
testMinimization1.result
testMinimization2.binaryPath
testMinimization2.args
runtime
testBasic.b
testRace
testMinimization2.result
filepath
buildRunner.cmd
testBasic.c
testMinimization2.err
testing
buildRunner
buildRunner.err
TestRunner.t
testBasic
testRace.t
exec
buildRunner.binary
testRace.binaryPath
testMinimization2.c
Members
X