github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/core/scc/cscc/configure_test.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 package cscc 17 18 import ( 19 "fmt" 20 "os" 21 "strings" 22 "testing" 23 "time" 24 25 "github.com/golang/protobuf/proto" 26 configtxtest "github.com/hyperledger/fabric/common/configtx/test" 27 "github.com/hyperledger/fabric/common/genesis" 28 "github.com/hyperledger/fabric/common/localmsp" 29 "github.com/hyperledger/fabric/common/mocks/scc" 30 "github.com/hyperledger/fabric/common/policies" 31 "github.com/hyperledger/fabric/core/chaincode" 32 "github.com/hyperledger/fabric/core/chaincode/shim" 33 "github.com/hyperledger/fabric/core/common/sysccprovider" 34 "github.com/hyperledger/fabric/core/deliverservice" 35 "github.com/hyperledger/fabric/core/deliverservice/blocksprovider" 36 "github.com/hyperledger/fabric/core/ledger/ledgermgmt" 37 "github.com/hyperledger/fabric/core/peer" 38 "github.com/hyperledger/fabric/core/policy" 39 policymocks "github.com/hyperledger/fabric/core/policy/mocks" 40 "github.com/hyperledger/fabric/gossip/api" 41 "github.com/hyperledger/fabric/gossip/service" 42 "github.com/hyperledger/fabric/msp/mgmt" 43 "github.com/hyperledger/fabric/msp/mgmt/testtools" 44 peergossip "github.com/hyperledger/fabric/peer/gossip" 45 "github.com/hyperledger/fabric/peer/gossip/mocks" 46 cb "github.com/hyperledger/fabric/protos/common" 47 pb "github.com/hyperledger/fabric/protos/peer" 48 "github.com/hyperledger/fabric/protos/utils" 49 "github.com/spf13/viper" 50 "github.com/stretchr/testify/assert" 51 ) 52 53 type mockDeliveryClient struct { 54 } 55 56 // StartDeliverForChannel dynamically starts delivery of new blocks from ordering service 57 // to channel peers. 58 func (ds *mockDeliveryClient) StartDeliverForChannel(chainID string, ledgerInfo blocksprovider.LedgerInfo) error { 59 return nil 60 } 61 62 // StopDeliverForChannel dynamically stops delivery of new blocks from ordering service 63 // to channel peers. 64 func (ds *mockDeliveryClient) StopDeliverForChannel(chainID string) error { 65 return nil 66 } 67 68 // Stop terminates delivery service and closes the connection 69 func (*mockDeliveryClient) Stop() { 70 71 } 72 73 type mockDeliveryClientFactory struct { 74 } 75 76 func (*mockDeliveryClientFactory) Service(g service.GossipService, endpoints []string, mcs api.MessageCryptoService) (deliverclient.DeliverService, error) { 77 return &mockDeliveryClient{}, nil 78 } 79 80 func TestMain(m *testing.M) { 81 msptesttools.LoadMSPSetupForTesting() 82 83 os.Exit(m.Run()) 84 } 85 86 func TestConfigerInit(t *testing.T) { 87 e := new(PeerConfiger) 88 stub := shim.NewMockStub("PeerConfiger", e) 89 90 if res := stub.MockInit("1", nil); res.Status != shim.OK { 91 fmt.Println("Init failed", string(res.Message)) 92 t.FailNow() 93 } 94 } 95 96 func TestConfigerInvokeInvalidParameters(t *testing.T) { 97 e := new(PeerConfiger) 98 stub := shim.NewMockStub("PeerConfiger", e) 99 100 res := stub.MockInit("1", nil) 101 assert.Equal(t, res.Status, int32(shim.OK), "Init failed") 102 103 res = stub.MockInvoke("2", nil) 104 assert.Equal(t, res.Status, int32(shim.ERROR), "CSCC invoke expected to fail having zero arguments") 105 assert.Equal(t, res.Message, "Incorrect number of arguments, 0") 106 107 args := [][]byte{[]byte("GetChannels")} 108 res = stub.MockInvokeWithSignedProposal("3", args, nil) 109 assert.Equal(t, res.Status, int32(shim.ERROR), "CSCC invoke expected to fail no signed proposal provided") 110 assert.Contains(t, res.Message, "failed authorization check") 111 112 args = [][]byte{[]byte("GetConfigBlock"), []byte("testChainID")} 113 res = stub.MockInvokeWithSignedProposal("4", args, nil) 114 assert.Equal(t, res.Status, int32(shim.ERROR), "CSCC invoke expected to fail no signed proposal provided") 115 assert.Contains(t, res.Message, "failed authorization check") 116 117 args = [][]byte{[]byte("fooFunction"), []byte("testChainID")} 118 res = stub.MockInvoke("5", args) 119 assert.Equal(t, res.Status, int32(shim.ERROR), "CSCC invoke expected wrong function name provided") 120 assert.Equal(t, res.Message, "Requested function fooFunction not found.") 121 } 122 123 func TestConfigerInvokeJoinChainMissingParams(t *testing.T) { 124 viper.Set("peer.fileSystemPath", "/tmp/hyperledgertest/") 125 os.Mkdir("/tmp/hyperledgertest", 0755) 126 defer os.RemoveAll("/tmp/hyperledgertest/") 127 128 e := new(PeerConfiger) 129 stub := shim.NewMockStub("PeerConfiger", e) 130 131 if res := stub.MockInit("1", nil); res.Status != shim.OK { 132 fmt.Println("Init failed", string(res.Message)) 133 t.FailNow() 134 } 135 136 // Failed path: expected to have at least one argument 137 args := [][]byte{[]byte("JoinChain")} 138 if res := stub.MockInvoke("2", args); res.Status == shim.OK { 139 t.Fatalf("cscc invoke JoinChain should have failed with invalid number of args: %v", args) 140 } 141 } 142 143 func TestConfigerInvokeJoinChainWrongParams(t *testing.T) { 144 viper.Set("peer.fileSystemPath", "/tmp/hyperledgertest/") 145 os.Mkdir("/tmp/hyperledgertest", 0755) 146 defer os.RemoveAll("/tmp/hyperledgertest/") 147 148 e := new(PeerConfiger) 149 stub := shim.NewMockStub("PeerConfiger", e) 150 151 if res := stub.MockInit("1", nil); res.Status != shim.OK { 152 fmt.Println("Init failed", string(res.Message)) 153 t.FailNow() 154 } 155 156 // Failed path: wrong parameter type 157 args := [][]byte{[]byte("JoinChain"), []byte("action")} 158 if res := stub.MockInvoke("2", args); res.Status == shim.OK { 159 t.Fatalf("cscc invoke JoinChain should have failed with null genesis block. args: %v", args) 160 } 161 } 162 163 func TestConfigerInvokeJoinChainCorrectParams(t *testing.T) { 164 sysccprovider.RegisterSystemChaincodeProviderFactory(&scc.MocksccProviderFactory{}) 165 166 viper.Set("peer.fileSystemPath", "/tmp/hyperledgertest/") 167 viper.Set("chaincode.executetimeout", "3s") 168 os.Mkdir("/tmp/hyperledgertest", 0755) 169 170 peer.MockInitialize() 171 ledgermgmt.InitializeTestEnv() 172 defer ledgermgmt.CleanupTestEnv() 173 defer os.RemoveAll("/tmp/hyperledgertest/") 174 175 e := new(PeerConfiger) 176 stub := shim.NewMockStub("PeerConfiger", e) 177 178 peerEndpoint := "localhost:13611" 179 getPeerEndpoint := func() (*pb.PeerEndpoint, error) { 180 return &pb.PeerEndpoint{Id: &pb.PeerID{Name: "cscctestpeer"}, Address: peerEndpoint}, nil 181 } 182 ccStartupTimeout := time.Duration(30000) * time.Millisecond 183 chaincode.NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout) 184 185 // Init the policy checker 186 policyManagerGetter := &policymocks.MockChannelPolicyManagerGetter{ 187 Managers: map[string]policies.Manager{ 188 "mytestchainid": &policymocks.MockChannelPolicyManager{MockPolicy: &policymocks.MockPolicy{Deserializer: &policymocks.MockIdentityDeserializer{[]byte("Alice"), []byte("msg1")}}}, 189 }, 190 } 191 192 identityDeserializer := &policymocks.MockIdentityDeserializer{[]byte("Alice"), []byte("msg1")} 193 194 e.policyChecker = policy.NewPolicyChecker( 195 policyManagerGetter, 196 identityDeserializer, 197 &policymocks.MockMSPPrincipalGetter{Principal: []byte("Alice")}, 198 ) 199 200 identity, _ := mgmt.GetLocalSigningIdentityOrPanic().Serialize() 201 messageCryptoService := peergossip.NewMCS(&mocks.ChannelPolicyManagerGetter{}, localmsp.NewSigner(), mgmt.NewDeserializersManager()) 202 secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager()) 203 service.InitGossipServiceCustomDeliveryFactory(identity, peerEndpoint, nil, &mockDeliveryClientFactory{}, messageCryptoService, secAdv, nil) 204 205 // Successful path for JoinChain 206 blockBytes := mockConfigBlock() 207 if blockBytes == nil { 208 t.Fatalf("cscc invoke JoinChain failed because invalid block") 209 } 210 args := [][]byte{[]byte("JoinChain"), blockBytes} 211 sProp, _ := utils.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1")) 212 identityDeserializer.Msg = sProp.ProposalBytes 213 sProp.Signature = sProp.ProposalBytes 214 215 // Try fail path with nil block 216 res := stub.MockInvokeWithSignedProposal("2", [][]byte{[]byte("JoinChain"), nil}, sProp) 217 assert.Equal(t, res.Status, int32(shim.ERROR)) 218 219 // Try fail path with block and nil payload header 220 payload, _ := proto.Marshal(&cb.Payload{}) 221 env, _ := proto.Marshal(&cb.Envelope{ 222 Payload: payload, 223 }) 224 badBlock := &cb.Block{ 225 Data: &cb.BlockData{ 226 Data: [][]byte{env}, 227 }, 228 } 229 badBlockBytes := utils.MarshalOrPanic(badBlock) 230 res = stub.MockInvokeWithSignedProposal("2", [][]byte{[]byte("JoinChain"), badBlockBytes}, sProp) 231 assert.Equal(t, res.Status, int32(shim.ERROR)) 232 233 // Now, continue with valid execution path 234 if res := stub.MockInvokeWithSignedProposal("2", args, sProp); res.Status != shim.OK { 235 t.Fatalf("cscc invoke JoinChain failed with: %v", res.Message) 236 } 237 238 // This call must fail 239 sProp.Signature = nil 240 res = stub.MockInvokeWithSignedProposal("3", args, sProp) 241 if res.Status == shim.OK { 242 t.Fatalf("cscc invoke JoinChain must fail : %v", res.Message) 243 } 244 assert.True(t, strings.HasPrefix(res.Message, "\"JoinChain\" request failed authorization check for channel")) 245 sProp.Signature = sProp.ProposalBytes 246 247 // Query the configuration block 248 //chainID := []byte{143, 222, 22, 192, 73, 145, 76, 110, 167, 154, 118, 66, 132, 204, 113, 168} 249 chainID, err := utils.GetChainIDFromBlockBytes(blockBytes) 250 if err != nil { 251 t.Fatalf("cscc invoke JoinChain failed with: %v", err) 252 } 253 args = [][]byte{[]byte("GetConfigBlock"), []byte(chainID)} 254 policyManagerGetter.Managers["mytestchainid"].(*policymocks.MockChannelPolicyManager).MockPolicy.(*policymocks.MockPolicy).Deserializer.(*policymocks.MockIdentityDeserializer).Msg = sProp.ProposalBytes 255 if res := stub.MockInvokeWithSignedProposal("2", args, sProp); res.Status != shim.OK { 256 t.Fatalf("cscc invoke GetConfigBlock failed with: %v", res.Message) 257 } 258 259 // get channels for the peer 260 args = [][]byte{[]byte(GetChannels)} 261 res = stub.MockInvokeWithSignedProposal("2", args, sProp) 262 if res.Status != shim.OK { 263 t.FailNow() 264 } 265 266 cqr := &pb.ChannelQueryResponse{} 267 err = proto.Unmarshal(res.Payload, cqr) 268 if err != nil { 269 t.FailNow() 270 } 271 272 // peer joined one channel so query should return an array with one channel 273 if len(cqr.GetChannels()) != 1 { 274 t.FailNow() 275 } 276 } 277 278 func TestPeerConfiger_SubmittingOrdererGenesis(t *testing.T) { 279 viper.Set("peer.fileSystemPath", "/tmp/hyperledgertest/") 280 os.Mkdir("/tmp/hyperledgertest", 0755) 281 defer os.RemoveAll("/tmp/hyperledgertest/") 282 283 e := new(PeerConfiger) 284 stub := shim.NewMockStub("PeerConfiger", e) 285 286 if res := stub.MockInit("1", nil); res.Status != shim.OK { 287 fmt.Println("Init failed", string(res.Message)) 288 t.FailNow() 289 } 290 291 block, err := genesis.NewFactoryImpl(configtxtest.OrdererTemplate()).Block("testChainID") 292 assert.NoError(t, err) 293 blockBytes := utils.MarshalOrPanic(block) 294 295 // Failed path: wrong parameter type 296 args := [][]byte{[]byte("JoinChain"), []byte(blockBytes)} 297 if res := stub.MockInvoke("2", args); res.Status == shim.OK { 298 t.Fatalf("cscc invoke JoinChain should have failed with wrong genesis block. args: %v", args) 299 } else { 300 assert.Contains(t, res.Message, "missing Application configuration group") 301 } 302 303 } 304 305 func mockConfigBlock() []byte { 306 var blockBytes []byte = nil 307 block, err := configtxtest.MakeGenesisBlock("mytestchainid") 308 if err == nil { 309 blockBytes = utils.MarshalOrPanic(block) 310 } 311 return blockBytes 312 }