lib/fs, lib/api, lib/model: Expose mtime remappings as part of /db/file (#7624)
* lib/fs, lib/api, lib/model: Expose mtime remappings as part of /db/file * Fix wrong error returned by CLI * Gofmt * Better names * Review comments * Review comments
This commit is contained in:
+57
-49
@@ -27,7 +27,7 @@ import (
|
||||
// see readShortAt()
|
||||
const randomBlockShift = 14 // 128k
|
||||
|
||||
// fakefs is a fake filesystem for testing and benchmarking. It has the
|
||||
// fakeFS is a fake filesystem for testing and benchmarking. It has the
|
||||
// following properties:
|
||||
//
|
||||
// - File metadata is kept in RAM. Specifically, we remember which files and
|
||||
@@ -37,7 +37,7 @@ const randomBlockShift = 14 // 128k
|
||||
// - File contents are generated pseudorandomly with just the file name as
|
||||
// seed. Writes are discarded, other than having the effect of increasing
|
||||
// the file size. If you only write data that you've read from a file with
|
||||
// the same name on a different fakefs, you'll never know the difference...
|
||||
// the same name on a different fakeFS, you'll never know the difference...
|
||||
//
|
||||
// - We totally ignore permissions - pretend you are root.
|
||||
//
|
||||
@@ -51,10 +51,10 @@ const randomBlockShift = 14 // 128k
|
||||
// insens=b "true" makes filesystem case-insensitive Windows- or OSX-style (default false)
|
||||
// latency=d to set the amount of time each "disk" operation takes, where d is time.ParseDuration format
|
||||
//
|
||||
// - Two fakefs:s pointing at the same root path see the same files.
|
||||
// - Two fakeFS:s pointing at the same root path see the same files.
|
||||
//
|
||||
type fakefs struct {
|
||||
counters fakefsCounters
|
||||
type fakeFS struct {
|
||||
counters fakeFSCounters
|
||||
uri string
|
||||
mut sync.Mutex
|
||||
root *fakeEntry
|
||||
@@ -63,7 +63,7 @@ type fakefs struct {
|
||||
latency time.Duration
|
||||
}
|
||||
|
||||
type fakefsCounters struct {
|
||||
type fakeFSCounters struct {
|
||||
Chmod int64
|
||||
Lchown int64
|
||||
Chtimes int64
|
||||
@@ -81,13 +81,13 @@ type fakefsCounters struct {
|
||||
}
|
||||
|
||||
var (
|
||||
fakefsMut sync.Mutex
|
||||
fakefsFs = make(map[string]*fakefs)
|
||||
fakeFSMut sync.Mutex
|
||||
fakeFSCache = make(map[string]*fakeFS)
|
||||
)
|
||||
|
||||
func newFakeFilesystem(rootURI string, _ ...Option) *fakefs {
|
||||
fakefsMut.Lock()
|
||||
defer fakefsMut.Unlock()
|
||||
func newFakeFilesystem(rootURI string, _ ...Option) *fakeFS {
|
||||
fakeFSMut.Lock()
|
||||
defer fakeFSMut.Unlock()
|
||||
|
||||
root := rootURI
|
||||
var params url.Values
|
||||
@@ -97,12 +97,12 @@ func newFakeFilesystem(rootURI string, _ ...Option) *fakefs {
|
||||
params = uri.Query()
|
||||
}
|
||||
|
||||
if fs, ok := fakefsFs[rootURI]; ok {
|
||||
if fs, ok := fakeFSCache[rootURI]; ok {
|
||||
// Already have an fs at this path
|
||||
return fs
|
||||
}
|
||||
|
||||
fs := &fakefs{
|
||||
fs := &fakeFS{
|
||||
uri: "fake://" + rootURI,
|
||||
root: &fakeEntry{
|
||||
name: "/",
|
||||
@@ -157,7 +157,7 @@ func newFakeFilesystem(rootURI string, _ ...Option) *fakefs {
|
||||
// the filesystem initially.
|
||||
fs.latency, _ = time.ParseDuration(params.Get("latency"))
|
||||
|
||||
fakefsFs[root] = fs
|
||||
fakeFSCache[root] = fs
|
||||
return fs
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ type fakeEntry struct {
|
||||
content []byte
|
||||
}
|
||||
|
||||
func (fs *fakefs) entryForName(name string) *fakeEntry {
|
||||
func (fs *fakeFS) entryForName(name string) *fakeEntry {
|
||||
// bug: lookup doesn't work through symlinks.
|
||||
if fs.insens {
|
||||
name = UnicodeLowercase(name)
|
||||
@@ -210,7 +210,7 @@ func (fs *fakefs) entryForName(name string) *fakeEntry {
|
||||
return entry
|
||||
}
|
||||
|
||||
func (fs *fakefs) Chmod(name string, mode FileMode) error {
|
||||
func (fs *fakeFS) Chmod(name string, mode FileMode) error {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.Chmod++
|
||||
@@ -223,7 +223,7 @@ func (fs *fakefs) Chmod(name string, mode FileMode) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Lchown(name string, uid, gid int) error {
|
||||
func (fs *fakeFS) Lchown(name string, uid, gid int) error {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.Lchown++
|
||||
@@ -237,7 +237,7 @@ func (fs *fakefs) Lchown(name string, uid, gid int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Chtimes(name string, atime time.Time, mtime time.Time) error {
|
||||
func (fs *fakeFS) Chtimes(name string, atime time.Time, mtime time.Time) error {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.Chtimes++
|
||||
@@ -250,7 +250,7 @@ func (fs *fakefs) Chtimes(name string, atime time.Time, mtime time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) create(name string) (*fakeEntry, error) {
|
||||
func (fs *fakeFS) create(name string) (*fakeEntry, error) {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.Create++
|
||||
@@ -296,7 +296,7 @@ func (fs *fakefs) create(name string) (*fakeEntry, error) {
|
||||
return new, nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Create(name string) (File, error) {
|
||||
func (fs *fakeFS) Create(name string) (File, error) {
|
||||
entry, err := fs.create(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -307,7 +307,7 @@ func (fs *fakefs) Create(name string) (File, error) {
|
||||
return &fakeFile{fakeEntry: entry}, nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) CreateSymlink(target, name string) error {
|
||||
func (fs *fakeFS) CreateSymlink(target, name string) error {
|
||||
entry, err := fs.create(name)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -317,7 +317,7 @@ func (fs *fakefs) CreateSymlink(target, name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) DirNames(name string) ([]string, error) {
|
||||
func (fs *fakeFS) DirNames(name string) ([]string, error) {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.DirNames++
|
||||
@@ -336,7 +336,7 @@ func (fs *fakefs) DirNames(name string) ([]string, error) {
|
||||
return names, nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Lstat(name string) (FileInfo, error) {
|
||||
func (fs *fakeFS) Lstat(name string) (FileInfo, error) {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.Lstat++
|
||||
@@ -355,7 +355,7 @@ func (fs *fakefs) Lstat(name string) (FileInfo, error) {
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Mkdir(name string, perm FileMode) error {
|
||||
func (fs *fakeFS) Mkdir(name string, perm FileMode) error {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.Mkdir++
|
||||
@@ -389,7 +389,7 @@ func (fs *fakefs) Mkdir(name string, perm FileMode) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) MkdirAll(name string, perm FileMode) error {
|
||||
func (fs *fakeFS) MkdirAll(name string, perm FileMode) error {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.MkdirAll++
|
||||
@@ -426,7 +426,7 @@ func (fs *fakefs) MkdirAll(name string, perm FileMode) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Open(name string) (File, error) {
|
||||
func (fs *fakeFS) Open(name string) (File, error) {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.Open++
|
||||
@@ -443,7 +443,7 @@ func (fs *fakefs) Open(name string) (File, error) {
|
||||
return &fakeFile{fakeEntry: entry}, nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) OpenFile(name string, flags int, mode FileMode) (File, error) {
|
||||
func (fs *fakeFS) OpenFile(name string, flags int, mode FileMode) (File, error) {
|
||||
if flags&os.O_CREATE == 0 {
|
||||
return fs.Open(name)
|
||||
}
|
||||
@@ -486,7 +486,7 @@ func (fs *fakefs) OpenFile(name string, flags int, mode FileMode) (File, error)
|
||||
return &fakeFile{fakeEntry: newEntry}, nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) ReadSymlink(name string) (string, error) {
|
||||
func (fs *fakeFS) ReadSymlink(name string) (string, error) {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.ReadSymlink++
|
||||
@@ -501,7 +501,7 @@ func (fs *fakefs) ReadSymlink(name string) (string, error) {
|
||||
return entry.dest, nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Remove(name string) error {
|
||||
func (fs *fakeFS) Remove(name string) error {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.Remove++
|
||||
@@ -524,7 +524,7 @@ func (fs *fakefs) Remove(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) RemoveAll(name string) error {
|
||||
func (fs *fakeFS) RemoveAll(name string) error {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.RemoveAll++
|
||||
@@ -536,7 +536,7 @@ func (fs *fakefs) RemoveAll(name string) error {
|
||||
|
||||
entry := fs.entryForName(filepath.Dir(name))
|
||||
if entry == nil {
|
||||
return nil // all tested real systems exibit this behaviour
|
||||
return nil // all tested real systems exhibit this behaviour
|
||||
}
|
||||
|
||||
// RemoveAll is easy when the file system uses garbage collection under
|
||||
@@ -545,7 +545,7 @@ func (fs *fakefs) RemoveAll(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Rename(oldname, newname string) error {
|
||||
func (fs *fakeFS) Rename(oldname, newname string) error {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
fs.counters.Rename++
|
||||
@@ -595,56 +595,56 @@ func (fs *fakefs) Rename(oldname, newname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Stat(name string) (FileInfo, error) {
|
||||
func (fs *fakeFS) Stat(name string) (FileInfo, error) {
|
||||
return fs.Lstat(name)
|
||||
}
|
||||
|
||||
func (fs *fakefs) SymlinksSupported() bool {
|
||||
func (fs *fakeFS) SymlinksSupported() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (fs *fakefs) Walk(name string, walkFn WalkFunc) error {
|
||||
func (fs *fakeFS) Walk(name string, walkFn WalkFunc) error {
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (fs *fakefs) Watch(path string, ignore Matcher, ctx context.Context, ignorePerms bool) (<-chan Event, <-chan error, error) {
|
||||
func (fs *fakeFS) Watch(path string, ignore Matcher, ctx context.Context, ignorePerms bool) (<-chan Event, <-chan error, error) {
|
||||
return nil, nil, ErrWatchNotSupported
|
||||
}
|
||||
|
||||
func (fs *fakefs) Hide(name string) error {
|
||||
func (fs *fakeFS) Hide(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Unhide(name string) error {
|
||||
func (fs *fakeFS) Unhide(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Glob(pattern string) ([]string, error) {
|
||||
func (fs *fakeFS) Glob(pattern string) ([]string, error) {
|
||||
// gnnh we don't seem to actually require this in practice
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (fs *fakefs) Roots() ([]string, error) {
|
||||
func (fs *fakeFS) Roots() ([]string, error) {
|
||||
return []string{"/"}, nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) Usage(name string) (Usage, error) {
|
||||
func (fs *fakeFS) Usage(name string) (Usage, error) {
|
||||
return Usage{}, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (fs *fakefs) Type() FilesystemType {
|
||||
func (fs *fakeFS) Type() FilesystemType {
|
||||
return FilesystemTypeFake
|
||||
}
|
||||
|
||||
func (fs *fakefs) URI() string {
|
||||
func (fs *fakeFS) URI() string {
|
||||
return fs.uri
|
||||
}
|
||||
|
||||
func (fs *fakefs) Options() []Option {
|
||||
func (fs *fakeFS) Options() []Option {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *fakefs) SameFile(fi1, fi2 FileInfo) bool {
|
||||
func (fs *fakeFS) SameFile(fi1, fi2 FileInfo) bool {
|
||||
// BUG: real systems base file sameness on path, inodes, etc
|
||||
// we try our best, but FileInfo just doesn't have enough data
|
||||
// so there be false positives, especially on Windows
|
||||
@@ -659,17 +659,25 @@ func (fs *fakefs) SameFile(fi1, fi2 FileInfo) bool {
|
||||
return ok && fi1.ModTime().Equal(fi2.ModTime()) && fi1.Mode() == fi2.Mode() && fi1.IsDir() == fi2.IsDir() && fi1.IsRegular() == fi2.IsRegular() && fi1.IsSymlink() == fi2.IsSymlink() && fi1.Owner() == fi2.Owner() && fi1.Group() == fi2.Group()
|
||||
}
|
||||
|
||||
func (fs *fakefs) resetCounters() {
|
||||
func (fs *fakeFS) underlying() (Filesystem, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (fs *fakeFS) wrapperType() filesystemWrapperType {
|
||||
return filesystemWrapperTypeNone
|
||||
}
|
||||
|
||||
func (fs *fakeFS) resetCounters() {
|
||||
fs.mut.Lock()
|
||||
fs.counters = fakefsCounters{}
|
||||
fs.counters = fakeFSCounters{}
|
||||
fs.mut.Unlock()
|
||||
}
|
||||
|
||||
func (fs *fakefs) reportMetricsPerOp(b *testing.B) {
|
||||
func (fs *fakeFS) reportMetricsPerOp(b *testing.B) {
|
||||
fs.reportMetricsPer(b, 1, "op")
|
||||
}
|
||||
|
||||
func (fs *fakefs) reportMetricsPer(b *testing.B, divisor float64, unit string) {
|
||||
func (fs *fakeFS) reportMetricsPer(b *testing.B, divisor float64, unit string) {
|
||||
fs.mut.Lock()
|
||||
defer fs.mut.Unlock()
|
||||
b.ReportMetric(float64(fs.counters.Lstat)/divisor/float64(b.N), "Lstat/"+unit)
|
||||
|
||||
Reference in New Issue
Block a user