Skip to content

Commit

Permalink
add black box testing for file
Browse files Browse the repository at this point in the history
  • Loading branch information
walldiss committed May 29, 2024
1 parent 9e82fd6 commit 1e7a637
Show file tree
Hide file tree
Showing 2 changed files with 234 additions and 38 deletions.
55 changes: 17 additions & 38 deletions share/store/file/mem_file_test.go
Original file line number Diff line number Diff line change
@@ -1,51 +1,30 @@
package file

import (
"context"
mrand "math/rand"
"testing"

"github.com/stretchr/testify/require"

"github.com/celestiaorg/celestia-node/share"
"github.com/celestiaorg/celestia-node/share/eds/edstest"
"github.com/celestiaorg/celestia-node/share/sharetest"
"github.com/celestiaorg/rsmt2d"
)

func TestMemFileShare(t *testing.T) {
eds := edstest.RandEDS(t, 32)
root, err := share.NewRoot(eds)
require.NoError(t, err)
fl := &MemFile{Eds: eds}

width := int(eds.Width())
for rowIdx := 0; rowIdx < width; rowIdx++ {
for colIdx := 0; colIdx < width; colIdx++ {
shr, err := fl.Share(context.TODO(), rowIdx, colIdx)
require.NoError(t, err)

err = shr.Validate(root, rowIdx, colIdx)
require.NoError(t, err)
}
func TestMemFile(t *testing.T) {
size := 8
newFile := func(eds *rsmt2d.ExtendedDataSquare) EdsFile {
return &MemFile{Eds: eds}
}
}

func TestMemFileDate(t *testing.T) {
size := 32
t.Run("Share", func(t *testing.T) {
testFileShare(t, newFile, size)
})

// generate EDS with random data and some shares with the same namespace
namespace := sharetest.RandV0Namespace()
amount := mrand.Intn(size*size-1) + 1
eds, dah := edstest.RandEDSWithNamespace(t, namespace, amount, size)
t.Run("AxisHalf", func(t *testing.T) {
testFileAxisHalf(t, newFile, size)
})

file := &MemFile{Eds: eds}
t.Run("Data", func(t *testing.T) {
testFileData(t, newFile, size)
})

for i, root := range dah.RowRoots {
if !namespace.IsOutsideRange(root, root) {
nd, err := file.Data(context.Background(), namespace, i)
require.NoError(t, err)
err = nd.Validate(dah, namespace, i)
require.NoError(t, err)
}
}
t.Run("EDS", func(t *testing.T) {
testFileEds(t, newFile, size)
})
}
217 changes: 217 additions & 0 deletions share/store/file/testing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
package file

import (
"context"
"fmt"
"github.com/celestiaorg/celestia-node/share/eds/edstest"

Check failure on line 6 in share/store/file/testing.go

View workflow job for this annotation

GitHub Actions / go-ci / Lint

File is not `gofumpt`-ed with `-extra` (gofumpt)
"github.com/celestiaorg/celestia-node/share/sharetest"
"github.com/stretchr/testify/require"
mrand "math/rand"
"strconv"
"sync"
"testing"

Check failure on line 12 in share/store/file/testing.go

View workflow job for this annotation

GitHub Actions / go-ci / Lint

File is not `gofumpt`-ed with `-extra` (gofumpt)

Check failure on line 13 in share/store/file/testing.go

View workflow job for this annotation

GitHub Actions / go-ci / Lint

File is not `goimports`-ed with -local github.com/celestiaorg/celestia-node (goimports)
"github.com/celestiaorg/nmt"
"github.com/celestiaorg/rsmt2d"

"github.com/celestiaorg/celestia-node/share"
)

type createFile func(eds *rsmt2d.ExtendedDataSquare) EdsFile

func testFileShare(t *testing.T, createFile createFile, odsSize int) {
eds := edstest.RandEDS(t, odsSize)
fl := createFile(eds)

dah, err := share.NewRoot(eds)
require.NoError(t, err)

width := int(eds.Width())
t.Run("single thread", func(t *testing.T) {
for x := 0; x < width; x++ {
for y := 0; y < width; y++ {
testShare(t, fl, eds, dah, x, y)
}
}
})

t.Run("parallel", func(t *testing.T) {
wg := sync.WaitGroup{}
for y := 0; y < width; y++ {
for x := 0; x < width; x++ {
wg.Add(1)
go func(x, y int) {
defer wg.Done()
testShare(t, fl, eds, dah, x, y)
}(x, y)
}
}
wg.Wait()
})
}

func testShare(t *testing.T,
fl EdsFile,
eds *rsmt2d.ExtendedDataSquare,

Check warning on line 55 in share/store/file/testing.go

View workflow job for this annotation

GitHub Actions / go-ci / Lint

unused-parameter: parameter 'eds' seems to be unused, consider removing or renaming it as _ (revive)
dah *share.Root,
x, y int) {

Check failure on line 57 in share/store/file/testing.go

View workflow job for this annotation

GitHub Actions / go-ci / Lint

File is not `gofumpt`-ed with `-extra` (gofumpt)
shr, err := fl.Share(context.TODO(), x, y)
require.NoError(t, err)

err = shr.Validate(dah, x, y)
require.NoError(t, err)
}

func testFileData(t *testing.T, createFile createFile, size int) {
t.Run("included", func(t *testing.T) {
// generate EDS with random data and some Shares with the same namespace
namespace := sharetest.RandV0Namespace()
amount := mrand.Intn(size*size-1) + 1

Check failure on line 69 in share/store/file/testing.go

View workflow job for this annotation

GitHub Actions / go-ci / Lint

G404: Use of weak random number generator (math/rand instead of crypto/rand) (gosec)
eds, dah := edstest.RandEDSWithNamespace(t, namespace, amount, size)
f := createFile(eds)
testData(t, f, namespace, dah)
})

t.Run("not included", func(t *testing.T) {
// generate EDS with random data and some Shares with the same namespace
eds := edstest.RandEDS(t, size)
dah, err := share.NewRoot(eds)
require.NoError(t, err)

maxNs := nmt.MaxNamespace(dah.RowRoots[(len(dah.RowRoots))/2-1], share.NamespaceSize)
targetNs, err := share.Namespace(maxNs).AddInt(-1)
require.NoError(t, err)

f := createFile(eds)
testData(t, f, targetNs, dah)
})
}

func testData(t *testing.T, f EdsFile, namespace share.Namespace, dah *share.Root) {
for i, root := range dah.RowRoots {
if !namespace.IsOutsideRange(root, root) {
nd, err := f.Data(context.Background(), namespace, i)
require.NoError(t, err)
err = nd.Validate(dah, namespace, i)
require.NoError(t, err)
}
}
}

func testFileAxisHalf(t *testing.T, createFile createFile, odsSize int) {
eds := edstest.RandEDS(t, odsSize)
fl := createFile(eds)

t.Run("single thread", func(t *testing.T) {
for _, axisType := range []rsmt2d.Axis{rsmt2d.Col, rsmt2d.Row} {
for i := 0; i < int(eds.Width()); i++ {
half, err := fl.AxisHalf(context.Background(), axisType, i)
require.NoError(t, err)
require.Len(t, half.Shares, odsSize)

var expected []share.Share
if half.IsParity {
expected = getAxis(eds, axisType, i)[odsSize:]
} else {
expected = getAxis(eds, axisType, i)[:odsSize]
}

require.Equal(t, expected, half.Shares)
}
}
})

t.Run("parallel", func(t *testing.T) {
wg := sync.WaitGroup{}
for _, axisType := range []rsmt2d.Axis{rsmt2d.Col, rsmt2d.Row} {
for i := 0; i < int(eds.Width()); i++ {
wg.Add(1)
go func(axisType rsmt2d.Axis, idx int) {
defer wg.Done()
half, err := fl.AxisHalf(context.Background(), axisType, idx)
require.NoError(t, err)
require.Len(t, half.Shares, odsSize)

var expected []share.Share
if half.IsParity {
expected = getAxis(eds, axisType, idx)[odsSize:]
} else {
expected = getAxis(eds, axisType, idx)[:odsSize]
}

require.Equal(t, expected, half.Shares)
}(axisType, i)
}
}
wg.Wait()
})
}

func testFileEds(t *testing.T, createFile createFile, size int) {
eds := edstest.RandEDS(t, size)
fl := createFile(eds)

eds2, err := fl.EDS(context.Background())
require.NoError(t, err)
require.True(t, eds.Equals(eds2))
}

func benchGetAxisFromFile(b *testing.B, newFile func(size int) EdsFile, minSize, maxSize int) {

Check failure on line 159 in share/store/file/testing.go

View workflow job for this annotation

GitHub Actions / go-ci / Lint

func `benchGetAxisFromFile` is unused (unused)
for size := minSize; size <= maxSize; size *= 2 {
f := newFile(size)

// loop over all possible axis types and quadrants
for _, axisType := range []rsmt2d.Axis{rsmt2d.Row, rsmt2d.Col} {
for _, squareHalf := range []int{0, 1} {
name := fmt.Sprintf("Size:%v/ProofType:%s/squareHalf:%s", size, axisType, strconv.Itoa(squareHalf))
b.Run(name, func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := f.AxisHalf(context.TODO(), axisType, f.Size()/2*(squareHalf))
require.NoError(b, err)
}
})
}
}
}
}

func benchGetShareFromFile(b *testing.B, newFile func(size int) EdsFile, minSize, maxSize int) {

Check failure on line 179 in share/store/file/testing.go

View workflow job for this annotation

GitHub Actions / go-ci / Lint

func `benchGetShareFromFile` is unused (unused)
for size := minSize; size <= maxSize; size *= 2 {
f := newFile(size)

// loop over all possible axis types and quadrants
for _, q := range quadrants {
name := fmt.Sprintf("Size:%v/quadrant:%s", size, q)
b.Run(name, func(b *testing.B) {
x, y := q.coordinates(f.Size())
// warm up cache
_, err := f.Share(context.TODO(), x, y)
require.NoError(b, err)

b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := f.Share(context.TODO(), x, y)
require.NoError(b, err)
}
})
}

}
}

type quadrant int

var (

Check failure on line 205 in share/store/file/testing.go

View workflow job for this annotation

GitHub Actions / go-ci / Lint

File is not `gofumpt`-ed with `-extra` (gofumpt)
quadrants = []quadrant{1, 2, 3, 4}

Check failure on line 206 in share/store/file/testing.go

View workflow job for this annotation

GitHub Actions / go-ci / Lint

var `quadrants` is unused (unused)
)

func (q quadrant) String() string {
return strconv.Itoa(int(q))
}

func (q quadrant) coordinates(edsSize int) (x, y int) {

Check failure on line 213 in share/store/file/testing.go

View workflow job for this annotation

GitHub Actions / go-ci / Lint

func `quadrant.coordinates` is unused (unused)
x = edsSize/2*(int(q-1)%2) + 1
y = edsSize/2*(int(q-1)/2) + 1
return
}

0 comments on commit 1e7a637

Please sign in to comment.