mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-28 04:28:53 -05:00
Abstract a bunch of (haphazzardly) duplicated tests into chunk_store_test
This commit is contained in:
+12
-97
@@ -6,7 +6,6 @@ import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/ref"
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
@@ -18,19 +17,28 @@ func TestAWSStoreTestSuite(t *testing.T) {
|
||||
}
|
||||
|
||||
type AWSStoreTestSuite struct {
|
||||
suite.Suite
|
||||
ChunkStoreTestSuite
|
||||
s3svc *mockS3
|
||||
store AWSStore
|
||||
}
|
||||
|
||||
func (suite *AWSStoreTestSuite) SetupTest() {
|
||||
suite.s3svc = &mockS3{data: map[string][]byte{}}
|
||||
|
||||
m := mockDDB("")
|
||||
|
||||
suite.store = AWSStore{
|
||||
"bucket",
|
||||
"table",
|
||||
suite.s3svc,
|
||||
nil,
|
||||
&m,
|
||||
}
|
||||
|
||||
suite.putCountFn = func() int {
|
||||
return suite.s3svc.numPuts
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *AWSStoreTestSuite) TearDownTest() {
|
||||
}
|
||||
|
||||
type mockS3 struct {
|
||||
@@ -64,67 +72,6 @@ func (m *mockS3) PutObject(input *s3.PutObjectInput) (*s3.PutObjectOutput, error
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (suite *AWSStoreTestSuite) TestAWSStorePut() {
|
||||
input := "abc"
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
r1 := w.Ref()
|
||||
|
||||
// See http://www.di-mgt.com.au/sha_testvectors.html
|
||||
suite.Equal("sha1-a9993e364706816aba3e25717850c26c9cd0d89d", r1.String())
|
||||
|
||||
// And reading it via the API should work...
|
||||
assertInputInStore(input, r1, suite.store, suite.Assert())
|
||||
|
||||
// Reading a non-existing ref fails
|
||||
hash := ref.NewHash()
|
||||
hash.Write([]byte("Non-existent"))
|
||||
v := suite.store.Get(ref.FromHash(hash))
|
||||
suite.Nil(v)
|
||||
|
||||
// Writing the same thing again shouldn't result in a duplicate call to AWSStore.PutObject()
|
||||
suite.Equal(1, suite.s3svc.numPuts)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *AWSStoreTestSuite) TestAWSStorePutRefAfterClose() {
|
||||
input := "abc"
|
||||
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
suite.NoError(w.Close())
|
||||
r1 := w.Ref()
|
||||
|
||||
// See http://www.di-mgt.com.au/sha_testvectors.html
|
||||
suite.Equal("sha1-a9993e364706816aba3e25717850c26c9cd0d89d", r1.String())
|
||||
|
||||
// And reading it via the API should work...
|
||||
assertInputInStore(input, r1, suite.store, suite.Assert())
|
||||
}
|
||||
|
||||
func (suite *AWSStoreTestSuite) TestAWSStorePutMultiRef() {
|
||||
input := "abc"
|
||||
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
r1 := w.Ref()
|
||||
suite.Equal(r1, w.Ref()) // calling ref again is valid, returns same value
|
||||
|
||||
// See http://www.di-mgt.com.au/sha_testvectors.html
|
||||
suite.Equal("sha1-a9993e364706816aba3e25717850c26c9cd0d89d", r1.String())
|
||||
|
||||
// And reading it via the API should work...
|
||||
assertInputInStore(input, r1, suite.store, suite.Assert())
|
||||
}
|
||||
|
||||
type mockAWSError string
|
||||
|
||||
func (m mockAWSError) Error() string { return string(m) }
|
||||
@@ -159,35 +106,3 @@ func (m *mockDDB) PutItem(input *dynamodb.PutItemInput) (*dynamodb.PutItemOutput
|
||||
*m = mockDDB(*(input.Item["hashRef"].S))
|
||||
return &dynamodb.PutItemOutput{}, nil
|
||||
}
|
||||
|
||||
func (suite *AWSStoreTestSuite) TestAWSStoreRoot() {
|
||||
m := mockDDB("")
|
||||
|
||||
suite.store = AWSStore{
|
||||
"bucket",
|
||||
"table",
|
||||
nil,
|
||||
&m,
|
||||
}
|
||||
|
||||
oldRoot := suite.store.Root()
|
||||
suite.Equal(oldRoot, ref.Ref{})
|
||||
|
||||
bogusRoot := ref.Parse("sha1-81c870618113ba29b6f2b396ea3a69c6f1d626c5") // sha1("Bogus, Dude")
|
||||
newRoot := ref.Parse("sha1-907d14fb3af2b0d4f18c2d46abe8aedce17367bd") // sha1("Hello, World")
|
||||
|
||||
// Try to update root with bogus oldRoot
|
||||
result := suite.store.UpdateRoot(newRoot, bogusRoot)
|
||||
suite.False(result)
|
||||
suite.Equal(ref.Ref{}, suite.store.Root())
|
||||
|
||||
// No do a valid update
|
||||
result = suite.store.UpdateRoot(newRoot, oldRoot)
|
||||
suite.True(result)
|
||||
suite.Equal(suite.store.Root(), newRoot)
|
||||
|
||||
// Now that there is a valid root, try to start a new lineage
|
||||
result = suite.store.UpdateRoot(bogusRoot, ref.Ref{})
|
||||
suite.False(result)
|
||||
suite.Equal(suite.store.Root(), newRoot)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
package chunks
|
||||
|
||||
import (
|
||||
"github.com/attic-labs/noms/ref"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type ChunkStoreTestSuite struct {
|
||||
suite.Suite
|
||||
store ChunkStore
|
||||
putCountFn func() int
|
||||
}
|
||||
|
||||
func (suite *ChunkStoreTestSuite) TestChunkStorePut() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
ref := w.Ref()
|
||||
|
||||
// See http://www.di-mgt.com.au/sha_testvectors.html
|
||||
suite.Equal("sha1-a9993e364706816aba3e25717850c26c9cd0d89d", ref.String())
|
||||
|
||||
// And reading it via the API should work...
|
||||
assertInputInStore(input, ref, suite.store, suite.Assert())
|
||||
if suite.putCountFn != nil {
|
||||
suite.Equal(1, suite.putCountFn())
|
||||
}
|
||||
|
||||
// Re-writing the same data should be idempotent and should not result in a second put
|
||||
w = suite.store.Put()
|
||||
_, err = w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
suite.Equal(ref, w.Ref())
|
||||
assertInputInStore(input, ref, suite.store, suite.Assert())
|
||||
|
||||
if suite.putCountFn != nil {
|
||||
suite.Equal(1, suite.putCountFn())
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ChunkStoreTestSuite) TestChunkStoreWriteAfterCloseFails() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
suite.NoError(w.Close())
|
||||
suite.Panics(func() { w.Write([]byte(input)) }, "Write() after Close() should barf!")
|
||||
}
|
||||
|
||||
func (suite *ChunkStoreTestSuite) TestChunkStoreWriteAfterRefFails() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
_ = w.Ref()
|
||||
suite.NoError(err)
|
||||
suite.Panics(func() { w.Write([]byte(input)) }, "Write() after Close() should barf!")
|
||||
}
|
||||
|
||||
func (suite *ChunkStoreTestSuite) TestChunkStorePutWithRefAfterClose() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
suite.NoError(w.Close())
|
||||
ref := w.Ref() // Ref() after Close() should work...
|
||||
|
||||
// And reading the data via the API should work...
|
||||
assertInputInStore(input, ref, suite.store, suite.Assert())
|
||||
}
|
||||
|
||||
func (suite *ChunkStoreTestSuite) TestChunkStorePutWithMultipleRef() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
w.Ref()
|
||||
ref := w.Ref() // Multiple calls to Ref() should work...
|
||||
|
||||
// And reading the data via the API should work...
|
||||
assertInputInStore(input, ref, suite.store, suite.Assert())
|
||||
}
|
||||
|
||||
func (suite *ChunkStoreTestSuite) TestChunkStoreRoot() {
|
||||
oldRoot := suite.store.Root()
|
||||
suite.Equal(oldRoot, ref.Ref{})
|
||||
|
||||
bogusRoot := ref.Parse("sha1-81c870618113ba29b6f2b396ea3a69c6f1d626c5") // sha1("Bogus, Dude")
|
||||
newRoot := ref.Parse("sha1-907d14fb3af2b0d4f18c2d46abe8aedce17367bd") // sha1("Hello, World")
|
||||
|
||||
// Try to update root with bogus oldRoot
|
||||
result := suite.store.UpdateRoot(newRoot, bogusRoot)
|
||||
suite.False(result)
|
||||
|
||||
// Now do a valid root update
|
||||
result = suite.store.UpdateRoot(newRoot, oldRoot)
|
||||
suite.True(result)
|
||||
}
|
||||
|
||||
func (suite *ChunkStoreTestSuite) TestChunkStoreGetNonExisting() {
|
||||
ref := ref.Parse("sha1-1111111111111111111111111111111111111111")
|
||||
r := suite.store.Get(ref)
|
||||
suite.Nil(r)
|
||||
}
|
||||
+14
-140
@@ -3,10 +3,8 @@ package chunks
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/ref"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
@@ -15,152 +13,28 @@ func TestFileStoreTestSuite(t *testing.T) {
|
||||
}
|
||||
|
||||
type FileStoreTestSuite struct {
|
||||
suite.Suite
|
||||
dir string
|
||||
store FileStore
|
||||
ChunkStoreTestSuite
|
||||
dir string
|
||||
putCount int
|
||||
}
|
||||
|
||||
func (suite *FileStoreTestSuite) SetupTest() {
|
||||
var err error
|
||||
suite.dir, err = ioutil.TempDir(os.TempDir(), "")
|
||||
suite.NoError(err)
|
||||
suite.store = NewFileStore(suite.dir, "root")
|
||||
|
||||
store := NewFileStore(suite.dir, "root")
|
||||
suite.putCount = 0
|
||||
store.mkdirAll = func(path string, perm os.FileMode) error {
|
||||
suite.putCount++
|
||||
return os.MkdirAll(path, perm)
|
||||
}
|
||||
suite.putCountFn = func() int {
|
||||
return suite.putCount
|
||||
}
|
||||
suite.store = store
|
||||
}
|
||||
|
||||
func (suite *FileStoreTestSuite) TearDownTest() {
|
||||
os.Remove(suite.dir)
|
||||
}
|
||||
|
||||
func (suite *FileStoreTestSuite) TestFileStorePut() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
ref := w.Ref()
|
||||
|
||||
// See http://www.di-mgt.com.au/sha_testvectors.html
|
||||
suite.Equal("sha1-a9993e364706816aba3e25717850c26c9cd0d89d", ref.String())
|
||||
|
||||
// There should also be a file there now...
|
||||
p := path.Join(suite.dir, "sha1", "a9", "99", ref.String())
|
||||
f, err := os.Open(p)
|
||||
suite.NoError(err)
|
||||
data, err := ioutil.ReadAll(f)
|
||||
suite.NoError(err)
|
||||
suite.Equal(input, string(data))
|
||||
|
||||
// And reading it via the API should work...
|
||||
assertInputInStore(input, ref, suite.store, suite.Assert())
|
||||
}
|
||||
|
||||
func (suite *FileStoreTestSuite) TestFileStoreWriteAfterCloseFails() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
suite.NoError(w.Close())
|
||||
suite.Panics(func() { w.Write([]byte(input)) }, "Write() after Close() should barf!")
|
||||
}
|
||||
|
||||
func (suite *FileStoreTestSuite) TestFileStoreWriteAfterRefFails() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
_ = w.Ref()
|
||||
suite.NoError(err)
|
||||
suite.Panics(func() { w.Write([]byte(input)) }, "Write() after Close() should barf!")
|
||||
}
|
||||
|
||||
func (suite *FileStoreTestSuite) TestFileStorePutWithRefAfterClose() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
suite.NoError(w.Close())
|
||||
ref := w.Ref() // Ref() after Close() should work...
|
||||
|
||||
// And reading the data via the API should work...
|
||||
assertInputInStore(input, ref, suite.store, suite.Assert())
|
||||
}
|
||||
|
||||
func (suite *FileStoreTestSuite) TestFileStorePutWithMultipleRef() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
w.Ref()
|
||||
ref := w.Ref() // Multiple calls to Ref() should work...
|
||||
|
||||
// And reading the data via the API should work...
|
||||
assertInputInStore(input, ref, suite.store, suite.Assert())
|
||||
}
|
||||
|
||||
func (suite *FileStoreTestSuite) TestFileStoreRoot() {
|
||||
oldRoot := suite.store.Root()
|
||||
suite.Equal(oldRoot, ref.Ref{})
|
||||
|
||||
// Root file should be absent
|
||||
f, err := os.Open(path.Join(suite.dir, "root"))
|
||||
suite.True(os.IsNotExist(err))
|
||||
|
||||
bogusRoot := ref.Parse("sha1-81c870618113ba29b6f2b396ea3a69c6f1d626c5") // sha1("Bogus, Dude")
|
||||
newRoot := ref.Parse("sha1-907d14fb3af2b0d4f18c2d46abe8aedce17367bd") // sha1("Hello, World")
|
||||
|
||||
// Try to update root with bogus oldRoot
|
||||
result := suite.store.UpdateRoot(newRoot, bogusRoot)
|
||||
suite.False(result)
|
||||
|
||||
// Root file should now be there, but should be empty
|
||||
f, err = os.Open(path.Join(suite.dir, "root"))
|
||||
suite.NoError(err)
|
||||
input, err := ioutil.ReadAll(f)
|
||||
suite.Equal(len(input), 0)
|
||||
|
||||
// Now do a valid root update
|
||||
result = suite.store.UpdateRoot(newRoot, oldRoot)
|
||||
suite.True(result)
|
||||
|
||||
// Root file should now contain "Hello, World" sha1
|
||||
f, err = os.Open(path.Join(suite.dir, "root"))
|
||||
suite.NoError(err)
|
||||
input, err = ioutil.ReadAll(f)
|
||||
suite.NoError(err)
|
||||
suite.Equal("sha1-907d14fb3af2b0d4f18c2d46abe8aedce17367bd", string(input))
|
||||
}
|
||||
|
||||
func (suite *FileStoreTestSuite) TestFileStorePutExisting() {
|
||||
input := "abc"
|
||||
|
||||
mkdirCount := 0
|
||||
suite.store.mkdirAll = func(path string, perm os.FileMode) error {
|
||||
mkdirCount++
|
||||
return os.MkdirAll(path, perm)
|
||||
}
|
||||
|
||||
write := func() {
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
w.Ref()
|
||||
}
|
||||
|
||||
write()
|
||||
|
||||
suite.Equal(1, mkdirCount)
|
||||
|
||||
write()
|
||||
|
||||
// Shouldn't have written the second time.
|
||||
suite.Equal(1, mkdirCount)
|
||||
}
|
||||
|
||||
func (suite *FileStoreTestSuite) TestFileStoreGetNonExisting() {
|
||||
ref := ref.Parse("sha1-1111111111111111111111111111111111111111")
|
||||
r := suite.store.Get(ref)
|
||||
suite.Nil(r)
|
||||
}
|
||||
|
||||
+15
-14
@@ -26,11 +26,12 @@ func toChunkKey(r ref.Ref) []byte {
|
||||
}
|
||||
|
||||
type LevelDBStore struct {
|
||||
db *leveldb.DB
|
||||
mu *sync.Mutex
|
||||
db *leveldb.DB
|
||||
mu *sync.Mutex
|
||||
putCount int // for testing
|
||||
}
|
||||
|
||||
func NewLevelDBStore(dir string) LevelDBStore {
|
||||
func NewLevelDBStore(dir string) *LevelDBStore {
|
||||
d.Exp.NotEmpty(dir)
|
||||
d.Exp.NoError(os.MkdirAll(dir, 0700))
|
||||
db, err := leveldb.OpenFile(dir, &opt.Options{
|
||||
@@ -39,10 +40,10 @@ func NewLevelDBStore(dir string) LevelDBStore {
|
||||
WriteBuffer: 1 << 24, // 16MiB
|
||||
})
|
||||
d.Chk.NoError(err)
|
||||
return LevelDBStore{db, &sync.Mutex{}}
|
||||
return &LevelDBStore{db, &sync.Mutex{}, 0}
|
||||
}
|
||||
|
||||
func (l LevelDBStore) Root() ref.Ref {
|
||||
func (l *LevelDBStore) Root() ref.Ref {
|
||||
val, err := l.db.Get([]byte(rootKey), nil)
|
||||
if err == errors.ErrNotFound {
|
||||
return ref.Ref{}
|
||||
@@ -52,7 +53,7 @@ func (l LevelDBStore) Root() ref.Ref {
|
||||
return ref.Parse(string(val))
|
||||
}
|
||||
|
||||
func (l LevelDBStore) UpdateRoot(current, last ref.Ref) bool {
|
||||
func (l *LevelDBStore) UpdateRoot(current, last ref.Ref) bool {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
if last != l.Root() {
|
||||
@@ -65,7 +66,7 @@ func (l LevelDBStore) UpdateRoot(current, last ref.Ref) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (l LevelDBStore) Get(ref ref.Ref) io.ReadCloser {
|
||||
func (l *LevelDBStore) Get(ref ref.Ref) io.ReadCloser {
|
||||
key := toChunkKey(ref)
|
||||
chunk, err := l.db.Get(key, nil)
|
||||
if err == errors.ErrNotFound {
|
||||
@@ -76,11 +77,11 @@ func (l LevelDBStore) Get(ref ref.Ref) io.ReadCloser {
|
||||
return ioutil.NopCloser(bytes.NewReader(chunk))
|
||||
}
|
||||
|
||||
func (l LevelDBStore) Put() ChunkWriter {
|
||||
func (l *LevelDBStore) Put() ChunkWriter {
|
||||
b := &bytes.Buffer{}
|
||||
h := ref.NewHash()
|
||||
return &ldbChunkWriter{
|
||||
db: l.db,
|
||||
ldb: l,
|
||||
buffer: b,
|
||||
writer: io.MultiWriter(b, h),
|
||||
hash: h,
|
||||
@@ -88,7 +89,7 @@ func (l LevelDBStore) Put() ChunkWriter {
|
||||
}
|
||||
|
||||
type ldbChunkWriter struct {
|
||||
db *leveldb.DB
|
||||
ldb *LevelDBStore
|
||||
buffer *bytes.Buffer
|
||||
writer io.Writer
|
||||
hash hash.Hash
|
||||
@@ -113,15 +114,16 @@ func (w *ldbChunkWriter) Close() error {
|
||||
|
||||
key := toChunkKey(ref.FromHash(w.hash))
|
||||
|
||||
exists, err := w.db.Has(key, &opt.ReadOptions{DontFillCache: true}) // This isn't really a "read", so don't signal the cache to treat it as one.
|
||||
exists, err := w.ldb.db.Has(key, &opt.ReadOptions{DontFillCache: true}) // This isn't really a "read", so don't signal the cache to treat it as one.
|
||||
d.Chk.NoError(err)
|
||||
if exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = w.db.Put(key, w.buffer.Bytes(), nil)
|
||||
err = w.ldb.db.Put(key, w.buffer.Bytes(), nil)
|
||||
d.Chk.NoError(err)
|
||||
w.buffer = nil
|
||||
w.ldb.putCount += 1
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -139,7 +141,6 @@ func (f ldbStoreFlags) createStore() ChunkStore {
|
||||
if *f.dir == "" {
|
||||
return nil
|
||||
} else {
|
||||
fs := NewLevelDBStore(*f.dir)
|
||||
return &fs
|
||||
return NewLevelDBStore(*f.dir)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/ref"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
@@ -14,100 +13,22 @@ func TestLevelDBStoreTestSuite(t *testing.T) {
|
||||
}
|
||||
|
||||
type LevelDBStoreTestSuite struct {
|
||||
suite.Suite
|
||||
dir string
|
||||
store LevelDBStore
|
||||
ChunkStoreTestSuite
|
||||
dir string
|
||||
}
|
||||
|
||||
func (suite *LevelDBStoreTestSuite) SetupTest() {
|
||||
var err error
|
||||
suite.dir, err = ioutil.TempDir(os.TempDir(), "")
|
||||
suite.NoError(err)
|
||||
suite.store = NewLevelDBStore(suite.dir)
|
||||
store := NewLevelDBStore(suite.dir)
|
||||
suite.putCountFn = func() int {
|
||||
return store.putCount
|
||||
}
|
||||
|
||||
suite.store = store
|
||||
}
|
||||
|
||||
func (suite *LevelDBStoreTestSuite) TearDownTest() {
|
||||
os.Remove(suite.dir)
|
||||
}
|
||||
|
||||
func (suite *LevelDBStoreTestSuite) TestLevelDBStorePut() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
ref := w.Ref()
|
||||
|
||||
// See http://www.di-mgt.com.au/sha_testvectors.html
|
||||
suite.Equal("sha1-a9993e364706816aba3e25717850c26c9cd0d89d", ref.String())
|
||||
|
||||
// And reading it via the API should work...
|
||||
assertInputInStore(input, ref, suite.store, suite.Assert())
|
||||
}
|
||||
|
||||
func (suite *LevelDBStoreTestSuite) TestLevelDBStoreWriteAfterCloseFails() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
suite.NoError(w.Close())
|
||||
suite.Panics(func() { w.Write([]byte(input)) }, "Write() after Close() should barf!")
|
||||
}
|
||||
|
||||
func (suite *LevelDBStoreTestSuite) TestLevelDBStoreWriteAfterRefFails() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
w.Ref()
|
||||
suite.Panics(func() { w.Write([]byte(input)) }, "Write() after Close() should barf!")
|
||||
}
|
||||
|
||||
func (suite *LevelDBStoreTestSuite) TestLevelDBStorePutWithRefAfterClose() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
suite.NoError(w.Close())
|
||||
ref := w.Ref() // Ref() after Close() should work...
|
||||
|
||||
// And reading the data via the API should work...
|
||||
assertInputInStore(input, ref, suite.store, suite.Assert())
|
||||
}
|
||||
|
||||
func (suite *LevelDBStoreTestSuite) TestLevelDBStorePutWithMultipleRef() {
|
||||
input := "abc"
|
||||
w := suite.store.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
suite.NoError(err)
|
||||
|
||||
w.Ref()
|
||||
ref := w.Ref() // Multiple calls to Ref() should work...
|
||||
|
||||
// And reading the data via the API should work...
|
||||
assertInputInStore(input, ref, suite.store, suite.Assert())
|
||||
}
|
||||
|
||||
func (suite *LevelDBStoreTestSuite) TestLevelDBStoreRoot() {
|
||||
oldRoot := suite.store.Root()
|
||||
suite.Equal(oldRoot, ref.Ref{})
|
||||
|
||||
bogusRoot := ref.Parse("sha1-81c870618113ba29b6f2b396ea3a69c6f1d626c5") // sha1("Bogus, Dude")
|
||||
newRoot := ref.Parse("sha1-907d14fb3af2b0d4f18c2d46abe8aedce17367bd") // sha1("Hello, World")
|
||||
|
||||
// Try to update root with bogus oldRoot
|
||||
result := suite.store.UpdateRoot(newRoot, bogusRoot)
|
||||
suite.False(result)
|
||||
|
||||
// Now do a valid root update
|
||||
result = suite.store.UpdateRoot(newRoot, oldRoot)
|
||||
suite.True(result)
|
||||
}
|
||||
|
||||
func (suite *LevelDBStoreTestSuite) TestLevelDBStoreGetNonExisting() {
|
||||
ref := ref.Parse("sha1-1111111111111111111111111111111111111111")
|
||||
r := suite.store.Get(ref)
|
||||
suite.Nil(r)
|
||||
}
|
||||
|
||||
+14
-24
@@ -1,32 +1,22 @@
|
||||
package chunks
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
func TestMemoryStorePut(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
s := MemoryStore{}
|
||||
assert.Equal(0, s.Len())
|
||||
|
||||
input := "abc"
|
||||
w := s.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
assert.NoError(err)
|
||||
ref := w.Ref()
|
||||
|
||||
// See http://www.di-mgt.com.au/sha_testvectors.html
|
||||
assert.Equal("sha1-a9993e364706816aba3e25717850c26c9cd0d89d", ref.String())
|
||||
|
||||
// Reading it back via the API should work...
|
||||
reader := s.Get(ref)
|
||||
data, err := ioutil.ReadAll(reader)
|
||||
assert.NoError(err)
|
||||
assert.Equal(input, string(data))
|
||||
|
||||
assert.Equal(1, s.Len())
|
||||
func TestMemoryStoreTestSuite(t *testing.T) {
|
||||
suite.Run(t, &MemoryStoreTestSuite{})
|
||||
}
|
||||
|
||||
type MemoryStoreTestSuite struct {
|
||||
ChunkStoreTestSuite
|
||||
}
|
||||
|
||||
func (suite *MemoryStoreTestSuite) SetupTest() {
|
||||
suite.store = &MemoryStore{}
|
||||
}
|
||||
|
||||
func (suite *MemoryStoreTestSuite) TearDownTest() {
|
||||
}
|
||||
|
||||
@@ -15,10 +15,11 @@ import (
|
||||
type ReadThroughStore struct {
|
||||
cachingStore ChunkStore
|
||||
backingStore ChunkStore
|
||||
putCount int
|
||||
}
|
||||
|
||||
func NewReadThroughStore(cachingStore ChunkStore, backingStore ChunkStore) ReadThroughStore {
|
||||
return ReadThroughStore{cachingStore, backingStore}
|
||||
return ReadThroughStore{cachingStore, backingStore, 0}
|
||||
}
|
||||
|
||||
// forwardCloser closes multiple io.Closer objects.
|
||||
|
||||
@@ -4,27 +4,40 @@ import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
func TestReadThroughStoreGet(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
func TestReadThroughStoreTestSuite(t *testing.T) {
|
||||
suite.Run(t, &ReadThroughStoreTestSuite{})
|
||||
}
|
||||
|
||||
type ReadThroughStoreTestSuite struct {
|
||||
ChunkStoreTestSuite
|
||||
}
|
||||
|
||||
func (suite *ReadThroughStoreTestSuite) SetupTest() {
|
||||
suite.store = NewReadThroughStore(&MemoryStore{}, &TestStore{})
|
||||
}
|
||||
|
||||
func (suite *ReadThroughStoreTestSuite) TearDownTest() {
|
||||
}
|
||||
|
||||
func (suite *LevelDBStoreTestSuite) TestReadThroughStoreGet() {
|
||||
bs := &TestStore{}
|
||||
|
||||
// Prepopulate the backing store with "abc".
|
||||
input := "abc"
|
||||
w := bs.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
assert.NoError(err)
|
||||
suite.NoError(err)
|
||||
ref := w.Ref()
|
||||
|
||||
// See http://www.di-mgt.com.au/sha_testvectors.html
|
||||
assert.Equal("sha1-a9993e364706816aba3e25717850c26c9cd0d89d", ref.String())
|
||||
suite.Equal("sha1-a9993e364706816aba3e25717850c26c9cd0d89d", ref.String())
|
||||
|
||||
assert.Equal(1, bs.Len())
|
||||
assert.Equal(1, bs.Writes)
|
||||
assert.Equal(0, bs.Reads)
|
||||
suite.Equal(1, bs.Len())
|
||||
suite.Equal(1, bs.Writes)
|
||||
suite.Equal(0, bs.Reads)
|
||||
|
||||
cs := &TestStore{}
|
||||
rts := NewReadThroughStore(cs, bs)
|
||||
@@ -32,35 +45,33 @@ func TestReadThroughStoreGet(t *testing.T) {
|
||||
// Now read "abc". It is not yet in the cache so we hit the backing store.
|
||||
reader := rts.Get(ref)
|
||||
data, err := ioutil.ReadAll(reader)
|
||||
assert.NoError(err)
|
||||
assert.Equal(input, string(data))
|
||||
suite.NoError(err)
|
||||
suite.Equal(input, string(data))
|
||||
reader.Close()
|
||||
|
||||
assert.Equal(1, bs.Len())
|
||||
assert.Equal(1, cs.Len())
|
||||
assert.Equal(1, cs.Writes)
|
||||
assert.Equal(1, bs.Writes)
|
||||
assert.Equal(1, cs.Reads)
|
||||
assert.Equal(1, bs.Reads)
|
||||
suite.Equal(1, bs.Len())
|
||||
suite.Equal(1, cs.Len())
|
||||
suite.Equal(1, cs.Writes)
|
||||
suite.Equal(1, bs.Writes)
|
||||
suite.Equal(1, cs.Reads)
|
||||
suite.Equal(1, bs.Reads)
|
||||
|
||||
// Reading it again should not hit the backing store.
|
||||
reader = rts.Get(ref)
|
||||
data, err = ioutil.ReadAll(reader)
|
||||
assert.NoError(err)
|
||||
assert.Equal(input, string(data))
|
||||
suite.NoError(err)
|
||||
suite.Equal(input, string(data))
|
||||
reader.Close()
|
||||
|
||||
assert.Equal(1, bs.Len())
|
||||
assert.Equal(1, cs.Len())
|
||||
assert.Equal(1, cs.Writes)
|
||||
assert.Equal(1, bs.Writes)
|
||||
assert.Equal(2, cs.Reads)
|
||||
assert.Equal(1, bs.Reads)
|
||||
suite.Equal(1, bs.Len())
|
||||
suite.Equal(1, cs.Len())
|
||||
suite.Equal(1, cs.Writes)
|
||||
suite.Equal(1, bs.Writes)
|
||||
suite.Equal(2, cs.Reads)
|
||||
suite.Equal(1, bs.Reads)
|
||||
}
|
||||
|
||||
func TestReadThroughStorePut(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
func (suite *LevelDBStoreTestSuite) TestReadThroughStorePut() {
|
||||
bs := &TestStore{}
|
||||
cs := &TestStore{}
|
||||
rts := NewReadThroughStore(cs, bs)
|
||||
@@ -69,13 +80,13 @@ func TestReadThroughStorePut(t *testing.T) {
|
||||
input := "abc"
|
||||
w := rts.Put()
|
||||
_, err := w.Write([]byte(input))
|
||||
assert.NoError(err)
|
||||
suite.NoError(err)
|
||||
ref := w.Ref()
|
||||
|
||||
// See http://www.di-mgt.com.au/sha_testvectors.html
|
||||
assert.Equal("sha1-a9993e364706816aba3e25717850c26c9cd0d89d", ref.String())
|
||||
suite.Equal("sha1-a9993e364706816aba3e25717850c26c9cd0d89d", ref.String())
|
||||
|
||||
assertInputInStore("abc", ref, bs, assert)
|
||||
assertInputInStore("abc", ref, cs, assert)
|
||||
assertInputInStore("abc", ref, rts, assert)
|
||||
assertInputInStore("abc", ref, bs, suite.Assert())
|
||||
assertInputInStore("abc", ref, cs, suite.Assert())
|
||||
assertInputInStore("abc", ref, rts, suite.Assert())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user