...

Source file src/golang.org/x/tools/cmd/file2fuzz/main_test.go

Documentation: golang.org/x/tools/cmd/file2fuzz

     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  }
   159  

View as plain text