golang.org/x/tools@v0.21.0/cmd/bisect/main_test.go (about) 1 // Copyright 2023 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 5 package main 6 7 import ( 8 "bytes" 9 "encoding/json" 10 "flag" 11 "fmt" 12 "go/build/constraint" 13 "math/rand" 14 "os" 15 "path/filepath" 16 "strings" 17 "testing" 18 19 "golang.org/x/tools/internal/bisect" 20 "golang.org/x/tools/internal/diffp" 21 "golang.org/x/tools/txtar" 22 ) 23 24 var update = flag.Bool("update", false, "update testdata with new stdout/stderr") 25 26 func Test(t *testing.T) { 27 files, err := filepath.Glob("testdata/*.txt") 28 if err != nil { 29 t.Fatal(err) 30 } 31 for _, file := range files { 32 t.Run(strings.TrimSuffix(filepath.Base(file), ".txt"), func(t *testing.T) { 33 data, err := os.ReadFile(file) 34 if err != nil { 35 t.Fatal(err) 36 } 37 a := txtar.Parse(data) 38 var wantStdout, wantStderr []byte 39 files := a.Files 40 if len(files) > 0 && files[0].Name == "stdout" { 41 wantStdout = files[0].Data 42 files = files[1:] 43 } 44 if len(files) > 0 && files[0].Name == "stderr" { 45 wantStderr = files[0].Data 46 files = files[1:] 47 } 48 if len(files) > 0 { 49 t.Fatalf("unexpected txtar entry: %s", files[0].Name) 50 } 51 52 var tt struct { 53 Fail string 54 Bisect Bisect 55 } 56 if err := json.Unmarshal(a.Comment, &tt); err != nil { 57 t.Fatal(err) 58 } 59 60 expr, err := constraint.Parse("//go:build " + tt.Fail) 61 if err != nil { 62 t.Fatalf("invalid Cmd: %v", err) 63 } 64 65 rnd := rand.New(rand.NewSource(1)) 66 b := &tt.Bisect 67 b.Cmd = "test" 68 b.Args = []string{"PATTERN"} 69 var stdout, stderr bytes.Buffer 70 b.Stdout = &stdout 71 b.Stderr = &stderr 72 b.TestRun = func(env []string, cmd string, args []string) (out []byte, err error) { 73 pattern := args[0] 74 m, err := bisect.New(pattern) 75 if err != nil { 76 t.Fatal(err) 77 } 78 have := make(map[string]bool) 79 for i, color := range colors { 80 if m.ShouldEnable(uint64(i)) { 81 have[color] = true 82 } 83 if m.ShouldReport(uint64(i)) { 84 out = fmt.Appendf(out, "%s %s\n", color, bisect.Marker(uint64(i))) 85 } 86 } 87 err = nil 88 if eval(rnd, expr, have) { 89 err = fmt.Errorf("failed") 90 } 91 return out, err 92 } 93 94 if !b.Search() { 95 stderr.WriteString("<bisect failed>\n") 96 } 97 rewrite := false 98 if !bytes.Equal(stdout.Bytes(), wantStdout) { 99 if *update { 100 rewrite = true 101 } else { 102 t.Errorf("incorrect stdout: %s", diffp.Diff("have", stdout.Bytes(), "want", wantStdout)) 103 } 104 } 105 if !bytes.Equal(stderr.Bytes(), wantStderr) { 106 if *update { 107 rewrite = true 108 } else { 109 t.Errorf("incorrect stderr: %s", diffp.Diff("have", stderr.Bytes(), "want", wantStderr)) 110 } 111 } 112 if rewrite { 113 a.Files = []txtar.File{{Name: "stdout", Data: stdout.Bytes()}, {Name: "stderr", Data: stderr.Bytes()}} 114 err := os.WriteFile(file, txtar.Format(a), 0666) 115 if err != nil { 116 t.Fatal(err) 117 } 118 t.Logf("updated %s", file) 119 } 120 }) 121 } 122 } 123 124 func eval(rnd *rand.Rand, z constraint.Expr, have map[string]bool) bool { 125 switch z := z.(type) { 126 default: 127 panic(fmt.Sprintf("unexpected type %T", z)) 128 case *constraint.NotExpr: 129 return !eval(rnd, z.X, have) 130 case *constraint.AndExpr: 131 return eval(rnd, z.X, have) && eval(rnd, z.Y, have) 132 case *constraint.OrExpr: 133 return eval(rnd, z.X, have) || eval(rnd, z.Y, have) 134 case *constraint.TagExpr: 135 if z.Tag == "random" { 136 return rnd.Intn(2) == 1 137 } 138 return have[z.Tag] 139 } 140 } 141 142 var colors = strings.Fields(` 143 aliceblue 144 amaranth 145 amber 146 amethyst 147 applegreen 148 applered 149 apricot 150 aquamarine 151 azure 152 babyblue 153 beige 154 brickred 155 black 156 blue 157 bluegreen 158 blueviolet 159 blush 160 bronze 161 brown 162 burgundy 163 byzantium 164 carmine 165 cerise 166 cerulean 167 champagne 168 chartreusegreen 169 chocolate 170 cobaltblue 171 coffee 172 copper 173 coral 174 crimson 175 cyan 176 desertsand 177 electricblue 178 emerald 179 erin 180 gold 181 gray 182 green 183 harlequin 184 indigo 185 ivory 186 jade 187 junglegreen 188 lavender 189 lemon 190 lilac 191 lime 192 magenta 193 magentarose 194 maroon 195 mauve 196 navyblue 197 ochre 198 olive 199 orange 200 orangered 201 orchid 202 peach 203 pear 204 periwinkle 205 persianblue 206 pink 207 plum 208 prussianblue 209 puce 210 purple 211 raspberry 212 red 213 redviolet 214 rose 215 ruby 216 salmon 217 sangria 218 sapphire 219 scarlet 220 silver 221 slategray 222 springbud 223 springgreen 224 tan 225 taupe 226 teal 227 turquoise 228 ultramarine 229 violet 230 viridian 231 white 232 yellow 233 `)