resurrected_god 0.14.0

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.
Files changed (141) hide show
  1. checksums.yaml +7 -0
  2. data/Announce.txt +135 -0
  3. data/Gemfile +5 -0
  4. data/LICENSE +22 -0
  5. data/README.md +33 -0
  6. data/Rakefile +129 -0
  7. data/bin/god +134 -0
  8. data/doc/god.asciidoc +1592 -0
  9. data/doc/intro.asciidoc +20 -0
  10. data/ext/god/.gitignore +5 -0
  11. data/ext/god/extconf.rb +56 -0
  12. data/ext/god/kqueue_handler.c +133 -0
  13. data/ext/god/netlink_handler.c +182 -0
  14. data/lib/god/behavior.rb +52 -0
  15. data/lib/god/behaviors/clean_pid_file.rb +21 -0
  16. data/lib/god/behaviors/clean_unix_socket.rb +21 -0
  17. data/lib/god/behaviors/notify_when_flapping.rb +51 -0
  18. data/lib/god/cli/command.rb +268 -0
  19. data/lib/god/cli/run.rb +170 -0
  20. data/lib/god/cli/version.rb +23 -0
  21. data/lib/god/compat19.rb +33 -0
  22. data/lib/god/condition.rb +96 -0
  23. data/lib/god/conditions/always.rb +36 -0
  24. data/lib/god/conditions/complex.rb +86 -0
  25. data/lib/god/conditions/cpu_usage.rb +80 -0
  26. data/lib/god/conditions/degrading_lambda.rb +52 -0
  27. data/lib/god/conditions/disk_usage.rb +32 -0
  28. data/lib/god/conditions/file_mtime.rb +28 -0
  29. data/lib/god/conditions/file_touched.rb +44 -0
  30. data/lib/god/conditions/flapping.rb +128 -0
  31. data/lib/god/conditions/http_response_code.rb +184 -0
  32. data/lib/god/conditions/lambda.rb +25 -0
  33. data/lib/god/conditions/memory_usage.rb +82 -0
  34. data/lib/god/conditions/process_exits.rb +66 -0
  35. data/lib/god/conditions/process_running.rb +63 -0
  36. data/lib/god/conditions/socket_responding.rb +142 -0
  37. data/lib/god/conditions/tries.rb +44 -0
  38. data/lib/god/configurable.rb +57 -0
  39. data/lib/god/contact.rb +114 -0
  40. data/lib/god/contacts/airbrake.rb +44 -0
  41. data/lib/god/contacts/campfire.rb +121 -0
  42. data/lib/god/contacts/email.rb +130 -0
  43. data/lib/god/contacts/hipchat.rb +117 -0
  44. data/lib/god/contacts/jabber.rb +75 -0
  45. data/lib/god/contacts/prowl.rb +57 -0
  46. data/lib/god/contacts/scout.rb +55 -0
  47. data/lib/god/contacts/sensu.rb +59 -0
  48. data/lib/god/contacts/slack.rb +98 -0
  49. data/lib/god/contacts/statsd.rb +46 -0
  50. data/lib/god/contacts/twitter.rb +51 -0
  51. data/lib/god/contacts/webhook.rb +74 -0
  52. data/lib/god/driver.rb +238 -0
  53. data/lib/god/errors.rb +24 -0
  54. data/lib/god/event_handler.rb +112 -0
  55. data/lib/god/event_handlers/dummy_handler.rb +13 -0
  56. data/lib/god/event_handlers/kqueue_handler.rb +17 -0
  57. data/lib/god/event_handlers/netlink_handler.rb +13 -0
  58. data/lib/god/logger.rb +109 -0
  59. data/lib/god/metric.rb +87 -0
  60. data/lib/god/process.rb +381 -0
  61. data/lib/god/registry.rb +32 -0
  62. data/lib/god/simple_logger.rb +59 -0
  63. data/lib/god/socket.rb +113 -0
  64. data/lib/god/sugar.rb +62 -0
  65. data/lib/god/sys_logger.rb +45 -0
  66. data/lib/god/system/portable_poller.rb +42 -0
  67. data/lib/god/system/process.rb +50 -0
  68. data/lib/god/system/slash_proc_poller.rb +92 -0
  69. data/lib/god/task.rb +552 -0
  70. data/lib/god/timeline.rb +25 -0
  71. data/lib/god/trigger.rb +43 -0
  72. data/lib/god/version.rb +4 -0
  73. data/lib/god/watch.rb +340 -0
  74. data/lib/god.rb +777 -0
  75. data/test/configs/child_events/child_events.god +44 -0
  76. data/test/configs/child_events/simple_server.rb +3 -0
  77. data/test/configs/child_polls/child_polls.god +37 -0
  78. data/test/configs/child_polls/simple_server.rb +12 -0
  79. data/test/configs/complex/complex.god +59 -0
  80. data/test/configs/complex/simple_server.rb +3 -0
  81. data/test/configs/contact/contact.god +118 -0
  82. data/test/configs/contact/simple_server.rb +3 -0
  83. data/test/configs/daemon_events/daemon_events.god +37 -0
  84. data/test/configs/daemon_events/simple_server.rb +8 -0
  85. data/test/configs/daemon_events/simple_server_stop.rb +11 -0
  86. data/test/configs/daemon_polls/daemon_polls.god +17 -0
  87. data/test/configs/daemon_polls/simple_server.rb +6 -0
  88. data/test/configs/degrading_lambda/degrading_lambda.god +31 -0
  89. data/test/configs/degrading_lambda/tcp_server.rb +15 -0
  90. data/test/configs/keepalive/keepalive.god +9 -0
  91. data/test/configs/keepalive/keepalive.rb +12 -0
  92. data/test/configs/lifecycle/lifecycle.god +25 -0
  93. data/test/configs/matias/matias.god +50 -0
  94. data/test/configs/real.rb +59 -0
  95. data/test/configs/running_load/running_load.god +16 -0
  96. data/test/configs/stop_options/simple_server.rb +12 -0
  97. data/test/configs/stop_options/stop_options.god +39 -0
  98. data/test/configs/stress/simple_server.rb +3 -0
  99. data/test/configs/stress/stress.god +15 -0
  100. data/test/configs/task/logs/.placeholder +0 -0
  101. data/test/configs/task/task.god +26 -0
  102. data/test/configs/test.rb +61 -0
  103. data/test/configs/usr1_trapper.rb +10 -0
  104. data/test/helper.rb +172 -0
  105. data/test/suite.rb +6 -0
  106. data/test/test_airbrake.rb +14 -0
  107. data/test/test_behavior.rb +18 -0
  108. data/test/test_campfire.rb +22 -0
  109. data/test/test_condition.rb +52 -0
  110. data/test/test_conditions_disk_usage.rb +50 -0
  111. data/test/test_conditions_http_response_code.rb +109 -0
  112. data/test/test_conditions_process_running.rb +40 -0
  113. data/test/test_conditions_socket_responding.rb +176 -0
  114. data/test/test_conditions_tries.rb +67 -0
  115. data/test/test_contact.rb +109 -0
  116. data/test/test_driver.rb +26 -0
  117. data/test/test_email.rb +34 -0
  118. data/test/test_event_handler.rb +82 -0
  119. data/test/test_god.rb +710 -0
  120. data/test/test_god_system.rb +201 -0
  121. data/test/test_handlers_kqueue_handler.rb +16 -0
  122. data/test/test_hipchat.rb +23 -0
  123. data/test/test_jabber.rb +29 -0
  124. data/test/test_logger.rb +55 -0
  125. data/test/test_metric.rb +74 -0
  126. data/test/test_process.rb +263 -0
  127. data/test/test_prowl.rb +15 -0
  128. data/test/test_registry.rb +15 -0
  129. data/test/test_sensu.rb +11 -0
  130. data/test/test_slack.rb +57 -0
  131. data/test/test_socket.rb +34 -0
  132. data/test/test_statsd.rb +22 -0
  133. data/test/test_sugar.rb +42 -0
  134. data/test/test_system_portable_poller.rb +17 -0
  135. data/test/test_system_process.rb +30 -0
  136. data/test/test_task.rb +246 -0
  137. data/test/test_timeline.rb +37 -0
  138. data/test/test_trigger.rb +63 -0
  139. data/test/test_watch.rb +286 -0
  140. data/test/test_webhook.rb +22 -0
  141. metadata +476 -0
@@ -0,0 +1,286 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestWatch < Minitest::Test
4
+ def setup
5
+ God.internal_init
6
+ @watch = Watch.new
7
+ @watch.name = 'foo'
8
+ @watch.start = lambda { }
9
+ @watch.stop = lambda { }
10
+ @watch.prepare
11
+ end
12
+
13
+ # new
14
+
15
+ def test_new_should_have_no_behaviors
16
+ assert_equal [], @watch.behaviors
17
+ end
18
+
19
+ def test_new_should_have_no_metrics
20
+ Watch::VALID_STATES.each do |state|
21
+ assert_equal [], @watch.metrics[state]
22
+ end
23
+ end
24
+
25
+ def test_new_should_have_standard_attributes
26
+ assert_nothing_raised do
27
+ @watch.name = 'foo'
28
+ @watch.start = 'start'
29
+ @watch.stop = 'stop'
30
+ @watch.restart = 'restart'
31
+ @watch.interval = 30
32
+ @watch.grace = 5
33
+ end
34
+ end
35
+
36
+ def test_new_should_have_unmonitored_state
37
+ assert_equal :unmonitored, @watch.state
38
+ end
39
+
40
+ # valid?
41
+
42
+ def test_valid?
43
+ God::Process.any_instance.expects(:valid?)
44
+ @watch.valid?
45
+ end
46
+
47
+ # behavior
48
+
49
+ def test_behavior_should_record_behavior
50
+ beh = nil
51
+ @watch.behavior(:fake_behavior) { |b| beh = b }
52
+ assert_equal 1, @watch.behaviors.size
53
+ assert_equal beh, @watch.behaviors.first
54
+ end
55
+
56
+ def test_invalid_behavior_should_abort
57
+ assert_abort do
58
+ @watch.behavior(:invalid)
59
+ end
60
+ end
61
+
62
+ # transition
63
+
64
+ def test_transition_should_abort_on_invalid_start_state
65
+ assert_abort do
66
+ @watch.transition(:foo, :bar)
67
+ end
68
+ end
69
+
70
+ def test_transition_should_accept_all_valid_start_states
71
+ assert_nothing_raised do
72
+ Watch::VALID_STATES.each do |state|
73
+ @watch.transition(state, :bar) { }
74
+ end
75
+ end
76
+ end
77
+
78
+ def test_transition_should_create_and_record_a_metric_for_the_given_start_state
79
+ @watch.transition(:init, :start) { }
80
+ assert_equal 1, @watch.metrics[:init].size
81
+ end
82
+
83
+ # lifecycle
84
+
85
+ def test_lifecycle_should_create_and_record_a_metric_for_nil_start_state
86
+ @watch.lifecycle { }
87
+ assert_equal 1, @watch.metrics[nil].size
88
+ end
89
+
90
+ # keepalive
91
+
92
+ def test_keepalive_should_place_metrics_on_up_state
93
+ @watch.keepalive(:memory_max => 5.megabytes, :cpu_max => 50.percent)
94
+ assert_equal 2, @watch.metrics[:up].size
95
+ end
96
+
97
+ # start_if
98
+
99
+ def test_start_if_should_place_a_metric_on_up_state
100
+ @watch.start_if { }
101
+ assert_equal 1, @watch.metrics[:up].size
102
+ end
103
+
104
+ # restart_if
105
+
106
+ def test_restart_if_should_place_a_metric_on_up_state
107
+ @watch.restart_if { }
108
+ assert_equal 1, @watch.metrics[:up].size
109
+ end
110
+
111
+ # monitor
112
+
113
+ def test_monitor_should_move_to_init_if_available
114
+ @watch.instance_eval do
115
+ transition(:init, :up) { }
116
+ end
117
+ @watch.expects(:move).with(:init)
118
+ @watch.monitor
119
+ end
120
+
121
+ def test_monitor_should_move_to_up_if_no_init_available
122
+ @watch.expects(:move).with(:up)
123
+ @watch.monitor
124
+ end
125
+
126
+ # unmonitor
127
+
128
+ def test_unmonitor_should_move_to_nil
129
+ @watch.expects(:move).with(:unmonitored)
130
+ @watch.unmonitor
131
+ end
132
+
133
+ # move
134
+
135
+ def test_move_should_not_clean_up_if_from_state_is_nil
136
+ @watch.driver.stubs(:in_driver_context?).returns(true)
137
+ @watch.driver.expects(:message).never
138
+
139
+ metric = nil
140
+
141
+ @watch.instance_eval do
142
+ transition(:init, :up) do |on|
143
+ metric = on
144
+ on.condition(:process_running) do |c|
145
+ c.running = true
146
+ c.interval = 10
147
+ end
148
+ end
149
+ end
150
+
151
+ metric.expects(:disable).never
152
+
153
+ @watch.move(:init)
154
+ end
155
+
156
+ def test_move_should_clean_up_from_state_if_not_nil
157
+ @watch.driver.stubs(:in_driver_context?).returns(true)
158
+ @watch.driver.expects(:message).never
159
+
160
+ metric = nil
161
+
162
+ @watch.instance_eval do
163
+ transition(:init, :up) do |on|
164
+ metric = on
165
+ on.condition(:process_running) do |c|
166
+ c.running = true
167
+ c.interval = 10
168
+ end
169
+ end
170
+ end
171
+
172
+ @watch.move(:init)
173
+
174
+ metric.expects(:disable)
175
+
176
+ @watch.move(:up)
177
+ end
178
+
179
+ def test_move_should_call_action
180
+ @watch.driver.stubs(:in_driver_context?).returns(true)
181
+ @watch.driver.expects(:message).never
182
+
183
+ @watch.expects(:action).with(:start)
184
+
185
+ @watch.move(:start)
186
+ end
187
+
188
+ def test_move_should_move_to_up_state_if_no_start_or_restart_metric
189
+ @watch.driver.stubs(:in_driver_context?).returns(true)
190
+ @watch.driver.expects(:message).never
191
+
192
+ [:start, :restart].each do |state|
193
+ @watch.expects(:action)
194
+ @watch.move(state)
195
+ assert_equal :up, @watch.state
196
+ end
197
+ end
198
+
199
+ def test_move_should_enable_destination_metric
200
+ @watch.driver.stubs(:in_driver_context?).returns(true)
201
+ @watch.driver.expects(:message).never
202
+
203
+ metric = nil
204
+
205
+ @watch.instance_eval do
206
+ transition(:init, :up) do |on|
207
+ metric = on
208
+ on.condition(:process_running) do |c|
209
+ c.running = true
210
+ c.interval = 10
211
+ end
212
+ end
213
+ end
214
+
215
+ metric.expects(:enable)
216
+
217
+ @watch.move(:init)
218
+ end
219
+
220
+ # action
221
+
222
+ def test_action_should_pass_start_and_stop_actions_to_call_action
223
+ @watch.driver.stubs(:in_driver_context?).returns(true)
224
+ @watch.driver.expects(:message).never
225
+
226
+ c = Conditions::FakePollCondition.new
227
+ [:start, :stop].each do |cmd|
228
+ @watch.expects(:call_action).with(c, cmd)
229
+ @watch.action(cmd, c)
230
+ end
231
+ end
232
+
233
+ def test_action_should_do_stop_then_start_if_no_restart_command
234
+ @watch.driver.stubs(:in_driver_context?).returns(true)
235
+ @watch.driver.expects(:message).never
236
+
237
+ c = Conditions::FakePollCondition.new
238
+ @watch.expects(:call_action).with(c, :stop)
239
+ @watch.expects(:call_action).with(c, :start)
240
+ @watch.action(:restart, c)
241
+ end
242
+
243
+ def test_action_should_restart_to_call_action_if_present
244
+ @watch.driver.stubs(:in_driver_context?).returns(true)
245
+ @watch.driver.expects(:message).never
246
+
247
+ @watch.restart = lambda { }
248
+ c = Conditions::FakePollCondition.new
249
+ @watch.expects(:call_action).with(c, :restart)
250
+ @watch.action(:restart, c)
251
+ end
252
+
253
+ # call_action
254
+
255
+ def test_call_action
256
+ c = Conditions::FakePollCondition.new
257
+ God::Process.any_instance.expects(:call_action).with(:start)
258
+ @watch.call_action(c, :start)
259
+ end
260
+
261
+ def test_call_action_should_call_before_start_when_behavior_has_that
262
+ @watch.behavior(:fake_behavior)
263
+ c = Conditions::FakePollCondition.new
264
+ God::Process.any_instance.expects(:call_action).with(:start)
265
+ Behaviors::FakeBehavior.any_instance.expects(:before_start)
266
+ @watch.call_action(c, :start)
267
+ end
268
+
269
+ def test_call_action_should_call_after_start_when_behavior_has_that
270
+ @watch.behavior(:fake_behavior)
271
+ c = Conditions::FakePollCondition.new
272
+ God::Process.any_instance.expects(:call_action).with(:start)
273
+ Behaviors::FakeBehavior.any_instance.expects(:after_start)
274
+ @watch.call_action(c, :start)
275
+ end
276
+
277
+ # canonical_hash_form
278
+
279
+ def test_canonical_hash_form_should_convert_symbol_to_hash
280
+ assert_equal({true => :foo}, @watch.canonical_hash_form(:foo))
281
+ end
282
+
283
+ def test_canonical_hash_form_should_convert_hash_to_hash
284
+ assert_equal({true => :foo}, @watch.canonical_hash_form(true => :foo))
285
+ end
286
+ end
@@ -0,0 +1,22 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestWebhook < Minitest::Test
4
+ def setup
5
+ @webhook = God::Contacts::Webhook.new
6
+ end
7
+
8
+ def test_notify
9
+ @webhook.url = 'http://example.com/switch'
10
+ Net::HTTP.any_instance.expects(:request).returns(Net::HTTPSuccess.new('a', 'b', 'c'))
11
+
12
+ @webhook.notify('msg', Time.now, 'prio', 'cat', 'host')
13
+ assert_equal "sent webhook to http://example.com/switch", @webhook.info
14
+ end
15
+
16
+ def test_notify_with_url_containing_query_parameters
17
+ @webhook.url = 'http://example.com/switch?api_key=123'
18
+ Net::HTTP::Post.expects(:new).with('/switch?api_key=123')
19
+
20
+ @webhook.notify('msg', Time.now, 'prio', 'cat', 'host')
21
+ end
22
+ end