mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-31 17:51:33 +02:00
chainio: add partial implementation of Consumer
interface
This commit is contained in:
202
chainio/consumer_test.go
Normal file
202
chainio/consumer_test.go
Normal file
@@ -0,0 +1,202 @@
|
||||
package chainio
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/lightningnetwork/lnd/fn/v2"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestNewBeatConsumer tests the NewBeatConsumer function.
|
||||
func TestNewBeatConsumer(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
quitChan := make(chan struct{})
|
||||
name := "test"
|
||||
|
||||
// Test the NewBeatConsumer function.
|
||||
b := NewBeatConsumer(quitChan, name)
|
||||
|
||||
// Assert the state.
|
||||
require.Equal(t, quitChan, b.quit)
|
||||
require.Equal(t, name, b.name)
|
||||
require.NotNil(t, b.BlockbeatChan)
|
||||
}
|
||||
|
||||
// TestProcessBlockSuccess tests when the block is processed successfully, no
|
||||
// error is returned.
|
||||
func TestProcessBlockSuccess(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Create a test consumer.
|
||||
quitChan := make(chan struct{})
|
||||
b := NewBeatConsumer(quitChan, "test")
|
||||
|
||||
// Create a mock beat.
|
||||
mockBeat := &MockBlockbeat{}
|
||||
defer mockBeat.AssertExpectations(t)
|
||||
mockBeat.On("logger").Return(clog)
|
||||
|
||||
// Mock the consumer's err chan.
|
||||
consumerErrChan := make(chan error, 1)
|
||||
b.errChan = consumerErrChan
|
||||
|
||||
// Call the method under test.
|
||||
resultChan := make(chan error, 1)
|
||||
go func() {
|
||||
resultChan <- b.ProcessBlock(mockBeat)
|
||||
}()
|
||||
|
||||
// Assert the beat is sent to the blockbeat channel.
|
||||
beat, err := fn.RecvOrTimeout(b.BlockbeatChan, time.Second)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, mockBeat, beat)
|
||||
|
||||
// Send nil to the consumer's error channel.
|
||||
consumerErrChan <- nil
|
||||
|
||||
// Assert the result of ProcessBlock is nil.
|
||||
result, err := fn.RecvOrTimeout(resultChan, time.Second)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, result)
|
||||
}
|
||||
|
||||
// TestProcessBlockConsumerQuitBeforeSend tests when the consumer is quit
|
||||
// before sending the beat, the method returns immediately.
|
||||
func TestProcessBlockConsumerQuitBeforeSend(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Create a test consumer.
|
||||
quitChan := make(chan struct{})
|
||||
b := NewBeatConsumer(quitChan, "test")
|
||||
|
||||
// Create a mock beat.
|
||||
mockBeat := &MockBlockbeat{}
|
||||
defer mockBeat.AssertExpectations(t)
|
||||
mockBeat.On("logger").Return(clog)
|
||||
|
||||
// Call the method under test.
|
||||
resultChan := make(chan error, 1)
|
||||
go func() {
|
||||
resultChan <- b.ProcessBlock(mockBeat)
|
||||
}()
|
||||
|
||||
// Instead of reading the BlockbeatChan, close the quit channel.
|
||||
close(quitChan)
|
||||
|
||||
// Assert ProcessBlock returned nil.
|
||||
result, err := fn.RecvOrTimeout(resultChan, time.Second)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, result)
|
||||
}
|
||||
|
||||
// TestProcessBlockConsumerQuitAfterSend tests when the consumer is quit after
|
||||
// sending the beat, the method returns immediately.
|
||||
func TestProcessBlockConsumerQuitAfterSend(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Create a test consumer.
|
||||
quitChan := make(chan struct{})
|
||||
b := NewBeatConsumer(quitChan, "test")
|
||||
|
||||
// Create a mock beat.
|
||||
mockBeat := &MockBlockbeat{}
|
||||
defer mockBeat.AssertExpectations(t)
|
||||
mockBeat.On("logger").Return(clog)
|
||||
|
||||
// Mock the consumer's err chan.
|
||||
consumerErrChan := make(chan error, 1)
|
||||
b.errChan = consumerErrChan
|
||||
|
||||
// Call the method under test.
|
||||
resultChan := make(chan error, 1)
|
||||
go func() {
|
||||
resultChan <- b.ProcessBlock(mockBeat)
|
||||
}()
|
||||
|
||||
// Assert the beat is sent to the blockbeat channel.
|
||||
beat, err := fn.RecvOrTimeout(b.BlockbeatChan, time.Second)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, mockBeat, beat)
|
||||
|
||||
// Instead of sending nil to the consumer's error channel, close the
|
||||
// quit chanel.
|
||||
close(quitChan)
|
||||
|
||||
// Assert ProcessBlock returned nil.
|
||||
result, err := fn.RecvOrTimeout(resultChan, time.Second)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, result)
|
||||
}
|
||||
|
||||
// TestNotifyBlockProcessedSendErr asserts the error can be sent and read by
|
||||
// the beat via NotifyBlockProcessed.
|
||||
func TestNotifyBlockProcessedSendErr(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Create a test consumer.
|
||||
quitChan := make(chan struct{})
|
||||
b := NewBeatConsumer(quitChan, "test")
|
||||
|
||||
// Create a mock beat.
|
||||
mockBeat := &MockBlockbeat{}
|
||||
defer mockBeat.AssertExpectations(t)
|
||||
mockBeat.On("logger").Return(clog)
|
||||
|
||||
// Mock the consumer's err chan.
|
||||
consumerErrChan := make(chan error, 1)
|
||||
b.errChan = consumerErrChan
|
||||
|
||||
// Call the method under test.
|
||||
done := make(chan error)
|
||||
go func() {
|
||||
defer close(done)
|
||||
b.NotifyBlockProcessed(mockBeat, errDummy)
|
||||
}()
|
||||
|
||||
// Assert the error is sent to the beat's err chan.
|
||||
result, err := fn.RecvOrTimeout(consumerErrChan, time.Second)
|
||||
require.NoError(t, err)
|
||||
require.ErrorIs(t, result, errDummy)
|
||||
|
||||
// Assert the done channel is closed.
|
||||
result, err = fn.RecvOrTimeout(done, time.Second)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, result)
|
||||
}
|
||||
|
||||
// TestNotifyBlockProcessedOnQuit asserts NotifyBlockProcessed exits
|
||||
// immediately when the quit channel is closed.
|
||||
func TestNotifyBlockProcessedOnQuit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Create a test consumer.
|
||||
quitChan := make(chan struct{})
|
||||
b := NewBeatConsumer(quitChan, "test")
|
||||
|
||||
// Create a mock beat.
|
||||
mockBeat := &MockBlockbeat{}
|
||||
defer mockBeat.AssertExpectations(t)
|
||||
mockBeat.On("logger").Return(clog)
|
||||
|
||||
// Mock the consumer's err chan - we don't buffer it so it will block
|
||||
// on sending the error.
|
||||
consumerErrChan := make(chan error)
|
||||
b.errChan = consumerErrChan
|
||||
|
||||
// Call the method under test.
|
||||
done := make(chan error)
|
||||
go func() {
|
||||
defer close(done)
|
||||
b.NotifyBlockProcessed(mockBeat, errDummy)
|
||||
}()
|
||||
|
||||
// Close the quit channel so the method will return.
|
||||
close(b.quit)
|
||||
|
||||
// Assert the done channel is closed.
|
||||
result, err := fn.RecvOrTimeout(done, time.Second)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, result)
|
||||
}
|
Reference in New Issue
Block a user