github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/core/ledger/kvledger/kv_ledger_provider_test.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package kvledger 8 9 import ( 10 "fmt" 11 "io/ioutil" 12 "os" 13 "path/filepath" 14 "testing" 15 16 "github.com/golang/protobuf/proto" 17 "github.com/hyperledger/fabric-protos-go/common" 18 "github.com/hyperledger/fabric-protos-go/ledger/queryresult" 19 "github.com/hyperledger/fabric-protos-go/peer" 20 "github.com/hyperledger/fabric/bccsp/sw" 21 configtxtest "github.com/hyperledger/fabric/common/configtx/test" 22 "github.com/hyperledger/fabric/common/ledger/blkstorage/fsblkstorage" 23 "github.com/hyperledger/fabric/common/ledger/dataformat" 24 "github.com/hyperledger/fabric/common/ledger/testutil" 25 "github.com/hyperledger/fabric/common/metrics/disabled" 26 "github.com/hyperledger/fabric/common/util" 27 "github.com/hyperledger/fabric/core/ledger" 28 lgr "github.com/hyperledger/fabric/core/ledger" 29 "github.com/hyperledger/fabric/core/ledger/kvledger/msgs" 30 "github.com/hyperledger/fabric/core/ledger/mock" 31 "github.com/hyperledger/fabric/protoutil" 32 "github.com/stretchr/testify/assert" 33 "github.com/stretchr/testify/require" 34 ) 35 36 func TestLedgerProvider(t *testing.T) { 37 conf, cleanup := testConfig(t) 38 defer cleanup() 39 provider := testutilNewProvider(conf, t) 40 numLedgers := 10 41 existingLedgerIDs, err := provider.List() 42 assert.NoError(t, err) 43 assert.Len(t, existingLedgerIDs, 0) 44 genesisBlocks := make([]*common.Block, numLedgers) 45 for i := 0; i < numLedgers; i++ { 46 genesisBlock, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(i)) 47 genesisBlocks[i] = genesisBlock 48 provider.Create(genesisBlock) 49 } 50 existingLedgerIDs, err = provider.List() 51 assert.NoError(t, err) 52 assert.Len(t, existingLedgerIDs, numLedgers) 53 54 // verify formatKey is present in idStore 55 s := provider.idStore 56 val, err := s.db.Get(formatKey) 57 require.NoError(t, err) 58 require.Equal(t, []byte(dataformat.Version20), val) 59 60 provider.Close() 61 62 provider = testutilNewProvider(conf, t) 63 defer provider.Close() 64 ledgerIds, _ := provider.List() 65 assert.Len(t, ledgerIds, numLedgers) 66 for i := 0; i < numLedgers; i++ { 67 assert.Equal(t, constructTestLedgerID(i), ledgerIds[i]) 68 } 69 for i := 0; i < numLedgers; i++ { 70 ledgerid := constructTestLedgerID(i) 71 status, _ := provider.Exists(ledgerid) 72 assert.True(t, status) 73 ledger, err := provider.Open(ledgerid) 74 assert.NoError(t, err) 75 bcInfo, err := ledger.GetBlockchainInfo() 76 ledger.Close() 77 assert.NoError(t, err) 78 assert.Equal(t, uint64(1), bcInfo.Height) 79 80 // check that the genesis block was persisted in the provider's db 81 s := provider.idStore 82 gbBytesInProviderStore, err := s.db.Get(s.encodeLedgerKey(ledgerid, ledgerKeyPrefix)) 83 assert.NoError(t, err) 84 gb := &common.Block{} 85 assert.NoError(t, proto.Unmarshal(gbBytesInProviderStore, gb)) 86 assert.True(t, proto.Equal(gb, genesisBlocks[i]), "proto messages are not equal") 87 88 // check that ledger metadata keys were persisted in idStore with active status 89 val, err := s.db.Get(s.encodeLedgerKey(ledgerid, metadataKeyPrefix)) 90 require.NoError(t, err) 91 metadata := &msgs.LedgerMetadata{} 92 require.NoError(t, proto.Unmarshal(val, metadata)) 93 require.Equal(t, msgs.Status_ACTIVE, metadata.Status) 94 } 95 gb, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(2)) 96 _, err = provider.Create(gb) 97 assert.Equal(t, ErrLedgerIDExists, err) 98 99 status, err := provider.Exists(constructTestLedgerID(numLedgers)) 100 assert.NoError(t, err, "Failed to check for ledger existence") 101 assert.Equal(t, status, false) 102 103 _, err = provider.Open(constructTestLedgerID(numLedgers)) 104 assert.Equal(t, ErrNonExistingLedgerID, err) 105 } 106 107 func TestGetActiveLedgerIDsIteratorError(t *testing.T) { 108 conf, cleanup := testConfig(t) 109 defer cleanup() 110 provider := testutilNewProvider(conf, t) 111 112 for i := 0; i < 2; i++ { 113 genesisBlock, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(i)) 114 provider.Create(genesisBlock) 115 } 116 117 // close provider to trigger db error 118 provider.Close() 119 _, err := provider.idStore.getActiveLedgerIDs() 120 require.EqualError(t, err, "error getting ledger ids from idStore: leveldb: closed") 121 } 122 123 func TestLedgerMetataDataUnmarshalError(t *testing.T) { 124 conf, cleanup := testConfig(t) 125 defer cleanup() 126 provider := testutilNewProvider(conf, t) 127 defer provider.Close() 128 129 ledgerID := constructTestLedgerID(0) 130 genesisBlock, _ := configtxtest.MakeGenesisBlock(ledgerID) 131 provider.Create(genesisBlock) 132 133 // put invalid bytes for the metatdata key 134 provider.idStore.db.Put(provider.idStore.encodeLedgerKey(ledgerID, metadataKeyPrefix), []byte("invalid"), true) 135 136 _, err := provider.List() 137 require.EqualError(t, err, "error unmarshalling ledger metadata: unexpected EOF") 138 139 _, err = provider.Open(ledgerID) 140 require.EqualError(t, err, "error unmarshalling ledger metadata: unexpected EOF") 141 } 142 143 func TestNewProviderIdStoreFormatError(t *testing.T) { 144 conf, cleanup := testConfig(t) 145 defer cleanup() 146 147 require.NoError(t, testutil.Unzip("tests/testdata/v11/sample_ledgers/ledgersData.zip", conf.RootFSPath, false)) 148 149 // NewProvider fails because ledgerProvider (idStore) has old format 150 _, err := NewProvider( 151 &lgr.Initializer{ 152 DeployedChaincodeInfoProvider: &mock.DeployedChaincodeInfoProvider{}, 153 MetricsProvider: &disabled.Provider{}, 154 Config: conf, 155 }, 156 ) 157 require.EqualError(t, err, fmt.Sprintf("unexpected format. db info = [leveldb for channel-IDs at [%s]], data format = [], expected format = [2.0]", LedgerProviderPath(conf.RootFSPath))) 158 } 159 160 func TestUpgradeIDStoreFormatDBError(t *testing.T) { 161 conf, cleanup := testConfig(t) 162 defer cleanup() 163 provider := testutilNewProvider(conf, t) 164 provider.Close() 165 166 err := provider.idStore.upgradeFormat() 167 require.EqualError(t, err, "error retrieving leveldb key [[]byte{0x66}]: leveldb: closed") 168 } 169 170 func TestLedgerProviderHistoryDBDisabled(t *testing.T) { 171 conf, cleanup := testConfig(t) 172 conf.HistoryDBConfig.Enabled = false 173 defer cleanup() 174 provider := testutilNewProvider(conf, t) 175 numLedgers := 10 176 existingLedgerIDs, err := provider.List() 177 assert.NoError(t, err) 178 assert.Len(t, existingLedgerIDs, 0) 179 genesisBlocks := make([]*common.Block, numLedgers) 180 for i := 0; i < numLedgers; i++ { 181 genesisBlock, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(i)) 182 genesisBlocks[i] = genesisBlock 183 provider.Create(genesisBlock) 184 } 185 existingLedgerIDs, err = provider.List() 186 assert.NoError(t, err) 187 assert.Len(t, existingLedgerIDs, numLedgers) 188 189 provider.Close() 190 191 provider = testutilNewProvider(conf, t) 192 defer provider.Close() 193 ledgerIds, _ := provider.List() 194 assert.Len(t, ledgerIds, numLedgers) 195 t.Logf("ledgerIDs=%#v", ledgerIds) 196 for i := 0; i < numLedgers; i++ { 197 assert.Equal(t, constructTestLedgerID(i), ledgerIds[i]) 198 } 199 for i := 0; i < numLedgers; i++ { 200 ledgerid := constructTestLedgerID(i) 201 status, _ := provider.Exists(ledgerid) 202 assert.True(t, status) 203 ledger, err := provider.Open(ledgerid) 204 assert.NoError(t, err) 205 bcInfo, err := ledger.GetBlockchainInfo() 206 ledger.Close() 207 assert.NoError(t, err) 208 assert.Equal(t, uint64(1), bcInfo.Height) 209 210 // check that the genesis block was persisted in the provider's db 211 s := provider.idStore 212 gbBytesInProviderStore, err := s.db.Get(s.encodeLedgerKey(ledgerid, ledgerKeyPrefix)) 213 assert.NoError(t, err) 214 gb := &common.Block{} 215 assert.NoError(t, proto.Unmarshal(gbBytesInProviderStore, gb)) 216 assert.True(t, proto.Equal(gb, genesisBlocks[i]), "proto messages are not equal") 217 } 218 gb, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(2)) 219 _, err = provider.Create(gb) 220 assert.Equal(t, ErrLedgerIDExists, err) 221 222 status, err := provider.Exists(constructTestLedgerID(numLedgers)) 223 assert.NoError(t, err, "Failed to check for ledger existence") 224 assert.Equal(t, status, false) 225 226 _, err = provider.Open(constructTestLedgerID(numLedgers)) 227 assert.Equal(t, ErrNonExistingLedgerID, err) 228 229 } 230 231 func TestRecovery(t *testing.T) { 232 conf, cleanup := testConfig(t) 233 defer cleanup() 234 provider1 := testutilNewProvider(conf, t) 235 defer provider1.Close() 236 237 // now create the genesis block 238 genesisBlock, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(1)) 239 ledger, err := provider1.openInternal(constructTestLedgerID(1)) 240 ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: genesisBlock}, &lgr.CommitOptions{}) 241 ledger.Close() 242 243 // Case 1: assume a crash happens, force underconstruction flag to be set to simulate 244 // a failure where ledgerid is being created - ie., block is written but flag is not unset 245 provider1.idStore.setUnderConstructionFlag(constructTestLedgerID(1)) 246 provider1.Close() 247 248 // construct a new provider1 to invoke recovery 249 provider1 = testutilNewProvider(conf, t) 250 // verify the underecoveryflag and open the ledger 251 flag, err := provider1.idStore.getUnderConstructionFlag() 252 assert.NoError(t, err, "Failed to read the underconstruction flag") 253 assert.Equal(t, "", flag) 254 ledger, err = provider1.Open(constructTestLedgerID(1)) 255 assert.NoError(t, err, "Failed to open the ledger") 256 ledger.Close() 257 258 // Case 0: assume a crash happens before the genesis block of ledger 2 is committed 259 // Open the ID store (inventory of chainIds/ledgerIds) 260 provider1.idStore.setUnderConstructionFlag(constructTestLedgerID(2)) 261 provider1.Close() 262 263 // construct a new provider to invoke recovery 264 provider2 := testutilNewProvider(conf, t) 265 defer provider2.Close() 266 assert.NoError(t, err, "Provider failed to recover an underConstructionLedger") 267 flag, err = provider2.idStore.getUnderConstructionFlag() 268 assert.NoError(t, err, "Failed to read the underconstruction flag") 269 assert.Equal(t, "", flag) 270 } 271 272 func TestRecoveryHistoryDBDisabled(t *testing.T) { 273 conf, cleanup := testConfig(t) 274 conf.HistoryDBConfig.Enabled = false 275 defer cleanup() 276 provider1 := testutilNewProvider(conf, t) 277 defer provider1.Close() 278 279 // now create the genesis block 280 genesisBlock, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(1)) 281 ledger, err := provider1.openInternal(constructTestLedgerID(1)) 282 assert.NoError(t, err, "Failed to open the ledger") 283 ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: genesisBlock}, &lgr.CommitOptions{}) 284 ledger.Close() 285 286 // Case 1: assume a crash happens, force underconstruction flag to be set to simulate 287 // a failure where ledgerid is being created - ie., block is written but flag is not unset 288 provider1.idStore.setUnderConstructionFlag(constructTestLedgerID(1)) 289 provider1.Close() 290 291 // construct a new provider to invoke recovery 292 provider2 := testutilNewProvider(conf, t) 293 defer provider2.Close() 294 // verify the underecoveryflag and open the ledger 295 flag, err := provider2.idStore.getUnderConstructionFlag() 296 assert.NoError(t, err, "Failed to read the underconstruction flag") 297 assert.Equal(t, "", flag) 298 ledger, err = provider2.Open(constructTestLedgerID(1)) 299 assert.NoError(t, err, "Failed to open the ledger") 300 ledger.Close() 301 302 // Case 0: assume a crash happens before the genesis block of ledger 2 is committed 303 // Open the ID store (inventory of chainIds/ledgerIds) 304 provider2.idStore.setUnderConstructionFlag(constructTestLedgerID(2)) 305 provider2.Close() 306 307 // construct a new provider to invoke recovery 308 provider3 := testutilNewProvider(conf, t) 309 defer provider3.Close() 310 assert.NoError(t, err, "Provider failed to recover an underConstructionLedger") 311 flag, err = provider3.idStore.getUnderConstructionFlag() 312 assert.NoError(t, err, "Failed to read the underconstruction flag") 313 assert.Equal(t, "", flag) 314 } 315 316 func TestMultipleLedgerBasicRW(t *testing.T) { 317 conf, cleanup := testConfig(t) 318 defer cleanup() 319 provider1 := testutilNewProvider(conf, t) 320 defer provider1.Close() 321 322 numLedgers := 10 323 ledgers := make([]lgr.PeerLedger, numLedgers) 324 for i := 0; i < numLedgers; i++ { 325 bg, gb := testutil.NewBlockGenerator(t, constructTestLedgerID(i), false) 326 l, err := provider1.Create(gb) 327 assert.NoError(t, err) 328 ledgers[i] = l 329 txid := util.GenerateUUID() 330 s, _ := l.NewTxSimulator(txid) 331 err = s.SetState("ns", "testKey", []byte(fmt.Sprintf("testValue_%d", i))) 332 s.Done() 333 assert.NoError(t, err) 334 res, err := s.GetTxSimulationResults() 335 assert.NoError(t, err) 336 pubSimBytes, _ := res.GetPubSimulationBytes() 337 b := bg.NextBlock([][]byte{pubSimBytes}) 338 err = l.CommitLegacy(&lgr.BlockAndPvtData{Block: b}, &ledger.CommitOptions{}) 339 l.Close() 340 assert.NoError(t, err) 341 } 342 343 provider1.Close() 344 345 provider2 := testutilNewProvider(conf, t) 346 defer provider2.Close() 347 ledgers = make([]lgr.PeerLedger, numLedgers) 348 for i := 0; i < numLedgers; i++ { 349 l, err := provider2.Open(constructTestLedgerID(i)) 350 assert.NoError(t, err) 351 ledgers[i] = l 352 } 353 354 for i, l := range ledgers { 355 q, _ := l.NewQueryExecutor() 356 val, err := q.GetState("ns", "testKey") 357 q.Done() 358 assert.NoError(t, err) 359 assert.Equal(t, []byte(fmt.Sprintf("testValue_%d", i)), val) 360 l.Close() 361 } 362 } 363 364 func TestLedgerBackup(t *testing.T) { 365 ledgerid := "TestLedger" 366 basePath, err := ioutil.TempDir("", "kvledger") 367 require.NoError(t, err, "Failed to create ledger directory") 368 defer os.RemoveAll(basePath) 369 originalPath := filepath.Join(basePath, "kvledger1") 370 restorePath := filepath.Join(basePath, "kvledger2") 371 372 // create and populate a ledger in the original environment 373 origConf := &lgr.Config{ 374 RootFSPath: originalPath, 375 StateDBConfig: &lgr.StateDBConfig{}, 376 PrivateDataConfig: &lgr.PrivateDataConfig{ 377 MaxBatchSize: 5000, 378 BatchesInterval: 1000, 379 PurgeInterval: 100, 380 }, 381 HistoryDBConfig: &lgr.HistoryDBConfig{ 382 Enabled: true, 383 }, 384 } 385 provider := testutilNewProvider(origConf, t) 386 bg, gb := testutil.NewBlockGenerator(t, ledgerid, false) 387 gbHash := protoutil.BlockHeaderHash(gb.Header) 388 ledger, _ := provider.Create(gb) 389 390 txid := util.GenerateUUID() 391 simulator, _ := ledger.NewTxSimulator(txid) 392 simulator.SetState("ns1", "key1", []byte("value1")) 393 simulator.SetState("ns1", "key2", []byte("value2")) 394 simulator.SetState("ns1", "key3", []byte("value3")) 395 simulator.Done() 396 simRes, _ := simulator.GetTxSimulationResults() 397 pubSimBytes, _ := simRes.GetPubSimulationBytes() 398 block1 := bg.NextBlock([][]byte{pubSimBytes}) 399 ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block1}, &lgr.CommitOptions{}) 400 401 txid = util.GenerateUUID() 402 simulator, _ = ledger.NewTxSimulator(txid) 403 simulator.SetState("ns1", "key1", []byte("value4")) 404 simulator.SetState("ns1", "key2", []byte("value5")) 405 simulator.SetState("ns1", "key3", []byte("value6")) 406 simulator.Done() 407 simRes, _ = simulator.GetTxSimulationResults() 408 pubSimBytes, _ = simRes.GetPubSimulationBytes() 409 block2 := bg.NextBlock([][]byte{pubSimBytes}) 410 ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block2}, &lgr.CommitOptions{}) 411 412 ledger.Close() 413 provider.Close() 414 415 // remove the statedb, historydb, and block indexes (they are supposed to be auto created during opening of an existing ledger) 416 // and rename the originalPath to restorePath 417 assert.NoError(t, os.RemoveAll(StateDBPath(originalPath))) 418 assert.NoError(t, os.RemoveAll(HistoryDBPath(originalPath))) 419 assert.NoError(t, os.RemoveAll(filepath.Join(BlockStorePath(originalPath), fsblkstorage.IndexDir))) 420 assert.NoError(t, os.Rename(originalPath, restorePath)) 421 422 // Instantiate the ledger from restore environment and this should behave exactly as it would have in the original environment 423 restoreConf := &lgr.Config{ 424 RootFSPath: restorePath, 425 StateDBConfig: &lgr.StateDBConfig{}, 426 PrivateDataConfig: &lgr.PrivateDataConfig{ 427 MaxBatchSize: 5000, 428 BatchesInterval: 1000, 429 PurgeInterval: 100, 430 }, 431 HistoryDBConfig: &lgr.HistoryDBConfig{ 432 Enabled: true, 433 }, 434 } 435 provider = testutilNewProvider(restoreConf, t) 436 defer provider.Close() 437 438 _, err = provider.Create(gb) 439 assert.Equal(t, ErrLedgerIDExists, err) 440 441 ledger, _ = provider.Open(ledgerid) 442 defer ledger.Close() 443 444 block1Hash := protoutil.BlockHeaderHash(block1.Header) 445 block2Hash := protoutil.BlockHeaderHash(block2.Header) 446 bcInfo, _ := ledger.GetBlockchainInfo() 447 assert.Equal(t, &common.BlockchainInfo{ 448 Height: 3, CurrentBlockHash: block2Hash, PreviousBlockHash: block1Hash, 449 }, bcInfo) 450 451 b0, _ := ledger.GetBlockByHash(gbHash) 452 assert.True(t, proto.Equal(b0, gb), "proto messages are not equal") 453 454 b1, _ := ledger.GetBlockByHash(block1Hash) 455 assert.True(t, proto.Equal(b1, block1), "proto messages are not equal") 456 457 b2, _ := ledger.GetBlockByHash(block2Hash) 458 assert.True(t, proto.Equal(b2, block2), "proto messages are not equal") 459 460 b0, _ = ledger.GetBlockByNumber(0) 461 assert.True(t, proto.Equal(b0, gb), "proto messages are not equal") 462 463 b1, _ = ledger.GetBlockByNumber(1) 464 assert.True(t, proto.Equal(b1, block1), "proto messages are not equal") 465 466 b2, _ = ledger.GetBlockByNumber(2) 467 assert.True(t, proto.Equal(b2, block2), "proto messages are not equal") 468 469 // get the tran id from the 2nd block, then use it to test GetTransactionByID() 470 txEnvBytes2 := block1.Data.Data[0] 471 txEnv2, err := protoutil.GetEnvelopeFromBlock(txEnvBytes2) 472 assert.NoError(t, err, "Error upon GetEnvelopeFromBlock") 473 payload2, err := protoutil.UnmarshalPayload(txEnv2.Payload) 474 assert.NoError(t, err, "Error upon GetPayload") 475 chdr, err := protoutil.UnmarshalChannelHeader(payload2.Header.ChannelHeader) 476 assert.NoError(t, err, "Error upon GetChannelHeaderFromBytes") 477 txID2 := chdr.TxId 478 processedTran2, err := ledger.GetTransactionByID(txID2) 479 assert.NoError(t, err, "Error upon GetTransactionByID") 480 // get the tran envelope from the retrieved ProcessedTransaction 481 retrievedTxEnv2 := processedTran2.TransactionEnvelope 482 assert.Equal(t, txEnv2, retrievedTxEnv2) 483 484 qe, _ := ledger.NewQueryExecutor() 485 value1, _ := qe.GetState("ns1", "key1") 486 assert.Equal(t, []byte("value4"), value1) 487 488 hqe, err := ledger.NewHistoryQueryExecutor() 489 assert.NoError(t, err) 490 itr, err := hqe.GetHistoryForKey("ns1", "key1") 491 assert.NoError(t, err) 492 defer itr.Close() 493 494 result1, err := itr.Next() 495 assert.NoError(t, err) 496 assert.Equal(t, []byte("value4"), result1.(*queryresult.KeyModification).Value) 497 result2, err := itr.Next() 498 assert.NoError(t, err) 499 assert.Equal(t, []byte("value1"), result2.(*queryresult.KeyModification).Value) 500 } 501 502 func constructTestLedgerID(i int) string { 503 return fmt.Sprintf("ledger_%06d", i) 504 } 505 506 func testConfig(t *testing.T) (conf *lgr.Config, cleanup func()) { 507 path, err := ioutil.TempDir("", "kvledger") 508 require.NoError(t, err, "Failed to create test ledger directory") 509 conf = &lgr.Config{ 510 RootFSPath: path, 511 StateDBConfig: &lgr.StateDBConfig{}, 512 PrivateDataConfig: &lgr.PrivateDataConfig{ 513 MaxBatchSize: 5000, 514 BatchesInterval: 1000, 515 PurgeInterval: 100, 516 }, 517 HistoryDBConfig: &lgr.HistoryDBConfig{ 518 Enabled: true, 519 }, 520 } 521 cleanup = func() { 522 os.RemoveAll(path) 523 } 524 525 return conf, cleanup 526 } 527 528 func testutilNewProvider(conf *lgr.Config, t *testing.T) *Provider { 529 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 530 assert.NoError(t, err) 531 532 provider, err := NewProvider( 533 &lgr.Initializer{ 534 DeployedChaincodeInfoProvider: &mock.DeployedChaincodeInfoProvider{}, 535 MetricsProvider: &disabled.Provider{}, 536 Config: conf, 537 Hasher: cryptoProvider, 538 }, 539 ) 540 require.NoError(t, err, "Failed to create new Provider") 541 return provider 542 } 543 544 func testutilNewProviderWithCollectionConfig( 545 t *testing.T, 546 namespace string, 547 btlConfigs map[string]uint64, 548 conf *lgr.Config, 549 ) *Provider { 550 provider := testutilNewProvider(conf, t) 551 mockCCInfoProvider := provider.initializer.DeployedChaincodeInfoProvider.(*mock.DeployedChaincodeInfoProvider) 552 collMap := map[string]*peer.StaticCollectionConfig{} 553 var collConf []*peer.CollectionConfig 554 for collName, btl := range btlConfigs { 555 staticConf := &peer.StaticCollectionConfig{Name: collName, BlockToLive: btl} 556 collMap[collName] = staticConf 557 collectionConf := &peer.CollectionConfig{} 558 collectionConf.Payload = &peer.CollectionConfig_StaticCollectionConfig{StaticCollectionConfig: staticConf} 559 collConf = append(collConf, collectionConf) 560 } 561 collectionConfPkg := &peer.CollectionConfigPackage{Config: collConf} 562 563 mockCCInfoProvider.ChaincodeInfoStub = func(channelName, ccName string, qe lgr.SimpleQueryExecutor) (*lgr.DeployedChaincodeInfo, error) { 564 if ccName == namespace { 565 return &lgr.DeployedChaincodeInfo{ 566 Name: namespace, ExplicitCollectionConfigPkg: collectionConfPkg}, nil 567 } 568 return nil, nil 569 } 570 571 mockCCInfoProvider.AllCollectionsConfigPkgStub = func(channelName, ccName string, qe lgr.SimpleQueryExecutor) (*peer.CollectionConfigPackage, error) { 572 if ccName == namespace { 573 return collectionConfPkg, nil 574 } 575 return nil, nil 576 } 577 578 mockCCInfoProvider.CollectionInfoStub = func(channelName, ccName, collName string, qe lgr.SimpleQueryExecutor) (*peer.StaticCollectionConfig, error) { 579 if ccName == namespace { 580 return collMap[collName], nil 581 } 582 return nil, nil 583 } 584 return provider 585 }