Skip to content

Commit d894e13

Browse files
committed
reimplement @oclancy's SeqReset UTs from PR connamara#784
PR connamara#784 which is intended to fix issue connamara#309
1 parent d942436 commit d894e13

File tree

1 file changed

+106
-4
lines changed

1 file changed

+106
-4
lines changed

UnitTests/SessionTest.cs

Lines changed: 106 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,12 @@ public void SendNOSMessage()
192192
_session!.Next(CreateNOSMessage(_seqNum++).ConstructString());
193193
}
194194

195-
public void SendNOSMessage(SeqNumType n)
195+
public void SendNOSMessage(SeqNumType n, bool possDupFlag=false)
196196
{
197-
_session!.Next(CreateNOSMessage(n).ConstructString());
197+
var msg = CreateNOSMessage(n);
198+
if (possDupFlag)
199+
msg.Header.SetField(new QuickFix.Fields.PossDupFlag(possDupFlag));
200+
_session!.Next(msg.ConstructString());
198201
}
199202

200203
public void SendResendRequest(SeqNumType begin, SeqNumType end)
@@ -212,11 +215,15 @@ public void SendResendRequest40(SeqNumType begin, SeqNumType end)
212215
}
213216

214217
private void SendTheMessage(QuickFix.Message msg)
218+
{
219+
SendTheMessage(msg, _seqNum++);
220+
}
221+
222+
private void SendTheMessage(QuickFix.Message msg, SeqNumType seqNum)
215223
{
216224
msg.Header.SetField(new QuickFix.Fields.TargetCompID(_sessionId.SenderCompID));
217225
msg.Header.SetField(new QuickFix.Fields.SenderCompID(_sessionId.TargetCompID));
218-
msg.Header.SetField(new QuickFix.Fields.MsgSeqNum(_seqNum++));
219-
226+
msg.Header.SetField(new QuickFix.Fields.MsgSeqNum(seqNum));
220227
_session!.Next(msg.ConstructString());
221228
}
222229

@@ -961,5 +968,100 @@ public void TestBasicResendRequest_WithMax() {
961968
Assert.That(_session.IsResendRequested, Is.False, $"seq num {i}");
962969
}
963970
}
971+
972+
[Test]
973+
public void TestSequenceResetNoGapFillIsProcessed()
974+
{
975+
Assert.That(_session!.IgnorePossDupResendRequests, Is.EqualTo(false));
976+
Logon();
977+
SendNOSMessage();
978+
SendNOSMessage();
979+
Assert.That(_session.NextTargetMsgSeqNum, Is.EqualTo(4));
980+
981+
QuickFix.FIX42.SequenceReset sr = new(new QuickFix.Fields.NewSeqNo(150));
982+
SendTheMessage(sr);
983+
984+
Assert.That(_session.NextTargetMsgSeqNum, Is.EqualTo(150));
985+
}
986+
987+
[Test]
988+
public void TestSequenceResetWithGapFillIsProcessed()
989+
{
990+
Assert.That(_session!.IgnorePossDupResendRequests, Is.EqualTo(false));
991+
Logon();
992+
SendNOSMessage();
993+
SendNOSMessage();
994+
Assert.That(_session.NextTargetMsgSeqNum, Is.EqualTo(4));
995+
996+
QuickFix.FIX42.SequenceReset sr = new(new QuickFix.Fields.NewSeqNo(150));
997+
sr.GapFillFlag = new QuickFix.Fields.GapFillFlag(true);
998+
SendTheMessage(sr);
999+
1000+
Assert.That(_session.NextTargetMsgSeqNum, Is.EqualTo(150));
1001+
}
1002+
1003+
[Test]
1004+
public void TestSequenceResetDuringResendRequestIsProcessed()
1005+
{
1006+
Assert.That(_session!.IgnorePossDupResendRequests, Is.EqualTo(false));
1007+
_session.RequiresOrigSendingTime = false; // default is true
1008+
Logon();
1009+
SendNOSMessage(); // seq 2
1010+
SendNOSMessage(10); // causes ResendRequest to be sent
1011+
Assert.That(_session.NextTargetMsgSeqNum, Is.EqualTo(3));
1012+
1013+
var resendRequest =
1014+
(QuickFix.FIX42.ResendRequest)_responder.MsgLookup[QuickFix.Fields.MsgType.RESEND_REQUEST].Dequeue();
1015+
Assert.That(resendRequest.BeginSeqNo.Value, Is.EqualTo(3));
1016+
Assert.That(resendRequest.EndSeqNo.Value, Is.EqualTo(0));
1017+
1018+
// Resend & GapFill through seq=9
1019+
SendNOSMessage(3);
1020+
SendNOSMessage(4);
1021+
QuickFix.FIX42.SequenceReset sr = new(new QuickFix.Fields.NewSeqNo(9));
1022+
SendTheMessage(sr, 5);
1023+
SendNOSMessage(9);
1024+
1025+
// We already processed 10, so the next one is 11
1026+
Assert.That(_session.NextTargetMsgSeqNum, Is.EqualTo(11));
1027+
}
1028+
1029+
[Test]
1030+
public void TestGapFillShouldNotBeIgnoredIfPossDup()
1031+
{
1032+
Assert.That(_session!.IgnorePossDupResendRequests, Is.EqualTo(false));
1033+
_session.RequiresOrigSendingTime = false; // default is true
1034+
Logon();
1035+
SendNOSMessage(); // seq 2
1036+
1037+
QuickFix.FIX42.Heartbeat hb = new();
1038+
SendTheMessage(hb, 5); // seq=5, causes ResendRequest to be sent
1039+
1040+
// Verify the ResendRequest that was just sent
1041+
var resendRequest =
1042+
(QuickFix.FIX42.ResendRequest)_responder.MsgLookup[QuickFix.Fields.MsgType.RESEND_REQUEST].Dequeue();
1043+
Assert.That(resendRequest.BeginSeqNo.Value, Is.EqualTo(3));
1044+
Assert.That(resendRequest.EndSeqNo.Value, Is.EqualTo(0));
1045+
1046+
Assert.That(_session.NextTargetMsgSeqNum, Is.EqualTo(3));
1047+
1048+
// Resends
1049+
SendNOSMessage(3, possDupFlag: true);
1050+
SendNOSMessage(4, possDupFlag: true);
1051+
// Now the session processes the Heartbeat/seq=5 from its queue.
1052+
Assert.That(_session.NextTargetMsgSeqNum, Is.EqualTo(6));
1053+
1054+
// But the counterparty still needs to resend the seq=5!
1055+
// The 5 is a Heartbeat, an admin message, so it's a gapfill.
1056+
// The gapfill goes to 7, omitting ever sending a 6.
1057+
QuickFix.FIX42.SequenceReset sr = new(new QuickFix.Fields.NewSeqNo(7));
1058+
sr.Header.SetField(new QuickFix.Fields.PossDupFlag(true));
1059+
sr.SetField(new QuickFix.Fields.GapFillFlag(true));
1060+
SendTheMessage(sr, 5);
1061+
1062+
// Even though client already processed the original Heartbeat/seq=5,
1063+
// it must not discard the GapFill 5.
1064+
Assert.That(_session.NextTargetMsgSeqNum, Is.EqualTo(7));
1065+
}
9641066
}
9651067

0 commit comments

Comments
 (0)