func TestBlocksItrBlockingNext(t *testing.T) { env := newTestEnv(t) defer env.Cleanup() blkfileMgrWrapper := newTestBlockfileWrapper(t, env) defer blkfileMgrWrapper.close() blkfileMgr := blkfileMgrWrapper.blockfileMgr blocks := testutil.ConstructTestBlocks(t, 10) blkfileMgrWrapper.addBlocks(blocks[:5]) itr, err := blkfileMgr.retrieveBlocks(2) defer itr.Close() testutil.AssertNoError(t, err, "") doneChan := make(chan bool) go testIterateAndVerify(t, itr, blocks[1:], doneChan) for { if itr.blockNumToRetrieve == 6 { break } time.Sleep(time.Millisecond * 10) } testAppendBlocks(blkfileMgrWrapper, blocks[5:7]) blkfileMgr.moveToNextFile() time.Sleep(time.Millisecond * 10) testAppendBlocks(blkfileMgrWrapper, blocks[7:]) <-doneChan }
func TestBlockfileMgrFileRolling(t *testing.T) { env := newTestEnv(t) blocks := testutil.ConstructTestBlocks(t, 100) size := 0 for _, block := range blocks { by, _, err := serializeBlock(block) testutil.AssertNoError(t, err, "Error while serializing block") blockBytesSize := len(by) encodedLen := proto.EncodeVarint(uint64(blockBytesSize)) size += blockBytesSize + len(encodedLen) } env.conf.maxBlockfileSize = int(0.75 * float64(size)) blkfileMgrWrapper := newTestBlockfileWrapper(t, env) blkfileMgrWrapper.addBlocks(blocks) testutil.AssertEquals(t, blkfileMgrWrapper.blockfileMgr.cpInfo.latestFileChunkSuffixNum, 1) blkfileMgrWrapper.testGetBlockByHash(blocks) blkfileMgrWrapper.close() env.Cleanup() env = newTestEnv(t) defer env.Cleanup() env.conf.maxBlockfileSize = int(0.40 * float64(size)) blkfileMgrWrapper = newTestBlockfileWrapper(t, env) defer blkfileMgrWrapper.close() blkfileMgrWrapper.addBlocks(blocks) testutil.AssertEquals(t, blkfileMgrWrapper.blockfileMgr.cpInfo.latestFileChunkSuffixNum, 2) blkfileMgrWrapper.testGetBlockByHash(blocks) }
func TestRawLedger(t *testing.T) { cleanup(t) rawLedger := NewFSBasedRawLedger(testFolder) defer rawLedger.Close() defer cleanup(t) // Construct test blocks and add to raw ledger blocks := testutil.ConstructTestBlocks(t, 10) for _, block := range blocks { rawLedger.CommitBlock(block) } // test GetBlockchainInfo() bcInfo, err := rawLedger.GetBlockchainInfo() testutil.AssertNoError(t, err, "Error in getting BlockchainInfo") testutil.AssertEquals(t, bcInfo.Height, uint64(10)) // test GetBlockByNumber() block, err := rawLedger.GetBlockByNumber(2) testutil.AssertNoError(t, err, "Error in getting block by number") testutil.AssertEquals(t, block, blocks[1]) // get blocks iterator for block number starting from 3 itr, err := rawLedger.GetBlocksIterator(3) testutil.AssertNoError(t, err, "Error in getting iterator") blockHolder, err := itr.Next() testutil.AssertNoError(t, err, "") testutil.AssertEquals(t, blockHolder.(ledger.BlockHolder).GetBlock(), blocks[2]) // get next block from iterator. The block should be 4th block blockHolder, err = itr.Next() testutil.AssertNoError(t, err, "") testutil.AssertEquals(t, blockHolder.(ledger.BlockHolder).GetBlock(), blocks[3]) }
func testBlockfileStream(t *testing.T, numBlocks int) { env := newTestEnv(t) defer env.Cleanup() w := newTestBlockfileWrapper(t, env) blockfileMgr := w.blockfileMgr blocks := testutil.ConstructTestBlocks(t, numBlocks) w.addBlocks(blocks) w.close() s, err := newBlockfileStream(blockfileMgr.rootDir, 0, 0) defer s.close() testutil.AssertNoError(t, err, "Error in constructing blockfile stream") blockCount := 0 for { blockBytes, err := s.nextBlockBytes() testutil.AssertNoError(t, err, "Error in getting next block") if blockBytes == nil { break } blockCount++ } // After the stream has been exhausted, both blockBytes and err should be nil blockBytes, err := s.nextBlockBytes() testutil.AssertNil(t, blockBytes) testutil.AssertNoError(t, err, "Error in getting next block after exhausting the file") testutil.AssertEquals(t, blockCount, numBlocks) }
func TestBlockfileMgrBlockIterator(t *testing.T) { env := newTestEnv(t) defer env.Cleanup() blkfileMgrWrapper := newTestBlockfileWrapper(t, env) defer blkfileMgrWrapper.close() blocks := testutil.ConstructTestBlocks(t, 10) blkfileMgrWrapper.addBlocks(blocks) testBlockfileMgrBlockIterator(t, blkfileMgrWrapper.blockfileMgr, 1, 8, blocks[0:8]) }
func TestBlockfileMgrBlockReadWrite(t *testing.T) { env := newTestEnv(t) defer env.Cleanup() blkfileMgrWrapper := newTestBlockfileWrapper(t, env) defer blkfileMgrWrapper.close() blocks := testutil.ConstructTestBlocks(t, 10) blkfileMgrWrapper.addBlocks(blocks) blkfileMgrWrapper.testGetBlockByHash(blocks) blkfileMgrWrapper.testGetBlockByNumber(blocks, 1) }
func testBlockIndexSelectiveIndexing(t *testing.T, indexItems []blkstorage.IndexableAttr) { env := newTestEnv(t) env.indexConfig.AttrsToIndex = indexItems defer env.Cleanup() blkfileMgrWrapper := newTestBlockfileWrapper(t, env) defer blkfileMgrWrapper.close() blocks := testutil.ConstructTestBlocks(t, 3) // add test blocks blkfileMgrWrapper.addBlocks(blocks) blockfileMgr := blkfileMgrWrapper.blockfileMgr // if index has been configured for an indexItem then the item should be indexed else not // test 'retrieveBlockByHash' block, err := blockfileMgr.retrieveBlockByHash(blocks[0].Header.Hash()) if testutil.Contains(indexItems, blkstorage.IndexableAttrBlockHash) { testutil.AssertNoError(t, err, "Error while retrieving block by hash") testutil.AssertEquals(t, block, blocks[0]) } else { testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed) } // test 'retrieveBlockByNumber' block, err = blockfileMgr.retrieveBlockByNumber(1) if testutil.Contains(indexItems, blkstorage.IndexableAttrBlockNum) { testutil.AssertNoError(t, err, "Error while retrieving block by number") testutil.AssertEquals(t, block, blocks[0]) } else { testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed) } // test 'retrieveTransactionByID' txid, err := extractTxID(blocks[0].Data.Data[0]) testutil.AssertNoError(t, err, "") tx, err := blockfileMgr.retrieveTransactionByID(txid) if testutil.Contains(indexItems, blkstorage.IndexableAttrTxID) { testutil.AssertNoError(t, err, "Error while retrieving tx by id") txOrig, err := extractTransaction(blocks[0].Data.Data[0]) testutil.AssertNoError(t, err, "") testutil.AssertEquals(t, tx, txOrig) } else { testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed) } //test 'retrieveTrasnactionsByBlockNumTranNum tx2, err := blockfileMgr.retrieveTransactionForBlockNumTranNum(1, 1) if testutil.Contains(indexItems, blkstorage.IndexableAttrBlockNumTranNum) { testutil.AssertNoError(t, err, "Error while retrieving tx by blockNum and tranNum") txOrig2, err2 := extractTransaction(blocks[0].Data.Data[0]) testutil.AssertNoError(t, err2, "") testutil.AssertEquals(t, tx2, txOrig2) } else { testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed) } }
func TestBlockfileMgrRestart(t *testing.T) { env := newTestEnv(t) defer env.Cleanup() blkfileMgrWrapper := newTestBlockfileWrapper(t, env) blocks := testutil.ConstructTestBlocks(t, 10) blkfileMgrWrapper.addBlocks(blocks) blkfileMgrWrapper.close() blkfileMgrWrapper = newTestBlockfileWrapper(t, env) defer blkfileMgrWrapper.close() testutil.AssertEquals(t, int(blkfileMgrWrapper.blockfileMgr.cpInfo.lastBlockNumber), 10) blkfileMgrWrapper.testGetBlockByHash(blocks) }
func TestBlockfileMgrBlockchainInfo(t *testing.T) { env := newTestEnv(t) defer env.Cleanup() blkfileMgrWrapper := newTestBlockfileWrapper(t, env) defer blkfileMgrWrapper.close() bcInfo := blkfileMgrWrapper.blockfileMgr.getBlockchainInfo() testutil.AssertEquals(t, bcInfo, &pb.BlockchainInfo{Height: 0, CurrentBlockHash: nil, PreviousBlockHash: nil}) blocks := testutil.ConstructTestBlocks(t, 10) blkfileMgrWrapper.addBlocks(blocks) bcInfo = blkfileMgrWrapper.blockfileMgr.getBlockchainInfo() testutil.AssertEquals(t, bcInfo.Height, uint64(10)) }
func testBlockIndexSync(t *testing.T, numBlocks int, numBlocksToIndex int, syncByRestart bool) { env := newTestEnv(t) defer env.Cleanup() blkfileMgrWrapper := newTestBlockfileWrapper(t, env) defer blkfileMgrWrapper.close() blkfileMgr := blkfileMgrWrapper.blockfileMgr origIndex := blkfileMgr.index // construct blocks for testing blocks := testutil.ConstructTestBlocks(t, numBlocks) // add a few blocks blkfileMgrWrapper.addBlocks(blocks[:numBlocksToIndex]) // Plug-in a noop index and add remaining blocks blkfileMgr.index = &noopIndex{} blkfileMgrWrapper.addBlocks(blocks[numBlocksToIndex:]) // Plug-in back the original index blkfileMgr.index = origIndex // The first set of blocks should be present in the orginal index for i := 1; i <= numBlocksToIndex; i++ { block, err := blkfileMgr.retrieveBlockByNumber(uint64(i)) testutil.AssertNoError(t, err, fmt.Sprintf("block [%d] should have been present in the index", i)) testutil.AssertEquals(t, block, blocks[i-1]) } // The last set of blocks should not be present in the original index for i := numBlocksToIndex + 1; i <= numBlocks; i++ { _, err := blkfileMgr.retrieveBlockByNumber(uint64(i)) testutil.AssertSame(t, err, blkstorage.ErrNotFoundInIndex) } // perform index sync if syncByRestart { blkfileMgrWrapper.close() blkfileMgrWrapper = newTestBlockfileWrapper(t, env) defer blkfileMgrWrapper.close() blkfileMgr = blkfileMgrWrapper.blockfileMgr } else { blkfileMgr.syncIndex() } // Now, last set of blocks should also be present in original index for i := numBlocksToIndex + 1; i <= numBlocks; i++ { block, err := blkfileMgr.retrieveBlockByNumber(uint64(i)) testutil.AssertNoError(t, err, fmt.Sprintf("block [%d] should have been present in the index", i)) testutil.AssertEquals(t, block, blocks[i-1]) } }
func TestBlockfileMgrGetTxById(t *testing.T) { env := newTestEnv(t) defer env.Cleanup() blkfileMgrWrapper := newTestBlockfileWrapper(t, env) defer blkfileMgrWrapper.close() blocks := testutil.ConstructTestBlocks(t, 10) blkfileMgrWrapper.addBlocks(blocks) for _, blk := range blocks { for j, txEnvelopeBytes := range blk.Data.Data { // blockNum starts with 1 txID, err := extractTxID(blk.Data.Data[j]) testutil.AssertNoError(t, err, "") txFromFileMgr, err := blkfileMgrWrapper.blockfileMgr.retrieveTransactionByID(txID) testutil.AssertNoError(t, err, "Error while retrieving tx from blkfileMgr") tx, err := extractTransaction(txEnvelopeBytes) testutil.AssertNoError(t, err, "Error while unmarshalling tx") testutil.AssertEquals(t, txFromFileMgr, tx) } } }
func testBlockFileStreamUnexpectedEOF(t *testing.T, numBlocks int, partialBlockBytes []byte) { env := newTestEnv(t) defer env.Cleanup() w := newTestBlockfileWrapper(t, env) blockfileMgr := w.blockfileMgr blocks := testutil.ConstructTestBlocks(t, numBlocks) w.addBlocks(blocks) blockfileMgr.currentFileWriter.append(partialBlockBytes, true) w.close() s, err := newBlockfileStream(blockfileMgr.rootDir, 0, 0) defer s.close() testutil.AssertNoError(t, err, "Error in constructing blockfile stream") for i := 0; i < numBlocks; i++ { blockBytes, err := s.nextBlockBytes() testutil.AssertNotNil(t, blockBytes) testutil.AssertNoError(t, err, "Error in getting next block") } blockBytes, err := s.nextBlockBytes() testutil.AssertNil(t, blockBytes) testutil.AssertSame(t, err, ErrUnexpectedEndOfBlockfile) }