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  }