github.com/ndau/noms@v1.0.5/go/nbs/dynamo_table_reader_test.go (about) 1 // Copyright 2017 Attic Labs, Inc. All rights reserved. 2 // Licensed under the Apache License, version 2.0: 3 // http://www.apache.org/licenses/LICENSE-2.0 4 5 package nbs 6 7 import ( 8 "testing" 9 10 "github.com/ndau/noms/go/util/sizecache" 11 "github.com/aws/aws-sdk-go/service/dynamodb" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func TestDynamoTableReaderAt(t *testing.T) { 16 ddb := makeFakeDDB(t) 17 18 chunks := [][]byte{ 19 []byte("hello2"), 20 []byte("goodbye2"), 21 []byte("badbye2"), 22 } 23 24 tableData, h := buildTable(chunks) 25 ddb.putData(fmtTableName(h), tableData) 26 27 t.Run("ddbTableStore", func(t *testing.T) { 28 t.Run("ReadTable", func(t *testing.T) { 29 test := func(dts *ddbTableStore) { 30 assert := assert.New(t) 31 data, err := dts.ReadTable(h, &Stats{}) 32 assert.NoError(err) 33 assert.Equal(tableData, data) 34 35 data, err = dts.ReadTable(computeAddr([]byte{}), &Stats{}) 36 assert.Error(err) 37 assert.IsType(tableNotInDynamoErr{}, err) 38 assert.Nil(data) 39 } 40 41 t.Run("EventuallyConsistentSuccess", func(t *testing.T) { 42 test(&ddbTableStore{ddb, "table", nil, nil}) 43 }) 44 45 t.Run("EventuallyConsistentFailure", func(t *testing.T) { 46 test(&ddbTableStore{&eventuallyConsistentDDB{ddb}, "table", nil, nil}) 47 }) 48 49 t.Run("WithCache", func(t *testing.T) { 50 tc := sizecache.New(uint64(2 * len(tableData))) 51 dts := &ddbTableStore{ddb, "table", nil, tc} 52 test(dts) 53 54 // Table should have been cached on read 55 baseline := ddb.numGets 56 _, err := dts.ReadTable(h, &Stats{}) 57 assert.NoError(t, err) 58 assert.Zero(t, ddb.numGets-baseline) 59 }) 60 }) 61 62 t.Run("WriteTable", func(t *testing.T) { 63 t.Run("WithoutCache", func(t *testing.T) { 64 assert := assert.New(t) 65 66 dts := &ddbTableStore{makeFakeDDB(t), "table", nil, nil} 67 assert.NoError(dts.Write(h, tableData)) 68 69 data, err := dts.ReadTable(h, &Stats{}) 70 assert.NoError(err) 71 assert.Equal(tableData, data) 72 }) 73 74 t.Run("WithCache", func(t *testing.T) { 75 assert := assert.New(t) 76 77 tc := sizecache.New(uint64(2 * len(tableData))) 78 dts := &ddbTableStore{makeFakeDDB(t), "table", nil, tc} 79 assert.NoError(dts.Write(h, tableData)) 80 81 // Table should have been cached on write 82 baseline := ddb.numGets 83 data, err := dts.ReadTable(h, &Stats{}) 84 assert.NoError(err) 85 assert.Equal(tableData, data) 86 assert.Zero(ddb.numGets - baseline) 87 }) 88 }) 89 }) 90 91 t.Run("ReadAtWithCache", func(t *testing.T) { 92 assert := assert.New(t) 93 stats := &Stats{} 94 95 tc := sizecache.New(uint64(2 * len(tableData))) 96 tra := &dynamoTableReaderAt{&ddbTableStore{ddb, "table", nil, tc}, h} 97 98 // First, read when table is not yet cached 99 scratch := make([]byte, len(tableData)/4) 100 baseline := ddb.numGets 101 _, err := tra.ReadAtWithStats(scratch, 0, stats) 102 assert.NoError(err) 103 assert.True(ddb.numGets > baseline) 104 105 // Table should have been cached on read so read again, a different slice this time 106 baseline = ddb.numGets 107 _, err = tra.ReadAtWithStats(scratch, int64(len(scratch)), stats) 108 assert.NoError(err) 109 assert.Zero(ddb.numGets - baseline) 110 }) 111 } 112 113 type eventuallyConsistentDDB struct { 114 ddbsvc 115 } 116 117 func (ec *eventuallyConsistentDDB) GetItem(input *dynamodb.GetItemInput) (*dynamodb.GetItemOutput, error) { 118 if input.ConsistentRead != nil && *(input.ConsistentRead) { 119 return ec.ddbsvc.GetItem(input) 120 } 121 return &dynamodb.GetItemOutput{}, nil 122 }