mirror of https://github.com/golang/go.git
121 lines
3.0 KiB
Go
121 lines
3.0 KiB
Go
// Copyright 2021 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package fstest
|
|
|
|
import (
|
|
"errors"
|
|
"internal/testenv"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestSymlink(t *testing.T) {
|
|
testenv.MustHaveSymlink(t)
|
|
|
|
tmp := t.TempDir()
|
|
tmpfs := os.DirFS(tmp)
|
|
|
|
if err := os.WriteFile(filepath.Join(tmp, "hello"), []byte("hello, world\n"), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := os.Symlink(filepath.Join(tmp, "hello"), filepath.Join(tmp, "hello.link")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Symlink("hello", filepath.Join(tmp, "hello_rel.link")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := TestFS(tmpfs, "hello", "hello.link"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestDash(t *testing.T) {
|
|
m := MapFS{
|
|
"a-b/a": {Data: []byte("a-b/a")},
|
|
}
|
|
if err := TestFS(m, "a-b/a"); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
type shuffledFS MapFS
|
|
|
|
func (fsys shuffledFS) Open(name string) (fs.File, error) {
|
|
f, err := MapFS(fsys).Open(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &shuffledFile{File: f}, nil
|
|
}
|
|
|
|
type shuffledFile struct{ fs.File }
|
|
|
|
func (f *shuffledFile) ReadDir(n int) ([]fs.DirEntry, error) {
|
|
dirents, err := f.File.(fs.ReadDirFile).ReadDir(n)
|
|
// Shuffle in a deterministic way, all we care about is making sure that the
|
|
// list of directory entries is not is the lexicographic order.
|
|
//
|
|
// We do this to make sure that the TestFS test suite is not affected by the
|
|
// order of directory entries.
|
|
slices.SortFunc(dirents, func(a, b fs.DirEntry) int {
|
|
return strings.Compare(b.Name(), a.Name())
|
|
})
|
|
return dirents, err
|
|
}
|
|
|
|
func TestShuffledFS(t *testing.T) {
|
|
fsys := shuffledFS{
|
|
"tmp/one": {Data: []byte("1")},
|
|
"tmp/two": {Data: []byte("2")},
|
|
"tmp/three": {Data: []byte("3")},
|
|
}
|
|
if err := TestFS(fsys, "tmp/one", "tmp/two", "tmp/three"); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// failPermFS is a filesystem that always fails with fs.ErrPermission.
|
|
type failPermFS struct{}
|
|
|
|
func (f failPermFS) Open(name string) (fs.File, error) {
|
|
if !fs.ValidPath(name) {
|
|
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrInvalid}
|
|
}
|
|
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrPermission}
|
|
}
|
|
|
|
func TestTestFSWrappedErrors(t *testing.T) {
|
|
err := TestFS(failPermFS{})
|
|
if err == nil {
|
|
t.Fatal("error expected")
|
|
}
|
|
t.Logf("Error (expecting wrapped fs.ErrPermission):\n%v", err)
|
|
|
|
if !errors.Is(err, fs.ErrPermission) {
|
|
t.Errorf("error should be a wrapped ErrPermission: %#v", err)
|
|
}
|
|
|
|
// TestFS is expected to return a list of errors.
|
|
// Enforce that the list can be extracted for browsing.
|
|
var errs interface{ Unwrap() []error }
|
|
if !errors.As(err, &errs) {
|
|
t.Errorf("caller should be able to extract the errors as a list: %#v", err)
|
|
} else {
|
|
for _, err := range errs.Unwrap() {
|
|
// ErrPermission is expected
|
|
// but any other error must be reported.
|
|
if !errors.Is(err, fs.ErrPermission) {
|
|
t.Errorf("unexpected error: %v", err)
|
|
}
|
|
}
|
|
}
|
|
}
|