| Index: client/cipd/internal/instancecache_test.go
|
| diff --git a/client/cipd/internal/instancecache_test.go b/client/cipd/internal/instancecache_test.go
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e7625d7ee0c4fbcfa2cc06547a842dcd0143492f
|
| --- /dev/null
|
| +++ b/client/cipd/internal/instancecache_test.go
|
| @@ -0,0 +1,138 @@
|
| +// Copyright 2015 The Chromium 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 internal
|
| +
|
| +import (
|
| + "bytes"
|
| + "fmt"
|
| + "io/ioutil"
|
| + "os"
|
| + "testing"
|
| + "time"
|
| +
|
| + "github.com/luci/luci-go/client/cipd/common"
|
| + "github.com/luci/luci-go/client/cipd/local"
|
| +
|
| + "path/filepath"
|
| + "strings"
|
| +
|
| + . "github.com/smartystreets/goconvey/convey"
|
| +)
|
| +
|
| +func TestInstanceCache(t *testing.T) {
|
| + Convey("InstanceCache", t, func(c C) {
|
| + tempDir, err := ioutil.TempDir("", "instanceche_test")
|
| + So(err, ShouldBeNil)
|
| + defer os.RemoveAll(tempDir)
|
| +
|
| + now := time.Date(2016, 1, 2, 3, 4, 5, 6, time.UTC)
|
| +
|
| + fs := local.NewFileSystem(tempDir, nil)
|
| + cache := NewInstanceCache(fs, nil)
|
| +
|
| + put := func(cache *InstanceCache, pin common.Pin, data string) {
|
| + err = cache.Put(pin, now, func(f *os.File) error {
|
| + _, err := f.WriteString(data)
|
| + So(err, ShouldBeNil)
|
| + return nil
|
| + })
|
| + So(err, ShouldBeNil)
|
| + }
|
| +
|
| + testHas := func(cache *InstanceCache, pin common.Pin, data string) {
|
| + buf := &bytes.Buffer{}
|
| + err = cache.Get(pin, buf, now)
|
| + So(err, ShouldBeNil)
|
| + So(buf.String(), ShouldEqual, data)
|
| + }
|
| +
|
| + Convey("Works", func() {
|
| + cache2 := NewInstanceCache(fs, nil)
|
| +
|
| + pin := common.Pin{"pkg", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}
|
| + err := cache.Get(pin, ioutil.Discard, now)
|
| + So(os.IsNotExist(err), ShouldBeTrue)
|
| +
|
| + // Add new.
|
| + put(cache, pin, "blah")
|
| + testHas(cache, pin, "blah")
|
| + testHas(cache2, pin, "blah")
|
| +
|
| + // Replace existing.
|
| + put(cache, pin, "huh")
|
| + testHas(cache, pin, "huh")
|
| + testHas(cache2, pin, "huh")
|
| + })
|
| +
|
| + pini := func(i int) common.Pin {
|
| + pin := common.Pin{"pkg", fmt.Sprintf("%d", i)}
|
| + pin.InstanceID = strings.Repeat("a", 40-len(pin.InstanceID)) + pin.InstanceID
|
| + return pin
|
| + }
|
| +
|
| + Convey("GC", func() {
|
| + // Add twice more the limit.
|
| + for i := 0; i < instanceCacheMaxSize*2; i++ {
|
| + put(cache, pini(i), "blah")
|
| + now = now.Add(time.Second)
|
| + }
|
| +
|
| + // Check the number of actual files.
|
| + tempDirFile, err := os.Open(tempDir)
|
| + So(err, ShouldBeNil)
|
| +
|
| + files, err := tempDirFile.Readdirnames(0)
|
| + So(err, ShouldBeNil)
|
| + So(files, ShouldHaveLength, instanceCacheMaxSize+1) // 1 for state.db
|
| +
|
| + // Try to get.
|
| + for i := 0; i < instanceCacheMaxSize*2; i++ {
|
| + err := cache.Get(pini(i), ioutil.Discard, now)
|
| + So(os.IsNotExist(err), ShouldEqual, i < instanceCacheMaxSize)
|
| + }
|
| +
|
| + })
|
| +
|
| + Convey("Sync", func() {
|
| + stateDbPath := filepath.Join(tempDir, instanceCacheStateFilename)
|
| + const count = 10
|
| +
|
| + testSync := func(causeResync func()) {
|
| + // Add instances.
|
| + for i := 0; i < count; i++ {
|
| + put(cache, pini(i), "blah")
|
| + }
|
| +
|
| + causeResync()
|
| +
|
| + // state.db must be restored.
|
| + for i := 0; i < count; i++ {
|
| + lastAccess, ok := cache.getAccessTime(now, pini(i))
|
| + So(ok, ShouldBeTrue)
|
| + So(lastAccess.IsZero(), ShouldBeTrue)
|
| + }
|
| +
|
| + _, ok := cache.getAccessTime(now, common.Pin{"nonexistent", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"})
|
| + So(ok, ShouldBeFalse)
|
| + }
|
| +
|
| + Convey("state.db disappeared", func() {
|
| + testSync(func() {
|
| + err := os.Remove(stateDbPath)
|
| + So(err, ShouldBeNil)
|
| + })
|
| + })
|
| +
|
| + Convey("state.db corrupted", func() {
|
| + testSync(func() {
|
| + f, err := os.Create(stateDbPath)
|
| + So(err, ShouldBeNil)
|
| + f.WriteString("blah")
|
| + defer f.Close()
|
| + })
|
| + })
|
| + })
|
| + })
|
| +}
|
|
|