Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor external stores into packages #592

Merged
merged 9 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,5 @@ linters:
linters-settings:
gofmt:
simplify: true
goimports:
local-prefixes: github.com/quickfixgo/quickfix
dupl:
threshold: 400
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ vet:
go vet `go list ./... | grep -v quickfix/gen`

test:
MONGODB_TEST_CXN=mongodb://db:27017 go test -v -cover . ./datadictionary ./internal
MONGODB_TEST_CXN=mongodb://db:27017 go test -v -cover `go list ./... | grep -v quickfix/gen`

linters-install:
@golangci-lint --version >/dev/null 2>&1 || { \
Expand Down Expand Up @@ -62,7 +62,7 @@ build-src:
build: build-src build-test-srv

test-ci:
go test -v -cover . ./datadictionary ./internal
go test -v -cover `go list ./... | grep -v quickfix/gen`

generate-ci: clean
mkdir -p gen; cd gen; go run ../cmd/generate-fix/generate-fix.go -pkg-root=github.com/quickfixgo/quickfix/gen ../spec/$(shell echo $(FIX_TEST) | tr '[:lower:]' '[:upper:]').xml;
Expand Down
8 changes: 5 additions & 3 deletions _test/test-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"github.com/quickfixgo/quickfix/config"
field "github.com/quickfixgo/quickfix/gen/field"
tag "github.com/quickfixgo/quickfix/gen/tag"
"github.com/quickfixgo/quickfix/store/file"
"github.com/quickfixgo/quickfix/store/mongo"
)

var router *quickfix.MessageRouter = quickfix.NewMessageRouter()
Expand Down Expand Up @@ -149,16 +151,16 @@ func main() {
appSettings.GlobalSettings().Set(config.MongoStoreReplicaSet, mongoReplicaSet)
appSettings.GlobalSettings().Set(config.DynamicSessions, "Y")

acceptor, err = quickfix.NewAcceptor(app, quickfix.NewMongoStoreFactory(appSettings), appSettings, fileLogFactory)
acceptor, err = quickfix.NewAcceptor(app, mongo.NewStoreFactory(appSettings), appSettings, fileLogFactory)
case "FILE":
fileStoreRootPath := path.Join(os.TempDir(), fmt.Sprintf("FileStoreTestSuite-%d", os.Getpid()))
fileStorePath := path.Join(fileStoreRootPath, fmt.Sprintf("%d", time.Now().UnixNano()))
appSettings.GlobalSettings().Set(config.FileStorePath, fileStorePath)
appSettings.GlobalSettings().Set(config.DynamicSessions, "Y")

acceptor, err = quickfix.NewAcceptor(app, quickfix.NewFileStoreFactory(appSettings), appSettings, fileLogFactory)
acceptor, err = quickfix.NewAcceptor(app, file.NewStoreFactory(appSettings), appSettings, fileLogFactory)
case "MEMORY":
acceptor, err = quickfix.NewAcceptor(app, quickfix.NewMemoryStoreFactory(), appSettings, fileLogFactory)
fallthrough
default:
acceptor, err = quickfix.NewAcceptor(app, quickfix.NewMemoryStoreFactory(), appSettings, fileLogFactory)
}
Expand Down
22 changes: 0 additions & 22 deletions fileutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import (
"fmt"
"os"
"strings"

"github.com/pkg/errors"
)

func sessionIDFilenamePrefix(s SessionID) string {
Expand All @@ -47,26 +45,6 @@ func sessionIDFilenamePrefix(s SessionID) string {
return strings.Join(fname, "-")
}

// closeFile behaves like Close, except that no error is returned if the file does not exist.
func closeFile(f *os.File) error {
if f != nil {
if err := f.Close(); err != nil {
if !os.IsNotExist(err) {
return err
}
}
}
return nil
}

// removeFile behaves like os.Remove, except that no error is returned if the file does not exist.
func removeFile(fname string) error {
if err := os.Remove(fname); (err != nil) && !os.IsNotExist(err) {
return errors.Wrapf(err, "remove %v", fname)
}
return nil
}

// openOrCreateFile opens a file for reading and writing, creating it if necessary.
func openOrCreateFile(fname string, perm os.FileMode) (f *os.File, err error) {
if f, err = os.OpenFile(fname, os.O_RDWR, perm); err != nil {
Expand Down
118 changes: 51 additions & 67 deletions store_test.go → internal/testsuite/store_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,99 +13,83 @@
// Contact [email protected] if any conditions of this licensing
// are not clear to you.

package quickfix
package testsuite

import (
"testing"
"time"

"github.com/quickfixgo/quickfix"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)

// MessageStoreTestSuite is the suite of all tests that should be run against all MessageStore implementations.
type MessageStoreTestSuite struct {
type StoreTestSuite struct {
suite.Suite
msgStore MessageStore
MsgStore quickfix.MessageStore
}

// MemoryStoreTestSuite runs all tests in the MessageStoreTestSuite against the MemoryStore implementation.
type MemoryStoreTestSuite struct {
MessageStoreTestSuite
}

func (suite *MemoryStoreTestSuite) SetupTest() {
var err error
suite.msgStore, err = NewMemoryStoreFactory().Create(SessionID{})
require.Nil(suite.T(), err)
}

func TestMemoryStoreTestSuite(t *testing.T) {
suite.Run(t, new(MemoryStoreTestSuite))
}

func (s *MessageStoreTestSuite) TestMessageStore_SetNextMsgSeqNum_Refresh_IncrNextMsgSeqNum() {
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))
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())
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())
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())
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())
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())
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())
s.Equal(868, s.MsgStore.NextSenderMsgSeqNum())
s.Equal(5310, s.MsgStore.NextTargetMsgSeqNum())
}

func (s *MessageStoreTestSuite) TestMessageStore_Reset() {
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))
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())
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())
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())
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())
s.Equal(1, s.MsgStore.NextSenderMsgSeqNum())
s.Equal(1, s.MsgStore.NextTargetMsgSeqNum())
}

func (s *MessageStoreTestSuite) TestMessageStore_SaveMessage_GetMessage() {
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",
}
for seqNum, msg := range expectedMsgsBySeqNum {
s.Require().Nil(s.msgStore.SaveMessage(seqNum, []byte(msg)))
s.Require().Nil(s.MsgStore.SaveMessage(seqNum, []byte(msg)))
}

// When the messages are retrieved from the MessageStore
actualMsgs, err := s.msgStore.GetMessages(1, 3)
actualMsgs, err := s.MsgStore.GetMessages(1, 3)
s.Require().Nil(err)

// Then the messages should be
Expand All @@ -115,10 +99,10 @@ func (s *MessageStoreTestSuite) TestMessageStore_SaveMessage_GetMessage() {
s.Equal(expectedMsgsBySeqNum[3], string(actualMsgs[2]))

// When the store is refreshed from its backing store
s.Require().Nil(s.msgStore.Refresh())
s.Require().Nil(s.MsgStore.Refresh())

// And the messages are retrieved from the MessageStore
actualMsgs, err = s.msgStore.GetMessages(1, 3)
actualMsgs, err = s.MsgStore.GetMessages(1, 3)
s.Require().Nil(err)

// Then the messages should still be
Expand All @@ -128,8 +112,8 @@ func (s *MessageStoreTestSuite) TestMessageStore_SaveMessage_GetMessage() {
s.Equal(expectedMsgsBySeqNum[3], string(actualMsgs[2]))
}

func (s *MessageStoreTestSuite) TestMessageStore_SaveMessage_AndIncrement_GetMessage() {
s.Require().Nil(s.msgStore.SetNextSenderMsgSeqNum(420))
func (s *StoreTestSuite) TestMessageStoreSaveMessageAndIncrementGetMessage() {
s.Require().Nil(s.MsgStore.SetNextSenderMsgSeqNum(420))

// Given the following saved messages
expectedMsgsBySeqNum := map[int]string{
Expand All @@ -138,12 +122,12 @@ func (s *MessageStoreTestSuite) TestMessageStore_SaveMessage_AndIncrement_GetMes
3: "and there was much rejoicing",
}
for seqNum, msg := range expectedMsgsBySeqNum {
s.Require().Nil(s.msgStore.SaveMessageAndIncrNextSenderMsgSeqNum(seqNum, []byte(msg)))
s.Require().Nil(s.MsgStore.SaveMessageAndIncrNextSenderMsgSeqNum(seqNum, []byte(msg)))
}
s.Equal(423, s.msgStore.NextSenderMsgSeqNum())
s.Equal(423, s.MsgStore.NextSenderMsgSeqNum())

// When the messages are retrieved from the MessageStore
actualMsgs, err := s.msgStore.GetMessages(1, 3)
actualMsgs, err := s.MsgStore.GetMessages(1, 3)
s.Require().Nil(err)

// Then the messages should be
Expand All @@ -153,13 +137,13 @@ func (s *MessageStoreTestSuite) TestMessageStore_SaveMessage_AndIncrement_GetMes
s.Equal(expectedMsgsBySeqNum[3], string(actualMsgs[2]))

// When the store is refreshed from its backing store
s.Require().Nil(s.msgStore.Refresh())
s.Require().Nil(s.MsgStore.Refresh())

// And the messages are retrieved from the MessageStore
actualMsgs, err = s.msgStore.GetMessages(1, 3)
actualMsgs, err = s.MsgStore.GetMessages(1, 3)
s.Require().Nil(err)

s.Equal(423, s.msgStore.NextSenderMsgSeqNum())
s.Equal(423, s.MsgStore.NextSenderMsgSeqNum())

// Then the messages should still be
s.Require().Len(actualMsgs, 3)
Expand All @@ -168,22 +152,22 @@ func (s *MessageStoreTestSuite) TestMessageStore_SaveMessage_AndIncrement_GetMes
s.Equal(expectedMsgsBySeqNum[3], string(actualMsgs[2]))
}

func (s *MessageStoreTestSuite) TestMessageStore_GetMessages_EmptyStore() {
func (s *StoreTestSuite) TestMessageStoreGetMessagesEmptyStore() {
// When messages are retrieved from an empty store
messages, err := s.msgStore.GetMessages(1, 2)
messages, err := s.MsgStore.GetMessages(1, 2)
require.Nil(s.T(), err)

// Then no messages should be returned
require.Empty(s.T(), messages, "Did not expect messages from empty store")
}

func (s *MessageStoreTestSuite) TestMessageStore_GetMessages_VariousRanges() {
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")))
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 {
Expand All @@ -203,7 +187,7 @@ func (s *MessageStoreTestSuite) TestMessageStore_GetMessages_VariousRanges() {

// Then the returned messages should be
for _, tc := range testCases {
actualMsgs, err := s.msgStore.GetMessages(tc.beginSeqNo, tc.endSeqNo)
actualMsgs, err := s.MsgStore.GetMessages(tc.beginSeqNo, tc.endSeqNo)
require.Nil(t, err)
require.Len(t, actualMsgs, len(tc.expectedBytes))
for i, expectedMsg := range tc.expectedBytes {
Expand All @@ -212,12 +196,12 @@ func (s *MessageStoreTestSuite) TestMessageStore_GetMessages_VariousRanges() {
}
}

func (s *MessageStoreTestSuite) TestMessageStore_CreationTime() {
s.False(s.msgStore.CreationTime().IsZero())
func (s *StoreTestSuite) TestMessageStoreCreationTime() {
s.False(s.MsgStore.CreationTime().IsZero())

t0 := time.Now()
s.Require().Nil(s.msgStore.Reset())
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))
s.Require().True(s.MsgStore.CreationTime().After(t0))
s.Require().True(s.MsgStore.CreationTime().Before(t1))
}
Loading
Loading