Skip to content

Commit 253d6c7

Browse files
committed
[FAB-4113] Improve UT coverage of orderer json ledger.
Change-Id: I1ede809652b530143cc444cb7886541634dfe83f Signed-off-by: Jay Guo <[email protected]>
1 parent 3b40efa commit 253d6c7

File tree

1 file changed

+102
-70
lines changed

1 file changed

+102
-70
lines changed

orderer/ledger/json/impl_test.go

+102-70
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,18 @@ limitations under the License.
1717
package jsonledger
1818

1919
import (
20-
"bytes"
2120
"io/ioutil"
2221
"os"
2322
"testing"
23+
"time"
2424

2525
"github.com/hyperledger/fabric/common/configtx/tool/provisional"
2626
"github.com/hyperledger/fabric/orderer/ledger"
2727
cb "github.com/hyperledger/fabric/protos/common"
2828
ab "github.com/hyperledger/fabric/protos/orderer"
2929

3030
logging "github.com/op/go-logging"
31+
"github.com/stretchr/testify/assert"
3132
)
3233

3334
var genesisBlock = cb.NewBlock(0, nil)
@@ -66,16 +67,13 @@ func (tev *testEnv) tearDown() {
6667
func TestInitialization(t *testing.T) {
6768
tev, fl := initialize(t)
6869
defer tev.tearDown()
69-
if fl.height != 1 {
70-
t.Fatalf("Block height should be 1")
71-
}
70+
assert.Equal(t, uint64(1), fl.height, "Block height should be 1")
71+
7272
block, found := fl.readBlock(0)
73-
if block == nil || !found {
74-
t.Fatalf("Error retrieving genesis block")
75-
}
76-
if !bytes.Equal(block.Header.Hash(), fl.lastHash) {
77-
t.Fatalf("Block hashes did no match")
78-
}
73+
assert.NotNil(t, block, "Error retrieving genesis block")
74+
assert.True(t, found, "Error retrieving genesis block")
75+
assert.Equal(t, fl.lastHash, block.Header.Hash(), "Block hashes did no match")
76+
7977
}
8078

8179
func TestReinitialization(t *testing.T) {
@@ -84,26 +82,18 @@ func TestReinitialization(t *testing.T) {
8482
ofl.Append(ledger.CreateNextBlock(ofl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}))
8583
flf := New(tev.location)
8684
chains := flf.ChainIDs()
87-
if len(chains) != 1 {
88-
t.Fatalf("Should have recovered the chain")
89-
}
85+
assert.Len(t, chains, 1, "Should have recovered the chain")
9086

9187
tfl, err := flf.GetOrCreate(chains[0])
92-
if err != nil {
93-
t.Fatalf("Unexpected error: %s", err)
94-
}
88+
assert.Nil(t, err, "Unexpected error: %s", err)
9589

9690
fl := tfl.(*jsonLedger)
97-
if fl.height != 2 {
98-
t.Fatalf("Block height should be 2")
99-
}
91+
assert.Equal(t, uint64(2), fl.height, "Block height should be 2")
92+
10093
block, found := fl.readBlock(1)
101-
if block == nil || !found {
102-
t.Fatalf("Error retrieving block 1")
103-
}
104-
if !bytes.Equal(block.Header.Hash(), fl.lastHash) {
105-
t.Fatalf("Block hashes did no match")
106-
}
94+
assert.NotNil(t, block, "Error retrieving block")
95+
assert.True(t, found, "Error retrieving block")
96+
assert.Equal(t, fl.lastHash, block.Header.Hash(), "Block hashes did no match")
10797
}
10898

10999
func TestMultiReinitialization(t *testing.T) {
@@ -112,73 +102,56 @@ func TestMultiReinitialization(t *testing.T) {
112102
flf := New(tev.location)
113103

114104
_, err := flf.GetOrCreate("foo")
115-
if err != nil {
116-
t.Fatalf("Error creating chain")
117-
}
105+
assert.Nil(t, err, "Error creating chain")
118106

119107
_, err = flf.GetOrCreate("bar")
120-
if err != nil {
121-
t.Fatalf("Error creating chain")
122-
}
108+
assert.Nil(t, err, "Error creating chain")
123109

124110
flf = New(tev.location)
125-
chains := flf.ChainIDs()
126-
if len(chains) != 3 {
127-
t.Fatalf("Should have recovered the chains")
128-
}
111+
assert.Len(t, flf.ChainIDs(), 3, "Should have recovered the chains")
129112
}
130113

131114
func TestAddition(t *testing.T) {
132115
tev, fl := initialize(t)
133116
defer tev.tearDown()
134117
prevHash := fl.lastHash
135118
fl.Append(ledger.CreateNextBlock(fl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}))
136-
if fl.height != 2 {
137-
t.Fatalf("Block height should be 2")
138-
}
119+
assert.Equal(t, uint64(2), fl.height, "Block height should be 2")
120+
139121
block, found := fl.readBlock(1)
140-
if block == nil || !found {
141-
t.Fatalf("Error retrieving genesis block")
142-
}
143-
if !bytes.Equal(block.Header.PreviousHash, prevHash) {
144-
t.Fatalf("Block hashes did no match")
145-
}
122+
assert.NotNil(t, block, "Error retrieving genesis block")
123+
assert.True(t, found, "Error retrieving genesis block")
124+
assert.Equal(t, prevHash, block.Header.PreviousHash, "Block hashes did no match")
146125
}
147126

148127
func TestRetrieval(t *testing.T) {
149128
tev, fl := initialize(t)
150129
defer tev.tearDown()
151130
fl.Append(ledger.CreateNextBlock(fl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}))
152131
it, num := fl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Oldest{}})
153-
if num != 0 {
154-
t.Fatalf("Expected genesis block iterator, but got %d", num)
155-
}
132+
assert.Equal(t, uint64(0), num, "Expected genesis block iterator, but got %d", num)
133+
156134
signal := it.ReadyChan()
157135
select {
158136
case <-signal:
159137
default:
160138
t.Fatalf("Should be ready for block read")
161139
}
140+
162141
block, status := it.Next()
163-
if status != cb.Status_SUCCESS {
164-
t.Fatalf("Expected to successfully read the genesis block")
165-
}
166-
if block.Header.Number != 0 {
167-
t.Fatalf("Expected to successfully retrieve the genesis block")
168-
}
142+
assert.Equal(t, cb.Status_SUCCESS, status, "Expected to successfully read the genesis block")
143+
assert.Equal(t, uint64(0), block.Header.Number, "Expected to successfully retrieve the genesis block")
144+
169145
signal = it.ReadyChan()
170146
select {
171147
case <-signal:
172148
default:
173149
t.Fatalf("Should still be ready for block read")
174150
}
151+
175152
block, status = it.Next()
176-
if status != cb.Status_SUCCESS {
177-
t.Fatalf("Expected to successfully read the second block")
178-
}
179-
if block.Header.Number != 1 {
180-
t.Fatalf("Expected to successfully retrieve the second block but got block number %d", block.Header.Number)
181-
}
153+
assert.Equal(t, cb.Status_SUCCESS, status, "Expected to successfully read the second block")
154+
assert.Equal(t, uint64(1), block.Header.Number, "Expected to successfully retrieve the second block but got block number %d", block.Header.Number)
182155
}
183156

184157
// Without file lock in the implementation, this test is flaky due to
@@ -202,35 +175,94 @@ func TestRaceCondition(t *testing.T) {
202175
fl.Append(ledger.CreateNextBlock(fl, []*cb.Envelope{{Payload: []byte("My Data")}}))
203176
<-complete
204177

205-
if status != cb.Status_SUCCESS {
206-
t.Fatalf("Expected to successfully read the block")
207-
}
178+
assert.Equal(t, cb.Status_SUCCESS, status, "Expected to successfully read the block")
208179
}
209180

210181
func TestBlockedRetrieval(t *testing.T) {
211182
tev, fl := initialize(t)
212183
defer tev.tearDown()
213184
it, num := fl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: 1}}})
214-
if num != 1 {
215-
t.Fatalf("Expected block iterator at 1, but got %d", num)
216-
}
185+
assert.Equal(t, uint64(1), num, "Expected block iterator at 1, but got %d", num)
186+
217187
signal := it.ReadyChan()
218188
select {
219189
case <-signal:
220190
t.Fatalf("Should not be ready for block read")
221191
default:
222192
}
223-
fl.Append(ledger.CreateNextBlock(fl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}))
193+
194+
fl.Append(ledger.CreateNextBlock(fl, []*cb.Envelope{{Payload: []byte("My Data")}}))
224195
select {
225196
case <-signal:
226197
default:
227198
t.Fatalf("Should now be ready for block read")
228199
}
200+
229201
block, status := it.Next()
230-
if status != cb.Status_SUCCESS {
231-
t.Fatalf("Expected to successfully read the second block")
202+
assert.Equal(t, cb.Status_SUCCESS, status, "Expected to successfully read the second block")
203+
assert.Equal(t, uint64(1), block.Header.Number, "Expected to successfully retrieve the second block")
204+
205+
go func() {
206+
// Add explicit sleep here to make sure `it.Next` is actually blocked waiting
207+
// for new block. According to Golang sched, `it.Next()` is run before this
208+
// goroutine, however it's not guaranteed to run till the channel operation
209+
// we desire, due to I/O operation in the middle. Consider making the
210+
// implementation more testable so we don't need to sleep here.
211+
time.Sleep(100 * time.Millisecond)
212+
fl.Append(ledger.CreateNextBlock(fl, []*cb.Envelope{{Payload: []byte("Another Data")}}))
213+
}()
214+
215+
block, status = it.Next()
216+
assert.Equal(t, cb.Status_SUCCESS, status, "Expected to successfully read the third block")
217+
assert.Equal(t, uint64(2), block.Header.Number, "Expected to successfully retrieve the third block")
218+
}
219+
220+
func TestInvalidRetrieval(t *testing.T) {
221+
tev, fl := initialize(t)
222+
defer tev.tearDown()
223+
224+
it, num := fl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: 2}}})
225+
assert.Equal(t, uint64(0), num, "Expected block number to be zero for invalid iterator")
226+
227+
_, status := it.Next()
228+
assert.Equal(t, cb.Status_NOT_FOUND, status, "Expected status_NOT_FOUND for invalid iterator")
229+
}
230+
231+
func TestBrokenBlockFile(t *testing.T) {
232+
tev, fl := initialize(t)
233+
defer tev.tearDown()
234+
235+
// Pollute block file so that unmarshalling would fail.
236+
file, err := os.OpenFile(fl.blockFilename(0), os.O_RDWR, 0700)
237+
assert.Nil(t, err, "Expected to successfully open block file")
238+
239+
_, err = file.WriteString("Hello, world!")
240+
assert.Nil(t, err, "Expected to successfully write to block file")
241+
242+
assert.NoError(t, file.Close(), "Expected to successfully close block file")
243+
244+
it, num := fl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Oldest{}})
245+
assert.Equal(t, uint64(0), num, "Expected genesis block iterator, but got %d", num)
246+
247+
_, status := it.Next()
248+
assert.Equal(t, cb.Status_SERVICE_UNAVAILABLE, status, "Expected reading the genesis block to fail")
249+
}
250+
251+
func TestInvalidAddition(t *testing.T) {
252+
tev, fl := initialize(t)
253+
defer tev.tearDown()
254+
255+
// Append block with invalid number
256+
{
257+
block := ledger.CreateNextBlock(fl, []*cb.Envelope{{Payload: []byte("My Data")}})
258+
block.Header.Number++
259+
assert.Error(t, fl.Append(block), "Addition of block with invalid number should fail")
232260
}
233-
if block.Header.Number != 1 {
234-
t.Fatalf("Expected to successfully retrieve the second block")
261+
262+
// Append block with invalid previousHash
263+
{
264+
block := ledger.CreateNextBlock(fl, []*cb.Envelope{{Payload: []byte("My Data")}})
265+
block.Header.PreviousHash = nil
266+
assert.Error(t, fl.Append(block), "Addition of block with invalid previousHash should fail")
235267
}
236268
}

0 commit comments

Comments
 (0)