|
10 | 10 | import static org.mockito.Mockito.atLeastOnce; |
11 | 11 | import static org.mockito.Mockito.mock; |
12 | 12 | import static org.mockito.Mockito.stub; |
| 13 | +import static org.mockito.Mockito.times; |
13 | 14 | import static org.mockito.Mockito.verify; |
14 | 15 | import static org.mockito.Mockito.verifyNoMoreInteractions; |
| 16 | +import static org.mockito.Mockito.when; |
15 | 17 | import static quickfix.SessionFactoryTestSupport.createSession; |
16 | 18 |
|
17 | 19 | import java.io.BufferedOutputStream; |
|
28 | 30 |
|
29 | 31 | import org.junit.Before; |
30 | 32 | import org.junit.Test; |
| 33 | +import org.mockito.ArgumentCaptor; |
31 | 34 |
|
32 | 35 | import quickfix.field.ApplVerID; |
33 | 36 | import quickfix.field.BeginSeqNo; |
@@ -1862,6 +1865,100 @@ private void testSequenceResetGapFillWithChunkSize(int chunkSize) |
1862 | 1865 | session.close(); |
1863 | 1866 | } |
1864 | 1867 |
|
| 1868 | + @Test |
| 1869 | + public void correct_sequence_number_for_last_gap_fill_if_next_sender_sequence_number_is_higher_than_the_last_message_resent() |
| 1870 | + throws IOException, InvalidMessage, FieldNotFound, RejectLogon, UnsupportedMessageType, |
| 1871 | + IncorrectTagValue, IncorrectDataFormat, NoSuchFieldException, IllegalAccessException { |
| 1872 | + final SessionID sessionID = new SessionID(FixVersions.BEGINSTRING_FIX44, "SENDER", "TARGET"); |
| 1873 | + final boolean resetOnLogon = false; |
| 1874 | + final boolean validateSequenceNumbers = true; |
| 1875 | + |
| 1876 | + Session session = new Session(new UnitTestApplication(), new MemoryStoreFactory(), |
| 1877 | + sessionID, null, null, null, |
| 1878 | + new DefaultMessageFactory(), 30, false, 30, true, resetOnLogon, |
| 1879 | + false, false, false, false, false, true, false, 1.5, null, validateSequenceNumbers, |
| 1880 | + new int[]{5}, false, false, false, true, false, true, false, null, true, 0, |
| 1881 | + false, false); |
| 1882 | + |
| 1883 | + Responder mockResponder = mock(Responder.class); |
| 1884 | + when(mockResponder.send(anyString())).thenReturn(true); |
| 1885 | + session.setResponder(mockResponder); |
| 1886 | + |
| 1887 | + session.logon(); |
| 1888 | + session.next(); |
| 1889 | + |
| 1890 | + ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class); |
| 1891 | + verify(mockResponder).send(messageCaptor.capture()); |
| 1892 | + session.next(createLogonResponse(sessionID, new Message(messageCaptor.getValue()), 101)); |
| 1893 | + MessageStore messageStore = session.getStore(); |
| 1894 | + |
| 1895 | + for (int i=messageStore.getNextSenderMsgSeqNum(); i<=5; i++) { |
| 1896 | + String executionReportString = "8=FIX.4.2\0019=0246\00135=8\001115=THEM\00134=" + i + "\00143=Y\001122=20100908-17:52:37.920\00149=THEM\00156=US\001369=178\00152=20100908-17:59:30.642\00137=10118506\00111=a00000052.1\00117=17537743\00120=0\001150=4\00139=4\00155=ETFC\00154=1\00138=500000\00144=0.998\00132=0\00131=0\001151=0\00114=0\0016=0\00160=20100908-17:52:37.920\00110=80\001"; |
| 1897 | + messageStore.set(i, executionReportString); |
| 1898 | + messageStore.incrNextSenderMsgSeqNum(); |
| 1899 | + } |
| 1900 | + |
| 1901 | + //simulate a bunch of admin messages that were not persisted |
| 1902 | + for (int i=0; i<5; i++) |
| 1903 | + messageStore.incrNextSenderMsgSeqNum(); |
| 1904 | + |
| 1905 | + final Message resendRequest = createResendRequest(1, 1); |
| 1906 | + session.next(resendRequest); |
| 1907 | + |
| 1908 | + verify(mockResponder, times(7)).send(messageCaptor.capture()); |
| 1909 | + Message lastGapFill = new Message(messageCaptor.getAllValues().get(messageCaptor.getAllValues().size()-1)); |
| 1910 | + assertEquals("4", lastGapFill.getHeader().getString(MsgType.FIELD)); |
| 1911 | + assertEquals(lastGapFill.getHeader().getString(MsgSeqNum.FIELD), "6"); |
| 1912 | + } |
| 1913 | + |
| 1914 | + @Test |
| 1915 | + public void correct_sequence_number_for_last_gap_fill_if_next_sender_sequence_number_is_higher_than_last_message_resent_when_enableNextExpectedMsgSeqNum_is_true() |
| 1916 | + throws FieldNotFound, InvalidMessage, IOException, RejectLogon, IncorrectDataFormat, IncorrectTagValue, |
| 1917 | + UnsupportedMessageType { |
| 1918 | + boolean enableNextExpectedMsgSeqNum = true; |
| 1919 | + |
| 1920 | + final SessionID sessionID = new SessionID(FixVersions.BEGINSTRING_FIX44, "SENDER", "TARGET"); |
| 1921 | + final boolean resetOnLogon = false; |
| 1922 | + final boolean validateSequenceNumbers = true; |
| 1923 | + |
| 1924 | + Session session = new Session(new UnitTestApplication(), new MemoryStoreFactory(), |
| 1925 | + sessionID, null, null, null, |
| 1926 | + new DefaultMessageFactory(), 30, false, 30, true, resetOnLogon, |
| 1927 | + false, false, false, false, false, true, false, 1.5, null, validateSequenceNumbers, |
| 1928 | + new int[]{5}, false, false, false, true, false, true, false, null, true, 0, |
| 1929 | + enableNextExpectedMsgSeqNum, false); |
| 1930 | + |
| 1931 | + Responder mockResponder = mock(Responder.class); |
| 1932 | + when(mockResponder.send(anyString())).thenReturn(true); |
| 1933 | + session.setResponder(mockResponder); |
| 1934 | + |
| 1935 | + session.logon(); |
| 1936 | + session.next(); |
| 1937 | + |
| 1938 | + ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class); |
| 1939 | + verify(mockResponder).send(messageCaptor.capture()); |
| 1940 | + session.next(createLogonResponse(sessionID, new Message(messageCaptor.getValue()), 101)); |
| 1941 | + MessageStore messageStore = session.getStore(); |
| 1942 | + |
| 1943 | + for (int i=messageStore.getNextSenderMsgSeqNum(); i<=5; i++) { |
| 1944 | + String executionReportString = "8=FIX.4.2\0019=0246\00135=8\001115=THEM\00134=" + i + "\00143=Y\001122=20100908-17:52:37.920\00149=THEM\00156=US\001369=178\00152=20100908-17:59:30.642\00137=10118506\00111=a00000052.1\00117=17537743\00120=0\001150=4\00139=4\00155=ETFC\00154=1\00138=500000\00144=0.998\00132=0\00131=0\001151=0\00114=0\0016=0\00160=20100908-17:52:37.920\00110=80\001"; |
| 1945 | + messageStore.set(i, executionReportString); |
| 1946 | + messageStore.incrNextSenderMsgSeqNum(); |
| 1947 | + } |
| 1948 | + |
| 1949 | + //simulate a bunch of admin messages that were not persisted |
| 1950 | + for (int i=0; i<5; i++) |
| 1951 | + messageStore.incrNextSenderMsgSeqNum(); |
| 1952 | + |
| 1953 | + final Message resendRequest = createResendRequest(1, 1); |
| 1954 | + session.next(resendRequest); |
| 1955 | + |
| 1956 | + verify(mockResponder, times(7)).send(messageCaptor.capture()); |
| 1957 | + Message lastGapFill = new Message(messageCaptor.getAllValues().get(messageCaptor.getAllValues().size()-1)); |
| 1958 | + assertEquals("4", lastGapFill.getHeader().getString(MsgType.FIELD)); |
| 1959 | + assertEquals(lastGapFill.getHeader().getString(MsgSeqNum.FIELD), "6"); |
| 1960 | + } |
| 1961 | + |
1865 | 1962 | @Test |
1866 | 1963 | // QFJ-795 |
1867 | 1964 | public void testMsgSeqNumTooHighWithDisconnectOnError() throws Exception { |
|
0 commit comments