Coverage for test_scheduling.py: 100%

60 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-23 11:16 -0600

1import datetime 

2 

3import pytest 

4 

5from plain.worker.scheduling import Schedule 

6 

7 

8def test_schedule(): 

9 s = Schedule(hour=9) 

10 assert s.next(datetime.datetime(2021, 1, 1, 8, 0)) == datetime.datetime( 

11 2021, 1, 1, 9, 0 

12 ) 

13 

14 

15def test_schedule_shorthands(): 

16 assert Schedule.from_cron("@yearly").next( 

17 datetime.datetime(2021, 1, 1) 

18 ) == datetime.datetime(2022, 1, 1) 

19 assert Schedule.from_cron("@annually").next( 

20 datetime.datetime(2021, 1, 1) 

21 ) == datetime.datetime(2022, 1, 1) 

22 assert Schedule.from_cron("@monthly").next( 

23 datetime.datetime(2021, 1, 1) 

24 ) == datetime.datetime(2021, 2, 1) 

25 assert Schedule.from_cron("@weekly").next( 

26 datetime.datetime(2021, 1, 1) 

27 ) == datetime.datetime(2021, 1, 4) 

28 assert Schedule.from_cron("@daily").next( 

29 datetime.datetime(2021, 1, 1) 

30 ) == datetime.datetime(2021, 1, 2) 

31 assert Schedule.from_cron("@midnight").next( 

32 datetime.datetime(2021, 1, 1) 

33 ) == datetime.datetime(2021, 1, 2) 

34 assert Schedule.from_cron("@hourly").next( 

35 datetime.datetime(2021, 1, 1) 

36 ) == datetime.datetime(2021, 1, 1, 1, 0) 

37 

38 

39def test_schedule_range(): 

40 s = Schedule(minute=0, hour="9-11") 

41 assert s.next(datetime.datetime(2021, 1, 1, 8, 0)) == datetime.datetime( 

42 2021, 1, 1, 9, 0 

43 ) 

44 assert s.next(datetime.datetime(2021, 1, 1, 9, 0)) == datetime.datetime( 

45 2021, 1, 1, 10, 0 

46 ) 

47 assert s.next(datetime.datetime(2021, 1, 1, 10, 0)) == datetime.datetime( 

48 2021, 1, 1, 11, 0 

49 ) 

50 assert s.next(datetime.datetime(2021, 1, 1, 11, 0)) == datetime.datetime( 

51 2021, 1, 2, 9, 0 

52 ) 

53 

54 

55def test_schedule_interval(): 

56 s = Schedule( 

57 minute="*/15", 

58 ) 

59 assert s.next(datetime.datetime(2021, 1, 1, 8, 0)) == datetime.datetime( 

60 2021, 1, 1, 8, 15 

61 ) 

62 assert s.next(datetime.datetime(2021, 1, 1, 8, 15)) == datetime.datetime( 

63 2021, 1, 1, 8, 30 

64 ) 

65 assert s.next(datetime.datetime(2021, 1, 1, 8, 30)) == datetime.datetime( 

66 2021, 1, 1, 8, 45 

67 ) 

68 assert s.next(datetime.datetime(2021, 1, 1, 8, 45)) == datetime.datetime( 

69 2021, 1, 1, 9, 0 

70 ) 

71 

72 

73def test_schedule_asterisk(): 

74 s = Schedule( 

75 minute="*", 

76 hour="*", 

77 day_of_month="*", 

78 month="*", 

79 day_of_week="*", 

80 ) 

81 assert s.next(datetime.datetime(2021, 1, 1, 8, 0)) == datetime.datetime( 

82 2021, 1, 1, 8, 1 

83 ) 

84 

85 

86def test_complex_combinations(): 

87 s = Schedule(minute=15, hour=15, day_of_week=0) # Every Monday at 15:15 

88 next_run = s.next(datetime.datetime(2021, 6, 1)) # Check from June 1, 2021 

89 assert next_run == datetime.datetime(2021, 6, 7, 15, 15) # Next Monday 

90 

91 

92def test_invalid_date_handling(): 

93 s = Schedule(day_of_month=31, month=2) # February 31st does not exist 

94 with pytest.raises(ValueError, match="No valid schedule match"): 

95 s.next(datetime.datetime(2021, 1, 1)) 

96 

97 

98def test_non_matching_schedule(): 

99 with pytest.raises(ValueError, match="Schedule component should be between"): 

100 Schedule(hour=25) # Invalid hour, used as example for handling 

101 

102 

103def test_boundary_transition(): 

104 s = Schedule( 

105 minute=0, hour=23, day_of_month=31, month=12 

106 ) # New Year's Eve at 23:00 

107 next_run = s.next(datetime.datetime(2021, 12, 31, 22, 0)) 

108 assert next_run == datetime.datetime(2021, 12, 31, 23, 0) 

109 next_run = s.next(datetime.datetime(2021, 12, 31, 23, 0)) 

110 assert next_run == datetime.datetime(2022, 12, 31, 23, 0) # Next year 

111 

112 

113# def test_daylight_saving_time(): 

114# # Assuming you are in a region that uses DST and your datetime objects are timezone-aware 

115# s = Schedule(hour=2) # 2 AM, a time that might be skipped on DST start in some regions 

116# start_time = datetime.datetime(2021, 3, 14, 1, 59, tzinfo=datetime.timezone.utc) # DST start in many regions 

117# next_run = s.next(start_time) 

118# assert next_run.hour == 3 # Depending on how your timezone data handles DST, this may need adjustment 

119 

120 

121def test_schedule_comma(): 

122 s = Schedule(minute=0, hour="9,12") # 9 AM and 12 PM 

123 assert s.next(datetime.datetime(2021, 1, 1, 8, 0)) == datetime.datetime( 

124 2021, 1, 1, 9, 0 

125 ) 

126 assert s.next(datetime.datetime(2021, 1, 1, 9, 0)) == datetime.datetime( 

127 2021, 1, 1, 12, 0 

128 ) 

129 assert s.next(datetime.datetime(2021, 1, 1, 12, 0)) == datetime.datetime( 

130 2021, 1, 2, 9, 0 

131 ) 

132 

133 

134def test_schedule_comma_ranges(): 

135 s = Schedule(minute=0, hour="9-11,12-14") # 9-11 AM and 12-2 PM 

136 assert s.next(datetime.datetime(2021, 1, 1, 8, 0)) == datetime.datetime( 

137 2021, 1, 1, 9, 0 

138 ) 

139 assert s.next(datetime.datetime(2021, 1, 1, 9, 0)) == datetime.datetime( 

140 2021, 1, 1, 10, 0 

141 ) 

142 assert s.next(datetime.datetime(2021, 1, 1, 10, 0)) == datetime.datetime( 

143 2021, 1, 1, 11, 0 

144 ) 

145 assert s.next(datetime.datetime(2021, 1, 1, 11, 0)) == datetime.datetime( 

146 2021, 1, 1, 12, 0 

147 ) 

148 assert s.next(datetime.datetime(2021, 1, 1, 12, 0)) == datetime.datetime( 

149 2021, 1, 1, 13, 0 

150 ) 

151 assert s.next(datetime.datetime(2021, 1, 1, 13, 0)) == datetime.datetime( 

152 2021, 1, 1, 14, 0 

153 ) 

154 assert s.next(datetime.datetime(2021, 1, 1, 14, 0)) == datetime.datetime( 

155 2021, 1, 2, 9, 0 

156 )