summaryrefslogtreecommitdiff
path: root/spec/unit/scheduler/scheduler_spec.rb
blob: 1bd289764312b2160bb7cc74a384bc457ac09c28 (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
#! /usr/bin/env ruby
require 'spec_helper'
require 'puppet/scheduler'

describe Puppet::Scheduler::Scheduler do
  let(:now) { 183550 }
  let(:timer) { MockTimer.new(now) }

  class MockTimer
    attr_reader :wait_for_calls

    def initialize(start=1729)
      @now = start
      @wait_for_calls = []
    end

    def wait_for(seconds)
      @wait_for_calls << seconds
      @now += seconds
    end

    def now
      @now
    end
  end

  def one_time_job(interval)
    Puppet::Scheduler::Job.new(interval) { |j| j.disable }
  end

  def disabled_job(interval)
    job = Puppet::Scheduler::Job.new(interval) { |j| j.disable }
    job.disable
    job
  end

  let(:scheduler) { Puppet::Scheduler::Scheduler.new(timer) }

  it "uses the minimum interval" do
    later_job = one_time_job(7)
    earlier_job = one_time_job(2)
    later_job.last_run = now
    earlier_job.last_run = now

    scheduler.run_loop([later_job, earlier_job])

    timer.wait_for_calls.should == [2, 5]
  end

  it "ignores disabled jobs when calculating intervals" do
    enabled = one_time_job(7)
    enabled.last_run = now
    disabled = disabled_job(2)

    scheduler.run_loop([enabled, disabled])

    timer.wait_for_calls.should == [7]
  end

  it "asks the timer to wait for the job interval" do
    job = one_time_job(5)
    job.last_run = now

    scheduler.run_loop([job])

    timer.wait_for_calls.should == [5]
  end

  it "does not run when there are no jobs" do
    scheduler.run_loop([])

    timer.wait_for_calls.should be_empty
  end

  it "does not run when there are only disabled jobs" do
    disabled_job = Puppet::Scheduler::Job.new(0)
    disabled_job.disable

    scheduler.run_loop([disabled_job])

    timer.wait_for_calls.should be_empty
  end

  it "stops running when there are no more enabled jobs" do
    disabling_job = Puppet::Scheduler::Job.new(0) do |j|
      j.disable
    end

    scheduler.run_loop([disabling_job])

    timer.wait_for_calls.size.should == 1
  end

  it "marks the start of the run loop" do
    disabled_job = Puppet::Scheduler::Job.new(0)

    disabled_job.disable

    scheduler.run_loop([disabled_job])

    disabled_job.start_time.should == now
  end

  it "calculates the next interval from the start of a job" do
    countdown = 2
    slow_job = Puppet::Scheduler::Job.new(10) do |job|
      timer.wait_for(3)
      countdown -= 1
      job.disable if countdown == 0
    end

    scheduler.run_loop([slow_job])

    timer.wait_for_calls.should == [0, 3, 7, 3]
  end
end