3845728524
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
132 lines
3.6 KiB
Go
132 lines
3.6 KiB
Go
package fscache // import "github.com/docker/docker/builder/fscache"
|
|
|
|
import (
|
|
"context"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/moby/buildkit/session/filesync"
|
|
"gotest.tools/assert"
|
|
is "gotest.tools/assert/cmp"
|
|
)
|
|
|
|
func TestFSCache(t *testing.T) {
|
|
tmpDir, err := ioutil.TempDir("", "fscache")
|
|
assert.Check(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
backend := NewNaiveCacheBackend(filepath.Join(tmpDir, "backend"))
|
|
|
|
opt := Opt{
|
|
Root: tmpDir,
|
|
Backend: backend,
|
|
GCPolicy: GCPolicy{MaxSize: 15, MaxKeepDuration: time.Hour},
|
|
}
|
|
|
|
fscache, err := NewFSCache(opt)
|
|
assert.Check(t, err)
|
|
|
|
defer fscache.Close()
|
|
|
|
err = fscache.RegisterTransport("test", &testTransport{})
|
|
assert.Check(t, err)
|
|
|
|
src1, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo", "data", "bar"})
|
|
assert.Check(t, err)
|
|
|
|
dt, err := ioutil.ReadFile(filepath.Join(src1.Root().Path(), "foo"))
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(string(dt), "data"))
|
|
|
|
// same id doesn't recalculate anything
|
|
src2, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo", "data2", "bar"})
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(src1.Root().Path(), src2.Root().Path()))
|
|
|
|
dt, err = ioutil.ReadFile(filepath.Join(src1.Root().Path(), "foo"))
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(string(dt), "data"))
|
|
assert.Check(t, src2.Close())
|
|
|
|
src3, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo2", "data2", "bar"})
|
|
assert.Check(t, err)
|
|
assert.Check(t, src1.Root().Path() != src3.Root().Path())
|
|
|
|
dt, err = ioutil.ReadFile(filepath.Join(src3.Root().Path(), "foo2"))
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(string(dt), "data2"))
|
|
|
|
s, err := fscache.DiskUsage(context.TODO())
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(s, int64(0)))
|
|
|
|
assert.Check(t, src3.Close())
|
|
|
|
s, err = fscache.DiskUsage(context.TODO())
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(s, int64(5)))
|
|
|
|
// new upload with the same shared key shoutl overwrite
|
|
src4, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo3", "data3", "bar"})
|
|
assert.Check(t, err)
|
|
assert.Check(t, src1.Root().Path() != src3.Root().Path())
|
|
|
|
dt, err = ioutil.ReadFile(filepath.Join(src3.Root().Path(), "foo3"))
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(string(dt), "data3"))
|
|
assert.Check(t, is.Equal(src4.Root().Path(), src3.Root().Path()))
|
|
assert.Check(t, src4.Close())
|
|
|
|
s, err = fscache.DiskUsage(context.TODO())
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(s, int64(10)))
|
|
|
|
// this one goes over the GC limit
|
|
src5, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo4", "datadata", "baz"})
|
|
assert.Check(t, err)
|
|
assert.Check(t, src5.Close())
|
|
|
|
// GC happens async
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
// only last insertion after GC
|
|
s, err = fscache.DiskUsage(context.TODO())
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(s, int64(8)))
|
|
|
|
// prune deletes everything
|
|
released, err := fscache.Prune(context.TODO())
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(released, uint64(8)))
|
|
|
|
s, err = fscache.DiskUsage(context.TODO())
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(s, int64(0)))
|
|
}
|
|
|
|
type testTransport struct {
|
|
}
|
|
|
|
func (t *testTransport) Copy(ctx context.Context, id RemoteIdentifier, dest string, cs filesync.CacheUpdater) error {
|
|
testid := id.(*testIdentifier)
|
|
return ioutil.WriteFile(filepath.Join(dest, testid.filename), []byte(testid.data), 0600)
|
|
}
|
|
|
|
type testIdentifier struct {
|
|
filename string
|
|
data string
|
|
sharedKey string
|
|
}
|
|
|
|
func (t *testIdentifier) Key() string {
|
|
return t.filename
|
|
}
|
|
func (t *testIdentifier) SharedKey() string {
|
|
return t.sharedKey
|
|
}
|
|
func (t *testIdentifier) Transport() string {
|
|
return "test"
|
|
}
|