2018-01-25 21:59:21 -08:00

135 lines
3.5 KiB
Go

package queue
import (
"context"
"errors"
"testing"
"github.com/ethereum/go-ethereum/accounts/keystore"
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/status-im/status-go/geth/common"
"github.com/stretchr/testify/suite"
)
func TestQueueTestSuite(t *testing.T) {
suite.Run(t, new(QueueTestSuite))
}
type QueueTestSuite struct {
suite.Suite
queue *TxQueue
}
func (s *QueueTestSuite) SetupTest() {
s.queue = New()
s.queue.Start()
}
func (s *QueueTestSuite) TearDownTest() {
s.queue.Stop()
}
func (s *QueueTestSuite) TestLockInprogressTransaction() {
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{})
s.NoError(s.queue.Enqueue(tx))
enquedTx, err := s.queue.Get(tx.ID)
s.NoError(err)
s.NoError(s.queue.LockInprogress(tx.ID))
s.Equal(tx, enquedTx)
// verify that tx was marked as being inprogress
s.Equal(ErrQueuedTxInProgress, s.queue.LockInprogress(tx.ID))
}
func (s *QueueTestSuite) TestGetTransaction() {
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{})
s.NoError(s.queue.Enqueue(tx))
for i := 2; i > 0; i-- {
enquedTx, err := s.queue.Get(tx.ID)
s.NoError(err)
s.Equal(tx, enquedTx)
}
}
func (s *QueueTestSuite) TestEnqueueProcessedTransaction() {
// enqueue will fail if transaction with hash will be enqueued
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{})
tx.Hash = gethcommon.Hash{1}
s.Equal(ErrQueuedTxAlreadyProcessed, s.queue.Enqueue(tx))
tx = common.CreateTransaction(context.Background(), common.SendTxArgs{})
tx.Err = errors.New("error")
s.Equal(ErrQueuedTxAlreadyProcessed, s.queue.Enqueue(tx))
}
func (s *QueueTestSuite) testDone(hash gethcommon.Hash, err error) *common.QueuedTx {
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{})
s.NoError(s.queue.Enqueue(tx))
s.NoError(s.queue.Done(tx.ID, hash, err))
return tx
}
func (s *QueueTestSuite) TestDoneSuccess() {
hash := gethcommon.Hash{1}
tx := s.testDone(hash, nil)
s.NoError(tx.Err)
s.Equal(hash, tx.Hash)
s.False(s.queue.Has(tx.ID))
// event is sent only if transaction was removed from a queue
select {
case <-tx.Done:
default:
s.Fail("No event was sent to Done channel")
}
}
func (s *QueueTestSuite) TestDoneTransientError() {
hash := gethcommon.Hash{1}
err := keystore.ErrDecrypt
tx := s.testDone(hash, err)
s.Equal(keystore.ErrDecrypt, tx.Err)
s.Equal(gethcommon.Hash{}, tx.Hash)
s.True(s.queue.Has(tx.ID))
}
func (s *QueueTestSuite) TestDoneError() {
hash := gethcommon.Hash{1}
err := errors.New("test")
tx := s.testDone(hash, err)
s.Equal(err, tx.Err)
s.NotEqual(hash, tx.Hash)
s.Equal(gethcommon.Hash{}, tx.Hash)
s.False(s.queue.Has(tx.ID))
// event is sent only if transaction was removed from a queue
select {
case <-tx.Done:
default:
s.Fail("No event was sent to Done channel")
}
}
func (s QueueTestSuite) TestMultipleDone() {
hash := gethcommon.Hash{1}
err := keystore.ErrDecrypt
tx := s.testDone(hash, err)
s.NoError(s.queue.Done(tx.ID, hash, nil))
s.Equal(ErrQueuedTxIDNotFound, s.queue.Done(tx.ID, hash, errors.New("timeout")))
}
func (s *QueueTestSuite) TestEviction() {
var first *common.QueuedTx
for i := 0; i < DefaultTxQueueCap; i++ {
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{})
if first == nil {
first = tx
}
s.NoError(s.queue.Enqueue(tx))
}
s.Equal(DefaultTxQueueCap, s.queue.Count())
tx := common.CreateTransaction(context.Background(), common.SendTxArgs{})
s.NoError(s.queue.Enqueue(tx))
s.Equal(DefaultTxQueueCap, s.queue.Count())
s.False(s.queue.Has(first.ID))
}