blockfile_mgr_test.go 7.49 KB
Newer Older
manish's avatar
manish committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
Copyright IBM Corp. 2016 All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

		 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package fsblkstorage

import (
	"fmt"
	"testing"

	"github.com/golang/protobuf/proto"
24
	"github.com/hyperledger/fabric/common/ledger/testutil"
25

26
	"github.com/hyperledger/fabric/protos/common"
27
	putil "github.com/hyperledger/fabric/protos/utils"
manish's avatar
manish committed
28
29
30
)

func TestBlockfileMgrBlockReadWrite(t *testing.T) {
31
	env := newTestEnv(t, NewConf(testPath, 0))
manish's avatar
manish committed
32
	defer env.Cleanup()
manish's avatar
manish committed
33
	blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger")
manish's avatar
manish committed
34
35
36
37
38
39
40
	defer blkfileMgrWrapper.close()
	blocks := testutil.ConstructTestBlocks(t, 10)
	blkfileMgrWrapper.addBlocks(blocks)
	blkfileMgrWrapper.testGetBlockByHash(blocks)
	blkfileMgrWrapper.testGetBlockByNumber(blocks, 1)
}

manish's avatar
manish committed
41
42
43
44
45
46
47
48
49
func TestBlockfileMgrCrashDuringWriting(t *testing.T) {
	testBlockfileMgrCrashDuringWriting(t, 10, 2, 1000, 10)
	testBlockfileMgrCrashDuringWriting(t, 10, 2, 1000, 1)
	testBlockfileMgrCrashDuringWriting(t, 10, 2, 1000, 0)
	testBlockfileMgrCrashDuringWriting(t, 0, 0, 1000, 10)
}

func testBlockfileMgrCrashDuringWriting(t *testing.T, numBlocksBeforeCheckpoint int,
	numBlocksAfterCheckpoint int, numLastBlockBytes int, numPartialBytesToWrite int) {
50
	env := newTestEnv(t, NewConf(testPath, 0))
manish's avatar
manish committed
51
	defer env.Cleanup()
manish's avatar
manish committed
52
53
	ledgerid := "testLedger"
	blkfileMgrWrapper := newTestBlockfileWrapper(env, ledgerid)
54
55
	bg := testutil.NewBlockGenerator(t)
	blocksBeforeCP := bg.NextTestBlocks(numBlocksBeforeCheckpoint)
manish's avatar
manish committed
56
57
58
59
60
61
62
	blkfileMgrWrapper.addBlocks(blocksBeforeCP)
	currentCPInfo := blkfileMgrWrapper.blockfileMgr.cpInfo
	cpInfo1 := &checkpointInfo{
		currentCPInfo.latestFileChunkSuffixNum,
		currentCPInfo.latestFileChunksize,
		currentCPInfo.lastBlockNumber}

63
	blocksAfterCP := bg.NextTestBlocks(numBlocksAfterCheckpoint)
manish's avatar
manish committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
	blkfileMgrWrapper.addBlocks(blocksAfterCP)
	cpInfo2 := blkfileMgrWrapper.blockfileMgr.cpInfo

	// simulate a crash scenario
	lastBlockBytes := []byte{}
	encodedLen := proto.EncodeVarint(uint64(numLastBlockBytes))
	randomBytes := testutil.ConstructRandomBytes(t, numLastBlockBytes)
	lastBlockBytes = append(lastBlockBytes, encodedLen...)
	lastBlockBytes = append(lastBlockBytes, randomBytes...)
	partialBytes := lastBlockBytes[:numPartialBytesToWrite]
	blkfileMgrWrapper.blockfileMgr.currentFileWriter.append(partialBytes, true)
	blkfileMgrWrapper.blockfileMgr.saveCurrentInfo(cpInfo1, true)
	blkfileMgrWrapper.close()

	// simulate a start after a crash
manish's avatar
manish committed
79
	blkfileMgrWrapper = newTestBlockfileWrapper(env, ledgerid)
manish's avatar
manish committed
80
81
82
83
84
	defer blkfileMgrWrapper.close()
	cpInfo3 := blkfileMgrWrapper.blockfileMgr.cpInfo
	testutil.AssertEquals(t, cpInfo3, cpInfo2)

	// add fresh blocks after restart
85
	blocksAfterRestart := bg.NextTestBlocks(2)
manish's avatar
manish committed
86
	blkfileMgrWrapper.addBlocks(blocksAfterRestart)
87
	allBlocks := []*common.Block{}
manish's avatar
manish committed
88
89
90
	allBlocks = append(allBlocks, blocksBeforeCP...)
	allBlocks = append(allBlocks, blocksAfterCP...)
	allBlocks = append(allBlocks, blocksAfterRestart...)
91
	testBlockfileMgrBlockIterator(t, blkfileMgrWrapper.blockfileMgr, 1, len(allBlocks), allBlocks)
manish's avatar
manish committed
92
93
}

manish's avatar
manish committed
94
func TestBlockfileMgrBlockIterator(t *testing.T) {
95
	env := newTestEnv(t, NewConf(testPath, 0))
manish's avatar
manish committed
96
	defer env.Cleanup()
manish's avatar
manish committed
97
	blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger")
manish's avatar
manish committed
98
99
100
	defer blkfileMgrWrapper.close()
	blocks := testutil.ConstructTestBlocks(t, 10)
	blkfileMgrWrapper.addBlocks(blocks)
manish's avatar
manish committed
101
102
103
104
	testBlockfileMgrBlockIterator(t, blkfileMgrWrapper.blockfileMgr, 1, 8, blocks[0:8])
}

func testBlockfileMgrBlockIterator(t *testing.T, blockfileMgr *blockfileMgr,
105
	firstBlockNum int, lastBlockNum int, expectedBlocks []*common.Block) {
manish's avatar
manish committed
106
	itr, err := blockfileMgr.retrieveBlocks(uint64(firstBlockNum))
manish's avatar
manish committed
107
108
109
	defer itr.Close()
	testutil.AssertNoError(t, err, "Error while getting blocks iterator")
	numBlocksItrated := 0
manish's avatar
manish committed
110
111
	for {
		block, err := itr.Next()
manish's avatar
manish committed
112
		testutil.AssertNoError(t, err, fmt.Sprintf("Error while getting block number [%d] from iterator", numBlocksItrated))
manish's avatar
manish committed
113
		testutil.AssertEquals(t, block.(*blockHolder).GetBlock(), expectedBlocks[numBlocksItrated])
manish's avatar
manish committed
114
115
116
117
		numBlocksItrated++
		if numBlocksItrated == lastBlockNum-firstBlockNum+1 {
			break
		}
manish's avatar
manish committed
118
	}
manish's avatar
manish committed
119
	testutil.AssertEquals(t, numBlocksItrated, lastBlockNum-firstBlockNum+1)
manish's avatar
manish committed
120
121
122
}

func TestBlockfileMgrBlockchainInfo(t *testing.T) {
123
	env := newTestEnv(t, NewConf(testPath, 0))
manish's avatar
manish committed
124
	defer env.Cleanup()
manish's avatar
manish committed
125
	blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger")
manish's avatar
manish committed
126
127
128
	defer blkfileMgrWrapper.close()

	bcInfo := blkfileMgrWrapper.blockfileMgr.getBlockchainInfo()
129
	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{Height: 0, CurrentBlockHash: nil, PreviousBlockHash: nil})
manish's avatar
manish committed
130
131
132
133
134
135
136
137

	blocks := testutil.ConstructTestBlocks(t, 10)
	blkfileMgrWrapper.addBlocks(blocks)
	bcInfo = blkfileMgrWrapper.blockfileMgr.getBlockchainInfo()
	testutil.AssertEquals(t, bcInfo.Height, uint64(10))
}

func TestBlockfileMgrGetTxById(t *testing.T) {
138
	env := newTestEnv(t, NewConf(testPath, 0))
manish's avatar
manish committed
139
	defer env.Cleanup()
manish's avatar
manish committed
140
	blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger")
manish's avatar
manish committed
141
142
143
	defer blkfileMgrWrapper.close()
	blocks := testutil.ConstructTestBlocks(t, 10)
	blkfileMgrWrapper.addBlocks(blocks)
144
145
	for _, blk := range blocks {
		for j, txEnvelopeBytes := range blk.Data.Data {
manish's avatar
manish committed
146
			// blockNum starts with 1
147
148
			txID, err := extractTxID(blk.Data.Data[j])
			testutil.AssertNoError(t, err, "")
149
			txEnvelopeFromFileMgr, err := blkfileMgrWrapper.blockfileMgr.retrieveTransactionByID(txID)
manish's avatar
manish committed
150
			testutil.AssertNoError(t, err, "Error while retrieving tx from blkfileMgr")
151
			txEnvelope, err := putil.GetEnvelopeFromBlock(txEnvelopeBytes)
manish's avatar
manish committed
152
			testutil.AssertNoError(t, err, "Error while unmarshalling tx")
153
			testutil.AssertEquals(t, txEnvelopeFromFileMgr, txEnvelope)
manish's avatar
manish committed
154
155
156
157
158
		}
	}
}

func TestBlockfileMgrRestart(t *testing.T) {
159
	env := newTestEnv(t, NewConf(testPath, 0))
manish's avatar
manish committed
160
	defer env.Cleanup()
manish's avatar
manish committed
161
162
	ledgerid := "testLedger"
	blkfileMgrWrapper := newTestBlockfileWrapper(env, ledgerid)
manish's avatar
manish committed
163
164
165
166
	blocks := testutil.ConstructTestBlocks(t, 10)
	blkfileMgrWrapper.addBlocks(blocks)
	blkfileMgrWrapper.close()

manish's avatar
manish committed
167
	blkfileMgrWrapper = newTestBlockfileWrapper(env, ledgerid)
manish's avatar
manish committed
168
169
170
171
172
173
174
175
176
	defer blkfileMgrWrapper.close()
	testutil.AssertEquals(t, int(blkfileMgrWrapper.blockfileMgr.cpInfo.lastBlockNumber), 10)
	blkfileMgrWrapper.testGetBlockByHash(blocks)
}

func TestBlockfileMgrFileRolling(t *testing.T) {
	blocks := testutil.ConstructTestBlocks(t, 100)
	size := 0
	for _, block := range blocks {
177
178
		by, _, err := serializeBlock(block)
		testutil.AssertNoError(t, err, "Error while serializing block")
manish's avatar
manish committed
179
180
181
182
183
		blockBytesSize := len(by)
		encodedLen := proto.EncodeVarint(uint64(blockBytesSize))
		size += blockBytesSize + len(encodedLen)
	}

manish's avatar
manish committed
184
	maxFileSie := int(0.75 * float64(size))
185
	env := newTestEnv(t, NewConf(testPath, maxFileSie))
manish's avatar
manish committed
186
187
188
	defer env.Cleanup()
	ledgerid := "testLedger"
	blkfileMgrWrapper := newTestBlockfileWrapper(env, ledgerid)
manish's avatar
manish committed
189
190
191
192
193
	blkfileMgrWrapper.addBlocks(blocks)
	testutil.AssertEquals(t, blkfileMgrWrapper.blockfileMgr.cpInfo.latestFileChunkSuffixNum, 1)
	blkfileMgrWrapper.testGetBlockByHash(blocks)
	blkfileMgrWrapper.close()

manish's avatar
manish committed
194
	blkfileMgrWrapper = newTestBlockfileWrapper(env, ledgerid)
manish's avatar
manish committed
195
196
197
198
199
	defer blkfileMgrWrapper.close()
	blkfileMgrWrapper.addBlocks(blocks)
	testutil.AssertEquals(t, blkfileMgrWrapper.blockfileMgr.cpInfo.latestFileChunkSuffixNum, 2)
	blkfileMgrWrapper.testGetBlockByHash(blocks)
}