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
data/test/test_god.rb ADDED
@@ -0,0 +1,710 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+ class TestGod < MiniTest::Test
3
+ def setup
4
+ God::Socket.stubs(:new).returns(true)
5
+ God.stubs(:setup).returns(true)
6
+ God.stubs(:validater).returns(true)
7
+ God.reset
8
+ God.pid_file_directory = '/var/run/god'
9
+ end
10
+
11
+ def teardown
12
+ God.main && God.main.kill
13
+ if God.watches
14
+ God.watches.each do |k, w|
15
+ w.driver.thread.kill
16
+ end
17
+ end
18
+ God.reset
19
+ #Some of the tests in this file intentionally set pid_file_directory to an invalid value
20
+ #This can cause a later test failure since God will call abort if pid_file_directory is not writable
21
+ God.pid_file_directory = '~/.god/pids'
22
+ end
23
+
24
+ # applog
25
+
26
+ def test_applog
27
+ LOG.expects(:log).with(nil, :debug, 'foo')
28
+ applog(nil, :debug, 'foo')
29
+ end
30
+
31
+ # internal_init
32
+
33
+ def test_init_should_initialize_watches_to_empty_array
34
+ God.internal_init { }
35
+ assert_equal Hash.new, God.watches
36
+ end
37
+
38
+ # # init
39
+
40
+ def test_pid_file_directory_should_abort_if_called_after_watch
41
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
42
+ assert_abort do
43
+ God.pid_file_directory = 'foo'
44
+ end
45
+ end
46
+
47
+ # pid_file_directory
48
+
49
+ def test_pid_file_directory_should_return_default_if_not_set_explicitly
50
+ God.internal_init
51
+ assert_equal '/var/run/god', God.pid_file_directory
52
+ end
53
+
54
+ def test_pid_file_directory_equals_should_set
55
+ God.pid_file_directory = '/foo'
56
+ God.internal_init
57
+ assert_equal '/foo', God.pid_file_directory
58
+ end
59
+
60
+ # watch
61
+
62
+ def test_watch_should_get_stored
63
+ watch = nil
64
+ God.watch do |w|
65
+ w.name = 'foo'
66
+ w.start = 'bar'
67
+ watch = w
68
+ end
69
+
70
+ assert_equal 1, God.watches.size
71
+ assert_equal watch, God.watches.values.first
72
+
73
+ assert_equal 0, God.groups.size
74
+ end
75
+
76
+ def test_watch_should_get_stored_in_pending_watches
77
+ watch = nil
78
+ God.watch do |w|
79
+ w.name = 'foo'
80
+ w.start = 'bar'
81
+ watch = w
82
+ end
83
+
84
+ assert_equal 1, God.pending_watches.size
85
+ assert_equal watch, God.pending_watches.first
86
+ end
87
+
88
+ def test_watch_should_register_processes
89
+ assert_nil God.registry['foo']
90
+ God.watch do |w|
91
+ w.name = 'foo'
92
+ w.start = 'bar'
93
+ end
94
+ assert_kind_of God::Process, God.registry['foo']
95
+ end
96
+
97
+ def test_watch_should_get_stored_by_group
98
+ a = nil
99
+
100
+ God.watch do |w|
101
+ a = w
102
+ w.name = 'foo'
103
+ w.start = 'bar'
104
+ w.group = 'test'
105
+ end
106
+
107
+ assert_equal({'test' => [a]}, God.groups)
108
+ end
109
+
110
+ def test_watches_should_get_stored_by_group
111
+ a = nil
112
+ b = nil
113
+
114
+ God.watch do |w|
115
+ a = w
116
+ w.name = 'foo'
117
+ w.start = 'bar'
118
+ w.group = 'test'
119
+ end
120
+
121
+ God.watch do |w|
122
+ b = w
123
+ w.name = 'bar'
124
+ w.start = 'baz'
125
+ w.group = 'test'
126
+ end
127
+
128
+ assert_equal({'test' => [a, b]}, God.groups)
129
+ end
130
+
131
+ def test_watch_should_allow_multiple_watches
132
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
133
+
134
+ assert_nothing_raised do
135
+ God.watch { |w| w.name = 'bar'; w.start = 'bar' }
136
+ end
137
+ end
138
+
139
+ def test_watch_should_disallow_duplicate_watch_names
140
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
141
+
142
+ assert_abort do
143
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
144
+ end
145
+ end
146
+
147
+ def test_watch_should_disallow_identical_watch_and_group_names
148
+ God.watch { |w| w.name = 'foo'; w.group = 'bar'; w.start = 'bar' }
149
+
150
+ assert_abort do
151
+ God.watch { |w| w.name = 'bar'; w.start = 'bar' }
152
+ end
153
+ end
154
+
155
+ def test_watch_should_disallow_identical_watch_and_group_names_other_way
156
+ God.watch { |w| w.name = 'bar'; w.start = 'bar' }
157
+
158
+ assert_abort do
159
+ God.watch { |w| w.name = 'foo'; w.group = 'bar'; w.start = 'bar' }
160
+ end
161
+ end
162
+
163
+ def test_watch_should_unwatch_new_watch_if_running_and_duplicate_watch
164
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
165
+ God.running = true
166
+
167
+ assert_nothing_raised do
168
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
169
+ end
170
+ end
171
+
172
+ # unwatch
173
+
174
+ def test_unwatch_should_unmonitor_watch
175
+ God.watch { |w| w.name = 'bar'; w.start = 'bar' }
176
+ w = God.watches['bar']
177
+ w.state = :up
178
+ w.expects(:unmonitor)
179
+ God.unwatch(w)
180
+ end
181
+
182
+ def test_unwatch_should_unregister_watch
183
+ God.watch { |w| w.name = 'bar'; w.start = 'bar' }
184
+ w = God.watches['bar']
185
+ w.expects(:unregister!)
186
+ God.unwatch(w)
187
+ end
188
+
189
+ def test_unwatch_should_remove_same_name_watches
190
+ God.watch { |w| w.name = 'bar'; w.start = 'bar' }
191
+ w = God.watches['bar']
192
+ God.unwatch(w)
193
+ assert_equal 0, God.watches.size
194
+ end
195
+
196
+ def test_unwatch_should_remove_from_group
197
+ God.watch do |w|
198
+ w.name = 'bar'
199
+ w.start = 'baz'
200
+ w.group = 'test'
201
+ end
202
+ w = God.watches['bar']
203
+ God.unwatch(w)
204
+ assert !God.groups[w.group].include?(w)
205
+ end
206
+
207
+ # contact
208
+
209
+ def test_contact_should_ensure_init_is_called
210
+ God.contact(:fake_contact) { |c| c.name = 'tom' }
211
+ assert God.inited
212
+ end
213
+
214
+ def test_contact_should_abort_on_invalid_contact_kind
215
+ assert_abort do
216
+ God.contact(:foo) { |c| c.name = 'tom' }
217
+ end
218
+ end
219
+
220
+ def test_contact_should_create_and_store_contact
221
+ contact = nil
222
+ God.contact(:fake_contact) { |c| c.name = 'tom'; contact = c }
223
+ assert_equal({"tom" => contact}, God.contacts)
224
+ end
225
+
226
+ def test_contact_should_add_to_group
227
+ God.contact(:fake_contact) { |c| c.name = 'tom'; c.group = 'devs' }
228
+ God.contact(:fake_contact) { |c| c.name = 'chris'; c.group = 'devs' }
229
+ assert_equal 2, God.contacts.size
230
+ assert_equal 1, God.contact_groups.size
231
+ end
232
+
233
+ def test_contact_should_abort_on_no_name
234
+ assert_abort do
235
+ God.contact(:fake_contact) { |c| }
236
+ end
237
+ end
238
+
239
+ def test_contact_should_abort_on_duplicate_contact_name
240
+ God.contact(:fake_contact) { |c| c.name = 'tom' }
241
+ assert_nothing_raised do
242
+ God.contact(:fake_contact) { |c| c.name = 'tom' }
243
+ end
244
+ end
245
+
246
+ def test_contact_should_abort_on_contact_with_same_name_as_group
247
+ God.contact(:fake_contact) { |c| c.name = 'tom'; c.group = 'devs' }
248
+ assert_nothing_raised do
249
+ God.contact(:fake_contact) { |c| c.name = 'devs' }
250
+ end
251
+ end
252
+
253
+ def test_contact_should_abort_on_contact_with_same_group_as_name
254
+ God.contact(:fake_contact) { |c| c.name = 'tom' }
255
+ assert_abort do
256
+ God.contact(:fake_contact) { |c| c.name = 'chris'; c.group = 'tom' }
257
+ end
258
+ end
259
+
260
+ def test_contact_should_abort_if_contact_is_invalid
261
+ assert_abort do
262
+ God.contact(:fake_contact) do |c|
263
+ c.name = 'tom'
264
+ c.stubs(:valid?).returns(false)
265
+ end
266
+ end
267
+ end
268
+
269
+ # control
270
+
271
+ def test_control_should_monitor_on_start
272
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
273
+
274
+ w = God.watches['foo']
275
+ w.expects(:monitor)
276
+ God.control('foo', 'start')
277
+ end
278
+
279
+ def test_control_should_move_to_restart_on_restart
280
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
281
+
282
+ w = God.watches['foo']
283
+ w.expects(:move).with(:restart)
284
+ God.control('foo', 'restart')
285
+ end
286
+
287
+ def test_control_should_unmonitor_and_stop_on_stop
288
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
289
+
290
+ w = God.watches['foo']
291
+ w.state = :up
292
+ w.expects(:unmonitor).returns(w)
293
+ w.expects(:action).with(:stop)
294
+ God.control('foo', 'stop')
295
+ end
296
+
297
+ def test_control_should_unmonitor_on_unmonitor
298
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
299
+
300
+ w = God.watches['foo']
301
+ w.state = :up
302
+ w.expects(:unmonitor).returns(w)
303
+ God.control('foo', 'unmonitor')
304
+ end
305
+
306
+ def test_control_should_unwatch_on_remove
307
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
308
+
309
+ w = God.watches['foo']
310
+ w.state = :up
311
+ God.expects(:unwatch)
312
+ God.control('foo', 'remove')
313
+ end
314
+
315
+ def test_control_should_raise_on_invalid_command
316
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
317
+
318
+ assert_raises InvalidCommandError do
319
+ God.control('foo', 'invalid')
320
+ end
321
+ end
322
+
323
+ def test_control_should_operate_on_each_watch_in_group
324
+ God.watch do |w|
325
+ w.name = 'foo1'
326
+ w.start = 'go'
327
+ w.group = 'bar'
328
+ end
329
+
330
+ God.watch do |w|
331
+ w.name = 'foo2'
332
+ w.start = 'go'
333
+ w.group = 'bar'
334
+ end
335
+
336
+ God.watch do |w|
337
+ w.name = 'bar1'
338
+ w.start = 'go'
339
+ w.group = 'foo'
340
+ end
341
+
342
+ God.watches['foo1'].expects(:monitor)
343
+ God.watches['foo2'].expects(:monitor)
344
+ God.watches['bar1'].expects(:monitor).never
345
+
346
+ God.control('bar', 'start')
347
+ end
348
+
349
+ def test_control_should_operate_on_all_watches_on_nil
350
+ God.watch do |w|
351
+ w.name = 'foo1'
352
+ w.start = 'go'
353
+ w.group = 'foo'
354
+ end
355
+
356
+ God.watch do |w|
357
+ w.name = 'foo2'
358
+ w.start = 'go'
359
+ w.group = 'foo'
360
+ end
361
+
362
+ God.watch do |w|
363
+ w.name = 'bar1'
364
+ w.start = 'go'
365
+ w.group = 'bar'
366
+ end
367
+
368
+ God.watches['foo1'].expects(:monitor)
369
+ God.watches['foo2'].expects(:monitor)
370
+ God.watches['bar1'].expects(:monitor)
371
+
372
+ God.control(nil, 'start')
373
+ end
374
+
375
+ def test_control_should_operate_on_all_watches_on_empty_string
376
+ God.watch do |w|
377
+ w.name = 'foo1'
378
+ w.start = 'go'
379
+ w.group = 'foo'
380
+ end
381
+
382
+ God.watch do |w|
383
+ w.name = 'foo2'
384
+ w.start = 'go'
385
+ w.group = 'foo'
386
+ end
387
+
388
+ God.watch do |w|
389
+ w.name = 'bar1'
390
+ w.start = 'go'
391
+ w.group = 'bar'
392
+ end
393
+
394
+ God.watches['foo1'].expects(:monitor)
395
+ God.watches['foo2'].expects(:monitor)
396
+ God.watches['bar1'].expects(:monitor)
397
+
398
+ God.control('', 'start')
399
+ end
400
+
401
+
402
+ # stop_all
403
+
404
+ # terminate
405
+
406
+ def test_terminate_should_exit
407
+ God.pid = nil
408
+ FileUtils.expects(:rm_f).never
409
+ God.expects(:exit!)
410
+ God.terminate
411
+ end
412
+
413
+ def test_terminate_should_delete_pid
414
+ God.pid = '/foo/bar'
415
+ FileUtils.expects(:rm_f).with("/foo/bar")
416
+ God.expects(:exit!)
417
+ God.terminate
418
+ end
419
+
420
+ # status
421
+
422
+ def test_status_should_show_state
423
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
424
+
425
+ w = God.watches['foo']
426
+ w.state = :up
427
+ assert_equal({'foo' => {:state => :up, :group => nil}}, God.status)
428
+ end
429
+
430
+ def test_status_should_show_state_with_group
431
+ God.watch { |w| w.name = 'foo'; w.start = 'bar'; w.group = 'g' }
432
+
433
+ w = God.watches['foo']
434
+ w.state = :up
435
+ assert_equal({'foo' => {:state => :up, :group => 'g'}}, God.status)
436
+ end
437
+
438
+ def test_status_should_show_unmonitored_for_nil_state
439
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
440
+
441
+ w = God.watches['foo']
442
+ assert_equal({'foo' => {:state => :unmonitored, :group => nil}}, God.status)
443
+ end
444
+
445
+ # running_log
446
+
447
+ def test_running_log_should_call_watch_log_since_on_main_log
448
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
449
+ t = Time.now
450
+ LOG.expects(:watch_log_since).with('foo', t)
451
+ God.running_log('foo', t)
452
+ end
453
+
454
+ def test_running_log_should_raise_on_unknown_watch
455
+ God.internal_init
456
+ assert_raises(NoSuchWatchError) do
457
+ God.running_log('foo', Time.now)
458
+ end
459
+ end
460
+
461
+ # running_load
462
+
463
+ def test_running_load_should_eval_code
464
+ code = <<-EOF
465
+ God.watch do |w|
466
+ w.name = 'foo'
467
+ w.start = 'go'
468
+ end
469
+ EOF
470
+
471
+ God.running_load(code, '/foo/bar.god')
472
+
473
+ assert_equal 1, God.watches.size
474
+ end
475
+
476
+ def test_running_load_should_monitor_new_watches
477
+ code = <<-EOF
478
+ God.watch do |w|
479
+ w.name = 'foo'
480
+ w.start = 'go'
481
+ end
482
+ EOF
483
+
484
+ Watch.any_instance.expects(:monitor)
485
+ God.running_load(code, '/foo/bar.god')
486
+ end
487
+
488
+ def test_running_load_should_not_monitor_new_watches_with_autostart_false
489
+ code = <<-EOF
490
+ God.watch do |w|
491
+ w.name = 'foo'
492
+ w.start = 'go'
493
+ w.autostart = false
494
+ end
495
+ EOF
496
+
497
+ Watch.any_instance.expects(:monitor).never
498
+ God.running_load(code, '/foo/bar.god')
499
+ end
500
+
501
+ def test_running_load_should_return_array_of_affected_watches
502
+ code = <<-EOF
503
+ God.watch do |w|
504
+ w.name = 'foo'
505
+ w.start = 'go'
506
+ end
507
+ EOF
508
+
509
+ w = nil
510
+ w, e = *God.running_load(code, '/foo/bar.god')
511
+ assert_equal 1, w.size
512
+ assert_equal 'foo', w.first
513
+ end
514
+
515
+ def test_running_load_should_clear_pending_watches
516
+ code = <<-EOF
517
+ God.watch do |w|
518
+ w.name = 'foo'
519
+ w.start = 'go'
520
+ end
521
+ EOF
522
+
523
+ God.running_load(code, '/foo/bar.god')
524
+ assert_equal 0, God.pending_watches.size
525
+ end
526
+
527
+ def test_running_load_with_stop
528
+ code_one = <<-EOF
529
+ God.watch do |w|
530
+ w.name = 'foo'
531
+ w.start = 'go'
532
+ end
533
+ EOF
534
+
535
+ code_two = <<-EOF
536
+ God.watch do |w|
537
+ w.name = 'bar'
538
+ w.start = 'go'
539
+ end
540
+ EOF
541
+
542
+ a, e, r = *God.running_load(code_one, '/foo/one.god', 'stop')
543
+
544
+ assert_equal 1, a.size
545
+ assert_equal 0, r.size
546
+
547
+ a, e, r = *God.running_load(code_two, '/foo/two.god', 'stop')
548
+
549
+ assert_equal 1, a.size
550
+ assert_equal 1, r.size
551
+ end
552
+
553
+ def test_running_load_with_remove
554
+ code_one = <<-EOF
555
+ God.watch do |w|
556
+ w.name = 'foo'
557
+ w.start = 'go'
558
+ end
559
+ EOF
560
+
561
+ code_two = <<-EOF
562
+ God.watch do |w|
563
+ w.name = 'bar'
564
+ w.start = 'go'
565
+ end
566
+ EOF
567
+
568
+ a, e, r = *God.running_load(code_one, '/foo/one.god', 'remove')
569
+
570
+ assert_equal 1, a.size
571
+ assert_equal 0, r.size
572
+
573
+ a, e, r = *God.running_load(code_two, '/foo/two.god', 'remove')
574
+
575
+ assert_equal 1, a.size
576
+ assert_equal 1, r.size
577
+ end
578
+
579
+ def test_running_load_with_leave
580
+ code_one = <<-EOF
581
+ God.watch do |w|
582
+ w.name = 'foo'
583
+ w.start = 'go'
584
+ end
585
+ EOF
586
+
587
+ code_two = <<-EOF
588
+ God.watch do |w|
589
+ w.name = 'bar'
590
+ w.start = 'go'
591
+ end
592
+ EOF
593
+
594
+ a, e, r = *God.running_load(code_one, '/foo/one.god', 'leave')
595
+
596
+ assert_equal 1, a.size
597
+ assert_equal 0, r.size
598
+
599
+ a, e, r = *God.running_load(code_two, '/foo/two.god', 'leave')
600
+
601
+ assert_equal 1, a.size
602
+ assert_equal 0, r.size
603
+ end
604
+
605
+ # load
606
+
607
+ def test_load_should_collect_and_load_globbed_path
608
+ Dir.expects(:[]).with('/path/to/*.thing').returns(['a', 'b'])
609
+ Kernel.expects(:load).with('a').once
610
+ Kernel.expects(:load).with('b').once
611
+ God.load('/path/to/*.thing')
612
+ end
613
+
614
+ # start
615
+
616
+ def test_start_should_kick_off_a_server_instance
617
+ God::Socket.expects(:new).returns(true)
618
+ God.start
619
+ end
620
+
621
+ def test_start_should_begin_monitoring_autostart_watches
622
+ God.watch do |w|
623
+ w.name = 'foo'
624
+ w.start = 'go'
625
+ end
626
+
627
+ Watch.any_instance.expects(:monitor).once
628
+ God.start
629
+ end
630
+
631
+ def test_start_should_not_begin_monitoring_non_autostart_watches
632
+ God.watch do |w|
633
+ w.name = 'foo'
634
+ w.start = 'go'
635
+ w.autostart = false
636
+ end
637
+
638
+ Watch.any_instance.expects(:monitor).never
639
+ God.start
640
+ end
641
+
642
+ def test_start_should_get_and_join_timer
643
+ God.watch { |w| w.name = 'foo'; w.start = 'bar' }
644
+ God.start
645
+ end
646
+
647
+ # at_exit
648
+
649
+ def test_at_exit_should_call_start
650
+ God.expects(:start).once
651
+ God.at_exit
652
+ end
653
+
654
+ # pattern_match
655
+
656
+ def test_pattern_match
657
+ list = %w{ mongrel-3000 mongrel-3001 fuzed22 fuzed fuzed2 apache mysql}
658
+
659
+ assert_equal %w{ mongrel-3000 }, God.pattern_match('m3000', list)
660
+ assert_equal %w{ mongrel-3001 }, God.pattern_match('m31', list)
661
+ assert_equal %w{ fuzed fuzed2 fuzed22}, God.pattern_match('fu', list)
662
+ assert_equal %w{ mysql }, God.pattern_match('sql', list)
663
+ end
664
+ end
665
+
666
+
667
+ # class TestGodOther < Minitest::Test
668
+ # def setup
669
+ # God::Socket.stubs(:new).returns(true)
670
+ # God.internal_init
671
+ # God.reset
672
+ # end
673
+ #
674
+ # def teardown
675
+ # God.main && God.main.kill
676
+ # end
677
+ #
678
+ # # setup
679
+ #
680
+ # def test_setup_should_create_pid_file_directory_if_it_doesnt_exist
681
+ # God.expects(:test).returns(false)
682
+ # FileUtils.expects(:mkdir_p).with(God.pid_file_directory)
683
+ # God.setup
684
+ # end
685
+ #
686
+ # def test_setup_should_raise_if_no_permissions_to_create_pid_file_directory
687
+ # God.expects(:test).returns(false)
688
+ # FileUtils.expects(:mkdir_p).raises(Errno::EACCES)
689
+ #
690
+ # assert_abort do
691
+ # God.setup
692
+ # end
693
+ # end
694
+ #
695
+ # # validate
696
+ #
697
+ # def test_validate_should_abort_if_pid_file_directory_is_unwriteable
698
+ # God.expects(:test).returns(false)
699
+ # assert_abort do
700
+ # God.validater
701
+ # end
702
+ # end
703
+ #
704
+ # def test_validate_should_not_abort_if_pid_file_directory_is_writeable
705
+ # God.expects(:test).returns(true)
706
+ # assert_nothing_raised do
707
+ # God.validater
708
+ # end
709
+ # end
710
+ # end