235 lines
7.9 KiB
Go
235 lines
7.9 KiB
Go
// Copyright (c) quickfixengine.org All rights reserved.
|
|
//
|
|
// This file may be distributed under the terms of the quickfixengine.org
|
|
// license as defined by quickfixengine.org and appearing in the file
|
|
// LICENSE included in the packaging of this file.
|
|
//
|
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
|
|
// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
//
|
|
// Contact ask@quickfixengine.org if any conditions of this licensing
|
|
// are not clear to you.
|
|
|
|
package testsuite
|
|
|
|
import (
|
|
"sort"
|
|
"time"
|
|
|
|
"quantex.com/qfixdpl/quickfix"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/stretchr/testify/suite"
|
|
)
|
|
|
|
type StoreTestSuite struct {
|
|
suite.Suite
|
|
MsgStore quickfix.MessageStore
|
|
}
|
|
|
|
func (s *StoreTestSuite) TestMessageStoreSetNextMsgSeqNumRefreshIncrNextMsgSeqNum() {
|
|
// Given a MessageStore with the following sender and target seqnums
|
|
s.Require().Nil(s.MsgStore.SetNextSenderMsgSeqNum(867))
|
|
s.Require().Nil(s.MsgStore.SetNextTargetMsgSeqNum(5309))
|
|
|
|
// When the store is refreshed from its backing store
|
|
s.Require().Nil(s.MsgStore.Refresh())
|
|
|
|
// Then the sender and target seqnums should still be
|
|
s.Equal(867, s.MsgStore.NextSenderMsgSeqNum())
|
|
s.Equal(5309, s.MsgStore.NextTargetMsgSeqNum())
|
|
|
|
// When the sender and target seqnums are incremented
|
|
s.Require().Nil(s.MsgStore.IncrNextSenderMsgSeqNum())
|
|
s.Require().Nil(s.MsgStore.IncrNextTargetMsgSeqNum())
|
|
|
|
// Then the sender and target seqnums should be
|
|
s.Equal(868, s.MsgStore.NextSenderMsgSeqNum())
|
|
s.Equal(5310, s.MsgStore.NextTargetMsgSeqNum())
|
|
|
|
// When the store is refreshed from its backing store
|
|
s.Require().Nil(s.MsgStore.Refresh())
|
|
|
|
// Then the sender and target seqnums should still be
|
|
s.Equal(868, s.MsgStore.NextSenderMsgSeqNum())
|
|
s.Equal(5310, s.MsgStore.NextTargetMsgSeqNum())
|
|
}
|
|
|
|
func (s *StoreTestSuite) TestMessageStoreReset() {
|
|
// Given a MessageStore with the following sender and target seqnums
|
|
s.Require().Nil(s.MsgStore.SetNextSenderMsgSeqNum(1234))
|
|
s.Require().Nil(s.MsgStore.SetNextTargetMsgSeqNum(5678))
|
|
|
|
// When the store is reset
|
|
s.Require().Nil(s.MsgStore.Reset())
|
|
|
|
// Then the sender and target seqnums should be
|
|
s.Equal(1, s.MsgStore.NextSenderMsgSeqNum())
|
|
s.Equal(1, s.MsgStore.NextTargetMsgSeqNum())
|
|
|
|
// When the store is refreshed from its backing store
|
|
s.Require().Nil(s.MsgStore.Refresh())
|
|
|
|
// Then the sender and target seqnums should still be
|
|
s.Equal(1, s.MsgStore.NextSenderMsgSeqNum())
|
|
s.Equal(1, s.MsgStore.NextTargetMsgSeqNum())
|
|
}
|
|
|
|
func (s *StoreTestSuite) fetchMessages(beginSeqNum, endSeqNum int) (msgs [][]byte) {
|
|
s.T().Helper()
|
|
|
|
// Fetch messages from the new iterator
|
|
err := s.MsgStore.IterateMessages(beginSeqNum, endSeqNum, func(msg []byte) error {
|
|
msgs = append(msgs, msg)
|
|
return nil
|
|
})
|
|
s.Require().Nil(err)
|
|
|
|
// Fetch messages from the old getter
|
|
oldMsgs, err := s.MsgStore.GetMessages(beginSeqNum, endSeqNum)
|
|
s.Require().Nil(err)
|
|
|
|
// Ensure the output is the same
|
|
s.Require().Len(msgs, len(oldMsgs))
|
|
for idx, msg := range msgs {
|
|
s.Require().EqualValues(msg, oldMsgs[idx])
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *StoreTestSuite) TestMessageStoreSaveMessageGetMessage() {
|
|
// Given the following saved messages
|
|
expectedMsgsBySeqNum := map[int]string{
|
|
1: "In the frozen land of Nador",
|
|
2: "they were forced to eat Robin's minstrels",
|
|
3: "and there was much rejoicing",
|
|
}
|
|
var seqNums []int
|
|
for seqNum := range expectedMsgsBySeqNum {
|
|
seqNums = append(seqNums, seqNum)
|
|
}
|
|
sort.Ints(seqNums)
|
|
for _, seqNum := range seqNums {
|
|
s.Require().Nil(s.MsgStore.SaveMessage(seqNum, []byte(expectedMsgsBySeqNum[seqNum])))
|
|
}
|
|
|
|
// When the messages are retrieved from the MessageStore
|
|
actualMsgs := s.fetchMessages(1, 3)
|
|
|
|
// Then the messages should be
|
|
s.Require().Len(actualMsgs, 3)
|
|
s.Equal(expectedMsgsBySeqNum[1], string(actualMsgs[0]))
|
|
s.Equal(expectedMsgsBySeqNum[2], string(actualMsgs[1]))
|
|
s.Equal(expectedMsgsBySeqNum[3], string(actualMsgs[2]))
|
|
|
|
// When the store is refreshed from its backing store
|
|
s.Require().Nil(s.MsgStore.Refresh())
|
|
|
|
// And the messages are retrieved from the MessageStore
|
|
actualMsgs = s.fetchMessages(1, 3)
|
|
|
|
// Then the messages should still be
|
|
s.Require().Len(actualMsgs, 3)
|
|
s.Equal(expectedMsgsBySeqNum[1], string(actualMsgs[0]))
|
|
s.Equal(expectedMsgsBySeqNum[2], string(actualMsgs[1]))
|
|
s.Equal(expectedMsgsBySeqNum[3], string(actualMsgs[2]))
|
|
}
|
|
|
|
func (s *StoreTestSuite) TestMessageStoreSaveMessageAndIncrementGetMessage() {
|
|
s.Require().Nil(s.MsgStore.SetNextSenderMsgSeqNum(420))
|
|
|
|
// Given the following saved messages
|
|
expectedMsgsBySeqNum := map[int]string{
|
|
1: "In the frozen land of Nador",
|
|
2: "they were forced to eat Robin's minstrels",
|
|
3: "and there was much rejoicing",
|
|
}
|
|
var seqNums []int
|
|
for seqNum := range expectedMsgsBySeqNum {
|
|
seqNums = append(seqNums, seqNum)
|
|
}
|
|
sort.Ints(seqNums)
|
|
for _, seqNum := range seqNums {
|
|
s.Require().Nil(s.MsgStore.SaveMessageAndIncrNextSenderMsgSeqNum(seqNum, []byte(expectedMsgsBySeqNum[seqNum])))
|
|
}
|
|
s.Equal(423, s.MsgStore.NextSenderMsgSeqNum())
|
|
|
|
// When the messages are retrieved from the MessageStore
|
|
actualMsgs := s.fetchMessages(1, 3)
|
|
|
|
// Then the messages should be
|
|
s.Require().Len(actualMsgs, 3)
|
|
s.Equal(expectedMsgsBySeqNum[1], string(actualMsgs[0]))
|
|
s.Equal(expectedMsgsBySeqNum[2], string(actualMsgs[1]))
|
|
s.Equal(expectedMsgsBySeqNum[3], string(actualMsgs[2]))
|
|
|
|
// When the store is refreshed from its backing store
|
|
s.Require().Nil(s.MsgStore.Refresh())
|
|
|
|
// And the messages are retrieved from the MessageStore
|
|
actualMsgs = s.fetchMessages(1, 3)
|
|
|
|
s.Equal(423, s.MsgStore.NextSenderMsgSeqNum())
|
|
|
|
// Then the messages should still be
|
|
s.Require().Len(actualMsgs, 3)
|
|
s.Equal(expectedMsgsBySeqNum[1], string(actualMsgs[0]))
|
|
s.Equal(expectedMsgsBySeqNum[2], string(actualMsgs[1]))
|
|
s.Equal(expectedMsgsBySeqNum[3], string(actualMsgs[2]))
|
|
}
|
|
|
|
func (s *StoreTestSuite) TestMessageStoreGetMessagesEmptyStore() {
|
|
// When messages are retrieved from an empty store
|
|
messages := s.fetchMessages(1, 2)
|
|
|
|
// Then no messages should be returned
|
|
require.Empty(s.T(), messages, "Did not expect messages from empty store")
|
|
}
|
|
|
|
func (s *StoreTestSuite) TestMessageStoreGetMessagesVariousRanges() {
|
|
t := s.T()
|
|
|
|
// Given the following saved messages
|
|
require.Nil(t, s.MsgStore.SaveMessage(1, []byte("hello")))
|
|
require.Nil(t, s.MsgStore.SaveMessage(2, []byte("cruel")))
|
|
require.Nil(t, s.MsgStore.SaveMessage(3, []byte("world")))
|
|
|
|
// When the following requests are made to the store
|
|
var testCases = []struct {
|
|
beginSeqNo, endSeqNo int
|
|
expectedBytes [][]byte
|
|
}{
|
|
{beginSeqNo: 1, endSeqNo: 1, expectedBytes: [][]byte{[]byte("hello")}},
|
|
{beginSeqNo: 1, endSeqNo: 2, expectedBytes: [][]byte{[]byte("hello"), []byte("cruel")}},
|
|
{beginSeqNo: 1, endSeqNo: 3, expectedBytes: [][]byte{[]byte("hello"), []byte("cruel"), []byte("world")}},
|
|
{beginSeqNo: 1, endSeqNo: 4, expectedBytes: [][]byte{[]byte("hello"), []byte("cruel"), []byte("world")}},
|
|
{beginSeqNo: 2, endSeqNo: 3, expectedBytes: [][]byte{[]byte("cruel"), []byte("world")}},
|
|
{beginSeqNo: 3, endSeqNo: 3, expectedBytes: [][]byte{[]byte("world")}},
|
|
{beginSeqNo: 3, endSeqNo: 4, expectedBytes: [][]byte{[]byte("world")}},
|
|
{beginSeqNo: 4, endSeqNo: 4, expectedBytes: [][]byte{}},
|
|
{beginSeqNo: 4, endSeqNo: 10, expectedBytes: [][]byte{}},
|
|
}
|
|
|
|
// Then the returned messages should be
|
|
for _, tc := range testCases {
|
|
actualMsgs := s.fetchMessages(tc.beginSeqNo, tc.endSeqNo)
|
|
require.Len(t, actualMsgs, len(tc.expectedBytes))
|
|
for i, expectedMsg := range tc.expectedBytes {
|
|
assert.Equal(t, string(expectedMsg), string(actualMsgs[i]))
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *StoreTestSuite) TestMessageStoreCreationTime() {
|
|
s.False(s.MsgStore.CreationTime().IsZero())
|
|
|
|
t0 := time.Now()
|
|
s.Require().Nil(s.MsgStore.Reset())
|
|
t1 := time.Now()
|
|
s.Require().True(s.MsgStore.CreationTime().After(t0))
|
|
s.Require().True(s.MsgStore.CreationTime().Before(t1))
|
|
}
|