@@ -68,6 +68,79 @@ describe("Uptime Calculator", () => {
6868 assert . strictEqual ( divisionKey , dayjs . utc ( "2023-08-12 20:46:00" ) . unix ( ) ) ;
6969 } ) ;
7070
71+ test ( "missing cleanup buckets are not created when createIfMissing is false" , ( ) => {
72+ let c2 = new UptimeCalculator ( ) ;
73+
74+ c2 . getMinutelyKey ( dayjs . utc ( "2023-08-12 20:46:59" ) ) ;
75+ c2 . getHourlyKey ( dayjs . utc ( "2023-08-12 20:46:59" ) ) ;
76+ c2 . getDailyKey ( dayjs . utc ( "2023-08-12 20:46:59" ) ) ;
77+
78+ let minutelyCleanupKey = c2 . getMinutelyKey ( dayjs . utc ( "2023-08-11 20:46:59" ) , false ) ;
79+ let hourlyCleanupKey = c2 . getHourlyKey ( dayjs . utc ( "2023-07-13 20:46:59" ) , false ) ;
80+ let dailyCleanupKey = c2 . getDailyKey ( dayjs . utc ( "2022-08-12 20:46:59" ) , false ) ;
81+
82+ assert . strictEqual ( c2 . minutelyUptimeDataList . length ( ) , 1 ) ;
83+ assert . strictEqual ( c2 . hourlyUptimeDataList . length ( ) , 1 ) ;
84+ assert . strictEqual ( c2 . dailyUptimeDataList . length ( ) , 1 ) ;
85+ assert . strictEqual ( c2 . minutelyUptimeDataList [ minutelyCleanupKey ] , undefined ) ;
86+ assert . strictEqual ( c2 . hourlyUptimeDataList [ hourlyCleanupKey ] , undefined ) ;
87+ assert . strictEqual ( c2 . dailyUptimeDataList [ dailyCleanupKey ] , undefined ) ;
88+ } ) ;
89+
90+ test ( "cleanup lookup should not create missing minutely/hourly buckets" , ( ) => {
91+ let startDate = dayjs . utc ( "2023-08-12 00:00:00" ) ;
92+
93+ // First test the broken version that creates missing buckets during cleanup lookup.
94+ let broken = new UptimeCalculator ( ) ;
95+ let minutelyQueueLimit = broken . minutelyUptimeDataList . __limit ;
96+ let hourlyQueueLimit = broken . hourlyUptimeDataList . __limit ;
97+ let totalTicks = Math . max ( minutelyQueueLimit , hourlyQueueLimit ) ;
98+
99+ let minutelyEndDate = startDate ;
100+ let hourlyEndDate = startDate ;
101+ for ( let tick = 0 ; tick < totalTicks ; tick ++ ) {
102+ minutelyEndDate = startDate . add ( tick , "minute" ) ;
103+ hourlyEndDate = startDate . add ( tick , "hour" ) ;
104+
105+ // Simulate normal key lookup that creates buckets.
106+ broken . getMinutelyKey ( minutelyEndDate ) ;
107+ broken . getHourlyKey ( hourlyEndDate ) ;
108+
109+ // Simulate pre-fix cleanup key lookup that accidentally creates missing buckets.
110+ broken . getMinutelyKey ( minutelyEndDate . subtract ( broken . statMinutelyKeepHour , "hour" ) ) ;
111+ broken . getHourlyKey ( hourlyEndDate . subtract ( broken . statHourlyKeepDay , "day" ) ) ;
112+ }
113+
114+ UptimeCalculator . currentDate = minutelyEndDate ;
115+ assert . strictEqual ( broken . getDataArray ( minutelyQueueLimit , "minute" ) . length , minutelyQueueLimit / 2 ) ;
116+
117+ UptimeCalculator . currentDate = hourlyEndDate ;
118+ assert . strictEqual ( broken . getDataArray ( hourlyQueueLimit , "hour" ) . length , hourlyQueueLimit / 2 ) ;
119+
120+ // Now test the fixed version that should not create missing buckets.
121+ let fixed = new UptimeCalculator ( ) ;
122+ let fixedMinutelyTickDate = startDate ;
123+ let fixedHourlyTickDate = startDate ;
124+ for ( let tick = 0 ; tick < totalTicks ; tick ++ ) {
125+ fixedMinutelyTickDate = startDate . add ( tick , "minute" ) ;
126+ fixedHourlyTickDate = startDate . add ( tick , "hour" ) ;
127+
128+ // Simulate normal key lookup that creates buckets.
129+ fixed . getMinutelyKey ( fixedMinutelyTickDate ) ;
130+ fixed . getHourlyKey ( fixedHourlyTickDate ) ;
131+
132+ // Simulate pre-fix cleanup key lookup that should not create missing buckets.
133+ fixed . getMinutelyKey ( fixedMinutelyTickDate . subtract ( fixed . statMinutelyKeepHour , "hour" ) , false ) ;
134+ fixed . getHourlyKey ( fixedHourlyTickDate . subtract ( fixed . statHourlyKeepDay , "day" ) , false ) ;
135+ }
136+
137+ UptimeCalculator . currentDate = minutelyEndDate ;
138+ assert . strictEqual ( fixed . getDataArray ( minutelyQueueLimit , "minute" ) . length , minutelyQueueLimit ) ;
139+
140+ UptimeCalculator . currentDate = hourlyEndDate ;
141+ assert . strictEqual ( fixed . getDataArray ( hourlyQueueLimit , "hour" ) . length , hourlyQueueLimit ) ;
142+ } ) ;
143+
71144 test ( "getDailyKey() returns correct timestamp for start of day" , ( ) => {
72145 let c2 = new UptimeCalculator ( ) ;
73146 let dailyKey = c2 . getDailyKey ( dayjs . utc ( "2023-08-12 20:46:00" ) ) ;
0 commit comments