github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/mempool/stdmap/backdata/mapBackData_test.go (about)

     1  package backdata
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  
     8  	"github.com/onflow/flow-go/model/flow"
     9  	"github.com/onflow/flow-go/utils/unittest"
    10  )
    11  
    12  func TestMapBackData_StoreAnd(t *testing.T) {
    13  	backData := NewMapBackData()
    14  	entities := unittest.EntityListFixture(100)
    15  
    16  	// Add
    17  	for _, e := range entities {
    18  		// all entities must be stored successfully
    19  		require.True(t, backData.Add(e.ID(), e))
    20  	}
    21  
    22  	// ByID
    23  	for _, expected := range entities {
    24  		// all entities must be retrievable successfully
    25  		actual, ok := backData.ByID(expected.ID())
    26  		require.True(t, ok)
    27  		require.Equal(t, expected, actual)
    28  	}
    29  
    30  	// All
    31  	all := backData.All()
    32  	require.Equal(t, len(entities), len(all))
    33  	for _, expected := range entities {
    34  		actual, ok := backData.ByID(expected.ID())
    35  		require.True(t, ok)
    36  		require.Equal(t, expected, actual)
    37  	}
    38  
    39  	// Identifiers
    40  	ids := backData.Identifiers()
    41  	require.Equal(t, len(entities), len(ids))
    42  	for _, id := range ids {
    43  		require.True(t, backData.Has(id))
    44  	}
    45  
    46  	// Entities
    47  	actualEntities := backData.Entities()
    48  	require.Equal(t, len(entities), len(actualEntities))
    49  	require.ElementsMatch(t, entities, actualEntities)
    50  }
    51  
    52  // TestMapBackData_AdjustWithInit tests the AdjustWithInit method of the MapBackData.
    53  // Note that as the backdata is not inherently thread-safe, this test is not concurrent.
    54  func TestMapBackData_AdjustWithInit(t *testing.T) {
    55  	backData := NewMapBackData()
    56  	entities := unittest.EntityListFixture(100)
    57  	ids := flow.GetIDs(entities)
    58  
    59  	// AdjustWithInit
    60  	for _, e := range entities {
    61  		// all entities must be adjusted successfully
    62  		actual, ok := backData.AdjustWithInit(e.ID(), func(entity flow.Entity) flow.Entity {
    63  			// increment nonce of the entity
    64  			entity.(*unittest.MockEntity).Nonce++
    65  			return entity
    66  		}, func() flow.Entity {
    67  			return e
    68  		})
    69  		require.True(t, ok)
    70  		require.Equal(t, e, actual)
    71  	}
    72  
    73  	// All
    74  	all := backData.All()
    75  	require.Equal(t, len(entities), len(all))
    76  	for _, expected := range entities {
    77  		actual, ok := backData.ByID(expected.ID())
    78  		require.True(t, ok)
    79  		require.Equal(t, expected.ID(), actual.ID())
    80  		require.Equal(t, uint64(1), actual.(*unittest.MockEntity).Nonce)
    81  	}
    82  
    83  	// Identifiers
    84  	retriedIds := backData.Identifiers()
    85  	require.Equal(t, len(entities), len(retriedIds))
    86  	require.ElementsMatch(t, ids, retriedIds)
    87  	for _, id := range retriedIds {
    88  		require.True(t, backData.Has(id))
    89  	}
    90  
    91  	// Entities
    92  	actualEntities := backData.Entities()
    93  	require.Equal(t, len(entities), len(actualEntities))
    94  	require.ElementsMatch(t, entities, actualEntities)
    95  
    96  	// ByID
    97  	for _, e := range entities {
    98  		// all entities must be retrieved successfully
    99  		actual, ok := backData.ByID(e.ID())
   100  		require.True(t, ok)
   101  		require.Equal(t, e.ID(), actual.ID())
   102  		require.Equal(t, uint64(1), actual.(*unittest.MockEntity).Nonce)
   103  	}
   104  
   105  	// GetWithInit
   106  	for _, e := range entities {
   107  		// all entities must be retrieved successfully
   108  		actual, ok := backData.GetWithInit(e.ID(), func() flow.Entity {
   109  			require.Fail(t, "should not be called") // entity has already been initialized
   110  			return e
   111  		})
   112  		require.True(t, ok)
   113  		require.Equal(t, e.ID(), actual.ID())
   114  		require.Equal(t, uint64(1), actual.(*unittest.MockEntity).Nonce)
   115  	}
   116  }
   117  
   118  // TestMapBackData_GetWithInit tests the GetWithInit method of the MapBackData.
   119  // Note that as the backdata is not inherently thread-safe, this test is not concurrent.
   120  func TestMapBackData_GetWithInit(t *testing.T) {
   121  	backData := NewMapBackData()
   122  	entities := unittest.EntityListFixture(100)
   123  
   124  	// GetWithInit
   125  	for _, e := range entities {
   126  		// all entities must be initialized retrieved successfully
   127  		actual, ok := backData.GetWithInit(e.ID(), func() flow.Entity {
   128  			return e // initialize with the entity
   129  		})
   130  		require.True(t, ok)
   131  		require.Equal(t, e, actual)
   132  	}
   133  
   134  	// All
   135  	all := backData.All()
   136  	require.Equal(t, len(entities), len(all))
   137  	for _, expected := range entities {
   138  		actual, ok := backData.ByID(expected.ID())
   139  		require.True(t, ok)
   140  		require.Equal(t, expected, actual)
   141  	}
   142  
   143  	// Identifiers
   144  	ids := backData.Identifiers()
   145  	require.Equal(t, len(entities), len(ids))
   146  	for _, id := range ids {
   147  		require.True(t, backData.Has(id))
   148  	}
   149  
   150  	// Entities
   151  	actualEntities := backData.Entities()
   152  	require.Equal(t, len(entities), len(actualEntities))
   153  	require.ElementsMatch(t, entities, actualEntities)
   154  
   155  	// Adjust
   156  	for _, e := range entities {
   157  		// all entities must be adjusted successfully
   158  		actual, ok := backData.Adjust(e.ID(), func(entity flow.Entity) flow.Entity {
   159  			// increment nonce of the entity
   160  			entity.(*unittest.MockEntity).Nonce++
   161  			return entity
   162  		})
   163  		require.True(t, ok)
   164  		require.Equal(t, e, actual)
   165  	}
   166  
   167  	// ByID; should return the latest version of the entity
   168  	for _, e := range entities {
   169  		// all entities must be retrieved successfully
   170  		actual, ok := backData.ByID(e.ID())
   171  		require.True(t, ok)
   172  		require.Equal(t, e.ID(), actual.ID())
   173  		require.Equal(t, uint64(1), actual.(*unittest.MockEntity).Nonce)
   174  	}
   175  
   176  	// GetWithInit; should return the latest version of the entity, than increment the nonce
   177  	for _, e := range entities {
   178  		// all entities must be retrieved successfully
   179  		actual, ok := backData.GetWithInit(e.ID(), func() flow.Entity {
   180  			require.Fail(t, "should not be called") // entity has already been initialized
   181  			return e
   182  		})
   183  		require.True(t, ok)
   184  		require.Equal(t, e.ID(), actual.ID())
   185  		require.Equal(t, uint64(1), actual.(*unittest.MockEntity).Nonce)
   186  	}
   187  }