2018-02-05 16:05:59 -05:00
|
|
|
package fscache // import "github.com/docker/docker/builder/fscache"
|
2017-05-15 17:54:27 -04:00
|
|
|
|
|
|
|
import (
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2018-03-13 15:28:34 -04:00
|
|
|
"github.com/gotestyourself/gotestyourself/assert"
|
|
|
|
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
2017-07-28 19:04:34 -04:00
|
|
|
"github.com/moby/buildkit/session/filesync"
|
2017-05-15 17:54:27 -04:00
|
|
|
"golang.org/x/net/context"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestFSCache(t *testing.T) {
|
|
|
|
tmpDir, err := ioutil.TempDir("", "fscache")
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
2017-05-15 17:54:27 -04:00
|
|
|
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)
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
2017-05-15 17:54:27 -04:00
|
|
|
|
|
|
|
defer fscache.Close()
|
|
|
|
|
|
|
|
err = fscache.RegisterTransport("test", &testTransport{})
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
2017-05-15 17:54:27 -04:00
|
|
|
|
|
|
|
src1, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo", "data", "bar"})
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
2017-05-15 17:54:27 -04:00
|
|
|
|
2017-08-03 20:22:00 -04:00
|
|
|
dt, err := ioutil.ReadFile(filepath.Join(src1.Root().Path(), "foo"))
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal(string(dt), "data"))
|
2017-05-15 17:54:27 -04:00
|
|
|
|
|
|
|
// same id doesn't recalculate anything
|
|
|
|
src2, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo", "data2", "bar"})
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal(src1.Root().Path(), src2.Root().Path()))
|
2017-05-15 17:54:27 -04:00
|
|
|
|
2017-08-03 20:22:00 -04:00
|
|
|
dt, err = ioutil.ReadFile(filepath.Join(src1.Root().Path(), "foo"))
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal(string(dt), "data"))
|
|
|
|
assert.Check(t, src2.Close())
|
2017-05-15 17:54:27 -04:00
|
|
|
|
|
|
|
src3, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo2", "data2", "bar"})
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, src1.Root().Path() != src3.Root().Path())
|
2017-05-15 17:54:27 -04:00
|
|
|
|
2017-08-03 20:22:00 -04:00
|
|
|
dt, err = ioutil.ReadFile(filepath.Join(src3.Root().Path(), "foo2"))
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal(string(dt), "data2"))
|
2017-05-15 17:54:27 -04:00
|
|
|
|
2018-03-29 11:34:58 -04:00
|
|
|
s, err := fscache.DiskUsage(context.TODO())
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal(s, int64(0)))
|
2017-05-15 17:54:27 -04:00
|
|
|
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, src3.Close())
|
2017-05-15 17:54:27 -04:00
|
|
|
|
2018-03-29 11:34:58 -04:00
|
|
|
s, err = fscache.DiskUsage(context.TODO())
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal(s, int64(5)))
|
2017-05-15 17:54:27 -04:00
|
|
|
|
|
|
|
// new upload with the same shared key shoutl overwrite
|
|
|
|
src4, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo3", "data3", "bar"})
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, src1.Root().Path() != src3.Root().Path())
|
2017-05-15 17:54:27 -04:00
|
|
|
|
2017-08-03 20:22:00 -04:00
|
|
|
dt, err = ioutil.ReadFile(filepath.Join(src3.Root().Path(), "foo3"))
|
2018-03-13 15:28:34 -04:00
|
|
|
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())
|
2017-05-15 17:54:27 -04:00
|
|
|
|
2018-03-29 11:34:58 -04:00
|
|
|
s, err = fscache.DiskUsage(context.TODO())
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal(s, int64(10)))
|
2017-05-15 17:54:27 -04:00
|
|
|
|
|
|
|
// this one goes over the GC limit
|
|
|
|
src5, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo4", "datadata", "baz"})
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, src5.Close())
|
2017-05-15 17:54:27 -04:00
|
|
|
|
|
|
|
// GC happens async
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
|
|
|
|
// only last insertion after GC
|
2018-03-29 11:34:58 -04:00
|
|
|
s, err = fscache.DiskUsage(context.TODO())
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal(s, int64(8)))
|
2017-05-15 17:54:27 -04:00
|
|
|
|
|
|
|
// prune deletes everything
|
2017-07-06 04:47:21 -04:00
|
|
|
released, err := fscache.Prune(context.TODO())
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal(released, uint64(8)))
|
2017-05-15 17:54:27 -04:00
|
|
|
|
2018-03-29 11:34:58 -04:00
|
|
|
s, err = fscache.DiskUsage(context.TODO())
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal(s, int64(0)))
|
2017-05-15 17:54:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
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"
|
|
|
|
}
|