github.com/true-sqn/fabric@v2.1.1+incompatible/internal/peer/channel/fetch_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package channel
     8  
     9  import (
    10  	"fmt"
    11  	"io/ioutil"
    12  	"os"
    13  	"path/filepath"
    14  	"testing"
    15  	"time"
    16  
    17  	cb "github.com/hyperledger/fabric-protos-go/common"
    18  	ab "github.com/hyperledger/fabric-protos-go/orderer"
    19  	"github.com/hyperledger/fabric/core/config/configtest"
    20  	"github.com/hyperledger/fabric/internal/peer/common"
    21  	"github.com/hyperledger/fabric/internal/peer/common/mock"
    22  	"github.com/hyperledger/fabric/protoutil"
    23  	"github.com/spf13/viper"
    24  	"github.com/stretchr/testify/assert"
    25  )
    26  
    27  func TestFetch(t *testing.T) {
    28  	defer resetFlags()
    29  	InitMSP()
    30  	resetFlags()
    31  	cleanup := configtest.SetDevFabricConfigPath(t)
    32  	defer cleanup()
    33  
    34  	mockchain := "mockchain"
    35  
    36  	signer, err := common.GetDefaultSigner()
    37  	if err != nil {
    38  		t.Fatalf("Get default signer error: %v", err)
    39  	}
    40  
    41  	mockCF := &ChannelCmdFactory{
    42  		BroadcastFactory: mockBroadcastClientFactory,
    43  		Signer:           signer,
    44  		DeliverClient:    getMockDeliverClient(mockchain),
    45  	}
    46  
    47  	tempDir, err := ioutil.TempDir("", "fetch-output")
    48  	if err != nil {
    49  		t.Fatalf("failed to create temporary directory")
    50  	}
    51  	defer os.RemoveAll(tempDir)
    52  
    53  	cmd := fetchCmd(mockCF)
    54  	AddFlags(cmd)
    55  
    56  	// success cases - block and outputBlockPath
    57  	blocksToFetch := []string{"oldest", "newest", "config", "1"}
    58  	for _, bestEffort := range []bool{false, true} {
    59  		for _, block := range blocksToFetch {
    60  			outputBlockPath := filepath.Join(tempDir, block+".block")
    61  			args := []string{"-c", mockchain, block, outputBlockPath}
    62  			if bestEffort {
    63  				args = append(args, "--bestEffort")
    64  			}
    65  			cmd.SetArgs(args)
    66  
    67  			err = cmd.Execute()
    68  			assert.NoError(t, err, "fetch command expected to succeed")
    69  
    70  			if _, err := os.Stat(outputBlockPath); os.IsNotExist(err) {
    71  				// path/to/whatever does not exist
    72  				t.Error("expected configuration block to be fetched")
    73  				t.Fail()
    74  			}
    75  		}
    76  	}
    77  
    78  	// failure case
    79  	blocksToFetchBad := []string{"banana"}
    80  	for _, block := range blocksToFetchBad {
    81  		outputBlockPath := filepath.Join(tempDir, block+".block")
    82  		args := []string{"-c", mockchain, block, outputBlockPath}
    83  		cmd.SetArgs(args)
    84  
    85  		err = cmd.Execute()
    86  		assert.Error(t, err, "fetch command expected to fail")
    87  		assert.Regexp(t, err.Error(), fmt.Sprintf("fetch target illegal: %s", block))
    88  
    89  		if fileInfo, _ := os.Stat(outputBlockPath); fileInfo != nil {
    90  			// path/to/whatever does exist
    91  			t.Error("expected configuration block to not be fetched")
    92  			t.Fail()
    93  		}
    94  	}
    95  }
    96  
    97  func TestFetchArgs(t *testing.T) {
    98  	// failure - no args
    99  	cmd := fetchCmd(nil)
   100  	AddFlags(cmd)
   101  	err := cmd.Execute()
   102  	assert.Error(t, err, "fetch command expected to fail")
   103  	assert.Contains(t, err.Error(), "fetch target required")
   104  
   105  	// failure - too many args
   106  	args := []string{"strawberry", "kiwi", "lemonade"}
   107  	cmd.SetArgs(args)
   108  	err = cmd.Execute()
   109  	assert.Error(t, err, "fetch command expected to fail")
   110  	assert.Contains(t, err.Error(), "trailing args detected")
   111  }
   112  
   113  func TestFetchNilCF(t *testing.T) {
   114  	defer viper.Reset()
   115  	defer resetFlags()
   116  
   117  	InitMSP()
   118  	resetFlags()
   119  	cleanup := configtest.SetDevFabricConfigPath(t)
   120  	defer cleanup()
   121  
   122  	mockchain := "mockchain"
   123  	viper.Set("peer.client.connTimeout", 10*time.Millisecond)
   124  	cmd := fetchCmd(nil)
   125  	AddFlags(cmd)
   126  	args := []string{"-c", mockchain, "oldest"}
   127  	cmd.SetArgs(args)
   128  	err := cmd.Execute()
   129  	assert.Error(t, err, "fetch command expected to fail")
   130  	assert.Contains(t, err.Error(), "deliver client failed to connect to")
   131  }
   132  
   133  func getMockDeliverClient(channelID string) *common.DeliverClient {
   134  	p := getMockDeliverClientWithBlock(channelID, createTestBlock())
   135  	return p
   136  }
   137  
   138  func getMockDeliverClientWithBlock(channelID string, block *cb.Block) *common.DeliverClient {
   139  	p := &common.DeliverClient{
   140  		Service:     getMockDeliverService(block),
   141  		ChannelID:   channelID,
   142  		TLSCertHash: []byte("tlscerthash"),
   143  	}
   144  	return p
   145  }
   146  
   147  func getMockDeliverService(block *cb.Block) *mock.DeliverService {
   148  	mockD := &mock.DeliverService{}
   149  	blockResponse := &ab.DeliverResponse{
   150  		Type: &ab.DeliverResponse_Block{
   151  			Block: block,
   152  		},
   153  	}
   154  	statusResponse := &ab.DeliverResponse{
   155  		Type: &ab.DeliverResponse_Status{Status: cb.Status_SUCCESS},
   156  	}
   157  	mockD.RecvStub = func() (*ab.DeliverResponse, error) {
   158  		// alternate returning block and status
   159  		if mockD.RecvCallCount()%2 == 1 {
   160  			return blockResponse, nil
   161  		}
   162  		return statusResponse, nil
   163  	}
   164  	mockD.CloseSendReturns(nil)
   165  	return mockD
   166  }
   167  
   168  func createTestBlock() *cb.Block {
   169  	metadataBytes := protoutil.MarshalOrPanic(&cb.Metadata{
   170  		Value: protoutil.MarshalOrPanic(&cb.OrdererBlockMetadata{
   171  			LastConfig: &cb.LastConfig{Index: 0},
   172  		}),
   173  	})
   174  
   175  	block := &cb.Block{
   176  		Header: &cb.BlockHeader{
   177  			Number: 0,
   178  		},
   179  		Metadata: &cb.BlockMetadata{
   180  			Metadata: [][]byte{metadataBytes},
   181  		},
   182  	}
   183  
   184  	return block
   185  }