Example #1
0
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:
	}
}
Example #2
0
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:
	}
}
Example #3
0
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)
	}
}
Example #4
0
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:
	}
}
Example #5
0
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:
	}
}
Example #6
0
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:
	}
}