|
45 | 45 | import java.io.FileOutputStream; |
46 | 46 | import java.io.IOException; |
47 | 47 | import java.lang.reflect.Field; |
| 48 | +import java.time.Duration; |
48 | 49 | import java.time.Instant; |
49 | 50 | import java.time.LocalDateTime; |
50 | 51 | import java.time.LocalTime; |
@@ -1023,6 +1024,69 @@ public void testLogonOutsideSessionTimeIsRejected() throws Exception { |
1023 | 1024 | } |
1024 | 1025 | } |
1025 | 1026 |
|
| 1027 | + @Test |
| 1028 | + public void testAcceptorRejectsLogonBeforeStartAndAcceptsAtNextStart() throws Exception { |
| 1029 | + // Schedule: America/New_York, StartDay=Sunday StartTime=17:02:00, EndDay=Sunday EndTime=17:00:00 |
| 1030 | + // Session active: Sunday 17:02 NY -> following Sunday 17:00 NY (2-minute gap each Sunday). |
| 1031 | + // January 2024: EST = UTC-5. Jan 7 = Sunday, Jan 14 = Sunday. |
| 1032 | + final LocalDateTime sessionDay = LocalDateTime.of(2024, 1, 7, 22, 30, 0); // 17:30 NY Sun Jan 7, inside session |
| 1033 | + final LocalDateTime afterEndTime = LocalDateTime.of(2024, 1, 14, 22, 0, 10); // 17:00:10 NY Sun Jan 14, just past EndTime |
| 1034 | + final LocalDateTime afterResetCheckTime = afterEndTime.plusSeconds(1); // 17:00:11 NY Sun Jan 14 |
| 1035 | + final LocalDateTime nextStartTime = LocalDateTime.of(2024, 1, 14, 22, 2, 10); // 17:02:10 NY Sun Jan 14, past StartTime |
| 1036 | + final MockSystemTimeSource systemTimeSource = new MockSystemTimeSource( |
| 1037 | + sessionDay.toInstant(ZoneOffset.UTC).toEpochMilli()); |
| 1038 | + SystemTime.setTimeSource(systemTimeSource); |
| 1039 | + |
| 1040 | + final SessionID sessionID = new SessionID( |
| 1041 | + FixVersions.BEGINSTRING_FIX44, "SENDER", "TARGET"); |
| 1042 | + final SessionSettings settings = SessionSettingsTest.setUpSession(null); |
| 1043 | + settings.setString("StartTime", "17:02:00"); |
| 1044 | + settings.setString("EndTime", "17:00:00"); |
| 1045 | + settings.setString("TimeZone", "America/New_York"); |
| 1046 | + settings.setString("StartDay", "Sunday"); |
| 1047 | + settings.setString("EndDay", "Sunday"); |
| 1048 | + setupFileStoreForQFJ357(sessionID, settings); |
| 1049 | + |
| 1050 | + final UnitTestApplication application = new UnitTestApplication(); |
| 1051 | + final UnitTestResponder responder = new UnitTestResponder(); |
| 1052 | + try (Session session = setUpFileStoreSession(application, false, |
| 1053 | + responder, settings, sessionID)) { |
| 1054 | + final SessionState state = getSessionState(session); |
| 1055 | + |
| 1056 | + int adminMessagesBeforeLogon = application.toAdminMessages.size(); |
| 1057 | + logonTo(session); |
| 1058 | + assertEquals(adminMessagesBeforeLogon + 1, application.toAdminMessages.size()); |
| 1059 | + assertEquals(MsgType.LOGON, application.lastToAdminMessage().getHeader() |
| 1060 | + .getString(MsgType.FIELD)); |
| 1061 | + assertTrue("Session should be connected", session.isLoggedOn()); |
| 1062 | + |
| 1063 | + systemTimeSource.increment(Duration.between(sessionDay, afterEndTime).toMillis()); |
| 1064 | + session.next(); |
| 1065 | + logoutFrom(session, state.getNextTargetMsgSeqNum()); |
| 1066 | + systemTimeSource.increment(Duration.between(afterEndTime, afterResetCheckTime).toMillis()); |
| 1067 | + session.next(); |
| 1068 | + assertFalse("Session should be disconnected after EndTime", session.isLoggedOn()); |
| 1069 | + |
| 1070 | + session.setResponder(responder); |
| 1071 | + adminMessagesBeforeLogon = application.toAdminMessages.size(); |
| 1072 | + logonTo(session); |
| 1073 | + assertEquals(adminMessagesBeforeLogon + 1, application.toAdminMessages.size()); |
| 1074 | + assertEquals(MsgType.LOGOUT, application.lastToAdminMessage().getHeader() |
| 1075 | + .getString(MsgType.FIELD)); |
| 1076 | + assertFalse("Session should reject logon attempts before StartTime", session.isLoggedOn()); |
| 1077 | + |
| 1078 | + systemTimeSource.increment(Duration.between(afterResetCheckTime, nextStartTime).toMillis()); |
| 1079 | + session.next(); |
| 1080 | + session.setResponder(responder); |
| 1081 | + adminMessagesBeforeLogon = application.toAdminMessages.size(); |
| 1082 | + logonTo(session); |
| 1083 | + assertEquals(adminMessagesBeforeLogon + 1, application.toAdminMessages.size()); |
| 1084 | + assertEquals(MsgType.LOGON, application.lastToAdminMessage().getHeader() |
| 1085 | + .getString(MsgType.FIELD)); |
| 1086 | + assertTrue("Session should accept logons again at StartTime", session.isLoggedOn()); |
| 1087 | + } |
| 1088 | + } |
| 1089 | + |
1026 | 1090 | // QFJ-357 |
1027 | 1091 | private void setupFileStoreForQFJ357(final SessionID sessionID, |
1028 | 1092 | final SessionSettings settings) throws ConfigError, |
|
0 commit comments