github.com/ethereum-optimism/optimism@v1.7.2/op-node/rollup/driver/metered_l1fetcher_test.go (about) 1 package driver 2 3 import ( 4 "context" 5 "errors" 6 "testing" 7 "time" 8 9 "github.com/ethereum-optimism/optimism/op-service/eth" 10 "github.com/ethereum-optimism/optimism/op-service/testutils" 11 "github.com/ethereum/go-ethereum/common" 12 "github.com/ethereum/go-ethereum/core/types" 13 "github.com/stretchr/testify/mock" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func TestDurationRecorded(t *testing.T) { 18 num := uint64(1234) 19 hash := common.Hash{0xaa} 20 ref := eth.L1BlockRef{Number: num} 21 info := &testutils.MockBlockInfo{} 22 expectedErr := errors.New("test error") 23 24 tests := []struct { 25 method string 26 expect func(inner *testutils.MockL1Source) 27 call func(t *testing.T, fetcher *MeteredL1Fetcher, inner *testutils.MockL1Source) 28 }{ 29 { 30 method: "L1BlockRefByLabel", 31 call: func(t *testing.T, fetcher *MeteredL1Fetcher, inner *testutils.MockL1Source) { 32 inner.ExpectL1BlockRefByLabel(eth.Finalized, ref, expectedErr) 33 34 result, err := fetcher.L1BlockRefByLabel(context.Background(), eth.Finalized) 35 require.Equal(t, ref, result) 36 require.Equal(t, expectedErr, err) 37 }, 38 }, 39 { 40 method: "L1BlockRefByNumber", 41 call: func(t *testing.T, fetcher *MeteredL1Fetcher, inner *testutils.MockL1Source) { 42 inner.ExpectL1BlockRefByNumber(num, ref, expectedErr) 43 44 result, err := fetcher.L1BlockRefByNumber(context.Background(), num) 45 require.Equal(t, ref, result) 46 require.Equal(t, expectedErr, err) 47 }, 48 }, 49 { 50 method: "L1BlockRefByHash", 51 call: func(t *testing.T, fetcher *MeteredL1Fetcher, inner *testutils.MockL1Source) { 52 inner.ExpectL1BlockRefByHash(hash, ref, expectedErr) 53 54 result, err := fetcher.L1BlockRefByHash(context.Background(), hash) 55 require.Equal(t, ref, result) 56 require.Equal(t, expectedErr, err) 57 }, 58 }, 59 { 60 method: "InfoByHash", 61 call: func(t *testing.T, fetcher *MeteredL1Fetcher, inner *testutils.MockL1Source) { 62 inner.ExpectInfoByHash(hash, info, expectedErr) 63 64 result, err := fetcher.InfoByHash(context.Background(), hash) 65 require.Equal(t, info, result) 66 require.Equal(t, expectedErr, err) 67 }, 68 }, 69 { 70 method: "InfoAndTxsByHash", 71 call: func(t *testing.T, fetcher *MeteredL1Fetcher, inner *testutils.MockL1Source) { 72 txs := types.Transactions{ 73 &types.Transaction{}, 74 } 75 inner.ExpectInfoAndTxsByHash(hash, info, txs, expectedErr) 76 77 actualInfo, actualTxs, err := fetcher.InfoAndTxsByHash(context.Background(), hash) 78 require.Equal(t, info, actualInfo) 79 require.Equal(t, txs, actualTxs) 80 require.Equal(t, expectedErr, err) 81 }, 82 }, 83 { 84 method: "FetchReceipts", 85 call: func(t *testing.T, fetcher *MeteredL1Fetcher, inner *testutils.MockL1Source) { 86 rcpts := types.Receipts{ 87 &types.Receipt{}, 88 } 89 inner.ExpectFetchReceipts(hash, info, rcpts, expectedErr) 90 91 actualInfo, actualRcpts, err := fetcher.FetchReceipts(context.Background(), hash) 92 require.Equal(t, info, actualInfo) 93 require.Equal(t, rcpts, actualRcpts) 94 require.Equal(t, expectedErr, err) 95 }, 96 }, 97 } 98 for _, test := range tests { 99 test := test 100 t.Run(test.method, func(t *testing.T) { 101 duration := 200 * time.Millisecond 102 fetcher, inner, metrics := createFetcher(duration) 103 defer inner.AssertExpectations(t) 104 defer metrics.AssertExpectations(t) 105 106 metrics.ExpectRecordRequestTime(test.method, duration) 107 108 test.call(t, fetcher, inner) 109 }) 110 } 111 } 112 113 // createFetcher creates a MeteredL1Fetcher with a mock inner. 114 // The clock used to calculate the current time will advance by clockIncrement on each call, making it appear as if 115 // each request takes that amount of time to execute. 116 func createFetcher(clockIncrement time.Duration) (*MeteredL1Fetcher, *testutils.MockL1Source, *mockMetrics) { 117 inner := &testutils.MockL1Source{} 118 currTime := time.UnixMilli(1294812934000000) 119 clock := func() time.Time { 120 currTime = currTime.Add(clockIncrement) 121 return currTime 122 } 123 metrics := &mockMetrics{} 124 fetcher := MeteredL1Fetcher{ 125 inner: inner, 126 metrics: metrics, 127 now: clock, 128 } 129 return &fetcher, inner, metrics 130 } 131 132 type mockMetrics struct { 133 mock.Mock 134 } 135 136 func (m *mockMetrics) RecordL1RequestTime(method string, duration time.Duration) { 137 m.MethodCalled("RecordL1RequestTime", method, duration) 138 } 139 140 func (m *mockMetrics) ExpectRecordRequestTime(method string, duration time.Duration) { 141 m.On("RecordL1RequestTime", method, duration).Once() 142 }