gps/filesystem_test.go
// Copyright 2017 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 gps
import (
"fmt"
"os"
"path/filepath"
"reflect"
"testing"
"github.com/golang/dep/internal/test"
)
// This file contains utilities for running tests around file system state.
type fsTestCase struct {
before, after filesystemState
}
// assert makes sure that the tc.after state matches the state of the actual host
// file system at tc.after.root.
func (tc fsTestCase) assert(t *testing.T) {
dirMap := make(map[string]bool)
fileMap := make(map[string]bool)
linkMap := make(map[string]bool)
for _, d := range tc.after.dirs {
dirMap[filepath.Join(tc.after.root, d)] = true
}
for _, f := range tc.after.files {
fileMap[filepath.Join(tc.after.root, f)] = true
}
for _, l := range tc.after.links {
linkMap[filepath.Join(tc.after.root, l.path)] = true
}
err := filepath.Walk(tc.after.root, func(path string, info os.FileInfo, err error) error {
if err != nil {
t.Errorf("filepath.Walk path=%q err=%q", path, err)
return err
}
if path == tc.after.root {
return nil
}
// Careful! Have to check whether the path is a symlink first because, on
// windows, a symlink to a directory will return 'true' for info.IsDir().
if (info.Mode() & os.ModeSymlink) != 0 {
if linkMap[path] {
delete(linkMap, path)
} else {
t.Errorf("unexpected symlink exists %q", path)
}
return nil
}
if info.IsDir() {
if dirMap[path] {
delete(dirMap, path)
} else {
t.Errorf("unexpected directory exists %q", path)
}
return nil
}
if fileMap[path] {
delete(fileMap, path)
} else {
t.Errorf("unexpected file exists %q", path)
}
return nil
})
if err != nil {
t.Errorf("filesystem.Walk err=%q", err)
}
for d := range dirMap {
t.Errorf("could not find expected directory %q", d)
}
for f := range fileMap {
t.Errorf("could not find expected file %q", f)
}
for l := range linkMap {
t.Errorf("could not find expected symlink %q", l)
}
}
// setup inflates fs onto the actual host file system at tc.before.root.
// It doesn't delete existing files and should be used on empty roots only.
func (tc fsTestCase) setup(t *testing.T) {
if err := tc.before.setup(); err != nil {
t.Fatal(err)
}
}
func TestDeriveFilesystemState(t *testing.T) {
testcases := []struct {
name string
fs fsTestCase
}{
{
name: "simple-case",
fs: fsTestCase{
before: filesystemState{
dirs: []string{
"simple-dir",
},
files: []string{
"simple-file",
},
},
after: filesystemState{
dirs: []string{
"simple-dir",
},
files: []string{
"simple-file",
},
},
},
},
{
name: "simple-symlink-case",
fs: fsTestCase{
before: filesystemState{
dirs: []string{
"simple-dir",
},
files: []string{
"simple-file",
},
links: []fsLink{
{
path: "link",
to: "nonexisting",
broken: true,
},
},
},
after: filesystemState{
dirs: []string{
"simple-dir",
},
files: []string{
"simple-file",
},
links: []fsLink{
{
path: "link",
to: "",
broken: true,
},
},
},
},
},
{
name: "complex-symlink-case",
fs: fsTestCase{
before: filesystemState{
links: []fsLink{
{
path: "link1",
to: "link2",
circular: true,
},
{
path: "link2",
to: "link1",
circular: true,
},
},
},
after: filesystemState{
links: []fsLink{
{
path: "link1",
to: "",
circular: true,
},
{
path: "link2",
to: "",
circular: true,
},
},
},
},
},
}
for _, tc := range testcases {
h := test.NewHelper(t)
h.TempDir(tc.name)
tc.fs.before.root = h.Path(tc.name)
tc.fs.after.root = h.Path(tc.name)
tc.fs.setup(t)
state, err := deriveFilesystemState(h.Path(tc.name))
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(tc.fs.after, state) {
fmt.Println(tc.fs.after)
fmt.Println(state)
t.Fatal("filesystem state mismatch")
}
h.Cleanup()
}
}