Skip to content

Commit 863d784

Browse files
committed
[FAB-5660] Improve UT coverage of solo consenter
Add test cases to cover re-validation path in solo consenter. Change-Id: Ic0b6e989e4c4ecac28fdffb66d9f870c5a178aba Signed-off-by: Jay Guo <guojiannan1101@gmail.com>
1 parent 900850f commit 863d784

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

orderer/consensus/solo/consensus_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package solo
1818

1919
import (
20+
"fmt"
2021
"testing"
2122
"time"
2223

@@ -310,3 +311,79 @@ func TestRecoverFromError(t *testing.T) {
310311
t.Fatalf("Expected block to be cut")
311312
}
312313
}
314+
315+
// This test checks that solo consenter re-validates message if config sequence has advanced
316+
func TestRevalidation(t *testing.T) {
317+
batchTimeout, _ := time.ParseDuration("1h")
318+
support := &mockmultichannel.ConsenterSupport{
319+
Blocks: make(chan *cb.Block),
320+
BlockCutterVal: mockblockcutter.NewReceiver(),
321+
SharedConfigVal: &mockconfig.Orderer{BatchTimeoutVal: batchTimeout},
322+
SequenceVal: uint64(1),
323+
}
324+
defer close(support.BlockCutterVal.Block)
325+
bs := newChain(support)
326+
wg := goWithWait(bs.main)
327+
defer bs.Halt()
328+
329+
t.Run("ConfigMsg", func(t *testing.T) {
330+
support.ProcessConfigMsgVal = testMessage
331+
332+
t.Run("Valid", func(t *testing.T) {
333+
assert.Nil(t, bs.Configure(testMessage, 0))
334+
335+
select {
336+
case <-support.Blocks:
337+
case <-time.After(time.Second):
338+
t.Fatalf("Expected one block to be cut but never got it")
339+
}
340+
})
341+
342+
t.Run("Invalid", func(t *testing.T) {
343+
support.ProcessConfigMsgErr = fmt.Errorf("Config message is not valid")
344+
assert.Nil(t, bs.Configure(testMessage, 0))
345+
346+
select {
347+
case <-support.Blocks:
348+
t.Fatalf("Expected no block to be cut")
349+
case <-time.After(100 * time.Millisecond):
350+
}
351+
})
352+
353+
})
354+
355+
t.Run("NormalMsg", func(t *testing.T) {
356+
support.BlockCutterVal.CutNext = true
357+
358+
t.Run("Valid", func(t *testing.T) {
359+
syncQueueMessage(testMessage, bs, support.BlockCutterVal)
360+
361+
select {
362+
case <-support.Blocks:
363+
case <-time.After(time.Second):
364+
t.Fatalf("Expected one block to be cut but never got it")
365+
}
366+
})
367+
368+
t.Run("Invalid", func(t *testing.T) {
369+
support.ProcessNormalMsgErr = fmt.Errorf("Normal message is not valid")
370+
// We are not calling `syncQueueMessage` here because we don't expect
371+
// `Ordered` to be invoked at all in this case, so we don't need to
372+
// synchronize on `support.BlockCutterVal.Block`.
373+
assert.Nil(t, bs.Order(testMessage, 0))
374+
375+
select {
376+
case <-support.Blocks:
377+
t.Fatalf("Expected no block to be cut")
378+
case <-time.After(100 * time.Millisecond):
379+
}
380+
})
381+
})
382+
383+
bs.Halt()
384+
select {
385+
case <-time.After(time.Second):
386+
t.Fatalf("Should have exited")
387+
case <-wg.done:
388+
}
389+
}

0 commit comments

Comments
 (0)