github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/state/eventstore/file/file_test.go (about)

     1  package file
     2  
     3  import (
     4  	"bufio"
     5  	"testing"
     6  
     7  	"github.com/gnolang/gno/tm2/pkg/amino"
     8  	storetypes "github.com/gnolang/gno/tm2/pkg/bft/state/eventstore/types"
     9  	"github.com/gnolang/gno/tm2/pkg/bft/types"
    10  	"github.com/gnolang/gno/tm2/pkg/testutils"
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  // generateTestTransactions generates random transaction results
    15  func generateTestTransactions(count int) []types.TxResult {
    16  	txs := make([]types.TxResult, count)
    17  
    18  	for i := 0; i < count; i++ {
    19  		txs[i] = types.TxResult{}
    20  	}
    21  
    22  	return txs
    23  }
    24  
    25  func TestTxEventStore_New(t *testing.T) {
    26  	t.Parallel()
    27  
    28  	t.Run("invalid file path specified", func(t *testing.T) {
    29  		t.Parallel()
    30  
    31  		cfg := &storetypes.Config{
    32  			EventStoreType: "invalid",
    33  		}
    34  
    35  		i, err := NewTxEventStore(cfg)
    36  
    37  		assert.Nil(t, i)
    38  		assert.ErrorIs(t, err, errInvalidType)
    39  	})
    40  
    41  	t.Run("invalid file path specified", func(t *testing.T) {
    42  		t.Parallel()
    43  
    44  		cfg := &storetypes.Config{
    45  			EventStoreType: EventStoreType,
    46  			Params:         nil,
    47  		}
    48  
    49  		i, err := NewTxEventStore(cfg)
    50  
    51  		assert.Nil(t, i)
    52  		assert.ErrorIs(t, err, errMissingPath)
    53  	})
    54  
    55  	t.Run("valid file path specified", func(t *testing.T) {
    56  		t.Parallel()
    57  
    58  		headPath := "."
    59  
    60  		cfg := &storetypes.Config{
    61  			EventStoreType: EventStoreType,
    62  			Params: map[string]any{
    63  				Path: headPath,
    64  			},
    65  		}
    66  
    67  		i, err := NewTxEventStore(cfg)
    68  		if i == nil {
    69  			t.Fatalf("unable to create event store")
    70  		}
    71  
    72  		assert.NoError(t, err)
    73  		assert.Equal(t, headPath, i.headPath)
    74  		assert.Equal(t, EventStoreType, i.GetType())
    75  	})
    76  }
    77  
    78  func TestTxEventStore_Append(t *testing.T) {
    79  	t.Parallel()
    80  
    81  	headFile, cleanup := testutils.NewTestFile(t)
    82  	t.Cleanup(func() {
    83  		cleanup()
    84  	})
    85  
    86  	eventStore, err := NewTxEventStore(&storetypes.Config{
    87  		EventStoreType: EventStoreType,
    88  		Params: map[string]any{
    89  			Path: headFile.Name(),
    90  		},
    91  	})
    92  	if err != nil {
    93  		t.Fatalf("unable to create tx event store, %v", err)
    94  	}
    95  
    96  	// Start the event store
    97  	if err = eventStore.Start(); err != nil {
    98  		t.Fatalf("unable to start event store, %v", err)
    99  	}
   100  
   101  	t.Cleanup(func() {
   102  		// Stop the event store
   103  		if err = eventStore.Stop(); err != nil {
   104  			t.Fatalf("unable to stop event store gracefully, %v", err)
   105  		}
   106  	})
   107  
   108  	numTxs := 10
   109  	txs := generateTestTransactions(numTxs)
   110  
   111  	for _, tx := range txs {
   112  		if err = eventStore.Append(tx); err != nil {
   113  			t.Fatalf("unable to store transaction, %v", err)
   114  		}
   115  	}
   116  
   117  	// Make sure the file group's size is valid
   118  	if eventStore.group.ReadGroupInfo().TotalSize == 0 {
   119  		t.Fatalf("invalid group size")
   120  	}
   121  
   122  	// Open file for reading
   123  	scanner := bufio.NewScanner(headFile)
   124  
   125  	linesRead := 0
   126  	for scanner.Scan() {
   127  		line := scanner.Bytes()
   128  
   129  		var txRes types.TxResult
   130  		if err = amino.UnmarshalJSON(line, &txRes); err != nil {
   131  			t.Fatalf("unable to read store line")
   132  		}
   133  
   134  		assert.Equal(t, txs[linesRead], txRes)
   135  
   136  		linesRead++
   137  	}
   138  
   139  	assert.Equal(t, numTxs, linesRead)
   140  }