flapjack 0.6.29 → 0.6.30

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -62,7 +62,7 @@ There's some rspec unit tests as well, run these like so:
62
62
 
63
63
  $ rspec spec
64
64
 
65
- NB, if the cucumber tests fail with a spurious lexing error on line 2 of events.feature, then try this:
65
+ NB, if the cucumber tests fail with a [spurious lexing error](https://github.com/cucumber/gherkin/issues/182) on line 2 of events.feature, then try this:
66
66
 
67
67
  $ cucumber -f fuubar features
68
68
 
@@ -1,11 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'yajl'
3
+ require 'yajl/json_gem'
4
4
  require 'redis'
5
- require 'yaml'
6
5
  require 'optparse'
7
6
  require 'ostruct'
8
- require 'flapjack/data/entity_check'
7
+
8
+ # add lib to the default include path
9
+ unless $:.include?(File.dirname(__FILE__) + '/../lib/')
10
+ $: << File.dirname(__FILE__) + '/../lib'
11
+ end
12
+
13
+ require 'flapjack/configuration'
14
+ require 'flapjack/data/contact'
15
+ require 'flapjack/data/entity'
9
16
 
10
17
  options = OpenStruct.new
11
18
  options.config = File.join('etc', 'flapjack_config.yaml')
@@ -35,109 +42,58 @@ end.parse!(ARGV)
35
42
 
36
43
  FLAPJACK_ENV = ENV['FLAPJACK_ENV'] || 'development'
37
44
 
38
- # load the config hash for the current environment
39
-
40
- if File.file?(options.config)
41
- config = YAML::load(File.open(options.config))
42
- else
43
- puts "Could not find config file at '#{options.config}', you may want to specify one with the --config option"
44
- exit(false)
45
- end
46
-
47
- config_env = config[FLAPJACK_ENV]
48
-
49
- if config_env.nil? || config_env.empty?
50
- puts "No config data for environment '#{FLAPJACK_ENV}' found in '#{options.config}'"
51
- exit(false)
52
- end
45
+ config_env = Flapjack::Configuration.new.load(options.config)
53
46
 
54
47
  if options.from
55
48
  filename = options.from
56
49
  file = File.new(filename)
57
50
  end
58
51
 
59
- parser = Yajl::Parser.new
60
-
61
- @redis_host = config_env['redis']['host'] || 'localhost'
62
- @redis_port = config_env['redis']['port'] || '6379'
63
- @redis_path = config_env['redis']['path'] || nil
64
- @redis_db = config_env['redis']['db'] || 0
65
-
66
- # add lib to the default include path
67
- unless $:.include?(File.dirname(__FILE__) + '/../lib/')
68
- $: << File.dirname(__FILE__) + '/../lib'
69
- end
70
-
71
- def get_redis_connection
72
- if @redis_path
73
- redis = Redis.new(:db => @redis_db, :path => @redis_path)
74
- else
75
- redis = Redis.new(:db => @redis_db, :host => @redis_host, :port => @redis_port)
76
- end
77
- redis
52
+ def get_redis_connection(cfg)
53
+ opts = cfg['path'] ? {:path => cfg['path']} :
54
+ {:host => cfg['host'], :port => cfg['port']}
55
+ Redis.new(opts.merge(:db => cfg['db']))
78
56
  end
79
57
 
80
58
  case command
81
59
  when "import-contacts"
82
- @persistence = get_redis_connection
83
- contacts = parser.parse(file)
84
- contacts.each {|contact|
85
- if not contact['id']
86
- puts "Contact not imported as it has no id: " + contact.inspect
87
- next
88
- end
89
- @persistence.multi
90
- @persistence.del("contact:#{contact['id']}")
91
- @persistence.del("contact_media:#{contact['id']}")
92
- @persistence.del("contact_pagerduty:#{contact['id']}")
93
- @persistence.hset("contact:#{contact['id']}", 'first_name', contact['first_name'])
94
- @persistence.hset("contact:#{contact['id']}", 'last_name', contact['last_name'])
95
- @persistence.hset("contact:#{contact['id']}", 'email', contact['email'])
96
- contact['media'].each_pair {|medium, address|
97
- case medium
98
- when 'pagerduty'
99
- @persistence.hset("contact_media:#{contact['id']}", medium, address['service_key'])
100
- @persistence.hset("contact_pagerduty:#{contact['id']}", 'subdomain', address['subdomain'])
101
- @persistence.hset("contact_pagerduty:#{contact['id']}", 'username', address['username'])
102
- @persistence.hset("contact_pagerduty:#{contact['id']}", 'password', address['password'])
103
- else
104
- @persistence.hset("contact_media:#{contact['id']}", medium, address)
60
+ contacts = JSON.parse(file)
61
+
62
+ if contacts && contacts.is_a?(Enumerable) && contacts.any? {|e| !e['id'].nil?}
63
+ @persistence = get_redis_connection(config_env['redis'])
64
+ @persistence.multi do
65
+ contacts.each do |contact|
66
+ unless contact['id']
67
+ puts "Contact not imported as it has no id: " + contact.inspect
68
+ next
69
+ end
70
+ Flapjack::Data::Contact.add(contact, :redis => @persistence)
105
71
  end
106
- }
107
- @persistence.exec
108
- }
72
+ end
73
+ @persistence.quit
74
+ end
109
75
 
110
76
  when "import-entities"
111
- @persistence = get_redis_connection
112
- entities = parser.parse(file)
113
- entities.each {|entity|
114
- if not entity['id']
115
- puts "Entity not imported as it has no id: " + entity.inspect
116
- next
117
- end
77
+ entities = JSON.parse(file)
78
+
79
+ if entities && entities.is_a?(Enumerable) && entities.any? {|e| !e['id'].nil?}
80
+ @persistence = get_redis_connection(config_env['redis'])
118
81
  @persistence.multi
119
- existing_name = @persistence.hget("entity:#{entity['id']}", 'name')
120
- @persistence.del("entity_id:#{existing_name}") unless existing_name == entity['name']
121
- @persistence.set("entity_id:#{entity['name']}", entity['id'])
122
- @persistence.hset("entity:#{entity['id']}", 'name', entity['name'])
123
-
124
- @persistence.del("contacts_for:#{entity['id']}")
125
- entity['contacts'].each {|contact|
126
- @persistence.sadd("contacts_for:#{entity['id']}", contact)
127
- }
82
+ entities.each do |entity|
83
+ unless entity['id']
84
+ puts "Entity not imported as it has no id: " + entity.inspect
85
+ next
86
+ end
87
+ Flapjack::Data::Entity.add(entity, :redis => @persistence)
88
+ end
128
89
  @persistence.exec
129
-
130
- }
90
+ @persistence.quit
91
+ end
131
92
 
132
93
  when "purge-events"
133
- @persistence = get_redis_connection
134
- events_size = @persistence.llen('events')
135
- puts "purging #{events_size} events..."
136
- timestamp = Time.now.to_i
137
- puts "renaming events to events.#{timestamp}"
138
- @persistence.rename('events', "events.#{timestamp}")
139
- puts "setting expiry of events.#{timestamp} to 8 hours"
140
- @persistence.expire("events.#{timestamp}", (60 * 60 * 8))
94
+ @persistence = get_redis_connection(config_env['redis'])
95
+ Flapjack::Data.Event.purge_all(:redis => @persistence)
96
+ @persistence.quit
141
97
 
142
98
  else
143
99
  puts "you need to give me something to do, eg a command like 'import-entities' or 'import-clients' etc"
data/lib/flapjack/api.rb CHANGED
@@ -25,7 +25,9 @@ module Flapjack
25
25
  # doesn't work with Rack::Test for some reason
26
26
  unless 'test'.eql?(FLAPJACK_ENV)
27
27
  rescue_exception = Proc.new { |env, exception|
28
- [503, {}, exception.message]
28
+ logger.error exception.message
29
+ logger.error exception.backtrace.join("\n")
30
+ [503, {}, {:status => 503, :reason => exception.message}.to_json]
29
31
  }
30
32
 
31
33
  use Rack::FiberPool, :size => 25, :rescue_exception => rescue_exception
@@ -38,17 +40,6 @@ module Flapjack
38
40
  Flapjack::API.bootstrap
39
41
  end
40
42
 
41
- helpers do
42
- def json_status(code, reason)
43
- status code
44
- {:status => code, :reason => reason}.to_json
45
- end
46
-
47
- def logger
48
- Flapjack::API.logger
49
- end
50
- end
51
-
52
43
  get '/entities' do
53
44
  content_type :json
54
45
  ret = Flapjack::Data::Entity.all(:redis => @@redis).sort_by(&:name).collect {|e|
@@ -211,7 +202,7 @@ module Flapjack
211
202
  params[:check], :redis => @@redis)
212
203
  entity_check.create_scheduled_maintenance(:start_time => params[:start_time],
213
204
  :duration => params[:duration], :summary => params[:summary])
214
- status 201
205
+ status 204
215
206
  end
216
207
 
217
208
  # create an acknowledgement for a service on an entity
@@ -232,15 +223,11 @@ module Flapjack
232
223
  params[:check], :redis => @@redis)
233
224
  entity_check.create_acknowledgement('summary' => params[:summary],
234
225
  'duration' => duration)
235
- status 201
226
+ status 204
236
227
  end
237
228
 
238
229
  not_found do
239
- json_status 404, "Not found"
240
- end
241
-
242
- error do
243
- json_status 500, env['sinatra.error'].message
230
+ [404, {}, {:status => 404, :reason => "Not found"}.to_json]
244
231
  end
245
232
 
246
233
  private
@@ -265,7 +252,7 @@ module Flapjack
265
252
  return unless value
266
253
  Time.iso8601(value).getutc.to_i
267
254
  rescue ArgumentError => e
268
- # FIXME log error
255
+ logger.error "Couldn't parse time from '#{value}'"
269
256
  nil
270
257
  end
271
258
 
@@ -16,56 +16,34 @@ module Flapjack
16
16
  @entity_check = entity_check
17
17
  end
18
18
 
19
- # if options[:chop] is true, overlapping outages at start and end
20
- # times will be sliced to fit.
21
19
  def outages(start_time, end_time, options = {})
22
- # states is an array of hashes, with [state, timestamp, summary] keys
23
- states = @entity_check.historical_states(start_time, end_time)
24
- return states if states.empty?
25
-
26
- # if it started failed, prepend the earlier event
27
- initial = @entity_check.historical_state_before(states.first[:timestamp])
28
- if (initial && (initial[:state] == Flapjack::Data::EntityCheck::STATE_CRITICAL))
29
- states.unshift(initial)
30
- end
31
-
32
- # if it ended failed, append the event when it recovered
33
- if states.last[:state] == Flapjack::Data::EntityCheck::STATE_CRITICAL
34
- # TODO ensure this event is not CRITICAL, get first non-CRITICAL if so
35
- last = @entity_check.historical_state_after(states.last[:timestamp])
36
- states.push(last) if last
37
- end
38
-
39
- last_state = nil
40
-
41
- # returns an array of hashes, with [:start_time, :end_time, :summary]
42
- time_periods = states.inject([]) do |ret, obj|
43
- if (obj[:state] == Flapjack::Data::EntityCheck::STATE_CRITICAL) &&
44
- (last_state.nil? || (last_state != Flapjack::Data::EntityCheck::STATE_CRITICAL))
45
-
46
- # flipped to failed, mark next outage
47
- last_state = obj[:state]
48
- ret << {:start_time => obj[:timestamp], :end_time => nil, :summary => obj[:summary]}
49
- elsif (obj[:state] != Flapjack::Data::EntityCheck::STATE_CRITICAL) &&
50
- (last_state == Flapjack::Data::EntityCheck::STATE_CRITICAL)
51
-
52
- # flipped to not failed, mark end time for the current outage
53
- last_state = obj[:state]
54
- ret.last[:end_time] = obj[:timestamp]
20
+ # hist_states is an array of hashes, with [state, timestamp, summary] keys
21
+ hist_states = @entity_check.historical_states(start_time, end_time)
22
+ return hist_states if hist_states.empty?
23
+
24
+ initial = @entity_check.historical_state_before(hist_states.first[:timestamp])
25
+ hist_states.unshift(initial) if initial
26
+
27
+ num_states = hist_states.size
28
+
29
+ hist_states.each_with_index do |obj, index|
30
+ if (index == 0)
31
+ # initial
32
+ obj[:start_time] = [obj.delete(:timestamp), start_time].max
33
+ obj[:end_time] = hist_states[index + 1][:timestamp]
34
+ elsif index == (num_states - 1)
35
+ # last
36
+ obj[:start_time] = obj.delete(:timestamp)
37
+ obj[:end_time] = end_time
38
+ else
39
+ # except for first and last
40
+ obj[:start_time] = obj.delete(:timestamp)
41
+ obj[:end_time] = hist_states[index + 1][:timestamp]
55
42
  end
56
- ret
43
+ obj[:duration] = obj[:end_time] - obj[:start_time]
57
44
  end
58
45
 
59
- if options[:chop]
60
- if start_time && (time_periods.first[:start_time] < start_time)
61
- time_periods.first[:start_time] = start_time
62
- end
63
- if time_periods.last[:end_time].nil? || (end_time && (time_periods.last[:end_time] > end_time))
64
- time_periods.last[:end_time] = (end_time || Time.now.to_i)
65
- end
66
- end
67
-
68
- time_periods
46
+ hist_states.reject {|obj| obj[:state] == 'ok'}
69
47
  end
70
48
 
71
49
  def unscheduled_maintenance(start_time, end_time)
@@ -106,10 +84,15 @@ module Flapjack
106
84
  def downtime(start_time, end_time)
107
85
  sched_maintenances = scheduled_maintenance(start_time, end_time)
108
86
 
109
- outs = outages(start_time, end_time, :chop => true)
87
+ outs = outages(start_time, end_time)
110
88
 
111
- total_secs = 0
112
- percentage = 0
89
+ total_secs = {}
90
+ percentages = {}
91
+
92
+ outs.collect {|obj| obj[:state]}.uniq.each do |st|
93
+ total_secs[st] = 0
94
+ percentages[st] = (start_time.nil? || end_time.nil?) ? nil : 0
95
+ end
113
96
 
114
97
  unless outs.empty?
115
98
 
@@ -126,10 +109,12 @@ module Flapjack
126
109
  next unless o[:start_time] < sm[:start_time] &&
127
110
  o[:end_time] > sm[:end_time]
128
111
  o[:delete] = true
129
- split_outs += [{:start_time => o[:start_time],
112
+ split_outs += [{:state => o[:state],
113
+ :start_time => o[:start_time],
130
114
  :end_time => sm[:start_time],
131
115
  :summary => "#{o[:summary]} [split start]"},
132
- {:start_time => sm[:end_time],
116
+ {:state => o[:state],
117
+ :start_time => sm[:end_time],
133
118
  :end_time => o[:end_time],
134
119
  :summary => "#{o[:summary]} [split finish]"}]
135
120
  }
@@ -165,16 +150,21 @@ module Flapjack
165
150
  outs.reject! {|o| o[:delete]}
166
151
  end
167
152
 
168
- # sum outage times
169
- total_secs = outs.inject(0) {|sum, o|
170
- sum += (o[:end_time] - o[:start_time])
153
+ total_secs = outs.inject(total_secs) {|ret, o|
154
+ ret[o[:state]] += (o[:end_time] - o[:start_time])
155
+ ret
171
156
  }
172
157
 
173
- percentage = (start_time.nil? || end_time.nil?) ? nil :
174
- (total_secs * 100) / (end_time - start_time)
158
+ unless (start_time.nil? || end_time.nil?)
159
+ total_secs.each_pair do |st, ts|
160
+ percentages[st] = (total_secs[st] * 100.0) / (end_time.to_f - start_time.to_f)
161
+ end
162
+ end
175
163
  end
176
164
 
177
- {:total_seconds => total_secs, :percentage => percentage, :downtime => outs}
165
+ total_secs['ok'] = (end_time - start_time) - total_secs.values.reduce(:+)
166
+ percentages['ok'] = 100 - percentages.values.reduce(:+)
167
+ {:total_seconds => total_secs, :percentages => percentages, :downtime => outs}
178
168
  end
179
169
 
180
170
  end
@@ -1,10 +1,62 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'yaml'
4
+
3
5
  module Flapjack
4
6
 
5
7
  class Configuration
6
8
 
7
- # TODO consolidate configuration code
9
+ def initialize(opts = {})
10
+ @logger = opts[:logger]
11
+ unless @logger
12
+ @logger = Logger.new(STDOUT)
13
+ @logger.level = Logger::ERROR
14
+ end
15
+ end
16
+
17
+ def logger
18
+ @logger
19
+ end
20
+
21
+ def load(filename)
22
+ unless File.file?(filename)
23
+ logger.error "Could not find file '#{filename}'"
24
+ return
25
+ end
26
+
27
+ unless defined?(FLAPJACK_ENV)
28
+ logger.error "Environment variable 'FLAPJACK_ENV' is not set"
29
+ return
30
+ end
31
+
32
+ config = YAML::load_file(filename)
33
+
34
+ if config.nil?
35
+ logger.error "Could not load config file '#{filename}'"
36
+ return
37
+ end
38
+
39
+ config_env = config[FLAPJACK_ENV]
40
+
41
+ if config_env.nil?
42
+ logger.error "No config data for environment '#{FLAPJACK_ENV}' found in '#{filename}'"
43
+ return
44
+ end
45
+
46
+ redis_defaults = {'host' => 'localhost',
47
+ 'port' => 6379,
48
+ 'path' => nil,
49
+ 'db' => 0}
50
+
51
+ config_env['redis'] = {} unless config_env.has_key?('redis')
52
+ redis_defaults.each_pair do |k,v|
53
+ next if config_env['redis'].has_key?(k) && (config_env['redis'][k] &&
54
+ !(config_env['redis'][k].is_a?(String) && config_env['redis'][k].empty?))
55
+ config_env['redis'][k] = v
56
+ end
57
+
58
+ config_env
59
+ end
8
60
 
9
61
  end
10
62
 
@@ -9,9 +9,8 @@ module Flapjack
9
9
  # takes a check, looks up contacts that are interested in this check (or in the check's entity)
10
10
  # and returns an array of contact ids
11
11
  def self.find_all_for_entity_check(entity_check, options = {})
12
- logger = options[:logger]
13
- logger = nil
14
12
  raise "Redis connection not set" unless redis = options[:redis]
13
+ logger = options[:logger]
15
14
 
16
15
  entity = entity_check.entity
17
16
  check = entity_check.check
@@ -26,16 +25,38 @@ module Flapjack
26
25
  union
27
26
  end
28
27
 
29
- def self.pagerduty_credentials_for_contact(contact, options = {})
30
- logger = options[:logger]
28
+ # NB: should probably be called in the context of a Redis multi block; not doing so
29
+ # here as calling classes may well be adding/updating multiple records in the one
30
+ # operation
31
+ def self.add(contact, options = {})
31
32
  raise "Redis connection not set" unless redis = options[:redis]
32
33
 
33
- service_key = redis.hget("contact_media:#{contact}", 'pagerduty')
34
- return nil unless service_key
34
+ redis.del("contact:#{contact['id']}")
35
+ redis.del("contact_media:#{contact['id']}")
36
+ redis.del("contact_pagerduty:#{contact['id']}")
37
+ redis.hset("contact:#{contact['id']}", 'first_name', contact['first_name'])
38
+ redis.hset("contact:#{contact['id']}", 'last_name', contact['last_name'])
39
+ redis.hset("contact:#{contact['id']}", 'email', contact['email'])
40
+ contact['media'].each_pair {|medium, address|
41
+ case medium
42
+ when 'pagerduty'
43
+ redis.hset("contact_media:#{contact['id']}", medium, address['service_key'])
44
+ redis.hset("contact_pagerduty:#{contact['id']}", 'subdomain', address['subdomain'])
45
+ redis.hset("contact_pagerduty:#{contact['id']}", 'username', address['username'])
46
+ redis.hset("contact_pagerduty:#{contact['id']}", 'password', address['password'])
47
+ else
48
+ redis.hset("contact_media:#{contact['id']}", medium, address)
49
+ end
50
+ }
51
+ end
52
+
53
+ def self.pagerduty_credentials_for_contact(contact, options = {})
54
+ raise "Redis connection not set" unless redis = options[:redis]
35
55
 
36
- deets = redis.hgetall("contact_pagerduty:#{contact}")
37
- return deets.merge('service_key' => service_key)
56
+ return unless service_key = redis.hget("contact_media:#{contact}", 'pagerduty')
38
57
 
58
+ redis.hgetall("contact_pagerduty:#{contact}").
59
+ merge('service_key' => service_key)
39
60
  end
40
61
 
41
62
  end
@@ -16,12 +16,14 @@ module Flapjack
16
16
  }
17
17
  end
18
18
 
19
+ # NB: should probably be called in the context of a Redis multi block; not doing so
20
+ # here as calling classes may well be adding/updating multiple records in the one
21
+ # operation
19
22
  def self.add(entity, options = {})
20
23
  raise "Redis connection not set" unless redis = options[:redis]
21
24
  raise "Entity name not provided" unless entity['name'] && !entity['name'].empty?
22
25
 
23
26
  if entity['id']
24
- redis.multi
25
27
  existing_name = redis.hget("entity:#{entity['id']}", 'name')
26
28
  redis.del("entity_id:#{existing_name}") unless existing_name == entity['name']
27
29
  redis.set("entity_id:#{entity['name']}", entity['id'])
@@ -33,7 +35,6 @@ module Flapjack
33
35
  redis.sadd("contacts_for:#{entity['id']}", contact)
34
36
  }
35
37
  end
36
- redis.exec
37
38
  else
38
39
  # empty string is the redis equivalent of a Ruby nil, i.e. key with
39
40
  # no value
@@ -45,6 +45,17 @@ module Flapjack
45
45
  opts[:persistence].llen('events')
46
46
  end
47
47
 
48
+ # FIXME make this use a logger taken from the opts
49
+ def self.purge_all(opts = {})
50
+ events_size = opts[:redis].llen('events')
51
+ puts "purging #{events_size} events..."
52
+ timestamp = Time.now.to_i
53
+ puts "renaming events to events.#{timestamp}"
54
+ opts[:redis].rename('events', "events.#{timestamp}")
55
+ puts "setting expiry of events.#{timestamp} to 8 hours"
56
+ opts[:redis].expire("events.#{timestamp}", (60 * 60 * 8))
57
+ end
58
+
48
59
  def initialize(attrs={})
49
60
  @attrs = attrs
50
61
  @attrs['time'] = Time.now.to_i unless @attrs.has_key?('time')
@@ -283,9 +283,6 @@ module Flapjack
283
283
  close # Blather::Client.close
284
284
  end
285
285
  end
286
- # FIXME: should we also set something so should_quit? returns true
287
- # to prevent retrieving more notifications from the queue while closing?
288
- # or does close only return once the connection is really and truely closed?
289
286
  else
290
287
  entity, check = event['event_id'].split(':')
291
288
  state = event['state']
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  module Flapjack
4
- VERSION = "0.6.29"
4
+ VERSION = "0.6.30"
5
5
  end
data/lib/flapjack/web.rb CHANGED
@@ -18,8 +18,8 @@ module Flapjack
18
18
  # doesn't work with Rack::Test for some reason
19
19
  unless 'test'.eql?(FLAPJACK_ENV)
20
20
  rescue_exception = Proc.new { |env, exception|
21
- p exception.message
22
- puts exception.backtrace.join("\n")
21
+ logger.error exception.message
22
+ logger.error exception.backtrace.join("\n")
23
23
  [503, {}, exception.message]
24
24
  }
25
25
 
@@ -104,10 +104,13 @@ describe 'Flapjack::API::EntityCheck::Presenter' do
104
104
  ecp = Flapjack::API::EntityCheckPresenter.new(entity_check)
105
105
  downtimes = ecp.downtime(time - (12 * 60 * 60), time)
106
106
 
107
+
107
108
  # 22 minutes, 3 + 8 + 11
108
109
  downtimes.should be_a(Hash)
109
- downtimes[:total_seconds].should == (22 * 60)
110
- downtimes[:percentage].should == (((22 * 60) * 100) / (12 * 60 * 60))
110
+ downtimes[:total_seconds].should == {'critical' => (22 * 60),
111
+ 'ok' => ((12 * 60 * 60) - (22 * 60))}
112
+ downtimes[:percentages].should == {'critical' => (((22 * 60) * 100.0) / (12 * 60 * 60)),
113
+ 'ok' => ((((12 * 60 * 60) - (22 * 60)) * 100.0) / (12 * 60 *60))}
111
114
  downtimes[:downtime].should be_an(Array)
112
115
  # the last outage gets split by the intervening maintenance period,
113
116
  # but the fully covered one gets removed.
@@ -34,10 +34,9 @@ describe Flapjack::Executive, :redis => true do
34
34
  shutdown_evt.should_receive(:time).and_return(Time.now)
35
35
  Flapjack::Data::Event.should_receive(:next).and_return(shutdown_evt)
36
36
 
37
- EventMachine::Synchrony::ConnectionPool.should_receive(:new).and_return(@redis)
38
-
39
37
  executive = Flapjack::Executive.new
40
38
  executive.bootstrap(:config => {})
39
+ executive.should_receive(:build_redis_connection_pool).and_return(@redis)
41
40
 
42
41
  # hacky, but the behaviour it's mimicking (shutdown from another thread) isn't
43
42
  # conducive to nice tests
@@ -139,7 +139,7 @@ describe Flapjack::Jabber do
139
139
 
140
140
  fj.should_receive(:connect)
141
141
  fj.should_receive(:connected?).exactly(3).times.and_return(true)
142
- fj.should_receive(:should_quit?).exactly(3).times.and_return(false, false, true)
142
+ fj.should_receive(:should_quit?).exactly(4).times.and_return(false, false, true)
143
143
  redis.should_receive(:blpop).twice.and_return(
144
144
  ["jabber_notifications", %q{{"notification_type":"problem","event_id":"main-example.com:ping","state":"critical","summary":"!!!"}}],
145
145
  ["jabber_notifications", %q{{"notification_type":"shutdown"}}]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flapjack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.29
4
+ version: 0.6.30
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-09-21 00:00:00.000000000 Z
14
+ date: 2012-09-24 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: daemons