flapjack 0.6.39 → 0.6.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -2
- data/Gemfile +5 -1
- data/README.md +3 -2
- data/Rakefile +2 -1
- data/bin/flapjack +2 -2
- data/bin/flapjack-nagios-receiver +2 -8
- data/bin/flapjack-populator +11 -11
- data/etc/flapjack_config.yaml.example +28 -0
- data/features/steps/events_steps.rb +1 -1
- data/features/steps/notifications_steps.rb +7 -4
- data/features/support/env.rb +17 -6
- data/flapjack.gemspec +1 -0
- data/lib/flapjack/api.rb +72 -28
- data/lib/flapjack/configuration.rb +9 -1
- data/lib/flapjack/coordinator.rb +138 -162
- data/lib/flapjack/data/contact.rb +3 -1
- data/lib/flapjack/data/entity.rb +10 -1
- data/lib/flapjack/data/entity_check.rb +19 -21
- data/lib/flapjack/data/event.rb +26 -27
- data/lib/flapjack/data/message.rb +45 -0
- data/lib/flapjack/data/notification.rb +49 -0
- data/lib/flapjack/executive.rb +53 -74
- data/lib/flapjack/filters/acknowledgement.rb +14 -11
- data/lib/flapjack/jabber.rb +84 -18
- data/lib/flapjack/notification/email.rb +67 -37
- data/lib/flapjack/notification/sms.rb +40 -28
- data/lib/flapjack/oobetet.rb +1 -1
- data/lib/flapjack/pagerduty.rb +24 -15
- data/lib/flapjack/patches.rb +3 -1
- data/lib/flapjack/pikelet.rb +51 -20
- data/lib/flapjack/rack_logger.rb +8 -0
- data/lib/flapjack/version.rb +1 -1
- data/lib/flapjack/web.rb +51 -27
- data/spec/lib/flapjack/api_spec.rb +28 -3
- data/spec/lib/flapjack/coordinator_spec.rb +69 -43
- data/spec/lib/flapjack/data/contact_spec.rb +17 -9
- data/spec/lib/flapjack/data/entity_check_spec.rb +0 -25
- data/spec/lib/flapjack/data/entity_spec.rb +4 -0
- data/spec/lib/flapjack/data/global_spec.rb +6 -0
- data/spec/lib/flapjack/data/message_spec.rb +6 -0
- data/spec/lib/flapjack/data/notification_spec.rb +6 -0
- data/spec/lib/flapjack/executive_spec.rb +2 -2
- data/spec/lib/flapjack/jabber_spec.rb +8 -9
- data/spec/lib/flapjack/pagerduty_spec.rb +53 -45
- data/spec/lib/flapjack/utility_spec.rb +55 -0
- data/spec/lib/flapjack/web_spec.rb +7 -5
- data/tasks/events.rake +26 -59
- data/tasks/profile.rake +366 -0
- metadata +30 -19
- data/lib/flapjack/notification/common.rb +0 -23
- data/lib/flapjack/persistence/couch.rb +0 -5
- data/lib/flapjack/persistence/couch/connection.rb +0 -66
- data/lib/flapjack/persistence/couch/couch.rb +0 -63
- data/lib/flapjack/persistence/data_mapper.rb +0 -3
- data/lib/flapjack/persistence/data_mapper/data_mapper.rb +0 -67
- data/lib/flapjack/persistence/data_mapper/models/check.rb +0 -90
- data/lib/flapjack/persistence/data_mapper/models/check_template.rb +0 -20
- data/lib/flapjack/persistence/data_mapper/models/event.rb +0 -19
- data/lib/flapjack/persistence/data_mapper/models/node.rb +0 -18
- data/lib/flapjack/persistence/data_mapper/models/related_check.rb +0 -15
- data/lib/flapjack/persistence/sqlite3.rb +0 -3
- data/lib/flapjack/persistence/sqlite3/sqlite3.rb +0 -166
- data/lib/flapjack/transports/beanstalkd.rb +0 -50
- data/lib/flapjack/transports/result.rb +0 -58
- data/lib/flapjack/worker/application.rb +0 -121
- data/lib/flapjack/worker/cli.rb +0 -49
data/lib/flapjack/patches.rb
CHANGED
|
@@ -88,6 +88,7 @@ module Resque
|
|
|
88
88
|
startup
|
|
89
89
|
|
|
90
90
|
loop do
|
|
91
|
+
|
|
91
92
|
break if shutdown?
|
|
92
93
|
|
|
93
94
|
if not paused? and job = reserve
|
|
@@ -118,8 +119,9 @@ module Resque
|
|
|
118
119
|
end
|
|
119
120
|
end
|
|
120
121
|
|
|
121
|
-
ensure
|
|
122
122
|
unregister_worker
|
|
123
|
+
rescue Exception => exception
|
|
124
|
+
unregister_worker(exception)
|
|
123
125
|
end
|
|
124
126
|
|
|
125
127
|
end
|
data/lib/flapjack/pikelet.rb
CHANGED
|
@@ -12,11 +12,36 @@ require 'log4r'
|
|
|
12
12
|
require 'log4r/outputter/consoleoutputters'
|
|
13
13
|
require 'log4r/outputter/syslogoutputter'
|
|
14
14
|
|
|
15
|
-
require 'flapjack/redis_pool'
|
|
16
|
-
|
|
17
15
|
module Flapjack
|
|
18
16
|
module Pikelet
|
|
19
|
-
attr_accessor :logger, :
|
|
17
|
+
attr_accessor :logger, :config
|
|
18
|
+
|
|
19
|
+
# Classes including a pikelet subclass and wanting to extend #bootstrap
|
|
20
|
+
# should alias the original method and make sure to call them
|
|
21
|
+
# as part of their interstitial method.
|
|
22
|
+
def bootstrap(opts = {})
|
|
23
|
+
return if @bootstrapped
|
|
24
|
+
|
|
25
|
+
unless @logger = opts[:logger]
|
|
26
|
+
@logger = Log4r::Logger.new("#{self.class.to_s.downcase.gsub('::', '-')}")
|
|
27
|
+
@logger.add(Log4r::StdoutOutputter.new("flapjack"))
|
|
28
|
+
@logger.add(Log4r::SyslogOutputter.new("flapjack"))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
@config = opts[:config] || {}
|
|
32
|
+
|
|
33
|
+
@bootstrapped = true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Aliasing isn't currently necessary for #cleanup, as it's empty anyway.
|
|
37
|
+
# It's probably best practice to do so, in case that changes.
|
|
38
|
+
def cleanup
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
module GenericPikelet
|
|
44
|
+
include Flapjack::Pikelet
|
|
20
45
|
|
|
21
46
|
def should_quit?
|
|
22
47
|
@should_quit
|
|
@@ -26,30 +51,36 @@ module Flapjack
|
|
|
26
51
|
@should_quit = true
|
|
27
52
|
end
|
|
28
53
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
end
|
|
54
|
+
alias_method :orig_bootstrap, :bootstrap
|
|
55
|
+
|
|
56
|
+
def bootstrap(opts = {})
|
|
57
|
+
@should_quit = false
|
|
58
|
+
|
|
59
|
+
orig_bootstrap(opts)
|
|
36
60
|
end
|
|
37
61
|
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
module ResquePikelet
|
|
65
|
+
include Flapjack::Pikelet
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
module ThinPikelet
|
|
69
|
+
include Flapjack::Pikelet
|
|
70
|
+
|
|
71
|
+
attr_accessor :port
|
|
72
|
+
|
|
73
|
+
alias_method :orig_bootstrap, :bootstrap
|
|
74
|
+
|
|
38
75
|
def bootstrap(opts = {})
|
|
39
76
|
return if @bootstrapped
|
|
40
77
|
|
|
41
|
-
|
|
42
|
-
@
|
|
43
|
-
@
|
|
44
|
-
@logger.add(Log4r::SyslogOutputter.new("flapjack"))
|
|
78
|
+
if config = opts[:config]
|
|
79
|
+
@port = config['port'] ? config['port'].to_i : nil
|
|
80
|
+
@port = 3001 if (@port.nil? || @port <= 0 || @port > 65535)
|
|
45
81
|
end
|
|
46
82
|
|
|
47
|
-
|
|
48
|
-
@config = opts[:config] || {}
|
|
49
|
-
|
|
50
|
-
@should_quit = false
|
|
51
|
-
|
|
52
|
-
@bootstrapped = true
|
|
83
|
+
orig_bootstrap(opts)
|
|
53
84
|
end
|
|
54
85
|
|
|
55
86
|
end
|
data/lib/flapjack/version.rb
CHANGED
data/lib/flapjack/web.rb
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
require 'fiber'
|
|
4
|
-
|
|
5
3
|
require 'chronic'
|
|
6
4
|
require 'chronic_duration'
|
|
7
5
|
require 'sinatra/base'
|
|
8
6
|
require 'haml'
|
|
9
7
|
require 'rack/fiber_pool'
|
|
10
8
|
|
|
9
|
+
require 'async-rack'
|
|
10
|
+
require 'flapjack/rack_logger'
|
|
11
|
+
|
|
11
12
|
require 'flapjack/pikelet'
|
|
12
13
|
require 'flapjack/data/contact'
|
|
13
14
|
require 'flapjack/data/entity_check'
|
|
15
|
+
require 'flapjack/redis_pool'
|
|
14
16
|
require 'flapjack/utility'
|
|
15
17
|
|
|
16
18
|
module Flapjack
|
|
17
19
|
class Web < Sinatra::Base
|
|
18
20
|
|
|
19
|
-
if 'test'.eql?(FLAPJACK_ENV)
|
|
21
|
+
if defined?(FLAPJACK_ENV) && 'test'.eql?(FLAPJACK_ENV)
|
|
20
22
|
# expose test errors properly
|
|
21
23
|
set :raise_errors, true
|
|
22
24
|
set :show_exceptions, false
|
|
@@ -39,21 +41,47 @@ module Flapjack
|
|
|
39
41
|
use Rack::FiberPool, :size => 25, :rescue_exception => rescue_exception
|
|
40
42
|
end
|
|
41
43
|
use Rack::MethodOverride
|
|
42
|
-
|
|
44
|
+
|
|
45
|
+
web_logger = Flapjack::RackLogger.new('log/web_access.log')
|
|
46
|
+
use Rack::CommonLogger, web_logger
|
|
47
|
+
|
|
48
|
+
class << self
|
|
49
|
+
include Flapjack::ThinPikelet
|
|
50
|
+
|
|
51
|
+
attr_accessor :redis
|
|
52
|
+
|
|
53
|
+
alias_method :thin_bootstrap, :bootstrap
|
|
54
|
+
alias_method :thin_cleanup, :cleanup
|
|
55
|
+
|
|
56
|
+
def bootstrap(opts = {})
|
|
57
|
+
thin_bootstrap(opts)
|
|
58
|
+
@redis = Flapjack::RedisPool.new(:config => opts[:redis_config], :size => 1)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def cleanup
|
|
62
|
+
@redis.empty! if @redis
|
|
63
|
+
thin_cleanup
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
43
68
|
include Flapjack::Utility
|
|
44
69
|
|
|
45
70
|
set :views, settings.root + '/web/views'
|
|
46
71
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
72
|
+
def redis
|
|
73
|
+
self.class.instance_variable_get('@redis')
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def logger
|
|
77
|
+
self.class.instance_variable_get('@logger')
|
|
50
78
|
end
|
|
51
79
|
|
|
52
80
|
get '/' do
|
|
53
81
|
self_stats
|
|
54
82
|
|
|
55
83
|
# TODO (?) recast as Entity.all do |e|; e.checks.do |ec|; ...
|
|
56
|
-
@states =
|
|
84
|
+
@states = redis.keys('*:*:states').map { |r|
|
|
57
85
|
parts = r.split(':')[0..1]
|
|
58
86
|
[parts[0], parts[1]] + entity_check_state(parts[0], parts[1])
|
|
59
87
|
}.compact.sort_by {|parts| parts }
|
|
@@ -62,7 +90,7 @@ module Flapjack
|
|
|
62
90
|
|
|
63
91
|
get '/failing' do
|
|
64
92
|
self_stats
|
|
65
|
-
@states =
|
|
93
|
+
@states = redis.zrange('failed_checks', 0, -1).map {|key|
|
|
66
94
|
parts = key.split(':')
|
|
67
95
|
[parts[0], parts[1]] + entity_check_state(parts[0], parts[1])
|
|
68
96
|
}.compact.sort_by {|parts| parts}
|
|
@@ -176,7 +204,7 @@ module Flapjack
|
|
|
176
204
|
end
|
|
177
205
|
|
|
178
206
|
get '/contacts' do
|
|
179
|
-
@contacts = Flapjack::Data::Contact.all(:redis =>
|
|
207
|
+
@contacts = Flapjack::Data::Contact.all(:redis => redis)
|
|
180
208
|
haml :contacts
|
|
181
209
|
end
|
|
182
210
|
|
|
@@ -184,7 +212,7 @@ module Flapjack
|
|
|
184
212
|
contact_id = params[:contact]
|
|
185
213
|
|
|
186
214
|
if contact_id
|
|
187
|
-
@contact = Flapjack::Data::Contact.find_by_id(contact_id, :redis =>
|
|
215
|
+
@contact = Flapjack::Data::Contact.find_by_id(contact_id, :redis => redis)
|
|
188
216
|
end
|
|
189
217
|
|
|
190
218
|
unless @contact
|
|
@@ -207,17 +235,17 @@ module Flapjack
|
|
|
207
235
|
|
|
208
236
|
def get_entity_check(entity, check)
|
|
209
237
|
entity_obj = (entity && entity.length > 0) ?
|
|
210
|
-
Flapjack::Data::Entity.find_by_name(entity, :redis =>
|
|
238
|
+
Flapjack::Data::Entity.find_by_name(entity, :redis => redis) : nil
|
|
211
239
|
return if entity_obj.nil? || (check.nil? || check.length == 0)
|
|
212
|
-
Flapjack::Data::EntityCheck.for_entity(entity_obj, check, :redis =>
|
|
240
|
+
Flapjack::Data::EntityCheck.for_entity(entity_obj, check, :redis => redis)
|
|
213
241
|
end
|
|
214
242
|
|
|
215
243
|
def entity_check_state(entity_name, check)
|
|
216
244
|
entity = Flapjack::Data::Entity.find_by_name(entity_name,
|
|
217
|
-
:redis =>
|
|
245
|
+
:redis => redis)
|
|
218
246
|
return if entity.nil?
|
|
219
247
|
entity_check = Flapjack::Data::EntityCheck.for_entity(entity,
|
|
220
|
-
check, :redis =>
|
|
248
|
+
check, :redis => redis)
|
|
221
249
|
latest_notif =
|
|
222
250
|
{:problem => entity_check.last_problem_notification,
|
|
223
251
|
:recovery => entity_check.last_recovery_notification,
|
|
@@ -238,22 +266,18 @@ module Flapjack
|
|
|
238
266
|
@pid = Process.pid
|
|
239
267
|
@instance_id = "#{@fqdn}:#{@pid}"
|
|
240
268
|
|
|
241
|
-
@keys =
|
|
242
|
-
@count_failing_checks =
|
|
243
|
-
@count_all_checks =
|
|
244
|
-
@executive_instances =
|
|
245
|
-
@event_counters =
|
|
246
|
-
@event_counters_instance =
|
|
247
|
-
@boot_time = Time.at(
|
|
269
|
+
@keys = redis.keys '*'
|
|
270
|
+
@count_failing_checks = redis.zcard 'failed_checks'
|
|
271
|
+
@count_all_checks = redis.keys('check:*:*').length
|
|
272
|
+
@executive_instances = redis.zrange('executive_instances', '0', '-1', :withscores => true)
|
|
273
|
+
@event_counters = redis.hgetall('event_counters')
|
|
274
|
+
@event_counters_instance = redis.hgetall("event_counters:#{@instance_id}")
|
|
275
|
+
@boot_time = Time.at(redis.zscore('executive_instances', @instance_id).to_i)
|
|
248
276
|
@uptime = Time.now.to_i - @boot_time.to_i
|
|
249
277
|
@uptime_string = time_period_in_words(@uptime)
|
|
250
278
|
@event_rate_all = (@uptime > 0) ?
|
|
251
279
|
(@event_counters_instance['all'].to_f / @uptime) : 0
|
|
252
|
-
@events_queued =
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
def logger
|
|
256
|
-
Flapjack::Web.logger
|
|
280
|
+
@events_queued = redis.llen('events')
|
|
257
281
|
end
|
|
258
282
|
|
|
259
283
|
end
|
|
@@ -10,7 +10,7 @@ describe 'Flapjack::API', :sinatra => true do
|
|
|
10
10
|
let(:entity) { mock(Flapjack::Data::Entity) }
|
|
11
11
|
let(:entity_check) { mock(Flapjack::Data::EntityCheck) }
|
|
12
12
|
|
|
13
|
-
let(:entity_name) { 'example.
|
|
13
|
+
let(:entity_name) { 'www.example.net'}
|
|
14
14
|
let(:entity_name_esc) { URI.escape(entity_name) }
|
|
15
15
|
let(:check) { 'ping' }
|
|
16
16
|
|
|
@@ -20,7 +20,8 @@ describe 'Flapjack::API', :sinatra => true do
|
|
|
20
20
|
let(:redis) { mock(::Redis) }
|
|
21
21
|
|
|
22
22
|
before(:each) do
|
|
23
|
-
Flapjack::
|
|
23
|
+
Flapjack::RedisPool.should_receive(:new).and_return(redis)
|
|
24
|
+
Flapjack::API.bootstrap(:config => {})
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
it "returns a list of checks for an entity" do
|
|
@@ -49,6 +50,17 @@ describe 'Flapjack::API', :sinatra => true do
|
|
|
49
50
|
last_response.body.should == result_json
|
|
50
51
|
end
|
|
51
52
|
|
|
53
|
+
it "creates an acknowledgement for an entity check" do
|
|
54
|
+
Flapjack::Data::Entity.should_receive(:find_by_name).
|
|
55
|
+
with(entity_name, :redis => redis).and_return(entity)
|
|
56
|
+
Flapjack::Data::EntityCheck.should_receive(:for_entity).
|
|
57
|
+
with(entity, check, :redis => redis).and_return(entity_check)
|
|
58
|
+
entity_check.should_receive(:create_acknowledgement).with('summary' => nil, 'duration' => (4 * 60 * 60))
|
|
59
|
+
|
|
60
|
+
post "/acknowledgements/#{entity_name_esc}/#{check}"
|
|
61
|
+
last_response.status.should == 204
|
|
62
|
+
end
|
|
63
|
+
|
|
52
64
|
it "returns a list of scheduled maintenance periods within a time window for an entity"
|
|
53
65
|
|
|
54
66
|
it "returns a list of scheduled maintenance periods for a check on an entity" do
|
|
@@ -167,6 +179,19 @@ describe 'Flapjack::API', :sinatra => true do
|
|
|
167
179
|
last_response.body.should == result_json
|
|
168
180
|
end
|
|
169
181
|
|
|
182
|
+
it "creates a test notification event for check on an entity" do
|
|
183
|
+
|
|
184
|
+
Flapjack::Data::Entity.should_receive(:find_by_name).
|
|
185
|
+
with(entity_name, :redis => redis).and_return(entity)
|
|
186
|
+
entity.should_receive(:name).and_return(entity_name)
|
|
187
|
+
Flapjack::Data::EntityCheck.should_receive(:for_entity).
|
|
188
|
+
with(entity, 'foo', :redis => redis).and_return(entity_check)
|
|
189
|
+
entity_check.should_receive(:test_notifications)
|
|
190
|
+
|
|
191
|
+
post "/test_notifications/#{entity_name_esc}/foo"
|
|
192
|
+
last_response.status.should == 204
|
|
193
|
+
end
|
|
194
|
+
|
|
170
195
|
it "creates entities from a submitted list" do
|
|
171
196
|
entities = {'entities' =>
|
|
172
197
|
[
|
|
@@ -266,4 +291,4 @@ describe 'Flapjack::API', :sinatra => true do
|
|
|
266
291
|
last_response.status.should == 200
|
|
267
292
|
end
|
|
268
293
|
|
|
269
|
-
end
|
|
294
|
+
end
|
|
@@ -13,57 +13,80 @@ describe Flapjack::Coordinator do
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
# temporary workaround for failing test due to preserved state;
|
|
18
|
-
# won't be needed soon as this code has been fixed in a branch
|
|
19
|
-
Flapjack::API.class_variable_set('@@redis', nil)
|
|
20
|
-
Flapjack::Web.class_variable_set('@@redis', nil)
|
|
21
|
-
}
|
|
16
|
+
let(:redis_config) { {} }
|
|
22
17
|
|
|
23
18
|
# leaving actual testing of daemonisation to that class's tests
|
|
24
19
|
it "daemonizes properly" do
|
|
25
|
-
fc = Flapjack::Coordinator.new(config)
|
|
20
|
+
fc = Flapjack::Coordinator.new(config, redis_config)
|
|
26
21
|
fc.should_receive(:daemonize)
|
|
27
22
|
fc.should_not_receive(:build_pikelet)
|
|
28
|
-
fc.should_not_receive(:build_resque_pikelet)
|
|
29
|
-
fc.should_not_receive(:build_thin_pikelet)
|
|
30
23
|
fc.start(:daemonize => true, :signals => false)
|
|
31
24
|
end
|
|
32
25
|
|
|
33
26
|
it "runs undaemonized" do
|
|
34
27
|
EM.should_receive(:synchrony).and_yield
|
|
35
28
|
|
|
36
|
-
fc = Flapjack::Coordinator.new(config)
|
|
37
|
-
fc.should_receive(:build_pikelet)
|
|
38
|
-
fc.should_receive(:build_resque_pikelet)
|
|
39
|
-
fc.should_receive(:build_thin_pikelet)
|
|
29
|
+
fc = Flapjack::Coordinator.new(config, redis_config)
|
|
30
|
+
fc.should_receive(:build_pikelet).exactly(3).times
|
|
40
31
|
fc.start(:daemonize => false, :signals => false)
|
|
41
32
|
end
|
|
42
33
|
|
|
43
34
|
it "starts after daemonizing" do
|
|
44
35
|
EM.should_receive(:synchrony).and_yield
|
|
45
36
|
|
|
46
|
-
fc = Flapjack::Coordinator.new(config)
|
|
47
|
-
fc.should_receive(:build_pikelet)
|
|
48
|
-
fc.should_receive(:build_resque_pikelet)
|
|
49
|
-
fc.should_receive(:build_thin_pikelet)
|
|
37
|
+
fc = Flapjack::Coordinator.new(config, redis_config)
|
|
38
|
+
fc.should_receive(:build_pikelet).exactly(3).times
|
|
50
39
|
fc.after_daemonize
|
|
51
40
|
end
|
|
52
41
|
|
|
53
|
-
it "traps system signals and shuts down"
|
|
42
|
+
it "traps system signals and shuts down" do
|
|
43
|
+
RbConfig::CONFIG.should_receive(:[]).with('host_os').and_return('darwin12.0.0')
|
|
44
|
+
|
|
45
|
+
Kernel.should_receive(:trap).with('INT').and_yield
|
|
46
|
+
Kernel.should_receive(:trap).with('TERM').and_yield
|
|
47
|
+
Kernel.should_receive(:trap).with('QUIT').and_yield
|
|
48
|
+
|
|
49
|
+
fc = Flapjack::Coordinator.new(config, redis_config)
|
|
50
|
+
fc.should_receive(:stop).exactly(3).times
|
|
51
|
+
|
|
52
|
+
fc.send(:setup_signals)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "only traps two system signals on Windows" do
|
|
56
|
+
RbConfig::CONFIG.should_receive(:[]).with('host_os').and_return('mswin')
|
|
57
|
+
|
|
58
|
+
Kernel.should_receive(:trap).with('INT').and_yield
|
|
59
|
+
Kernel.should_receive(:trap).with('TERM').and_yield
|
|
60
|
+
Kernel.should_not_receive(:trap).with('QUIT')
|
|
61
|
+
|
|
62
|
+
fc = Flapjack::Coordinator.new(config, redis_config)
|
|
63
|
+
fc.should_receive(:stop).twice
|
|
64
|
+
|
|
65
|
+
fc.send(:setup_signals)
|
|
66
|
+
end
|
|
54
67
|
|
|
55
|
-
# TODO whem merged with other changes, this will check pik[:class] instead,
|
|
56
|
-
# having to create instances of the pikelet classes is messy
|
|
57
68
|
it "stops its services when closing" do
|
|
58
69
|
fiber_exec = mock('fiber_exec')
|
|
59
70
|
fiber_rsq = mock('fiber_rsq')
|
|
60
71
|
|
|
61
|
-
exec =
|
|
72
|
+
exec = mock('executive')
|
|
73
|
+
exec.should_receive(:is_a?).with(Flapjack::GenericPikelet).twice.and_return(true)
|
|
74
|
+
exec.should_receive(:stop)
|
|
62
75
|
exec.should_receive(:add_shutdown_event)
|
|
63
|
-
|
|
76
|
+
exec.should_receive(:cleanup)
|
|
77
|
+
|
|
78
|
+
email = mock('worker')
|
|
79
|
+
email.should_receive(:is_a?).with(Flapjack::GenericPikelet).twice.and_return(false)
|
|
64
80
|
email.should_receive(:shutdown)
|
|
65
|
-
|
|
81
|
+
Flapjack::Notification::Email.should_receive(:cleanup)
|
|
82
|
+
|
|
83
|
+
backend = mock('backend')
|
|
84
|
+
backend.should_receive(:size).twice.and_return(1, 0)
|
|
85
|
+
web = mock('web')
|
|
86
|
+
web.should_receive(:is_a?).with(Flapjack::GenericPikelet).twice.and_return(false)
|
|
87
|
+
web.should_receive(:backend).twice.and_return(backend)
|
|
66
88
|
web.should_receive(:stop!)
|
|
89
|
+
Flapjack::Web.should_receive(:cleanup)
|
|
67
90
|
|
|
68
91
|
redis = mock('redis')
|
|
69
92
|
redis.should_receive(:quit)
|
|
@@ -74,16 +97,17 @@ describe Flapjack::Coordinator do
|
|
|
74
97
|
fiber_stop.should_receive(:resume)
|
|
75
98
|
Fiber.should_receive(:new).twice.and_yield.and_return(fiber, fiber_stop)
|
|
76
99
|
|
|
77
|
-
fiber_exec.should_receive(:alive?).and_return(true, false)
|
|
78
|
-
fiber_rsq.should_receive(:alive?).and_return(true, false)
|
|
100
|
+
fiber_exec.should_receive(:alive?).exactly(3).times.and_return(true, true, false)
|
|
101
|
+
fiber_rsq.should_receive(:alive?).exactly(3).and_return(true, false, false)
|
|
79
102
|
|
|
103
|
+
EM::Synchrony.should_receive(:sleep)
|
|
80
104
|
EM.should_receive(:stop)
|
|
81
105
|
|
|
82
|
-
pikelets = [{:fiber => fiber_exec, :instance => exec},
|
|
83
|
-
{:fiber => fiber_rsq, :instance => email},
|
|
84
|
-
{:instance => web}]
|
|
106
|
+
pikelets = [{:fiber => fiber_exec, :instance => exec, :class => Flapjack::Executive},
|
|
107
|
+
{:fiber => fiber_rsq, :instance => email, :class => Flapjack::Notification::Email},
|
|
108
|
+
{:instance => web, :class => Flapjack::Web}]
|
|
85
109
|
|
|
86
|
-
fc = Flapjack::Coordinator.new
|
|
110
|
+
fc = Flapjack::Coordinator.new(config, redis_config)
|
|
87
111
|
fc.instance_variable_set('@redis_options', {})
|
|
88
112
|
fc.instance_variable_set('@pikelets', pikelets)
|
|
89
113
|
fc.stop
|
|
@@ -93,37 +117,39 @@ describe Flapjack::Coordinator do
|
|
|
93
117
|
exec = mock('executive')
|
|
94
118
|
exec.should_receive(:bootstrap)
|
|
95
119
|
Flapjack::Executive.should_receive(:new).and_return(exec)
|
|
120
|
+
exec.should_receive(:is_a?).with(Flapjack::GenericPikelet).and_return(true)
|
|
96
121
|
exec.should_receive(:main)
|
|
97
122
|
|
|
98
123
|
fiber.should_receive(:resume)
|
|
99
124
|
Fiber.should_receive(:new).and_yield.and_return(fiber)
|
|
100
125
|
|
|
101
|
-
fc = Flapjack::Coordinator.new
|
|
126
|
+
fc = Flapjack::Coordinator.new(config, redis_config)
|
|
102
127
|
fc.send(:build_pikelet, 'executive', {})
|
|
103
128
|
pikelets = fc.instance_variable_get('@pikelets')
|
|
104
129
|
pikelets.should_not be_nil
|
|
105
130
|
pikelets.should be_an(Array)
|
|
106
131
|
pikelets.should have(1).pikelet
|
|
107
|
-
pikelets.first.should == {:fiber => fiber, :
|
|
132
|
+
pikelets.first.should == {:fiber => fiber, :class => Flapjack::Executive, :instance => exec}
|
|
108
133
|
end
|
|
109
134
|
|
|
110
|
-
it "handles an exception raised by a
|
|
135
|
+
it "handles an exception raised by a fiber pikelet" do
|
|
111
136
|
jabber = mock('jabber')
|
|
112
137
|
jabber.should_receive(:bootstrap)
|
|
113
138
|
Flapjack::Jabber.should_receive(:new).and_return(jabber)
|
|
139
|
+
jabber.should_receive(:is_a?).with(Flapjack::GenericPikelet).and_return(true)
|
|
114
140
|
jabber.should_receive(:main).and_raise(RuntimeError)
|
|
115
141
|
|
|
116
142
|
fiber.should_receive(:resume)
|
|
117
143
|
Fiber.should_receive(:new).and_yield.and_return(fiber)
|
|
118
144
|
|
|
119
|
-
fc = Flapjack::Coordinator.new
|
|
145
|
+
fc = Flapjack::Coordinator.new(config, redis_config)
|
|
120
146
|
fc.should_receive(:stop)
|
|
121
147
|
fc.send(:build_pikelet, 'jabber_gateway', {})
|
|
122
148
|
pikelets = fc.instance_variable_get('@pikelets')
|
|
123
149
|
pikelets.should_not be_nil
|
|
124
150
|
pikelets.should be_an(Array)
|
|
125
151
|
pikelets.should have(1).pikelet
|
|
126
|
-
pikelets.first.should == {:fiber => fiber, :
|
|
152
|
+
pikelets.first.should == {:fiber => fiber, :class => Flapjack::Jabber, :instance => jabber}
|
|
127
153
|
end
|
|
128
154
|
|
|
129
155
|
it "creates a resque worker pikelet" do
|
|
@@ -138,20 +164,18 @@ describe Flapjack::Coordinator do
|
|
|
138
164
|
fiber.should_receive(:resume)
|
|
139
165
|
Fiber.should_receive(:new).and_yield.and_return(fiber)
|
|
140
166
|
|
|
141
|
-
fc = Flapjack::Coordinator.new
|
|
142
|
-
fc.send(:
|
|
167
|
+
fc = Flapjack::Coordinator.new(config, redis_config)
|
|
168
|
+
fc.send(:build_pikelet, 'email_notifier', {})
|
|
143
169
|
pikelets = fc.instance_variable_get('@pikelets')
|
|
144
170
|
pikelets.should_not be_nil
|
|
145
171
|
pikelets.should be_an(Array)
|
|
146
172
|
pikelets.should have(1).pikelet
|
|
147
|
-
pikelets.first.should == {:fiber => fiber, :
|
|
173
|
+
pikelets.first.should == {:fiber => fiber, :class => Flapjack::Notification::Email,
|
|
174
|
+
:instance => worker}
|
|
148
175
|
end
|
|
149
176
|
|
|
150
|
-
it "handles an exception raised by a resque worker pikelet"
|
|
151
|
-
|
|
152
177
|
it "creates a thin server pikelet" do
|
|
153
178
|
redis = mock('redis')
|
|
154
|
-
Flapjack::RedisPool.should_receive(:new).and_return(redis)
|
|
155
179
|
|
|
156
180
|
server = mock('server')
|
|
157
181
|
server.should_receive(:start)
|
|
@@ -159,13 +183,15 @@ describe Flapjack::Coordinator do
|
|
|
159
183
|
with(/^(?:\d{1,3}\.){3}\d{1,3}$/, an_instance_of(Fixnum), Flapjack::Web, :signals => false).
|
|
160
184
|
and_return(server)
|
|
161
185
|
|
|
162
|
-
|
|
163
|
-
|
|
186
|
+
Flapjack::RedisPool.should_receive(:new)
|
|
187
|
+
|
|
188
|
+
fc = Flapjack::Coordinator.new(config, redis_config)
|
|
189
|
+
fc.send(:build_pikelet, 'web', {})
|
|
164
190
|
pikelets = fc.instance_variable_get('@pikelets')
|
|
165
191
|
pikelets.should_not be_nil
|
|
166
192
|
pikelets.should be_an(Array)
|
|
167
193
|
pikelets.should have(1).pikelet
|
|
168
|
-
pikelets.first.should == {:
|
|
194
|
+
pikelets.first.should == {:class => Flapjack::Web, :instance => server}
|
|
169
195
|
end
|
|
170
196
|
|
|
171
197
|
# NB: exceptions are handled directly by the Thin pikelets
|