github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/common/ledger/blkstorage/fsblkstorage/metrics_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package fsblkstorage 8 9 import ( 10 "testing" 11 "time" 12 13 "github.com/hyperledger/fabric/common/ledger/testutil" 14 "github.com/hyperledger/fabric/common/metrics" 15 "github.com/hyperledger/fabric/common/metrics/metricsfakes" 16 "github.com/stretchr/testify/assert" 17 ) 18 19 func TestStatsBlockchainHeight(t *testing.T) { 20 testMetricProvider := testutilConstructMetricProvider() 21 env := newTestEnvWithMetricsProvider(t, NewConf(testPath(), 0), testMetricProvider.fakeProvider) 22 defer env.Cleanup() 23 24 provider := env.provider 25 ledgerid := "ledger-stats" 26 store, err := provider.OpenBlockStore(ledgerid) 27 assert.NoError(t, err) 28 defer store.Shutdown() 29 30 // add genesis block 31 blockGenerator, genesisBlock := testutil.NewBlockGenerator(t, "testchannelid", false) 32 err = store.AddBlock(genesisBlock) 33 assert.NoError(t, err) 34 35 // add one more block 36 b1 := blockGenerator.NextBlock([][]byte{}) 37 err = store.AddBlock(b1) 38 assert.NoError(t, err) 39 40 // should have 3 calls for fakeBlockchainHeightGauge: OpenBlockStore, genesis block, and block b1 41 fakeBlockchainHeightGauge := testMetricProvider.fakeBlockchainHeightGauge 42 expectedCallCount := 3 43 assert.Equal(t, expectedCallCount, fakeBlockchainHeightGauge.SetCallCount()) 44 45 // verify the call for OpenBlockStore 46 assert.Equal(t, float64(0), fakeBlockchainHeightGauge.SetArgsForCall(0)) 47 assert.Equal(t, []string{"channel", ledgerid}, fakeBlockchainHeightGauge.WithArgsForCall(0)) 48 49 // verify the call for adding genesis block 50 assert.Equal(t, float64(1), fakeBlockchainHeightGauge.SetArgsForCall(1)) 51 assert.Equal(t, []string{"channel", ledgerid}, fakeBlockchainHeightGauge.WithArgsForCall(1)) 52 53 // verify the call for adding block b1 54 assert.Equal(t, float64(2), fakeBlockchainHeightGauge.SetArgsForCall(2)) 55 assert.Equal(t, []string{"channel", ledgerid}, fakeBlockchainHeightGauge.WithArgsForCall(2)) 56 57 // shutdown and reopen the store to verify blockchain height 58 store.Shutdown() 59 store, err = provider.OpenBlockStore(ledgerid) 60 assert.NoError(t, err) 61 62 // verify the call when opening an existing ledger - should set height correctly 63 assert.Equal(t, float64(2), fakeBlockchainHeightGauge.SetArgsForCall(3)) 64 assert.Equal(t, []string{"channel", ledgerid}, fakeBlockchainHeightGauge.WithArgsForCall(3)) 65 66 // invoke updateBlockStats api explicitly and verify the call with fake metrics 67 store.(*fsBlockStore).updateBlockStats(10, 1*time.Second) 68 assert.Equal(t, float64(11), fakeBlockchainHeightGauge.SetArgsForCall(4)) 69 assert.Equal(t, []string{"channel", ledgerid}, fakeBlockchainHeightGauge.WithArgsForCall(4)) 70 } 71 72 func TestStatsBlockCommit(t *testing.T) { 73 testMetricProvider := testutilConstructMetricProvider() 74 env := newTestEnvWithMetricsProvider(t, NewConf(testPath(), 0), testMetricProvider.fakeProvider) 75 defer env.Cleanup() 76 77 provider := env.provider 78 ledgerid := "ledger-stats" 79 store, err := provider.OpenBlockStore(ledgerid) 80 assert.NoError(t, err) 81 defer store.Shutdown() 82 83 // add a genesis block 84 blockGenerator, genesisBlock := testutil.NewBlockGenerator(t, "testchannelid", false) 85 err = store.AddBlock(genesisBlock) 86 assert.NoError(t, err) 87 88 // add 3 more blocks 89 for i := 1; i <= 3; i++ { 90 b := blockGenerator.NextBlock([][]byte{}) 91 err = store.AddBlock(b) 92 assert.NoError(t, err) 93 } 94 95 fakeBlockstorageCommitTimeHist := testMetricProvider.fakeBlockstorageCommitTimeHist 96 97 // should have 4 calls to fakeBlockstorageCommitTimeHist: genesis block, and 3 blocks 98 expectedCallCount := 1 + 3 99 assert.Equal(t, expectedCallCount, fakeBlockstorageCommitTimeHist.ObserveCallCount()) 100 101 // verify the value of channel in each call (0, 1, 2, 3) 102 for i := 0; i < expectedCallCount; i++ { 103 assert.Equal(t, []string{"channel", ledgerid}, fakeBlockstorageCommitTimeHist.WithArgsForCall(i)) 104 } 105 106 // invoke updateBlockStats api explicitly and verify with fake metrics (call number is 4) 107 store.(*fsBlockStore).updateBlockStats(4, 10*time.Second) 108 assert.Equal(t, 109 []string{"channel", ledgerid}, 110 testMetricProvider.fakeBlockstorageCommitTimeHist.WithArgsForCall(4), 111 ) 112 assert.Equal(t, 113 float64(10), 114 testMetricProvider.fakeBlockstorageCommitTimeHist.ObserveArgsForCall(4), 115 ) 116 } 117 118 type testMetricProvider struct { 119 fakeProvider *metricsfakes.Provider 120 fakeBlockchainHeightGauge *metricsfakes.Gauge 121 fakeBlockstorageCommitTimeHist *metricsfakes.Histogram 122 } 123 124 func testutilConstructMetricProvider() *testMetricProvider { 125 fakeProvider := &metricsfakes.Provider{} 126 fakeBlockchainHeightGauge := testutilConstructGauge() 127 fakeBlockstorageCommitTimeHist := testutilConstructHist() 128 fakeProvider.NewGaugeStub = func(opts metrics.GaugeOpts) metrics.Gauge { 129 switch opts.Name { 130 case blockchainHeightOpts.Name: 131 return fakeBlockchainHeightGauge 132 default: 133 return nil 134 } 135 } 136 fakeProvider.NewHistogramStub = func(opts metrics.HistogramOpts) metrics.Histogram { 137 switch opts.Name { 138 case blockstorageCommitTimeOpts.Name: 139 return fakeBlockstorageCommitTimeHist 140 default: 141 return nil 142 } 143 } 144 145 return &testMetricProvider{ 146 fakeProvider, 147 fakeBlockchainHeightGauge, 148 fakeBlockstorageCommitTimeHist, 149 } 150 } 151 152 func testutilConstructGauge() *metricsfakes.Gauge { 153 fakeGauge := &metricsfakes.Gauge{} 154 fakeGauge.WithStub = func(lableValues ...string) metrics.Gauge { 155 return fakeGauge 156 } 157 return fakeGauge 158 } 159 160 func testutilConstructHist() *metricsfakes.Histogram { 161 fakeHist := &metricsfakes.Histogram{} 162 fakeHist.WithStub = func(lableValues ...string) metrics.Histogram { 163 return fakeHist 164 } 165 return fakeHist 166 }