summaryrefslogtreecommitdiffstats
path: root/spec/unit/type/schedule.rb
blob: 8807d0fa05cb2c4fd2a2237c509a0e4dfe5de2d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#!/usr/bin/env ruby

require File.dirname(__FILE__) + '/../../spec_helper'

module ScheduleTesting

    def format(time)
        time.strftime("%H:%M:%S")
    end

    def diff(unit, incr, method, count)
        diff = Time.now.to_i.send(method, incr * count)
        Time.at(diff)
    end

    def month(method, count)
        diff(:hour, 3600 * 24 * 30, method, count)
    end

    def week(method, count)
        diff(:hour, 3600 * 24 * 7, method, count)
    end

    def day(method, count)
        diff(:hour, 3600 * 24, method, count)
    end

    def hour(method, count)
        diff(:hour, 3600, method, count)
    end

    def min(method, count)
        diff(:min, 60, method, count)
    end

    def sec(method, count)
        diff(:sec, 1, method, count)
    end

end

describe Puppet::Type.type(:schedule) do
    before :each do
      Puppet.settings.stubs(:value).with(:ignoreschedules).returns(false)

      @schedule = Puppet::Type.type(:schedule).new(:name => "testing")
    end

    describe Puppet::Type.type(:schedule) do
        include ScheduleTesting

        it "should default to :distance for period-matching" do
            @schedule[:periodmatch].should == :distance
        end

        it "should default to a :repeat of 1" do
            @schedule[:repeat].should == 1
        end

        it "should never match when the period is :never" do
            @schedule[:period] = :never
            @schedule.match?.should be_false
        end
    end

    describe Puppet::Type.type(:schedule), "when producing default schedules" do
        include ScheduleTesting

        %w{hourly daily weekly monthly never}.each do |period|
            period = period.to_sym
            it "should produce a #{period} schedule with the period set appropriately" do
                schedules = Puppet::Type.type(:schedule).mkdefaultschedules
                schedules.find { |s| s[:name] == period.to_s and s[:period] == period }.should be_instance_of(Puppet::Type.type(:schedule))
            end
        end

        it "should produce a schedule named puppet with a period of hourly and a repeat of 2" do
            schedules = Puppet::Type.type(:schedule).mkdefaultschedules
            schedules.find { |s|
                s[:name] == "puppet" and s[:period] == :hourly and s[:repeat] == 2
            }.should be_instance_of(Puppet::Type.type(:schedule))
        end
    end

    describe Puppet::Type.type(:schedule), "when matching ranges" do
        include ScheduleTesting

        it "should match when the start time is before the current time and the end time is after the current time" do
            @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now + 10)]
            @schedule.match?.should be_true
        end

        it "should not match when the start time is after the current time" do
            @schedule[:range] = "%s - %s" % [format(Time.now + 5), format(Time.now + 10)]
            @schedule.match?.should be_false
        end

        it "should not match when the end time is previous to the current time" do
            @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now - 5)]
            @schedule.match?.should be_false
        end
    end

    describe Puppet::Type.type(:schedule), "when matching hourly by distance" do
        include ScheduleTesting

        before do
            @schedule[:period] = :hourly
            @schedule[:periodmatch] = :distance
        end

        it "should match an hour ago" do
            @schedule.match?(hour("-", 1)).should be_true
        end

        it "should not match now" do
            @schedule.match?(Time.now).should be_false
        end

        it "should not match 59 minutes ago" do
            @schedule.match?(min("-", 59)).should be_false
        end
    end

    describe Puppet::Type.type(:schedule), "when matching daily by distance" do
        include ScheduleTesting

        before do
            @schedule[:period] = :daily
            @schedule[:periodmatch] = :distance
        end

        it "should match when the previous time was one day ago" do
            @schedule.match?(day("-", 1)).should be_true
        end

        it "should not match when the previous time is now" do
            @schedule.match?(Time.now).should be_false
        end

        it "should not match when the previous time was 23 hours ago" do
            @schedule.match?(hour("-", 23)).should be_false
        end
    end

    describe Puppet::Type.type(:schedule), "when matching weekly by distance" do
        include ScheduleTesting

        before do
            @schedule[:period] = :weekly
            @schedule[:periodmatch] = :distance
        end

        it "should match seven days ago" do
            @schedule.match?(day("-", 7)).should be_true
        end

        it "should not match now" do
            @schedule.match?(Time.now).should be_false
        end

        it "should not match six days ago" do
            @schedule.match?(day("-", 6)).should be_false
        end
    end

    describe Puppet::Type.type(:schedule), "when matching monthly by distance" do
        include ScheduleTesting

        before do
            @schedule[:period] = :monthly
            @schedule[:periodmatch] = :distance
        end

        it "should match 32 days ago" do
            @schedule.match?(day("-", 32)).should be_true
        end

        it "should not match now" do
            @schedule.match?(Time.now).should be_false
        end

        it "should not match 27 days ago" do
            @schedule.match?(day("-", 27)).should be_false
        end
    end

    describe Puppet::Type.type(:schedule), "when matching hourly by number" do
        include ScheduleTesting

        before do
            @schedule[:period] = :hourly
            @schedule[:periodmatch] = :number
        end

        it "should match if the times are one minute apart and the current minute is 0" do
            current = Time.now

            # Subtract an hour, reset the minute to zero, then add 59 minutes, so we're the previous hour plus 59 minutes.
            previous = (current - 3600 - (current.min * 60) + (59 * 60))

            # Now set the "current" time to the zero minute of the current hour.
            now = (current - (current.min * 60))
            Time.stubs(:now).returns(now)
            @schedule.match?(previous).should be_true
        end

        it "should not match if the times are 58 minutes apart and the current minute is 59" do
            current = Time.now

            # reset the minute to zero
            previous = current - (current.min * 60)

            # Now set the "current" time to the 59th minute of the current hour.
            now = (current - (current.min * 60) + (59 * 60))
            Time.stubs(:now).returns(now)
            @schedule.match?(previous).should be_false
        end
    end

    describe Puppet::Type.type(:schedule), "when matching daily by number" do
        include ScheduleTesting

        before do
            @schedule[:period] = :daily
            @schedule[:periodmatch] = :number
        end

        it "should match if the times are one minute apart and the current minute and hour are 0" do
            zero = Time.now

            # Reset the current time to X:00:00
            current = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec

            # Now set the previous time to one minute before that
            previous = current - 60

            Time.stubs(:now).returns(current)
            @schedule.match?(previous).should be_true
        end

        it "should not match if the times are 23 hours and 58 minutes apart and the current hour is 23 and the current minute is 59" do
            zero = Time.now

            # Reset the previous time to 00:00:00
            previous = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec

            # Set the current time to 23:59
            now = previous + (23 * 3600) + (59 * 60)

            Time.stubs(:now).returns(now)
            @schedule.match?(previous).should be_false
        end
    end

    describe Puppet::Type.type(:schedule), "when matching weekly by number" do
        include ScheduleTesting

        before do
            @schedule[:period] = :weekly
            @schedule[:periodmatch] = :number
        end

        it "should match if the previous time is prior to the most recent Sunday" do
            now = Time.now

            # Subtract the number days we've progressed into the week, plus one because we're zero-indexed.
            previous = now - (3600 * 24 * (now.wday + 1))

            @schedule.match?(previous).should be_true
        end

        it "should not match if the previous time is after the most recent Saturday" do
            now = Time.now

            # Subtract the number days we've progressed into the week
            previous = now - (3600 * 24 * now.wday)

            @schedule.match?(previous).should be_false
        end
    end

    describe Puppet::Type.type(:schedule), "when matching monthly by number" do
        include ScheduleTesting

        before do
            @schedule[:period] = :monthly
            @schedule[:periodmatch] = :number
        end

        it "should match when the previous time is prior to the first day of this month" do
            now = Time.now

            # Subtract the number days we've progressed into the month
            previous = now - (3600 * 24 * now.day)

            @schedule.match?(previous).should be_true
        end

        it "should not match when the previous time is after the last day of last month" do
            now = Time.now

            # Subtract the number days we've progressed into the month, minus one
            previous = now - (3600 * 24 * (now.day - 1))

            @schedule.match?(previous).should be_false
        end
    end

    describe Puppet::Type.type(:schedule), "when matching with a repeat greater than one" do
        include ScheduleTesting

        before do
            @schedule[:period] = :daily
            @schedule[:repeat] = 2
        end

        it "should fail if the periodmatch is 'number'" do
            @schedule[:periodmatch] = :number
            proc { @schedule[:repeat] = 2 }.should raise_error(Puppet::Error)
        end

        it "should match if the previous run was further away than the distance divided by the repeat" do
            previous = Time.now - (3600 * 13)
            @schedule.match?(previous).should be_true
        end

        it "should not match if the previous run was closer than the distance divided by the repeat" do
            previous = Time.now - (3600 * 11)
            @schedule.match?(previous).should be_false
        end
    end
end