github.com/defanghe/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 }