Skip to content
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
67 changes: 67 additions & 0 deletions logon_state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,32 @@ func (s *LogonStateTestSuite) TestFixMsgInLogon() {
s.NextSenderMsgSeqNum(3)
}

func (s *LogonStateTestSuite) TestFixMsgInLogonResetSeqNum() {
s.Require().Nil(s.store.IncrNextTargetMsgSeqNum())

logon := s.Logon()
logon.Body.SetField(tagHeartBtInt, FIXInt(32))
logon.Body.SetField(tagResetSeqNumFlag, FIXBoolean(true))

s.MockApp.On("FromAdmin").Return(nil)
s.MockApp.On("OnLogon")
s.MockApp.On("ToAdmin")
s.fixMsgIn(s.session, logon)

s.MockApp.AssertExpectations(s.T())

s.State(inSession{})
s.Equal(32*time.Second, s.session.HeartBtInt)

s.LastToAdminMessageSent()
s.MessageType(enum.MsgType_LOGON, s.MockApp.lastToAdmin)
s.FieldEquals(tagHeartBtInt, 32, s.MockApp.lastToAdmin.Body)
s.FieldEquals(tagResetSeqNumFlag, true, s.MockApp.lastToAdmin.Body)

s.NextTargetMsgSeqNum(2)
s.NextSenderMsgSeqNum(2)
}

func (s *LogonStateTestSuite) TestFixMsgInLogonInitiateLogon() {
s.session.InitiateLogon = true
s.Require().Nil(s.store.IncrNextSenderMsgSeqNum())
Expand All @@ -111,6 +137,47 @@ func (s *LogonStateTestSuite) TestFixMsgInLogonInitiateLogon() {
s.NextSenderMsgSeqNum(2)
}

func (s *LogonStateTestSuite) TestFixMsgInLogonInitiateLogonExpectResetSeqNum() {
s.session.InitiateLogon = true
s.session.sentReset = true
s.Require().Nil(s.store.IncrNextSenderMsgSeqNum())

logon := s.Logon()
logon.Body.SetField(tagHeartBtInt, FIXInt(32))
logon.Body.SetField(tagResetSeqNumFlag, FIXBoolean(true))

s.MockApp.On("FromAdmin").Return(nil)
s.MockApp.On("OnLogon")
s.fixMsgIn(s.session, logon)

s.MockApp.AssertExpectations(s.T())
s.State(inSession{})

s.NextTargetMsgSeqNum(2)
s.NextSenderMsgSeqNum(2)
}

func (s *LogonStateTestSuite) TestFixMsgInLogonInitiateLogonUnExpectedResetSeqNum() {
s.session.InitiateLogon = true
s.session.sentReset = false
s.Require().Nil(s.store.IncrNextTargetMsgSeqNum())
s.Require().Nil(s.store.IncrNextSenderMsgSeqNum())

logon := s.Logon()
logon.Body.SetField(tagHeartBtInt, FIXInt(32))
logon.Body.SetField(tagResetSeqNumFlag, FIXBoolean(true))

s.MockApp.On("FromAdmin").Return(nil)
s.MockApp.On("OnLogon")
s.fixMsgIn(s.session, logon)

s.MockApp.AssertExpectations(s.T())
s.State(inSession{})

s.NextTargetMsgSeqNum(2)
s.NextSenderMsgSeqNum(1)
}

func (s *LogonStateTestSuite) TestFixMsgInLogonRefreshOnLogon() {
var tests = []bool{true, false}

Expand Down
10 changes: 8 additions & 2 deletions quickfix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ func (s *MockStore) Refresh() error {
type MockApp struct {
mock.Mock

lastToAdmin Message
lastToApp Message
decorateToAdmin func(Message)
lastToAdmin Message
lastToApp Message
}

func (e *MockApp) OnCreate(sessionID SessionID) {
Expand All @@ -90,6 +91,11 @@ func (e *MockApp) FromAdmin(msg Message, sessionID SessionID) (reject MessageRej

func (e *MockApp) ToAdmin(msg Message, sessionID SessionID) {
e.Called()

if e.decorateToAdmin != nil {
e.decorateToAdmin(msg)
}

e.lastToAdmin = msg
}

Expand Down
27 changes: 26 additions & 1 deletion session.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type session struct {
stateTimer internal.EventTimer
peerTimer internal.EventTimer
messageStash map[int]Message
sentReset bool

targetDefaultApplVerID string

Expand Down Expand Up @@ -241,6 +242,26 @@ func (s *session) prepMessageForSend(msg *Message) error {

if isAdminMessageType(string(msgType)) {
s.application.ToAdmin(*msg, s.sessionID)

if msgType.String() == enum.MsgType_LOGON {
var resetSeqNumFlag FIXBoolean
if msg.Body.Has(tagResetSeqNumFlag) {
if err := msg.Body.GetField(tagResetSeqNumFlag, &resetSeqNumFlag); err != nil {
return err
}
}

if resetSeqNumFlag.Bool() {
if err := s.store.Reset(); err != nil {
return err
}

s.sentReset = true
seqNum = s.store.NextSenderMsgSeqNum()
msg.Header.SetField(tagMsgSeqNum, FIXInt(seqNum))
}

}
} else {
if err := s.application.ToApp(*msg, s.sessionID); err != nil {
return err
Expand Down Expand Up @@ -333,7 +354,9 @@ func (s *session) handleLogon(msg Message) error {
if err := msg.Body.GetField(tagResetSeqNumFlag, &resetSeqNumFlag); err == nil {
if resetSeqNumFlag {
s.log.OnEvent("Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1")
resetStore = true
if !s.sentReset {
resetStore = true
}
}
}

Expand All @@ -358,6 +381,7 @@ func (s *session) handleLogon(msg Message) error {
return err
}
}
s.sentReset = false

s.peerTimer.Reset(time.Duration(float64(1.2) * float64(s.HeartBtInt)))
s.application.OnLogon(s.sessionID)
Expand Down Expand Up @@ -596,6 +620,7 @@ func (s *session) onAdmin(msg interface{}) {
s.messageIn = msg.messageIn
s.messageOut = msg.messageOut
s.messageStash = make(map[int]Message)
s.sentReset = false

s.Connect(s)

Expand Down
29 changes: 29 additions & 0 deletions session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ func (s *SessionSuite) TestOnAdminConnectInitiateLogon() {

s.MockApp.AssertExpectations(s.T())
s.True(s.session.InitiateLogon)
s.False(s.sentReset)
s.State(logonState{})
s.LastToAdminMessageSent()
s.MessageType(enum.MsgType_LOGON, s.MockApp.lastToAdmin)
Expand All @@ -498,6 +499,34 @@ func (s *SessionSuite) TestOnAdminConnectInitiateLogon() {
s.NextSenderMsgSeqNum(3)
}

func (s *SessionSuite) TestInitiateLogonResetSeqNumFlag() {
adminMsg := connect{
messageOut: s.Receiver.sendChannel,
}
s.session.State = latentState{}
s.session.HeartBtInt = time.Duration(45) * time.Second
s.session.store.IncrNextTargetMsgSeqNum()
s.session.store.IncrNextSenderMsgSeqNum()
s.session.InitiateLogon = true

s.MockApp.On("ToAdmin")
s.MockApp.decorateToAdmin = func(msg Message) {
msg.Body.SetField(tagResetSeqNumFlag, FIXBoolean(true))
}
s.session.onAdmin(adminMsg)

s.MockApp.AssertExpectations(s.T())
s.True(s.session.InitiateLogon)
s.True(s.sentReset)
s.State(logonState{})
s.LastToAdminMessageSent()
s.MessageType(enum.MsgType_LOGON, s.MockApp.lastToAdmin)
s.FieldEquals(tagMsgSeqNum, 1, s.MockApp.lastToAdmin.Header)
s.FieldEquals(tagResetSeqNumFlag, true, s.MockApp.lastToAdmin.Body)
s.NextSenderMsgSeqNum(2)
s.NextTargetMsgSeqNum(1)
}

func (s *SessionSuite) TestOnAdminConnectInitiateLogonFIXT11() {
s.session.sessionID.BeginString = enum.BeginStringFIXT11
s.session.DefaultApplVerID = "8"
Expand Down