Skip to content

Commit d0dbe03

Browse files
authored
Merge pull request #230 from cbusbey/resend_fix
fixes bug in resend state where resend response is processed incomplete
2 parents e33c0c0 + 41e45f1 commit d0dbe03

File tree

4 files changed

+80
-11
lines changed

4 files changed

+80
-11
lines changed

in_session_test.go

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,12 @@ func TestInSessionTestSuite(t *testing.T) {
1919
func (s *InSessionTestSuite) SetupTest() {
2020
s.Init()
2121
s.session.State = inSession{}
22+
s.session.messageStash = make(map[int]Message)
2223
}
2324

24-
func (s *InSessionTestSuite) TestIsLoggedOn() {
25+
func (s *InSessionTestSuite) TestPreliminary() {
2526
s.True(s.session.IsLoggedOn())
26-
}
27-
28-
func (s *InSessionTestSuite) TestIsConnected() {
2927
s.True(s.session.IsConnected())
30-
}
31-
32-
func (s *InSessionTestSuite) TestIsSessionTime() {
3328
s.True(s.session.IsSessionTime())
3429
}
3530

@@ -115,3 +110,26 @@ func (s *InSessionTestSuite) TestStop() {
115110
s.Stopped()
116111
s.Disconnected()
117112
}
113+
114+
func (s *InSessionTestSuite) TestFIXMsgInTargetTooHigh() {
115+
s.MessageFactory.seqNum = 5
116+
117+
s.MockApp.On("ToAdmin")
118+
msgSeqNumTooHigh := s.NewOrderSingle()
119+
s.fixMsgIn(s.session, msgSeqNumTooHigh)
120+
121+
s.MockApp.AssertExpectations(s.T())
122+
s.LastToAdminMessageSent()
123+
s.MessageType(enum.MsgType_RESEND_REQUEST, s.MockApp.lastToAdmin)
124+
s.FieldEquals(tagBeginSeqNo, 1, s.MockApp.lastToAdmin.Body)
125+
126+
s.State(resendState{})
127+
s.NextTargetMsgSeqNum(1)
128+
129+
stashedMsg, ok := s.session.messageStash[6]
130+
s.True(ok)
131+
132+
rawMsg, _ := msgSeqNumTooHigh.Build()
133+
stashedRawMsg, _ := stashedMsg.Build()
134+
s.Equal(string(rawMsg), string(stashedRawMsg))
135+
}

quickfix_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ type MessageFactory struct {
104104
seqNum int
105105
}
106106

107+
func (m *MessageFactory) SetNextSeqNum(next int) {
108+
m.seqNum = next - 1
109+
}
110+
107111
func (m *MessageFactory) buildMessage(msgType string) Message {
108112
m.seqNum++
109113
msg := NewMessage()

resend_state.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,22 @@ func (s resendState) Timeout(session *session, event internal.Event) (nextState
2323
func (s resendState) FixMsgIn(session *session, msg Message) (nextState sessionState) {
2424
nextState = inSession{}.FixMsgIn(session, msg)
2525

26-
if !nextState.IsLoggedOn() || len(session.messageStash) == 0 {
26+
if _, stillInResend := nextState.(resendState); stillInResend || !nextState.IsLoggedOn() {
2727
return
2828
}
2929

30-
targetSeqNum := session.store.NextTargetMsgSeqNum()
31-
if msg, ok := session.messageStash[targetSeqNum]; ok {
30+
for len(session.messageStash) > 0 {
31+
targetSeqNum := session.store.NextTargetMsgSeqNum()
32+
msg, ok := session.messageStash[targetSeqNum]
33+
if !ok {
34+
return s
35+
}
3236
delete(session.messageStash, targetSeqNum)
33-
nextState = nextState.FixMsgIn(session, msg)
37+
38+
nextState = inSession{}.FixMsgIn(session, msg)
39+
if !nextState.IsLoggedOn() {
40+
return
41+
}
3442
}
3543

3644
return

resend_state_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package quickfix
33
import (
44
"testing"
55

6+
"github.com/quickfixgo/quickfix/enum"
67
"github.com/quickfixgo/quickfix/internal"
78
"github.com/stretchr/testify/suite"
89
)
@@ -18,6 +19,7 @@ func TestResendStateTestSuite(t *testing.T) {
1819
func (s *resendStateTestSuite) SetupTest() {
1920
s.Init()
2021
s.session.State = resendState{}
22+
s.session.messageStash = make(map[int]Message)
2123
}
2224

2325
func (s *resendStateTestSuite) TestIsLoggedOn() {
@@ -56,3 +58,40 @@ func (s *resendStateTestSuite) TestTimeoutUnchangedNeedHeartbeat() {
5658
s.MockApp.AssertExpectations(s.T())
5759
s.State(resendState{})
5860
}
61+
62+
func (s *resendStateTestSuite) TestFixMsgIn() {
63+
s.session.State = inSession{}
64+
65+
//in session expects seq number 1, send too high
66+
s.MessageFactory.SetNextSeqNum(2)
67+
s.MockApp.On("ToAdmin")
68+
69+
msgSeqNum2 := s.NewOrderSingle()
70+
s.fixMsgIn(s.session, msgSeqNum2)
71+
72+
s.MockApp.AssertExpectations(s.T())
73+
s.State(resendState{})
74+
s.LastToAdminMessageSent()
75+
s.MessageType(enum.MsgType_RESEND_REQUEST, s.MockApp.lastToAdmin)
76+
s.FieldEquals(tagBeginSeqNo, 1, s.MockApp.lastToAdmin.Body)
77+
s.NextTargetMsgSeqNum(1)
78+
79+
msgSeqNum3 := s.NewOrderSingle()
80+
s.fixMsgIn(s.session, msgSeqNum3)
81+
s.State(resendState{})
82+
s.NextTargetMsgSeqNum(1)
83+
84+
msgSeqNum4 := s.NewOrderSingle()
85+
s.fixMsgIn(s.session, msgSeqNum4)
86+
87+
s.State(resendState{})
88+
s.NextTargetMsgSeqNum(1)
89+
90+
s.MessageFactory.SetNextSeqNum(1)
91+
s.MockApp.On("FromApp").Return(nil)
92+
s.fixMsgIn(s.session, s.NewOrderSingle())
93+
94+
s.MockApp.AssertNumberOfCalls(s.T(), "FromApp", 4)
95+
s.State(inSession{})
96+
s.NextTargetMsgSeqNum(5)
97+
}

0 commit comments

Comments
 (0)