@@ -250,6 +250,117 @@ pub fn get_cleanup_param(
250250 Ok ( result)
251251}
252252
253+ #[ cfg( test) ]
254+ mod tests {
255+ use super :: * ;
256+ use crate :: planner:: patterns:: build_patterns;
257+ use promql_utilities:: ast_matching:: PromQLMatchResult ;
258+ use promql_utilities:: query_logics:: enums:: QueryPatternType ;
259+
260+ fn match_query ( query : & str ) -> ( QueryPatternType , PromQLMatchResult ) {
261+ let ast = promql_parser:: parser:: parse ( query) . unwrap ( ) ;
262+ let patterns = build_patterns ( ) ;
263+ for ( pt, pattern) in & patterns {
264+ let result = pattern. matches ( & ast) ;
265+ if result. matches {
266+ return ( * pt, result) ;
267+ }
268+ }
269+ panic ! ( "no pattern matched query: {}" , query) ;
270+ }
271+
272+ // --- get_effective_repeat ---
273+
274+ #[ test]
275+ fn effective_repeat_no_step ( ) {
276+ assert_eq ! ( get_effective_repeat( 300 , 0 ) , 300 ) ;
277+ }
278+
279+ #[ test]
280+ fn effective_repeat_step_smaller_than_t_repeat ( ) {
281+ assert_eq ! ( get_effective_repeat( 300 , 30 ) , 30 ) ;
282+ }
283+
284+ #[ test]
285+ fn effective_repeat_step_larger_than_t_repeat ( ) {
286+ assert_eq ! ( get_effective_repeat( 30 , 300 ) , 30 ) ;
287+ }
288+
289+ // --- get_cleanup_param ---
290+
291+ #[ test]
292+ fn cleanup_param_circular_buffer_spatial_instant_query ( ) {
293+ let ( pt, mr) = match_query ( "sum(some_metric)" ) ;
294+ assert_eq ! ( pt, QueryPatternType :: OnlySpatial ) ;
295+ // t_lookback = t_repeat = 300 (OnlySpatial path)
296+ // effective_repeat = 300 (step=0)
297+ // ceil((300 + 0) / 300) = 1
298+ let result =
299+ get_cleanup_param ( CleanupPolicy :: CircularBuffer , pt, & mr, 300 , "tumbling" , 0 , 0 )
300+ . unwrap ( ) ;
301+ assert_eq ! ( result, 1 ) ;
302+ }
303+
304+ #[ test]
305+ fn cleanup_param_circular_buffer_spatial_range_query ( ) {
306+ let ( pt, mr) = match_query ( "sum(some_metric)" ) ;
307+ // t_lookback = t_repeat = 300, effective_repeat = min(300, 30) = 30
308+ // ceil((300 + 3600) / 30) = ceil(130) = 130
309+ let result =
310+ get_cleanup_param ( CleanupPolicy :: CircularBuffer , pt, & mr, 300 , "tumbling" , 3600 , 30 )
311+ . unwrap ( ) ;
312+ assert_eq ! ( result, 130 ) ;
313+ }
314+
315+ #[ test]
316+ fn cleanup_param_read_based_spatial_instant_query ( ) {
317+ let ( pt, mr) = match_query ( "sum(some_metric)" ) ;
318+ // lookback_buckets = ceil(300/300) = 1, num_steps = 1 → result = 1
319+ let result =
320+ get_cleanup_param ( CleanupPolicy :: ReadBased , pt, & mr, 300 , "tumbling" , 0 , 0 ) . unwrap ( ) ;
321+ assert_eq ! ( result, 1 ) ;
322+ }
323+
324+ #[ test]
325+ fn cleanup_param_read_based_spatial_range_query ( ) {
326+ let ( pt, mr) = match_query ( "sum(some_metric)" ) ;
327+ // lookback_buckets = ceil(300/30) = 10, num_steps = 3600/30 + 1 = 121
328+ // result = 10 * 121 = 1210
329+ let result =
330+ get_cleanup_param ( CleanupPolicy :: ReadBased , pt, & mr, 300 , "tumbling" , 3600 , 30 )
331+ . unwrap ( ) ;
332+ assert_eq ! ( result, 1210 ) ;
333+ }
334+
335+ #[ test]
336+ fn cleanup_param_circular_buffer_temporal_instant_query ( ) {
337+ let ( pt, mr) = match_query ( "rate(some_metric[5m])" ) ;
338+ assert_eq ! ( pt, QueryPatternType :: OnlyTemporal ) ;
339+ // t_lookback = 5m = 300s (from [5m] range vector), range_duration=0, step=0
340+ // effective_repeat = 60, ceil((300 + 0) / 60) = 5
341+ let result =
342+ get_cleanup_param ( CleanupPolicy :: CircularBuffer , pt, & mr, 60 , "tumbling" , 0 , 0 )
343+ . unwrap ( ) ;
344+ assert_eq ! ( result, 5 ) ;
345+ }
346+
347+ #[ test]
348+ fn cleanup_param_no_cleanup_returns_error ( ) {
349+ let ( pt, mr) = match_query ( "sum(some_metric)" ) ;
350+ let result = get_cleanup_param ( CleanupPolicy :: NoCleanup , pt, & mr, 300 , "tumbling" , 0 , 0 ) ;
351+ assert ! ( result. is_err( ) ) ;
352+ }
353+
354+ #[ test]
355+ fn cleanup_param_mismatched_range_and_step_returns_error ( ) {
356+ let ( pt, mr) = match_query ( "sum(some_metric)" ) ;
357+ // range_duration > 0 but step == 0 is invalid
358+ let result =
359+ get_cleanup_param ( CleanupPolicy :: CircularBuffer , pt, & mr, 300 , "tumbling" , 3600 , 0 ) ;
360+ assert ! ( result. is_err( ) ) ;
361+ }
362+ }
363+
253364pub fn set_subpopulation_labels (
254365 statistic : Statistic ,
255366 aggregation_type : & str ,
0 commit comments