@@ -17,17 +17,18 @@ limitations under the License.
17
17
package jsonledger
18
18
19
19
import (
20
- "bytes"
21
20
"io/ioutil"
22
21
"os"
23
22
"testing"
23
+ "time"
24
24
25
25
"github.com/hyperledger/fabric/common/configtx/tool/provisional"
26
26
"github.com/hyperledger/fabric/orderer/ledger"
27
27
cb "github.com/hyperledger/fabric/protos/common"
28
28
ab "github.com/hyperledger/fabric/protos/orderer"
29
29
30
30
logging "github.com/op/go-logging"
31
+ "github.com/stretchr/testify/assert"
31
32
)
32
33
33
34
var genesisBlock = cb .NewBlock (0 , nil )
@@ -66,16 +67,13 @@ func (tev *testEnv) tearDown() {
66
67
func TestInitialization (t * testing.T ) {
67
68
tev , fl := initialize (t )
68
69
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
+
72
72
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
+
79
77
}
80
78
81
79
func TestReinitialization (t * testing.T ) {
@@ -84,26 +82,18 @@ func TestReinitialization(t *testing.T) {
84
82
ofl .Append (ledger .CreateNextBlock (ofl , []* cb.Envelope {& cb.Envelope {Payload : []byte ("My Data" )}}))
85
83
flf := New (tev .location )
86
84
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" )
90
86
91
87
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 )
95
89
96
90
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
+
100
93
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" )
107
97
}
108
98
109
99
func TestMultiReinitialization (t * testing.T ) {
@@ -112,73 +102,56 @@ func TestMultiReinitialization(t *testing.T) {
112
102
flf := New (tev .location )
113
103
114
104
_ , err := flf .GetOrCreate ("foo" )
115
- if err != nil {
116
- t .Fatalf ("Error creating chain" )
117
- }
105
+ assert .Nil (t , err , "Error creating chain" )
118
106
119
107
_ , err = flf .GetOrCreate ("bar" )
120
- if err != nil {
121
- t .Fatalf ("Error creating chain" )
122
- }
108
+ assert .Nil (t , err , "Error creating chain" )
123
109
124
110
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" )
129
112
}
130
113
131
114
func TestAddition (t * testing.T ) {
132
115
tev , fl := initialize (t )
133
116
defer tev .tearDown ()
134
117
prevHash := fl .lastHash
135
118
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
+
139
121
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" )
146
125
}
147
126
148
127
func TestRetrieval (t * testing.T ) {
149
128
tev , fl := initialize (t )
150
129
defer tev .tearDown ()
151
130
fl .Append (ledger .CreateNextBlock (fl , []* cb.Envelope {& cb.Envelope {Payload : []byte ("My Data" )}}))
152
131
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
+
156
134
signal := it .ReadyChan ()
157
135
select {
158
136
case <- signal :
159
137
default :
160
138
t .Fatalf ("Should be ready for block read" )
161
139
}
140
+
162
141
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
+
169
145
signal = it .ReadyChan ()
170
146
select {
171
147
case <- signal :
172
148
default :
173
149
t .Fatalf ("Should still be ready for block read" )
174
150
}
151
+
175
152
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 )
182
155
}
183
156
184
157
// Without file lock in the implementation, this test is flaky due to
@@ -202,35 +175,94 @@ func TestRaceCondition(t *testing.T) {
202
175
fl .Append (ledger .CreateNextBlock (fl , []* cb.Envelope {{Payload : []byte ("My Data" )}}))
203
176
<- complete
204
177
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" )
208
179
}
209
180
210
181
func TestBlockedRetrieval (t * testing.T ) {
211
182
tev , fl := initialize (t )
212
183
defer tev .tearDown ()
213
184
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
+
217
187
signal := it .ReadyChan ()
218
188
select {
219
189
case <- signal :
220
190
t .Fatalf ("Should not be ready for block read" )
221
191
default :
222
192
}
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" )}}))
224
195
select {
225
196
case <- signal :
226
197
default :
227
198
t .Fatalf ("Should now be ready for block read" )
228
199
}
200
+
229
201
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" )
232
260
}
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" )
235
267
}
236
268
}
0 commit comments