github.com/jgbaldwinbrown/perf@v0.1.1/benchfmt/files_test.go (about) 1 // Copyright 2022 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 benchfmt 6 7 import ( 8 "errors" 9 "io/fs" 10 "os" 11 "strings" 12 "testing" 13 ) 14 15 func TestFiles(t *testing.T) { 16 // Switch to testdata/files directory. 17 oldDir, err := os.Getwd() 18 if err != nil { 19 t.Fatal(err) 20 } 21 defer os.Chdir(oldDir) 22 if err := os.Chdir("testdata/files"); err != nil { 23 t.Fatal(err) 24 } 25 26 check := func(f *Files, want ...string) { 27 t.Helper() 28 for f.Scan() { 29 switch res := f.Result(); res := res.(type) { 30 default: 31 t.Fatalf("unexpected result type %T", res) 32 case *SyntaxError: 33 t.Fatalf("unexpected Result error %s", res) 34 return 35 case *Result: 36 if len(want) == 0 { 37 t.Errorf("got result, want end of stream") 38 return 39 } 40 got := res.GetConfig(".file") + " " + string(res.Name.Full()) 41 if got != want[0] { 42 t.Errorf("got %q, want %q", got, want[0]) 43 } 44 want = want[1:] 45 } 46 } 47 48 err := f.Err() 49 noent := errors.Is(err, fs.ErrNotExist) 50 wantNoent := len(want) == 1 && strings.HasPrefix(want[0], "ErrNotExist") 51 if wantNoent { 52 want = want[1:] 53 } 54 if err != nil && !noent { 55 t.Errorf("got unexpected error %s", err) 56 } else if noent && !wantNoent { 57 t.Errorf("got %s, want success", err) 58 } else if !noent && wantNoent { 59 t.Errorf("got success, want ErrNotExist") 60 } 61 62 if len(want) != 0 { 63 t.Errorf("got end of stream, want %v", want) 64 } 65 } 66 67 // Basic tests. 68 check( 69 &Files{Paths: []string{"a", "b"}}, 70 "a X", "a Y", "b Z", 71 ) 72 check( 73 &Files{Paths: []string{"a", "b", "c", "d"}}, 74 "a X", "a Y", "b Z", "ErrNotExist", 75 ) 76 77 // Ambiguous paths. 78 check( 79 &Files{Paths: []string{"a", "b", "a"}}, 80 "a#0 X", "a#0 Y", "b Z", "a#1 X", "a#1 Y", 81 ) 82 83 // AllowStdin. 84 check( 85 &Files{Paths: []string{"-"}}, 86 "ErrNotExist", 87 ) 88 fakeStdin("BenchmarkIn 1 1 ns/op\n", func() { 89 check( 90 &Files{ 91 Paths: []string{"-"}, 92 AllowStdin: true, 93 }, 94 "- In", 95 ) 96 }) 97 98 // Labels. 99 check( 100 &Files{ 101 Paths: []string{"a", "b"}, 102 AllowLabels: true, 103 }, 104 "a X", "a Y", "b Z", 105 ) 106 check( 107 &Files{ 108 Paths: []string{"foo=a", "b"}, 109 AllowLabels: true, 110 }, 111 "foo X", "foo Y", "b Z", 112 ) 113 fakeStdin("BenchmarkIn 1 1 ns/op\n", func() { 114 check( 115 &Files{ 116 Paths: []string{"foo=-"}, 117 AllowStdin: true, 118 AllowLabels: true, 119 }, 120 "foo In", 121 ) 122 }) 123 124 // Ambiguous labels don't get disambiguated. 125 check( 126 &Files{ 127 Paths: []string{"foo=a", "foo=a"}, 128 AllowLabels: true, 129 }, 130 "foo X", "foo Y", "foo X", "foo Y", 131 ) 132 } 133 134 func fakeStdin(content string, cb func()) { 135 r, w, err := os.Pipe() 136 if err != nil { 137 panic(err) 138 } 139 go func() { 140 defer w.Close() 141 w.WriteString(content) 142 }() 143 defer r.Close() 144 defer func(orig *os.File) { os.Stdin = orig }(os.Stdin) 145 os.Stdin = r 146 cb() 147 }