Skip to content

Commit

Permalink
Merge pull request #212 from onflow/fxamacker/add-more-tests
Browse files Browse the repository at this point in the history
Add DumpArraySlabs, DumpMapSlabs, and more tests
  • Loading branch information
fxamacker authored Nov 19, 2021
2 parents 6a06b64 + 472f40f commit 6268d6a
Show file tree
Hide file tree
Showing 6 changed files with 767 additions and 229 deletions.
56 changes: 24 additions & 32 deletions array.go
Original file line number Diff line number Diff line change
Expand Up @@ -798,25 +798,17 @@ func (a *ArrayDataSlab) PopIterate(storage SlabStorage, fn ArrayPopIterationFunc
}

func (a *ArrayDataSlab) String() string {
var elements []Storable
if len(a.elements) <= 6 {
elements = a.elements
} else {
elements = append(elements, a.elements[:3]...)
elements = append(elements, a.elements[len(a.elements)-3:]...)
}

var elemsStr []string
for _, e := range elements {
for _, e := range a.elements {
elemsStr = append(elemsStr, fmt.Sprint(e))
}

if len(a.elements) > 6 {
elemsStr = append(elemsStr, "")
copy(elemsStr[4:], elemsStr[3:])
elemsStr[3] = "..."
}
return fmt.Sprintf("[%s]", strings.Join(elemsStr, " "))
return fmt.Sprintf("ArrayDataSlab id:%s size:%d count:%d elements: [%s]",
a.header.id,
a.header.size,
a.header.count,
strings.Join(elemsStr, " "),
)
}

func newArrayMetaDataSlabFromData(
Expand Down Expand Up @@ -1793,7 +1785,13 @@ func (a *ArrayMetaDataSlab) String() string {
for _, h := range a.childrenHeaders {
elemsStr = append(elemsStr, fmt.Sprintf("{id:%s size:%d count:%d}", h.id, h.size, h.count))
}
return fmt.Sprintf("[%s]", strings.Join(elemsStr, " "))

return fmt.Sprintf("ArrayMetaDataSlab id:%s size:%d count:%d children: [%s]",
a.header.id,
a.header.size,
a.header.count,
strings.Join(elemsStr, " "),
)
}

func NewArray(storage SlabStorage, address Address, typeInfo TypeInfo) (*Array, error) {
Expand Down Expand Up @@ -2120,30 +2118,24 @@ func (a *Array) Type() TypeInfo {
}

func (a *Array) String() string {
if a.root.IsData() {
return a.root.String()
iterator, err := a.Iterator()
if err != nil {
return err.Error()
}
meta := a.root.(*ArrayMetaDataSlab)
return a.string(meta)
}

func (a *Array) string(meta *ArrayMetaDataSlab) string {
var elemsStr []string

for _, h := range meta.childrenHeaders {
child, err := getArraySlab(a.Storage, h.id)
for {
v, err := iterator.Next()
if err != nil {
return err.Error()
}
if child.IsData() {
data := child.(*ArrayDataSlab)
elemsStr = append(elemsStr, data.String())
} else {
meta := child.(*ArrayMetaDataSlab)
elemsStr = append(elemsStr, a.string(meta))
if v == nil {
break
}
elemsStr = append(elemsStr, fmt.Sprintf("%s", v))
}
return strings.Join(elemsStr, " ")

return fmt.Sprintf("[%s]", strings.Join(elemsStr, " "))
}

func getArraySlab(storage SlabStorage, id StorageID) (ArraySlab, error) {
Expand Down
46 changes: 21 additions & 25 deletions array_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ package atree

import (
"bytes"
"errors"
"fmt"
"reflect"
"strings"

"github.com/fxamacker/cbor/v2"
)
Expand Down Expand Up @@ -97,6 +99,16 @@ func GetArrayStats(a *Array) (ArrayStats, error) {

// PrintArray prints array slab data to stdout.
func PrintArray(a *Array) {
dumps, err := DumpArraySlabs(a)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(strings.Join(dumps, "\n"))
}

func DumpArraySlabs(a *Array) ([]string, error) {
var dumps []string

nextLevelIDs := []StorageID{a.StorageID()}

Expand All @@ -113,20 +125,12 @@ func PrintArray(a *Array) {

slab, err := getArraySlab(a.Storage, id)
if err != nil {
fmt.Println(err)
return
return nil, err
}

if slab.IsData() {
dataSlab := slab.(*ArrayDataSlab)
fmt.Printf(
"level %d leaf (id:%s size:%d count:%d next:%s): %s\n",
level+1,
dataSlab.header.id,
dataSlab.header.size,
dataSlab.header.count,
dataSlab.next,
dataSlab)
dumps = append(dumps, fmt.Sprintf("level %d, %s", level+1, dataSlab))

childStorables := dataSlab.ChildStorables()
for _, e := range childStorables {
Expand All @@ -137,20 +141,12 @@ func PrintArray(a *Array) {

} else {
meta := slab.(*ArrayMetaDataSlab)
fmt.Printf(
"level %d meta (id:%s size:%d count:%d) children: %s\n",
level+1,
meta.header.id,
meta.header.size,
meta.header.count,
meta,
)
dumps = append(dumps, fmt.Sprintf("level %d, %s", level+1, meta))

for _, storable := range slab.ChildStorables() {
id, ok := storable.(StorageIDStorable)
if !ok {
fmt.Printf("metadata slab's child storables are not of type StorageIDStorable")
return
return nil, errors.New("metadata slab's child storables are not of type StorageIDStorable")
}
nextLevelIDs = append(nextLevelIDs, StorageID(id))
}
Expand All @@ -163,15 +159,15 @@ func PrintArray(a *Array) {
for _, id := range overflowIDs {
slab, found, err := a.Storage.Retrieve(id)
if err != nil {
fmt.Println(err.Error())
return
return nil, err
}
if !found {
fmt.Printf("slab %s not found\n", id)
return
return nil, NewSlabNotFoundErrorf(id, "slab not found during array slab dump")
}
fmt.Printf("overflow: (id %s) %s\n", id, slab)
dumps = append(dumps, fmt.Sprintf("overflow: %s", slab))
}

return dumps, nil
}

type TypeInfoComparator func(TypeInfo, TypeInfo) bool
Expand Down
83 changes: 78 additions & 5 deletions array_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2164,7 +2164,7 @@ func TestArrayString(t *testing.T) {
})

t.Run("large", func(t *testing.T) {
const arraySize = 190
const arraySize = 120

typeInfo := testTypeInfo{42}
storage := newTestPersistentStorage(t)
Expand All @@ -2178,10 +2178,83 @@ func TestArrayString(t *testing.T) {
require.NoError(t, err)
}

wantArrayString := `[0 1 2 ... 51 52 53] [54 55 56 ... 97 98 99] [100 101 102 ... 187 188 189]`
require.Equal(t, wantArrayString, array.String())
want := `[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119]`
require.Equal(t, want, array.String())
})
}

func TestArraySlabDump(t *testing.T) {
SetThreshold(256)
defer SetThreshold(1024)

wantMetaDataSlabString := `[{id:0x102030405060708.2 size:213 count:54} {id:0x102030405060708.3 size:205 count:46} {id:0x102030405060708.4 size:381 count:90}]`
require.Equal(t, wantMetaDataSlabString, array.root.String())
t.Run("small", func(t *testing.T) {
const arraySize = 6

typeInfo := testTypeInfo{42}
storage := newTestPersistentStorage(t)
address := Address{1, 2, 3, 4, 5, 6, 7, 8}

array, err := NewArray(storage, address, typeInfo)
require.NoError(t, err)

for i := uint64(0); i < arraySize; i++ {
err := array.Append(Uint64Value(i))
require.NoError(t, err)
}

want := []string{
"level 1, ArrayDataSlab id:0x102030405060708.1 size:23 count:6 elements: [0 1 2 3 4 5]",
}
dumps, err := DumpArraySlabs(array)
require.NoError(t, err)
require.Equal(t, want, dumps)
})

t.Run("large", func(t *testing.T) {
const arraySize = 120

typeInfo := testTypeInfo{42}
storage := newTestPersistentStorage(t)
address := Address{1, 2, 3, 4, 5, 6, 7, 8}

array, err := NewArray(storage, address, typeInfo)
require.NoError(t, err)

for i := uint64(0); i < arraySize; i++ {
err := array.Append(Uint64Value(i))
require.NoError(t, err)
}

want := []string{
"level 1, ArrayMetaDataSlab id:0x102030405060708.1 size:52 count:120 children: [{id:0x102030405060708.2 size:213 count:54} {id:0x102030405060708.3 size:285 count:66}]",
"level 2, ArrayDataSlab id:0x102030405060708.2 size:213 count:54 elements: [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53]",
"level 2, ArrayDataSlab id:0x102030405060708.3 size:285 count:66 elements: [54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119]",
}

dumps, err := DumpArraySlabs(array)
require.NoError(t, err)
require.Equal(t, want, dumps)
})

t.Run("overflow", func(t *testing.T) {

typeInfo := testTypeInfo{42}
storage := newTestPersistentStorage(t)
address := Address{1, 2, 3, 4, 5, 6, 7, 8}

array, err := NewArray(storage, address, typeInfo)
require.NoError(t, err)

err = array.Append(NewStringValue(strings.Repeat("a", int(MaxInlineArrayElementSize))))
require.NoError(t, err)

want := []string{
"level 1, ArrayDataSlab id:0x102030405060708.1 size:24 count:1 elements: [StorageIDStorable({[1 2 3 4 5 6 7 8] [0 0 0 0 0 0 0 2]})]",
"overflow: &{0x102030405060708.2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}",
}

dumps, err := DumpArraySlabs(array)
require.NoError(t, err)
require.Equal(t, want, dumps)
})
}
Loading

0 comments on commit 6268d6a

Please sign in to comment.