Source file src/io/ioutil/tempfile_test.go

     1  // Copyright 2010 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 ioutil_test
     6  
     7  import (
     8  	"io/fs"
     9  	. "io/ioutil"
    10  	"os"
    11  	"path/filepath"
    12  	"regexp"
    13  	"strings"
    14  	"testing"
    15  )
    16  
    17  func TestTempFile(t *testing.T) {
    18  	dir, err := TempDir("", "TestTempFile_BadDir")
    19  	if err != nil {
    20  		t.Fatal(err)
    21  	}
    22  	defer os.RemoveAll(dir)
    23  
    24  	nonexistentDir := filepath.Join(dir, "_not_exists_")
    25  	f, err := TempFile(nonexistentDir, "foo")
    26  	if f != nil || err == nil {
    27  		t.Errorf("TempFile(%q, `foo`) = %v, %v", nonexistentDir, f, err)
    28  	}
    29  }
    30  
    31  func TestTempFile_pattern(t *testing.T) {
    32  	tests := []struct{ pattern, prefix, suffix string }{
    33  		{"ioutil_test", "ioutil_test", ""},
    34  		{"ioutil_test*", "ioutil_test", ""},
    35  		{"ioutil_test*xyz", "ioutil_test", "xyz"},
    36  	}
    37  	for _, test := range tests {
    38  		f, err := TempFile("", test.pattern)
    39  		if err != nil {
    40  			t.Errorf("TempFile(..., %q) error: %v", test.pattern, err)
    41  			continue
    42  		}
    43  		defer os.Remove(f.Name())
    44  		base := filepath.Base(f.Name())
    45  		f.Close()
    46  		if !(strings.HasPrefix(base, test.prefix) && strings.HasSuffix(base, test.suffix)) {
    47  			t.Errorf("TempFile pattern %q created bad name %q; want prefix %q & suffix %q",
    48  				test.pattern, base, test.prefix, test.suffix)
    49  		}
    50  	}
    51  }
    52  
    53  // This string is from os.errPatternHasSeparator.
    54  const patternHasSeparator = "pattern contains path separator"
    55  
    56  func TestTempFile_BadPattern(t *testing.T) {
    57  	tmpDir, err := TempDir("", t.Name())
    58  	if err != nil {
    59  		t.Fatal(err)
    60  	}
    61  	defer os.RemoveAll(tmpDir)
    62  
    63  	const sep = string(os.PathSeparator)
    64  	tests := []struct {
    65  		pattern string
    66  		wantErr bool
    67  	}{
    68  		{"ioutil*test", false},
    69  		{"ioutil_test*foo", false},
    70  		{"ioutil_test" + sep + "foo", true},
    71  		{"ioutil_test*" + sep + "foo", true},
    72  		{"ioutil_test" + sep + "*foo", true},
    73  		{sep + "ioutil_test" + sep + "*foo", true},
    74  		{"ioutil_test*foo" + sep, true},
    75  	}
    76  	for _, tt := range tests {
    77  		t.Run(tt.pattern, func(t *testing.T) {
    78  			tmpfile, err := TempFile(tmpDir, tt.pattern)
    79  			defer func() {
    80  				if tmpfile != nil {
    81  					tmpfile.Close()
    82  				}
    83  			}()
    84  			if tt.wantErr {
    85  				if err == nil {
    86  					t.Errorf("Expected an error for pattern %q", tt.pattern)
    87  				} else if !strings.Contains(err.Error(), patternHasSeparator) {
    88  					t.Errorf("Error mismatch: got %#v, want %q for pattern %q", err, patternHasSeparator, tt.pattern)
    89  				}
    90  			} else if err != nil {
    91  				t.Errorf("Unexpected error %v for pattern %q", err, tt.pattern)
    92  			}
    93  		})
    94  	}
    95  }
    96  
    97  func TestTempDir(t *testing.T) {
    98  	name, err := TempDir("/_not_exists_", "foo")
    99  	if name != "" || err == nil {
   100  		t.Errorf("TempDir(`/_not_exists_`, `foo`) = %v, %v", name, err)
   101  	}
   102  
   103  	tests := []struct {
   104  		pattern                string
   105  		wantPrefix, wantSuffix string
   106  	}{
   107  		{"ioutil_test", "ioutil_test", ""},
   108  		{"ioutil_test*", "ioutil_test", ""},
   109  		{"ioutil_test*xyz", "ioutil_test", "xyz"},
   110  	}
   111  
   112  	dir := os.TempDir()
   113  
   114  	runTestTempDir := func(t *testing.T, pattern, wantRePat string) {
   115  		name, err := TempDir(dir, pattern)
   116  		if name == "" || err != nil {
   117  			t.Fatalf("TempDir(dir, `ioutil_test`) = %v, %v", name, err)
   118  		}
   119  		defer os.Remove(name)
   120  
   121  		re := regexp.MustCompile(wantRePat)
   122  		if !re.MatchString(name) {
   123  			t.Errorf("TempDir(%q, %q) created bad name\n\t%q\ndid not match pattern\n\t%q", dir, pattern, name, wantRePat)
   124  		}
   125  	}
   126  
   127  	for _, tt := range tests {
   128  		t.Run(tt.pattern, func(t *testing.T) {
   129  			wantRePat := "^" + regexp.QuoteMeta(filepath.Join(dir, tt.wantPrefix)) + "[0-9]+" + regexp.QuoteMeta(tt.wantSuffix) + "$"
   130  			runTestTempDir(t, tt.pattern, wantRePat)
   131  		})
   132  	}
   133  
   134  	// Separately testing "*xyz" (which has no prefix). That is when constructing the
   135  	// pattern to assert on, as in the previous loop, using filepath.Join for an empty
   136  	// prefix filepath.Join(dir, ""), produces the pattern:
   137  	//     ^<DIR>[0-9]+xyz$
   138  	// yet we just want to match
   139  	//     "^<DIR>/[0-9]+xyz"
   140  	t.Run("*xyz", func(t *testing.T) {
   141  		wantRePat := "^" + regexp.QuoteMeta(filepath.Join(dir)) + regexp.QuoteMeta(string(filepath.Separator)) + "[0-9]+xyz$"
   142  		runTestTempDir(t, "*xyz", wantRePat)
   143  	})
   144  }
   145  
   146  // test that we return a nice error message if the dir argument to TempDir doesn't
   147  // exist (or that it's empty and os.TempDir doesn't exist)
   148  func TestTempDir_BadDir(t *testing.T) {
   149  	dir, err := TempDir("", "TestTempDir_BadDir")
   150  	if err != nil {
   151  		t.Fatal(err)
   152  	}
   153  	defer os.RemoveAll(dir)
   154  
   155  	badDir := filepath.Join(dir, "not-exist")
   156  	_, err = TempDir(badDir, "foo")
   157  	if pe, ok := err.(*fs.PathError); !ok || !os.IsNotExist(err) || pe.Path != badDir {
   158  		t.Errorf("TempDir error = %#v; want PathError for path %q satisifying os.IsNotExist", err, badDir)
   159  	}
   160  }
   161  
   162  func TestTempDir_BadPattern(t *testing.T) {
   163  	tmpDir, err := TempDir("", t.Name())
   164  	if err != nil {
   165  		t.Fatal(err)
   166  	}
   167  	defer os.RemoveAll(tmpDir)
   168  
   169  	const sep = string(os.PathSeparator)
   170  	tests := []struct {
   171  		pattern string
   172  		wantErr bool
   173  	}{
   174  		{"ioutil*test", false},
   175  		{"ioutil_test*foo", false},
   176  		{"ioutil_test" + sep + "foo", true},
   177  		{"ioutil_test*" + sep + "foo", true},
   178  		{"ioutil_test" + sep + "*foo", true},
   179  		{sep + "ioutil_test" + sep + "*foo", true},
   180  		{"ioutil_test*foo" + sep, true},
   181  	}
   182  	for _, tt := range tests {
   183  		t.Run(tt.pattern, func(t *testing.T) {
   184  			_, err := TempDir(tmpDir, tt.pattern)
   185  			if tt.wantErr {
   186  				if err == nil {
   187  					t.Errorf("Expected an error for pattern %q", tt.pattern)
   188  				} else if !strings.Contains(err.Error(), patternHasSeparator) {
   189  					t.Errorf("Error mismatch: got %#v, want %q for pattern %q", err, patternHasSeparator, tt.pattern)
   190  				}
   191  			} else if err != nil {
   192  				t.Errorf("Unexpected error %v for pattern %q", err, tt.pattern)
   193  			}
   194  		})
   195  	}
   196  }
   197  

View as plain text