github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/pkg/fileutils/fileutils_test.go (about)

     1  package fileutils
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path"
     7  	"path/filepath"
     8  	"runtime"
     9  	"strings"
    10  	"testing"
    11  
    12  	"fmt"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  // CopyFile with invalid src
    18  func TestCopyFileWithInvalidSrc(t *testing.T) {
    19  	tempFolder, err := ioutil.TempDir("", "docker-fileutils-test")
    20  	defer os.RemoveAll(tempFolder)
    21  	if err != nil {
    22  		t.Fatal(err)
    23  	}
    24  	bytes, err := CopyFile("/invalid/file/path", path.Join(tempFolder, "dest"))
    25  	if err == nil {
    26  		t.Fatal("Should have fail to copy an invalid src file")
    27  	}
    28  	if bytes != 0 {
    29  		t.Fatal("Should have written 0 bytes")
    30  	}
    31  
    32  }
    33  
    34  // CopyFile with invalid dest
    35  func TestCopyFileWithInvalidDest(t *testing.T) {
    36  	tempFolder, err := ioutil.TempDir("", "docker-fileutils-test")
    37  	defer os.RemoveAll(tempFolder)
    38  	if err != nil {
    39  		t.Fatal(err)
    40  	}
    41  	src := path.Join(tempFolder, "file")
    42  	err = ioutil.WriteFile(src, []byte("content"), 0740)
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	bytes, err := CopyFile(src, path.Join(tempFolder, "/invalid/dest/path"))
    47  	if err == nil {
    48  		t.Fatal("Should have fail to copy an invalid src file")
    49  	}
    50  	if bytes != 0 {
    51  		t.Fatal("Should have written 0 bytes")
    52  	}
    53  
    54  }
    55  
    56  // CopyFile with same src and dest
    57  func TestCopyFileWithSameSrcAndDest(t *testing.T) {
    58  	tempFolder, err := ioutil.TempDir("", "docker-fileutils-test")
    59  	defer os.RemoveAll(tempFolder)
    60  	if err != nil {
    61  		t.Fatal(err)
    62  	}
    63  	file := path.Join(tempFolder, "file")
    64  	err = ioutil.WriteFile(file, []byte("content"), 0740)
    65  	if err != nil {
    66  		t.Fatal(err)
    67  	}
    68  	bytes, err := CopyFile(file, file)
    69  	if err != nil {
    70  		t.Fatal(err)
    71  	}
    72  	if bytes != 0 {
    73  		t.Fatal("Should have written 0 bytes as it is the same file.")
    74  	}
    75  }
    76  
    77  // CopyFile with same src and dest but path is different and not clean
    78  func TestCopyFileWithSameSrcAndDestWithPathNameDifferent(t *testing.T) {
    79  	tempFolder, err := ioutil.TempDir("", "docker-fileutils-test")
    80  	defer os.RemoveAll(tempFolder)
    81  	if err != nil {
    82  		t.Fatal(err)
    83  	}
    84  	testFolder := path.Join(tempFolder, "test")
    85  	err = os.MkdirAll(testFolder, 0740)
    86  	if err != nil {
    87  		t.Fatal(err)
    88  	}
    89  	file := path.Join(testFolder, "file")
    90  	sameFile := testFolder + "/../test/file"
    91  	err = ioutil.WriteFile(file, []byte("content"), 0740)
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  	bytes, err := CopyFile(file, sameFile)
    96  	if err != nil {
    97  		t.Fatal(err)
    98  	}
    99  	if bytes != 0 {
   100  		t.Fatal("Should have written 0 bytes as it is the same file.")
   101  	}
   102  }
   103  
   104  func TestCopyFile(t *testing.T) {
   105  	tempFolder, err := ioutil.TempDir("", "docker-fileutils-test")
   106  	defer os.RemoveAll(tempFolder)
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  	src := path.Join(tempFolder, "src")
   111  	dest := path.Join(tempFolder, "dest")
   112  	ioutil.WriteFile(src, []byte("content"), 0777)
   113  	ioutil.WriteFile(dest, []byte("destContent"), 0777)
   114  	bytes, err := CopyFile(src, dest)
   115  	if err != nil {
   116  		t.Fatal(err)
   117  	}
   118  	if bytes != 7 {
   119  		t.Fatalf("Should have written %d bytes but wrote %d", 7, bytes)
   120  	}
   121  	actual, err := ioutil.ReadFile(dest)
   122  	if err != nil {
   123  		t.Fatal(err)
   124  	}
   125  	if string(actual) != "content" {
   126  		t.Fatalf("Dest content was '%s', expected '%s'", string(actual), "content")
   127  	}
   128  }
   129  
   130  // Reading a symlink to a directory must return the directory
   131  func TestReadSymlinkedDirectoryExistingDirectory(t *testing.T) {
   132  	// TODO Windows: Port this test
   133  	if runtime.GOOS == "windows" {
   134  		t.Skip("Needs porting to Windows")
   135  	}
   136  	var err error
   137  	if err = os.Mkdir("/tmp/testReadSymlinkToExistingDirectory", 0777); err != nil {
   138  		t.Errorf("failed to create directory: %s", err)
   139  	}
   140  
   141  	if err = os.Symlink("/tmp/testReadSymlinkToExistingDirectory", "/tmp/dirLinkTest"); err != nil {
   142  		t.Errorf("failed to create symlink: %s", err)
   143  	}
   144  
   145  	var path string
   146  	if path, err = ReadSymlinkedDirectory("/tmp/dirLinkTest"); err != nil {
   147  		t.Fatalf("failed to read symlink to directory: %s", err)
   148  	}
   149  
   150  	if path != "/tmp/testReadSymlinkToExistingDirectory" {
   151  		t.Fatalf("symlink returned unexpected directory: %s", path)
   152  	}
   153  
   154  	if err = os.Remove("/tmp/testReadSymlinkToExistingDirectory"); err != nil {
   155  		t.Errorf("failed to remove temporary directory: %s", err)
   156  	}
   157  
   158  	if err = os.Remove("/tmp/dirLinkTest"); err != nil {
   159  		t.Errorf("failed to remove symlink: %s", err)
   160  	}
   161  }
   162  
   163  // Reading a non-existing symlink must fail
   164  func TestReadSymlinkedDirectoryNonExistingSymlink(t *testing.T) {
   165  	var path string
   166  	var err error
   167  	if path, err = ReadSymlinkedDirectory("/tmp/test/foo/Non/ExistingPath"); err == nil {
   168  		t.Fatalf("error expected for non-existing symlink")
   169  	}
   170  
   171  	if path != "" {
   172  		t.Fatalf("expected empty path, but '%s' was returned", path)
   173  	}
   174  }
   175  
   176  // Reading a symlink to a file must fail
   177  func TestReadSymlinkedDirectoryToFile(t *testing.T) {
   178  	// TODO Windows: Port this test
   179  	if runtime.GOOS == "windows" {
   180  		t.Skip("Needs porting to Windows")
   181  	}
   182  	var err error
   183  	var file *os.File
   184  
   185  	if file, err = os.Create("/tmp/testReadSymlinkToFile"); err != nil {
   186  		t.Fatalf("failed to create file: %s", err)
   187  	}
   188  
   189  	file.Close()
   190  
   191  	if err = os.Symlink("/tmp/testReadSymlinkToFile", "/tmp/fileLinkTest"); err != nil {
   192  		t.Errorf("failed to create symlink: %s", err)
   193  	}
   194  
   195  	var path string
   196  	if path, err = ReadSymlinkedDirectory("/tmp/fileLinkTest"); err == nil {
   197  		t.Fatalf("ReadSymlinkedDirectory on a symlink to a file should've failed")
   198  	}
   199  
   200  	if path != "" {
   201  		t.Fatalf("path should've been empty: %s", path)
   202  	}
   203  
   204  	if err = os.Remove("/tmp/testReadSymlinkToFile"); err != nil {
   205  		t.Errorf("failed to remove file: %s", err)
   206  	}
   207  
   208  	if err = os.Remove("/tmp/fileLinkTest"); err != nil {
   209  		t.Errorf("failed to remove symlink: %s", err)
   210  	}
   211  }
   212  
   213  func TestWildcardMatches(t *testing.T) {
   214  	match, _ := Matches("fileutils.go", []string{"*"})
   215  	if !match {
   216  		t.Errorf("failed to get a wildcard match, got %v", match)
   217  	}
   218  }
   219  
   220  // A simple pattern match should return true.
   221  func TestPatternMatches(t *testing.T) {
   222  	match, _ := Matches("fileutils.go", []string{"*.go"})
   223  	if !match {
   224  		t.Errorf("failed to get a match, got %v", match)
   225  	}
   226  }
   227  
   228  // An exclusion followed by an inclusion should return true.
   229  func TestExclusionPatternMatchesPatternBefore(t *testing.T) {
   230  	match, _ := Matches("fileutils.go", []string{"!fileutils.go", "*.go"})
   231  	if !match {
   232  		t.Errorf("failed to get true match on exclusion pattern, got %v", match)
   233  	}
   234  }
   235  
   236  // A folder pattern followed by an exception should return false.
   237  func TestPatternMatchesFolderExclusions(t *testing.T) {
   238  	match, _ := Matches("docs/README.md", []string{"docs", "!docs/README.md"})
   239  	if match {
   240  		t.Errorf("failed to get a false match on exclusion pattern, got %v", match)
   241  	}
   242  }
   243  
   244  // A folder pattern followed by an exception should return false.
   245  func TestPatternMatchesFolderWithSlashExclusions(t *testing.T) {
   246  	match, _ := Matches("docs/README.md", []string{"docs/", "!docs/README.md"})
   247  	if match {
   248  		t.Errorf("failed to get a false match on exclusion pattern, got %v", match)
   249  	}
   250  }
   251  
   252  // A folder pattern followed by an exception should return false.
   253  func TestPatternMatchesFolderWildcardExclusions(t *testing.T) {
   254  	match, _ := Matches("docs/README.md", []string{"docs/*", "!docs/README.md"})
   255  	if match {
   256  		t.Errorf("failed to get a false match on exclusion pattern, got %v", match)
   257  	}
   258  }
   259  
   260  // A pattern followed by an exclusion should return false.
   261  func TestExclusionPatternMatchesPatternAfter(t *testing.T) {
   262  	match, _ := Matches("fileutils.go", []string{"*.go", "!fileutils.go"})
   263  	if match {
   264  		t.Errorf("failed to get false match on exclusion pattern, got %v", match)
   265  	}
   266  }
   267  
   268  // A filename evaluating to . should return false.
   269  func TestExclusionPatternMatchesWholeDirectory(t *testing.T) {
   270  	match, _ := Matches(".", []string{"*.go"})
   271  	if match {
   272  		t.Errorf("failed to get false match on ., got %v", match)
   273  	}
   274  }
   275  
   276  // A single ! pattern should return an error.
   277  func TestSingleExclamationError(t *testing.T) {
   278  	_, err := Matches("fileutils.go", []string{"!"})
   279  	if err == nil {
   280  		t.Errorf("failed to get an error for a single exclamation point, got %v", err)
   281  	}
   282  }
   283  
   284  // Matches with no patterns
   285  func TestMatchesWithNoPatterns(t *testing.T) {
   286  	matches, err := Matches("/any/path/there", []string{})
   287  	if err != nil {
   288  		t.Fatal(err)
   289  	}
   290  	if matches {
   291  		t.Fatalf("Should not have match anything")
   292  	}
   293  }
   294  
   295  // Matches with malformed patterns
   296  func TestMatchesWithMalformedPatterns(t *testing.T) {
   297  	matches, err := Matches("/any/path/there", []string{"["})
   298  	if err == nil {
   299  		t.Fatal("Should have failed because of a malformed syntax in the pattern")
   300  	}
   301  	if matches {
   302  		t.Fatalf("Should not have match anything")
   303  	}
   304  }
   305  
   306  type matchesTestCase struct {
   307  	pattern string
   308  	text    string
   309  	pass    bool
   310  }
   311  
   312  func TestMatches(t *testing.T) {
   313  	tests := []matchesTestCase{
   314  		{"**", "file", true},
   315  		{"**", "file/", true},
   316  		{"**/", "file", true}, // weird one
   317  		{"**/", "file/", true},
   318  		{"**", "/", true},
   319  		{"**/", "/", true},
   320  		{"**", "dir/file", true},
   321  		{"**/", "dir/file", true},
   322  		{"**", "dir/file/", true},
   323  		{"**/", "dir/file/", true},
   324  		{"**/**", "dir/file", true},
   325  		{"**/**", "dir/file/", true},
   326  		{"dir/**", "dir/file", true},
   327  		{"dir/**", "dir/file/", true},
   328  		{"dir/**", "dir/dir2/file", true},
   329  		{"dir/**", "dir/dir2/file/", true},
   330  		{"**/dir2/*", "dir/dir2/file", true},
   331  		{"**/dir2/*", "dir/dir2/file/", true},
   332  		{"**/dir2/**", "dir/dir2/dir3/file", true},
   333  		{"**/dir2/**", "dir/dir2/dir3/file/", true},
   334  		{"**file", "file", true},
   335  		{"**file", "dir/file", true},
   336  		{"**/file", "dir/file", true},
   337  		{"**file", "dir/dir/file", true},
   338  		{"**/file", "dir/dir/file", true},
   339  		{"**/file*", "dir/dir/file", true},
   340  		{"**/file*", "dir/dir/file.txt", true},
   341  		{"**/file*txt", "dir/dir/file.txt", true},
   342  		{"**/file*.txt", "dir/dir/file.txt", true},
   343  		{"**/file*.txt*", "dir/dir/file.txt", true},
   344  		{"**/**/*.txt", "dir/dir/file.txt", true},
   345  		{"**/**/*.txt2", "dir/dir/file.txt", false},
   346  		{"**/*.txt", "file.txt", true},
   347  		{"**/**/*.txt", "file.txt", true},
   348  		{"a**/*.txt", "a/file.txt", true},
   349  		{"a**/*.txt", "a/dir/file.txt", true},
   350  		{"a**/*.txt", "a/dir/dir/file.txt", true},
   351  		{"a/*.txt", "a/dir/file.txt", false},
   352  		{"a/*.txt", "a/file.txt", true},
   353  		{"a/*.txt**", "a/file.txt", true},
   354  		{"a[b-d]e", "ae", false},
   355  		{"a[b-d]e", "ace", true},
   356  		{"a[b-d]e", "aae", false},
   357  		{"a[^b-d]e", "aze", true},
   358  		{".*", ".foo", true},
   359  		{".*", "foo", false},
   360  		{"abc.def", "abcdef", false},
   361  		{"abc.def", "abc.def", true},
   362  		{"abc.def", "abcZdef", false},
   363  		{"abc?def", "abcZdef", true},
   364  		{"abc?def", "abcdef", false},
   365  		{"a\\\\", "a\\", true},
   366  		{"**/foo/bar", "foo/bar", true},
   367  		{"**/foo/bar", "dir/foo/bar", true},
   368  		{"**/foo/bar", "dir/dir2/foo/bar", true},
   369  		{"abc/**", "abc", false},
   370  		{"abc/**", "abc/def", true},
   371  		{"abc/**", "abc/def/ghi", true},
   372  		{"**/.foo", ".foo", true},
   373  		{"**/.foo", "bar.foo", false},
   374  	}
   375  
   376  	if runtime.GOOS != "windows" {
   377  		tests = append(tests, []matchesTestCase{
   378  			{"a\\*b", "a*b", true},
   379  			{"a\\", "a", false},
   380  			{"a\\", "a\\", false},
   381  		}...)
   382  	}
   383  
   384  	for _, test := range tests {
   385  		desc := fmt.Sprintf("pattern=%q text=%q", test.pattern, test.text)
   386  		pm, err := NewPatternMatcher([]string{test.pattern})
   387  		require.NoError(t, err, desc)
   388  		res, _ := pm.Matches(test.text)
   389  		assert.Equal(t, test.pass, res, desc)
   390  	}
   391  }
   392  
   393  func TestCleanPatterns(t *testing.T) {
   394  	patterns := []string{"docs", "config"}
   395  	pm, err := NewPatternMatcher(patterns)
   396  	if err != nil {
   397  		t.Fatalf("invalid pattern %v", patterns)
   398  	}
   399  	cleaned := pm.Patterns()
   400  	if len(cleaned) != 2 {
   401  		t.Errorf("expected 2 element slice, got %v", len(cleaned))
   402  	}
   403  }
   404  
   405  func TestCleanPatternsStripEmptyPatterns(t *testing.T) {
   406  	patterns := []string{"docs", "config", ""}
   407  	pm, err := NewPatternMatcher(patterns)
   408  	if err != nil {
   409  		t.Fatalf("invalid pattern %v", patterns)
   410  	}
   411  	cleaned := pm.Patterns()
   412  	if len(cleaned) != 2 {
   413  		t.Errorf("expected 2 element slice, got %v", len(cleaned))
   414  	}
   415  }
   416  
   417  func TestCleanPatternsExceptionFlag(t *testing.T) {
   418  	patterns := []string{"docs", "!docs/README.md"}
   419  	pm, err := NewPatternMatcher(patterns)
   420  	if err != nil {
   421  		t.Fatalf("invalid pattern %v", patterns)
   422  	}
   423  	if !pm.Exclusions() {
   424  		t.Errorf("expected exceptions to be true, got %v", pm.Exclusions())
   425  	}
   426  }
   427  
   428  func TestCleanPatternsLeadingSpaceTrimmed(t *testing.T) {
   429  	patterns := []string{"docs", "  !docs/README.md"}
   430  	pm, err := NewPatternMatcher(patterns)
   431  	if err != nil {
   432  		t.Fatalf("invalid pattern %v", patterns)
   433  	}
   434  	if !pm.Exclusions() {
   435  		t.Errorf("expected exceptions to be true, got %v", pm.Exclusions())
   436  	}
   437  }
   438  
   439  func TestCleanPatternsTrailingSpaceTrimmed(t *testing.T) {
   440  	patterns := []string{"docs", "!docs/README.md  "}
   441  	pm, err := NewPatternMatcher(patterns)
   442  	if err != nil {
   443  		t.Fatalf("invalid pattern %v", patterns)
   444  	}
   445  	if !pm.Exclusions() {
   446  		t.Errorf("expected exceptions to be true, got %v", pm.Exclusions())
   447  	}
   448  }
   449  
   450  func TestCleanPatternsErrorSingleException(t *testing.T) {
   451  	patterns := []string{"!"}
   452  	_, err := NewPatternMatcher(patterns)
   453  	if err == nil {
   454  		t.Errorf("expected error on single exclamation point, got %v", err)
   455  	}
   456  }
   457  
   458  func TestCreateIfNotExistsDir(t *testing.T) {
   459  	tempFolder, err := ioutil.TempDir("", "docker-fileutils-test")
   460  	if err != nil {
   461  		t.Fatal(err)
   462  	}
   463  	defer os.RemoveAll(tempFolder)
   464  
   465  	folderToCreate := filepath.Join(tempFolder, "tocreate")
   466  
   467  	if err := CreateIfNotExists(folderToCreate, true); err != nil {
   468  		t.Fatal(err)
   469  	}
   470  	fileinfo, err := os.Stat(folderToCreate)
   471  	if err != nil {
   472  		t.Fatalf("Should have create a folder, got %v", err)
   473  	}
   474  
   475  	if !fileinfo.IsDir() {
   476  		t.Fatalf("Should have been a dir, seems it's not")
   477  	}
   478  }
   479  
   480  func TestCreateIfNotExistsFile(t *testing.T) {
   481  	tempFolder, err := ioutil.TempDir("", "docker-fileutils-test")
   482  	if err != nil {
   483  		t.Fatal(err)
   484  	}
   485  	defer os.RemoveAll(tempFolder)
   486  
   487  	fileToCreate := filepath.Join(tempFolder, "file/to/create")
   488  
   489  	if err := CreateIfNotExists(fileToCreate, false); err != nil {
   490  		t.Fatal(err)
   491  	}
   492  	fileinfo, err := os.Stat(fileToCreate)
   493  	if err != nil {
   494  		t.Fatalf("Should have create a file, got %v", err)
   495  	}
   496  
   497  	if fileinfo.IsDir() {
   498  		t.Fatalf("Should have been a file, seems it's not")
   499  	}
   500  }
   501  
   502  // These matchTests are stolen from go's filepath Match tests.
   503  type matchTest struct {
   504  	pattern, s string
   505  	match      bool
   506  	err        error
   507  }
   508  
   509  var matchTests = []matchTest{
   510  	{"abc", "abc", true, nil},
   511  	{"*", "abc", true, nil},
   512  	{"*c", "abc", true, nil},
   513  	{"a*", "a", true, nil},
   514  	{"a*", "abc", true, nil},
   515  	{"a*", "ab/c", true, nil},
   516  	{"a*/b", "abc/b", true, nil},
   517  	{"a*/b", "a/c/b", false, nil},
   518  	{"a*b*c*d*e*/f", "axbxcxdxe/f", true, nil},
   519  	{"a*b*c*d*e*/f", "axbxcxdxexxx/f", true, nil},
   520  	{"a*b*c*d*e*/f", "axbxcxdxe/xxx/f", false, nil},
   521  	{"a*b*c*d*e*/f", "axbxcxdxexxx/fff", false, nil},
   522  	{"a*b?c*x", "abxbbxdbxebxczzx", true, nil},
   523  	{"a*b?c*x", "abxbbxdbxebxczzy", false, nil},
   524  	{"ab[c]", "abc", true, nil},
   525  	{"ab[b-d]", "abc", true, nil},
   526  	{"ab[e-g]", "abc", false, nil},
   527  	{"ab[^c]", "abc", false, nil},
   528  	{"ab[^b-d]", "abc", false, nil},
   529  	{"ab[^e-g]", "abc", true, nil},
   530  	{"a\\*b", "a*b", true, nil},
   531  	{"a\\*b", "ab", false, nil},
   532  	{"a?b", "a☺b", true, nil},
   533  	{"a[^a]b", "a☺b", true, nil},
   534  	{"a???b", "a☺b", false, nil},
   535  	{"a[^a][^a][^a]b", "a☺b", false, nil},
   536  	{"[a-ζ]*", "α", true, nil},
   537  	{"*[a-ζ]", "A", false, nil},
   538  	{"a?b", "a/b", false, nil},
   539  	{"a*b", "a/b", false, nil},
   540  	{"[\\]a]", "]", true, nil},
   541  	{"[\\-]", "-", true, nil},
   542  	{"[x\\-]", "x", true, nil},
   543  	{"[x\\-]", "-", true, nil},
   544  	{"[x\\-]", "z", false, nil},
   545  	{"[\\-x]", "x", true, nil},
   546  	{"[\\-x]", "-", true, nil},
   547  	{"[\\-x]", "a", false, nil},
   548  	{"[]a]", "]", false, filepath.ErrBadPattern},
   549  	{"[-]", "-", false, filepath.ErrBadPattern},
   550  	{"[x-]", "x", false, filepath.ErrBadPattern},
   551  	{"[x-]", "-", false, filepath.ErrBadPattern},
   552  	{"[x-]", "z", false, filepath.ErrBadPattern},
   553  	{"[-x]", "x", false, filepath.ErrBadPattern},
   554  	{"[-x]", "-", false, filepath.ErrBadPattern},
   555  	{"[-x]", "a", false, filepath.ErrBadPattern},
   556  	{"\\", "a", false, filepath.ErrBadPattern},
   557  	{"[a-b-c]", "a", false, filepath.ErrBadPattern},
   558  	{"[", "a", false, filepath.ErrBadPattern},
   559  	{"[^", "a", false, filepath.ErrBadPattern},
   560  	{"[^bc", "a", false, filepath.ErrBadPattern},
   561  	{"a[", "a", false, filepath.ErrBadPattern}, // was nil but IMO its wrong
   562  	{"a[", "ab", false, filepath.ErrBadPattern},
   563  	{"*x", "xxx", true, nil},
   564  }
   565  
   566  func errp(e error) string {
   567  	if e == nil {
   568  		return "<nil>"
   569  	}
   570  	return e.Error()
   571  }
   572  
   573  // TestMatch test's our version of filepath.Match, called regexpMatch.
   574  func TestMatch(t *testing.T) {
   575  	for _, tt := range matchTests {
   576  		pattern := tt.pattern
   577  		s := tt.s
   578  		if runtime.GOOS == "windows" {
   579  			if strings.Contains(pattern, "\\") {
   580  				// no escape allowed on windows.
   581  				continue
   582  			}
   583  			pattern = filepath.Clean(pattern)
   584  			s = filepath.Clean(s)
   585  		}
   586  		ok, err := Matches(s, []string{pattern})
   587  		if ok != tt.match || err != tt.err {
   588  			t.Fatalf("Match(%#q, %#q) = %v, %q want %v, %q", pattern, s, ok, errp(err), tt.match, errp(tt.err))
   589  		}
   590  	}
   591  }