@@ -370,6 +370,85 @@ def test_missing_intervals_end_bounded_with_ignore_cron(make_snapshot):
370370 ]
371371
372372
373+ def test_missing_intervals_past_end_date_with_lookback (make_snapshot ):
374+ snapshot : Snapshot = make_snapshot (
375+ SqlModel (
376+ name = "test_model" ,
377+ kind = IncrementalByTimeRangeKind (time_column = TimeColumn (column = "ds" ), lookback = 2 ),
378+ owner = "owner" ,
379+ cron = "@daily" ,
380+ query = parse_one ("SELECT 1, ds FROM name" ),
381+ start = "2023-01-01" ,
382+ end = "2023-01-05" , # inclusive, equivalent to to_timestamp('2023-01-05 23:59:59.999999')
383+ )
384+ )
385+
386+ start_time = to_timestamp ("2023-01-01" )
387+ end_time = to_timestamp (
388+ "2023-01-06"
389+ ) # exclusive because to_timestamp() returns a timestamp and not a date
390+ assert snapshot .inclusive_exclusive (snapshot .node .start , snapshot .node .end ) == (
391+ start_time ,
392+ end_time ,
393+ )
394+
395+ # baseline - all intervals missing
396+ assert snapshot .missing_intervals (start_time , end_time , execution_time = end_time ) == [
397+ (to_timestamp ("2023-01-01" ), to_timestamp ("2023-01-02" )),
398+ (to_timestamp ("2023-01-02" ), to_timestamp ("2023-01-03" )),
399+ (to_timestamp ("2023-01-03" ), to_timestamp ("2023-01-04" )),
400+ (to_timestamp ("2023-01-04" ), to_timestamp ("2023-01-05" )),
401+ (to_timestamp ("2023-01-05" ), to_timestamp ("2023-01-06" )),
402+ ]
403+
404+ # fully backfill model - no intervals missing
405+ snapshot .add_interval (start_time , end_time )
406+
407+ # even though lookback=2, because every interval has been filled,
408+ # there should be no missing intervals
409+ assert snapshot .missing_intervals (start_time , end_time , execution_time = end_time ) == []
410+
411+ # however, when running for a new interval, this triggers lookback
412+ # in this case, we remove the most recent interval (the one for 2023-01-05) to simulate it being new
413+ # since lookback=2 days, this triggers missing intervals for 2023-01-03, 2023-01-04, 2023-01-05
414+ snapshot .remove_interval (interval = (to_timestamp ("2023-01-05" ), to_timestamp ("2023-01-06" )))
415+ assert snapshot .missing_intervals (start_time , end_time , execution_time = end_time ) == [
416+ (to_timestamp ("2023-01-03" ), to_timestamp ("2023-01-04" )),
417+ (to_timestamp ("2023-01-04" ), to_timestamp ("2023-01-05" )),
418+ (to_timestamp ("2023-01-05" ), to_timestamp ("2023-01-06" )),
419+ ]
420+
421+ # put the interval we just removed back to make the model fully backfilled again
422+ snapshot .add_interval (to_timestamp ("2023-01-05" ), to_timestamp ("2023-01-06" ))
423+ assert snapshot .missing_intervals (start_time , end_time , execution_time = end_time ) == []
424+
425+ # running on the end date + 1 day (2023-01-07)
426+ # 2023-01-06 "would" run and since lookback=2 this pulls in 2023-01-04 and 2023-01-05 as well
427+ # however, only 2023-01-04 and 2023-01-05 are within the model end date
428+ end_time = to_timestamp ("2023-01-07" )
429+ assert snapshot .missing_intervals (start_time , end_time , execution_time = end_time ) == [
430+ (to_timestamp ("2023-01-04" ), to_timestamp ("2023-01-05" )),
431+ (to_timestamp ("2023-01-05" ), to_timestamp ("2023-01-06" )),
432+ ]
433+
434+ # running on the end date + 2 days (2023-01-08)
435+ # 2023-01-07 "would" run and since lookback=2 this pulls in 2023-01-06 and 2023-01-05 as well
436+ # however, only 2023-01-05 is within the model end date
437+ end_time = to_timestamp ("2023-01-08" )
438+ assert snapshot .missing_intervals (start_time , end_time , execution_time = end_time ) == [
439+ (to_timestamp ("2023-01-05" ), to_timestamp ("2023-01-06" ))
440+ ]
441+
442+ # running on the end date + 3 days (2023-01-09)
443+ # no missing intervals because subtracting 2 days for lookback exceeds the models end date
444+ end_time = to_timestamp ("2023-01-09" )
445+ assert snapshot .missing_intervals (start_time , end_time , execution_time = end_time ) == []
446+
447+ # running way in the future, no missing intervals because subtracting 2 days for lookback still exceeds the models end date
448+ end_time = to_timestamp ("2024-01-01" )
449+ assert snapshot .missing_intervals (start_time , end_time , execution_time = end_time ) == []
450+
451+
373452def test_incremental_time_self_reference (make_snapshot ):
374453 snapshot = make_snapshot (
375454 SqlModel (
0 commit comments