Skip to content

Commit

Permalink
add approval tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangchiqing committed Jan 10, 2025
1 parent 407c409 commit b9a5e64
Showing 1 changed file with 58 additions and 8 deletions.
66 changes: 58 additions & 8 deletions storage/store/approvals_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@ package store_test

import (
"errors"
"sync"
"testing"

"github.com/dgraph-io/badger/v2"
"github.com/stretchr/testify/require"

"github.com/onflow/flow-go/module/metrics"
"github.com/onflow/flow-go/storage"
bstorage "github.com/onflow/flow-go/storage/badger"
"github.com/onflow/flow-go/storage/operation/dbtest"
"github.com/onflow/flow-go/storage/store"
"github.com/onflow/flow-go/utils/unittest"
)

func TestApprovalStoreAndRetrieve(t *testing.T) {
unittest.RunWithBadgerDB(t, func(db *badger.DB) {
dbtest.RunWithDB(t, func(t *testing.T, db storage.DB) {
metrics := metrics.NewNoopCollector()
store := bstorage.NewResultApprovals(metrics, db)
store := store.NewResultApprovals(metrics, db)

approval := unittest.ResultApprovalFixture()
err := store.Store(approval)
Expand All @@ -36,9 +37,9 @@ func TestApprovalStoreAndRetrieve(t *testing.T) {
}

func TestApprovalStoreTwice(t *testing.T) {
unittest.RunWithBadgerDB(t, func(db *badger.DB) {
dbtest.RunWithDB(t, func(t *testing.T, db storage.DB) {
metrics := metrics.NewNoopCollector()
store := bstorage.NewResultApprovals(metrics, db)
store := store.NewResultApprovals(metrics, db)

approval := unittest.ResultApprovalFixture()
err := store.Store(approval)
Expand All @@ -56,9 +57,9 @@ func TestApprovalStoreTwice(t *testing.T) {
}

func TestApprovalStoreTwoDifferentApprovalsShouldFail(t *testing.T) {
unittest.RunWithBadgerDB(t, func(db *badger.DB) {
dbtest.RunWithDB(t, func(t *testing.T, db storage.DB) {
metrics := metrics.NewNoopCollector()
store := bstorage.NewResultApprovals(metrics, db)
store := store.NewResultApprovals(metrics, db)

approval1 := unittest.ResultApprovalFixture()
approval2 := unittest.ResultApprovalFixture()
Expand All @@ -79,3 +80,52 @@ func TestApprovalStoreTwoDifferentApprovalsShouldFail(t *testing.T) {
require.True(t, errors.Is(err, storage.ErrDataMismatch))
})
}

// verify that storing and indexing two conflicting approvals concurrently should fail
// one of them is succeed, the other one should fail
func TestApprovalStoreTwoDifferentApprovalsConcurrently(t *testing.T) {
dbtest.RunWithDB(t, func(t *testing.T, db storage.DB) {
metrics := metrics.NewNoopCollector()
store := store.NewResultApprovals(metrics, db)

approval1 := unittest.ResultApprovalFixture()
approval2 := unittest.ResultApprovalFixture()

var wg sync.WaitGroup
wg.Add(2)

var firstIndexErr, secondIndexErr error

// First goroutine stores and indexes the first approval.
go func() {
defer wg.Done()

err := store.Store(approval1)
require.NoError(t, err)

firstIndexErr = store.Index(approval1.Body.ExecutionResultID, approval1.Body.ChunkIndex, approval1.ID())
}()

// Second goroutine stores and tries to index the second approval for the same chunk.
go func() {
defer wg.Done()

err := store.Store(approval2)
require.NoError(t, err)

secondIndexErr = store.Index(approval1.Body.ExecutionResultID, approval1.Body.ChunkIndex, approval2.ID())
}()

// Wait for both goroutines to finish
wg.Wait()

// Check that one of the Index operations succeeded and the other failed
if firstIndexErr == nil {
require.Error(t, secondIndexErr)
require.True(t, errors.Is(secondIndexErr, storage.ErrDataMismatch))
} else {
require.NoError(t, secondIndexErr)
require.True(t, errors.Is(firstIndexErr, storage.ErrDataMismatch))
}
})
}

0 comments on commit b9a5e64

Please sign in to comment.