func TestBatchTimer(t *testing.T) { support := &mockmultichain.ConsenterSupport{ Batches: make(chan []*cb.Envelope), BlockCutterVal: mockblockcutter.NewReceiver(), } defer close(support.BlockCutterVal.Block) bs := newChain(time.Millisecond, support) wg := goWithWait(bs.main) defer bs.Halt() syncQueueMessage(testMessage, bs, support.BlockCutterVal) select { case <-support.Batches: case <-time.After(time.Second): t.Fatalf("Expected a block to be cut because of batch timer expiration but did not") } syncQueueMessage(testMessage, bs, support.BlockCutterVal) select { case <-support.Batches: case <-time.After(time.Second): t.Fatalf("Did not create the second batch, indicating that the timer was not appopriately reset") } bs.Halt() select { case <-support.Batches: t.Fatalf("Expected no invocations of Append") case <-wg.done: } }
func TestConfigStyleMultiBatch(t *testing.T) { support := &mockmultichain.ConsenterSupport{ Batches: make(chan []*cb.Envelope), BlockCutterVal: mockblockcutter.NewReceiver(), } defer close(support.BlockCutterVal.Block) bs := newChain(time.Hour, support) wg := goWithWait(bs.main) defer bs.Halt() syncQueueMessage(testMessage, bs, support.BlockCutterVal) support.BlockCutterVal.IsolatedTx = true syncQueueMessage(testMessage, bs, support.BlockCutterVal) select { case <-support.Batches: case <-time.After(time.Second): t.Fatalf("Expected two blocks to be cut but never got the first") } select { case <-support.Batches: case <-time.After(time.Second): t.Fatalf("Expected the config type tx to create two blocks, but only go the first") } bs.Halt() select { case <-time.After(time.Second): t.Fatalf("Should have exited") case <-wg.done: } }
func TestKafkaConsenterEmptyBatch(t *testing.T) { var wg sync.WaitGroup defer wg.Wait() cs := &mockmultichain.ConsenterSupport{ Batches: make(chan []*cb.Envelope), BlockCutterVal: mockblockcutter.NewReceiver(), ChainIDVal: provisional.TestChainID, SharedConfigVal: newMockSharedConfigManager(), } defer close(cs.BlockCutterVal.Block) co := mockNewConsenter(t, testConf.Kafka.Version, testConf.Kafka.Retry) ch := newChain(co, cs) ch.lastProcessed = testOldestOffset - 1 go ch.Start() defer ch.Halt() wg.Add(1) go func() { defer wg.Done() // Wait until the mock producer is done before messing around with its disk select { case <-ch.producer.(*mockProducerImpl).isSetup: // Dispense the CONNECT message that is posted with Start() <-co.prodDisk case <-time.After(testTimePadding): t.Fatal("Mock producer not setup in time") } }() wg.Wait() wg.Add(1) go func() { defer wg.Done() // Pick up the message that will be posted via the syncQueueMessage/Enqueue call below msg := <-co.prodDisk // Place it to the right location so that the mockConsumer can read it co.consDisk <- msg }() syncQueueMessage(newTestEnvelope("one"), ch, cs.BlockCutterVal) // The message has already been moved to the consumer's disk, // otherwise syncQueueMessage wouldn't return, so the Wait() // here is unnecessary but let's be paranoid. wg.Wait() // Stop the loop ch.Halt() select { case <-cs.Batches: t.Fatal("Expected no invocations of Append") case <-ch.haltedChan: // If we're here, we definitely had a chance to invoke Append but didn't (which is great) } }
func TestEmptyBatch(t *testing.T) { support := &mockmultichain.ConsenterSupport{ Batches: make(chan []*cb.Envelope), BlockCutterVal: mockblockcutter.NewReceiver(), } defer close(support.BlockCutterVal.Block) bs := newChain(time.Millisecond, support) wg := goWithWait(bs.main) defer bs.Halt() syncQueueMessage(testMessage, bs, support.BlockCutterVal) bs.Halt() select { case <-support.Batches: t.Fatalf("Expected no invocations of Append") case <-wg.done: } }
func TestBatchTimerHaltOnFilledBatch(t *testing.T) { support := &mockmultichain.ConsenterSupport{ Batches: make(chan []*cb.Envelope), BlockCutterVal: mockblockcutter.NewReceiver(), } defer close(support.BlockCutterVal.Block) bs := newChain(time.Hour, support) wg := goWithWait(bs.main) defer bs.Halt() syncQueueMessage(testMessage, bs, support.BlockCutterVal) support.BlockCutterVal.CutNext = true syncQueueMessage(testMessage, bs, support.BlockCutterVal) select { case <-support.Batches: case <-time.After(time.Second): t.Fatalf("Expected a block to be cut because the batch was filled, but did not") } // Change the batch timeout to be near instant, if the timer was not reset, it will still be waiting an hour bs.batchTimeout = time.Millisecond support.BlockCutterVal.CutNext = false syncQueueMessage(testMessage, bs, support.BlockCutterVal) select { case <-support.Batches: case <-time.After(time.Second): t.Fatalf("Did not create the second batch, indicating that the old timer was still running") } bs.Halt() select { case <-time.After(time.Second): t.Fatalf("Should have exited") case <-wg.done: } }
func TestKafkaConsenterConfigStyleMultiBatch(t *testing.T) { var wg sync.WaitGroup defer wg.Wait() cs := &mockmultichain.ConsenterSupport{ Batches: make(chan []*cb.Envelope), BlockCutterVal: mockblockcutter.NewReceiver(), ChainIDVal: provisional.TestChainID, SharedConfigVal: newMockSharedConfigManager(), } defer close(cs.BlockCutterVal.Block) co := mockNewConsenter(t, testConf.Kafka.Version, testConf.Kafka.Retry) ch := newChain(co, cs) ch.lastProcessed = testOldestOffset - 1 go ch.Start() defer ch.Halt() wg.Add(1) go func() { defer wg.Done() // Wait until the mock producer is done before messing around with its disk select { case <-ch.producer.(*mockProducerImpl).isSetup: // Dispense the CONNECT message that is posted with Start() <-co.prodDisk case <-time.After(testTimePadding): t.Fatal("Mock producer not setup in time") } }() wg.Wait() wg.Add(1) go func() { defer wg.Done() // Pick up the message that will be posted via the syncQueueMessage/Enqueue call below msg := <-co.prodDisk // Place it to the right location so that the mockConsumer can read it co.consDisk <- msg }() syncQueueMessage(newTestEnvelope("one"), ch, cs.BlockCutterVal) wg.Wait() cs.BlockCutterVal.IsolatedTx = true wg.Add(1) go func() { defer wg.Done() // Pick up the message that will be posted via the syncQueueMessage/Enqueue call below msg := <-co.prodDisk // Place it to the right location so that the mockConsumer can read it co.consDisk <- msg }() syncQueueMessage(newTestEnvelope("two"), ch, cs.BlockCutterVal) wg.Wait() ch.Halt() select { case <-cs.Batches: case <-time.After(testTimePadding): t.Fatal("Expected two blocks to be cut but never got the first") } select { case <-cs.Batches: case <-time.After(testTimePadding): t.Fatal("Expected the config type tx to create two blocks, but only got the first") } select { case <-time.After(testTimePadding): t.Fatal("Should have exited") case <-ch.haltedChan: } }