golang.org/x/tools@v0.21.1-0.20240520172518-788d39e776b1/cmd/file2fuzz/main_test.go (about) 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 5 package main 6 7 import ( 8 "os" 9 "os/exec" 10 "path/filepath" 11 "strings" 12 "sync" 13 "testing" 14 15 "golang.org/x/tools/internal/testenv" 16 ) 17 18 func TestMain(m *testing.M) { 19 if os.Getenv("GO_FILE2FUZZ_TEST_IS_FILE2FUZZ") != "" { 20 main() 21 os.Exit(0) 22 } 23 24 os.Exit(m.Run()) 25 } 26 27 var f2f struct { 28 once sync.Once 29 path string 30 err error 31 } 32 33 func file2fuzz(t *testing.T, dir string, args []string, stdin string) (string, bool) { 34 testenv.NeedsExec(t) 35 36 f2f.once.Do(func() { 37 f2f.path, f2f.err = os.Executable() 38 }) 39 if f2f.err != nil { 40 t.Fatal(f2f.err) 41 } 42 43 cmd := exec.Command(f2f.path, args...) 44 cmd.Dir = dir 45 cmd.Env = append(os.Environ(), "PWD="+dir, "GO_FILE2FUZZ_TEST_IS_FILE2FUZZ=1") 46 if stdin != "" { 47 cmd.Stdin = strings.NewReader(stdin) 48 } 49 out, err := cmd.CombinedOutput() 50 if err != nil { 51 return string(out), true 52 } 53 return string(out), false 54 } 55 56 func TestFile2Fuzz(t *testing.T) { 57 type file struct { 58 name string 59 dir bool 60 content string 61 } 62 tests := []struct { 63 name string 64 args []string 65 stdin string 66 inputFiles []file 67 expectedStdout string 68 expectedFiles []file 69 expectedError string 70 }{ 71 { 72 name: "stdin, stdout", 73 stdin: "hello", 74 expectedStdout: "go test fuzz v1\n[]byte(\"hello\")", 75 }, 76 { 77 name: "stdin, output file", 78 stdin: "hello", 79 args: []string{"-o", "output"}, 80 expectedFiles: []file{{name: "output", content: "go test fuzz v1\n[]byte(\"hello\")"}}, 81 }, 82 { 83 name: "stdin, output directory", 84 stdin: "hello", 85 args: []string{"-o", "output"}, 86 inputFiles: []file{{name: "output", dir: true}}, 87 expectedFiles: []file{{name: "output/ffc7b87a0377262d4f77926bd235551d78e6037bbe970d81ec39ac1d95542f7b", content: "go test fuzz v1\n[]byte(\"hello\")"}}, 88 }, 89 { 90 name: "input file, output file", 91 args: []string{"-o", "output", "input"}, 92 inputFiles: []file{{name: "input", content: "hello"}}, 93 expectedFiles: []file{{name: "output", content: "go test fuzz v1\n[]byte(\"hello\")"}}, 94 }, 95 { 96 name: "input file, output directory", 97 args: []string{"-o", "output", "input"}, 98 inputFiles: []file{{name: "output", dir: true}, {name: "input", content: "hello"}}, 99 expectedFiles: []file{{name: "output/ffc7b87a0377262d4f77926bd235551d78e6037bbe970d81ec39ac1d95542f7b", content: "go test fuzz v1\n[]byte(\"hello\")"}}, 100 }, 101 { 102 name: "input files, output directory", 103 args: []string{"-o", "output", "input", "input-2"}, 104 inputFiles: []file{{name: "output", dir: true}, {name: "input", content: "hello"}, {name: "input-2", content: "hello :)"}}, 105 expectedFiles: []file{ 106 {name: "output/ffc7b87a0377262d4f77926bd235551d78e6037bbe970d81ec39ac1d95542f7b", content: "go test fuzz v1\n[]byte(\"hello\")"}, 107 {name: "output/28059db30ce420ff65b2c29b749804c69c601aeca21b3cbf0644244ff080d7a5", content: "go test fuzz v1\n[]byte(\"hello :)\")"}, 108 }, 109 }, 110 { 111 name: "input files, no output", 112 args: []string{"input", "input-2"}, 113 inputFiles: []file{{name: "output", dir: true}, {name: "input", content: "hello"}, {name: "input-2", content: "hello :)"}}, 114 expectedError: "file2fuzz: -o required with multiple input files\n", 115 }, 116 } 117 118 for _, tc := range tests { 119 t.Run(tc.name, func(t *testing.T) { 120 tmp, err := os.MkdirTemp(os.TempDir(), "file2fuzz") 121 if err != nil { 122 t.Fatalf("os.MkdirTemp failed: %s", err) 123 } 124 defer os.RemoveAll(tmp) 125 for _, f := range tc.inputFiles { 126 if f.dir { 127 if err := os.Mkdir(filepath.Join(tmp, f.name), 0777); err != nil { 128 t.Fatalf("failed to create test directory: %s", err) 129 } 130 } else { 131 if err := os.WriteFile(filepath.Join(tmp, f.name), []byte(f.content), 0666); err != nil { 132 t.Fatalf("failed to create test input file: %s", err) 133 } 134 } 135 } 136 137 out, failed := file2fuzz(t, tmp, tc.args, tc.stdin) 138 if failed && tc.expectedError == "" { 139 t.Fatalf("file2fuzz failed unexpectedly: %s", out) 140 } else if failed && out != tc.expectedError { 141 t.Fatalf("file2fuzz returned unexpected error: got %q, want %q", out, tc.expectedError) 142 } 143 if !failed && out != tc.expectedStdout { 144 t.Fatalf("file2fuzz unexpected stdout: got %q, want %q", out, tc.expectedStdout) 145 } 146 147 for _, f := range tc.expectedFiles { 148 c, err := os.ReadFile(filepath.Join(tmp, f.name)) 149 if err != nil { 150 t.Fatalf("failed to read expected output file %q: %s", f.name, err) 151 } 152 if string(c) != f.content { 153 t.Fatalf("expected output file %q contains unexpected content: got %s, want %s", f.name, string(c), f.content) 154 } 155 } 156 }) 157 } 158 }