github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/snapshotgrpc/snapshot_service_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package snapshotgrpc 8 9 import ( 10 "context" 11 "fmt" 12 "io/ioutil" 13 "testing" 14 15 "github.com/hechain20/hechain/common/configtx/test" 16 "github.com/hechain20/hechain/core/ledger/ledgermgmt" 17 "github.com/hechain20/hechain/core/ledger/ledgermgmt/ledgermgmttest" 18 "github.com/hechain20/hechain/core/ledger/snapshotgrpc/mock" 19 "github.com/hechain20/hechain/protoutil" 20 "github.com/hyperledger/fabric-protos-go/common" 21 pb "github.com/hyperledger/fabric-protos-go/peer" 22 "github.com/stretchr/testify/require" 23 ) 24 25 //go:generate counterfeiter -o mock/ledger_getter.go -fake-name LedgerGetter . ledgerGetter 26 //go:generate counterfeiter -o mock/acl_provider.go -fake-name ACLProvider . aclProvider 27 28 type ledgerGetter interface { 29 LedgerGetter 30 } 31 32 type aclProvider interface { 33 ACLProvider 34 } 35 36 func TestSnapshot(t *testing.T) { 37 testDir, err := ioutil.TempDir("", "snapshotgrpc") 38 require.NoError(t, err) 39 40 ledgerID := "testsnapshot" 41 ledgermgmtInitializer := ledgermgmttest.NewInitializer(testDir) 42 ledgerMgr := ledgermgmt.NewLedgerMgr(ledgermgmtInitializer) 43 gb, err := test.MakeGenesisBlock(ledgerID) 44 require.NoError(t, err) 45 lgr, err := ledgerMgr.CreateLedger(ledgerID, gb) 46 require.NoError(t, err) 47 defer lgr.Close() 48 49 fakeLedgerGetter := &mock.LedgerGetter{} 50 fakeLedgerGetter.GetLedgerReturns(lgr) 51 fakeACLProvider := &mock.ACLProvider{} 52 fakeACLProvider.CheckACLNoChannelReturns(nil) 53 snapshotSvc := &SnapshotService{LedgerGetter: fakeLedgerGetter, ACLProvider: fakeACLProvider} 54 55 // test generate, cancel and query bindings 56 var signedRequest *pb.SignedSnapshotRequest 57 testData := []uint64{100, 50, 200} 58 for _, blockNumber := range testData { 59 signedRequest = createSignedRequest(ledgerID, blockNumber) 60 _, err = snapshotSvc.Generate(context.Background(), signedRequest) 61 require.NoError(t, err) 62 } 63 64 signedRequest = createSignedRequest(ledgerID, 100) 65 _, err = snapshotSvc.Cancel(context.Background(), signedRequest) 66 require.NoError(t, err) 67 68 expectedResponse := &pb.QueryPendingSnapshotsResponse{BlockNumbers: []uint64{50, 200}} 69 signedQuery := createSignedQuery(ledgerID) 70 resp, err := snapshotSvc.QueryPendings(context.Background(), signedQuery) 71 require.NoError(t, err) 72 require.Equal(t, expectedResponse, resp) 73 74 // test error propagation from ledger, generate blockNumber=50 should return an error 75 signedRequest = createSignedRequest(ledgerID, 50) 76 _, err = snapshotSvc.Generate(context.Background(), signedRequest) 77 require.EqualError(t, err, "duplicate snapshot request for block number 50") 78 79 // test error propagation from ledger, cancel blockNumber=100 again should return an error 80 signedRequest = createSignedRequest(ledgerID, 100) 81 _, err = snapshotSvc.Cancel(context.Background(), signedRequest) 82 require.EqualError(t, err, "no snapshot request exists for block number 100") 83 84 // common error tests for all requests 85 tests := []struct { 86 name string 87 channelID string 88 signedRequest *pb.SignedSnapshotRequest 89 errMsg string 90 }{ 91 { 92 name: "unmarshal error", 93 signedRequest: &pb.SignedSnapshotRequest{Request: []byte("dummy")}, 94 errMsg: "failed to unmarshal snapshot request: proto: can't skip unknown wire type 4", 95 }, 96 { 97 name: "missing channel ID", 98 channelID: "", 99 signedRequest: createSignedQuery(""), 100 errMsg: "missing channel ID", 101 }, 102 { 103 name: "missing signature header", 104 channelID: "", 105 signedRequest: &pb.SignedSnapshotRequest{Request: protoutil.MarshalOrPanic(&pb.SnapshotQuery{})}, 106 errMsg: "missing signature header", 107 }, 108 { 109 name: "cannot find ledger", 110 channelID: ledgerID, 111 signedRequest: createSignedQuery(ledgerID), 112 errMsg: "cannot find ledger for channel " + ledgerID, 113 }, 114 } 115 116 fakeLedgerGetter.GetLedgerReturns(nil) 117 for _, test := range tests { 118 t.Run(test.name, func(t *testing.T) { 119 _, err := snapshotSvc.Generate(context.Background(), test.signedRequest) 120 require.EqualError(t, err, test.errMsg) 121 _, err = snapshotSvc.Cancel(context.Background(), test.signedRequest) 122 require.EqualError(t, err, test.errMsg) 123 _, err = snapshotSvc.QueryPendings(context.Background(), test.signedRequest) 124 require.EqualError(t, err, test.errMsg) 125 }) 126 } 127 128 // test error propagation of CheckACLNoChannel 129 fakeACLProvider.CheckACLNoChannelReturns(fmt.Errorf("fake-check-acl-error")) 130 signedRequest = createSignedQuery(ledgerID) 131 _, err = snapshotSvc.Generate(context.Background(), signedRequest) 132 require.EqualError(t, err, "fake-check-acl-error") 133 _, err = snapshotSvc.Cancel(context.Background(), signedRequest) 134 require.EqualError(t, err, "fake-check-acl-error") 135 _, err = snapshotSvc.QueryPendings(context.Background(), signedRequest) 136 require.EqualError(t, err, "fake-check-acl-error") 137 138 // verify panic from generate/cancel after ledger is closed 139 lgr.Close() 140 fakeLedgerGetter.GetLedgerReturns(lgr) 141 fakeACLProvider.CheckACLNoChannelReturns(nil) 142 143 require.PanicsWithError( 144 t, 145 "send on closed channel", 146 func() { snapshotSvc.Generate(context.Background(), signedRequest) }, 147 ) 148 require.PanicsWithError( 149 t, 150 "send on closed channel", 151 func() { snapshotSvc.Cancel(context.Background(), signedRequest) }, 152 ) 153 } 154 155 func createSignedRequest(channelID string, blockNumber uint64) *pb.SignedSnapshotRequest { 156 sigHeader := &common.SignatureHeader{ 157 Creator: []byte("creator"), 158 Nonce: []byte("nonce-ignored"), 159 } 160 request := &pb.SnapshotRequest{ 161 SignatureHeader: sigHeader, 162 ChannelId: channelID, 163 BlockNumber: blockNumber, 164 } 165 return &pb.SignedSnapshotRequest{ 166 Request: protoutil.MarshalOrPanic(request), 167 Signature: []byte("dummy-signatures"), 168 } 169 } 170 171 func createSignedQuery(channelID string) *pb.SignedSnapshotRequest { 172 sigHeader := &common.SignatureHeader{ 173 Creator: []byte("creator"), 174 Nonce: []byte("nonce-ignored"), 175 } 176 query := &pb.SnapshotQuery{ 177 SignatureHeader: sigHeader, 178 ChannelId: channelID, 179 } 180 return &pb.SignedSnapshotRequest{ 181 Request: protoutil.MarshalOrPanic(query), 182 Signature: []byte("dummy-signatures"), 183 } 184 }