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

View as plain text