tailfs: clean up naming and package structure
- Restyles tailfs -> tailFS - Defines interfaces for main TailFS types - Moves implemenatation of TailFS into tailfsimpl package Updates tailscale/corp#16827 Signed-off-by: Percy Wegmann <percy@tailscale.com>
This commit is contained in:

committed by
Percy Wegmann

parent
79b547804b
commit
abab0d4197
104
tailfs/tailfsimpl/webdavfs/stat_cache_test.go
Normal file
104
tailfs/tailfsimpl/webdavfs/stat_cache_test.go
Normal file
@ -0,0 +1,104 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package webdavfs
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"tailscale.com/tailfs/tailfsimpl/shared"
|
||||
"tailscale.com/tstest"
|
||||
)
|
||||
|
||||
func TestStatCache(t *testing.T) {
|
||||
// Make sure we don't leak goroutines
|
||||
tstest.ResourceCheck(t)
|
||||
|
||||
dir, err := os.MkdirTemp("", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// create file of size 1
|
||||
filename := filepath.Join(dir, "thefile")
|
||||
err = os.WriteFile(filename, []byte("1"), 0644)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stat := func(name string) (os.FileInfo, error) {
|
||||
return os.Stat(name)
|
||||
}
|
||||
ttl := 1 * time.Second
|
||||
c := newStatCache(ttl)
|
||||
|
||||
// fetch new stat
|
||||
fi, err := c.getOrFetch(filename, stat)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if fi.Size() != 1 {
|
||||
t.Errorf("got size %d, want 1", fi.Size())
|
||||
}
|
||||
// save original FileInfo as a StaticFileInfo so we can reuse it later
|
||||
// without worrying about the underlying FileInfo changing.
|
||||
originalFI := &shared.StaticFileInfo{
|
||||
Named: fi.Name(),
|
||||
Sized: fi.Size(),
|
||||
Moded: fi.Mode(),
|
||||
ModdedTime: fi.ModTime(),
|
||||
Dir: fi.IsDir(),
|
||||
}
|
||||
|
||||
// update file to size 2
|
||||
err = os.WriteFile(filename, []byte("12"), 0644)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// fetch stat again, should still be cached
|
||||
fi, err = c.getOrFetch(filename, stat)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if fi.Size() != 1 {
|
||||
t.Errorf("got size %d, want 1", fi.Size())
|
||||
}
|
||||
|
||||
// wait for cache to expire and refetch stat, size should reflect new size
|
||||
time.Sleep(ttl * 2)
|
||||
|
||||
fi, err = c.getOrFetch(filename, stat)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if fi.Size() != 2 {
|
||||
t.Errorf("got size %d, want 2", fi.Size())
|
||||
}
|
||||
|
||||
// explicitly set the original FileInfo and make sure it's returned
|
||||
c.set(dir, []fs.FileInfo{originalFI})
|
||||
fi, err = c.getOrFetch(filename, stat)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if fi.Size() != 1 {
|
||||
t.Errorf("got size %d, want 1", fi.Size())
|
||||
}
|
||||
|
||||
// invalidate the cache and make sure the new size is returned
|
||||
c.invalidate()
|
||||
fi, err = c.getOrFetch(filename, stat)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if fi.Size() != 2 {
|
||||
t.Errorf("got size %d, want 2", fi.Size())
|
||||
}
|
||||
|
||||
c.stop()
|
||||
}
|
Reference in New Issue
Block a user