tighten up Hub and add comments
[god.git] / test / test_god.rb
blobd167ea511d97f019ecb30ce798584fba25649b91
1 require File.dirname(__FILE__) + '/helper'
3 class TestGod < Test::Unit::TestCase
4   def setup
5     God::Socket.stubs(:new).returns(true)
6     God.stubs(:setup).returns(true)
7     God.stubs(:validater).returns(true)
8     God.reset
9   end
10   
11   def teardown
12     Timer.get.timer.kill
13   end
14   
15   # applog
16   
17   def test_applog
18     LOG.expects(:log).with(nil, :debug, 'foo')
19     applog(nil, :debug, 'foo')
20   end
21   
22   # internal_init
23   
24   def test_init_should_initialize_watches_to_empty_array
25     God.internal_init { }
26     assert_equal Hash.new, God.watches
27   end
28   
29   # init
30   
31   def test_pid_file_directory_should_abort_if_called_after_watch
32     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
33     
34     assert_abort do
35       God.pid_file_directory = 'foo'
36     end
37   end
38   
39   # pid_file_directory
40   
41   def test_pid_file_directory_should_return_default_if_not_set_explicitly
42     God.internal_init
43     assert_equal '/var/run/god', God.pid_file_directory
44   end
45   
46   def test_pid_file_directory_equals_should_set
47     God.pid_file_directory = '/foo'
48     God.internal_init
49     assert_equal '/foo', God.pid_file_directory
50   end
51   
52   # watch
53   
54   def test_watch_should_get_stored
55     watch = nil
56     God.watch do |w|
57       w.name = 'foo'
58       w.start = 'bar'
59       watch = w
60     end
61     
62     assert_equal 1, God.watches.size
63     assert_equal watch, God.watches.values.first
64     
65     assert_equal 0, God.groups.size
66   end
67   
68   def test_watch_should_get_stored_in_pending_watches
69     watch = nil
70     God.watch do |w|
71       w.name = 'foo'
72       w.start = 'bar'
73       watch = w
74     end
75     
76     assert_equal 1, God.pending_watches.size
77     assert_equal watch, God.pending_watches.first
78   end
79   
80   def test_watch_should_register_processes
81     assert_nil God.registry['foo']
82     God.watch do |w|
83       w.name = 'foo'
84       w.start = 'bar'
85     end
86     assert_kind_of God::Process, God.registry['foo']
87   end
88   
89   def test_watch_should_get_stored_by_group
90     a = nil
91     
92     God.watch do |w|
93       a = w
94       w.name = 'foo'
95       w.start = 'bar'
96       w.group = 'test'
97     end
98     
99     assert_equal({'test' => [a]}, God.groups)
100   end
101   
102   def test_watches_should_get_stored_by_group
103     a = nil
104     b = nil
105     
106     God.watch do |w|
107       a = w
108       w.name = 'foo'
109       w.start = 'bar'
110       w.group = 'test'
111     end
112     
113     God.watch do |w|
114       b = w
115       w.name = 'bar'
116       w.start = 'baz'
117       w.group = 'test'
118     end
119     
120     assert_equal({'test' => [a, b]}, God.groups)
121   end
122       
123   def test_watch_should_allow_multiple_watches
124     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
125     
126     assert_nothing_raised do
127       God.watch { |w| w.name = 'bar'; w.start = 'bar' }
128     end
129   end
130   
131   def test_watch_should_disallow_duplicate_watch_names
132     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
133     
134     assert_abort do
135       God.watch { |w| w.name = 'foo'; w.start = 'bar' }
136     end
137   end
138   
139   def test_watch_should_disallow_identical_watch_and_group_names
140     God.watch { |w| w.name = 'foo'; w.group = 'bar'; w.start = 'bar' }
141     
142     assert_abort do
143       God.watch { |w| w.name = 'bar'; w.start = 'bar' }
144     end
145   end
146   
147   def test_watch_should_disallow_identical_watch_and_group_names_other_way
148     God.watch { |w| w.name = 'bar'; w.start = 'bar' }
149     
150     assert_abort do
151       God.watch { |w| w.name = 'foo'; w.group = 'bar'; w.start = 'bar' }
152     end
153   end
154   
155   def test_watch_should_unwatch_new_watch_if_running_and_duplicate_watch
156     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
157     God.running = true
158     
159     assert_nothing_raised do
160       no_stdout do
161         God.watch { |w| w.name = 'foo'; w.start = 'bar' }
162       end
163     end
164   end
165   
166   # unwatch
167   
168   def test_unwatch_should_unmonitor_watch
169     God.watch { |w| w.name = 'bar'; w.start = 'bar' }
170     w = God.watches['bar']
171     w.state = :up
172     w.expects(:unmonitor)
173     no_stdout do
174       God.unwatch(w)
175     end
176   end
177   
178   def test_unwatch_should_unregister_watch
179     God.watch { |w| w.name = 'bar'; w.start = 'bar' }
180     w = God.watches['bar']
181     w.expects(:unregister!)
182     no_stdout do
183       God.unwatch(w)
184     end
185   end
186   
187   def test_unwatch_should_remove_same_name_watches
188     God.watch { |w| w.name = 'bar'; w.start = 'bar' }
189     w = God.watches['bar']
190     no_stdout do
191       God.unwatch(w)
192     end
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     no_stdout do
204       God.unwatch(w)
205     end
206     assert !God.groups[w.group].include?(w)
207   end
208   
209   # contact
210   
211   def test_contact_should_ensure_init_is_called
212     God.contact(:fake_contact) { |c| c.name = 'tom' }
213     assert God.inited
214   end
215   
216   def test_contact_should_abort_on_invalid_contact_kind
217     assert_abort do
218       God.contact(:foo) { |c| c.name = 'tom' }
219     end
220   end
221   
222   def test_contact_should_create_and_store_contact
223     contact = nil
224     God.contact(:fake_contact) { |c| c.name = 'tom'; contact = c }
225     assert [contact], God.contacts
226   end
227   
228   def test_contact_should_add_to_group
229     God.contact(:fake_contact) { |c| c.name = 'tom'; c.group = 'devs' }
230     God.contact(:fake_contact) { |c| c.name = 'chris'; c.group = 'devs' }
231     assert 2, God.contact_groups.size
232   end
233   
234   def test_contact_should_abort_on_no_name
235     no_stdout do
236       assert_abort do
237         God.contact(:fake_contact) { |c| }
238       end
239     end
240   end
241   
242   def test_contact_should_abort_on_duplicate_contact_name
243     God.contact(:fake_contact) { |c| c.name = 'tom' }
244     assert_abort do
245       God.contact(:fake_contact) { |c| c.name = 'tom' }
246     end
247   end
248   
249   def test_contact_should_abort_on_contact_with_same_name_as_group
250     God.contact(:fake_contact) { |c| c.name = 'tom'; c.group = 'devs' }
251     assert_abort do
252       God.contact(:fake_contact) { |c| c.name = 'devs' }
253     end
254   end
255   
256   def test_contact_should_abort_on_contact_with_same_group_as_name
257     God.contact(:fake_contact) { |c| c.name = 'tom' }
258     assert_abort do
259       God.contact(:fake_contact) { |c| c.name = 'chris'; c.group = 'tom' }
260     end
261   end
262   
263   def test_contact_should_abort_if_contact_is_invalid
264     assert_abort do
265       God.contact(:fake_contact) do |c|
266         c.name = 'tom'
267         c.stubs(:valid?).returns(false)
268       end
269     end
270   end
271   
272   # control
273   
274   def test_control_should_monitor_on_start
275     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
276     
277     w = God.watches['foo']
278     w.expects(:monitor)
279     God.control('foo', 'start')
280   end
281   
282   def test_control_should_move_to_restart_on_restart
283     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
284     
285     w = God.watches['foo']
286     w.expects(:move).with(:restart)
287     God.control('foo', 'restart')
288   end
289   
290   def test_control_should_unmonitor_and_stop_on_stop
291     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
292     
293     w = God.watches['foo']
294     w.state = :up
295     w.expects(:unmonitor).returns(w)
296     w.expects(:action).with(:stop)
297     God.control('foo', 'stop')
298   end
299   
300   def test_control_should_unmonitor_on_unmonitor
301     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
302     
303     w = God.watches['foo']
304     w.state = :up
305     w.expects(:unmonitor).returns(w)
306     God.control('foo', 'unmonitor')
307   end
308   
309   def test_control_should_unwatch_on_remove
310     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
311     
312     w = God.watches['foo']
313     w.state = :up
314     God.expects(:unwatch)
315     God.control('foo', 'remove')
316   end
317   
318   def test_control_should_raise_on_invalid_command
319     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
320     
321     assert_raise InvalidCommandError do
322       God.control('foo', 'invalid')
323     end
324   end
325   
326   def test_control_should_operate_on_each_watch_in_group
327     God.watch do |w|
328       w.name = 'foo1'
329       w.start = 'go'
330       w.group = 'bar'
331     end
332     
333     God.watch do |w|
334       w.name = 'foo2'
335       w.start = 'go'
336       w.group = 'bar'
337     end
338     
339     God.watches['foo1'].expects(:monitor)
340     God.watches['foo2'].expects(:monitor)
341     
342     God.control('bar', 'start')
343   end
344   
345   # stop_all
346   
347   # terminate
348   
349   def test_terminate_should_exit
350     God.pid = nil
351     FileUtils.expects(:rm_f).never
352     God.expects(:exit!)
353     God.terminate
354   end
355   
356   def test_terminate_should_delete_pid
357     God.pid = '/foo/bar'
358     FileUtils.expects(:rm_f).with("/foo/bar")
359     God.expects(:exit!)
360     God.terminate
361   end
362   
363   # status
364   
365   def test_status_should_show_state
366     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
367     
368     w = God.watches['foo']
369     w.state = :up
370     assert_equal({'foo' => {:state => :up}}, God.status)
371   end
372   
373   def test_status_should_show_unmonitored_for_nil_state
374     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
375     
376     w = God.watches['foo']
377     assert_equal({'foo' => {:state => :unmonitored}}, God.status)
378   end
379   
380   # running_log
381   
382   def test_running_log_should_call_watch_log_since_on_main_log
383     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
384     t = Time.now
385     LOG.expects(:watch_log_since).with('foo', t)
386     God.running_log('foo', t)
387   end
388   
389   def test_running_log_should_raise_on_unknown_watch
390     God.internal_init
391     assert_raise(NoSuchWatchError) do
392       God.running_log('foo', Time.now)
393     end
394   end
395   
396   # running_load
397   
398   def test_running_load_should_eval_code
399     code = <<-EOF
400       God.watch do |w|
401         w.name = 'foo'
402         w.start = 'go'
403       end
404     EOF
405     
406     no_stdout do
407       God.running_load(code, '/foo/bar.god')
408     end
409     
410     assert_equal 1, God.watches.size
411   end
412   
413   def test_running_load_should_monitor_new_watches
414     code = <<-EOF
415       God.watch do |w|
416         w.name = 'foo'
417         w.start = 'go'
418       end
419     EOF
420     
421     Watch.any_instance.expects(:monitor)
422     no_stdout do
423       God.running_load(code, '/foo/bar.god')
424     end
425   end
426   
427   def test_running_load_should_not_monitor_new_watches_with_autostart_false
428     code = <<-EOF
429       God.watch do |w|
430         w.name = 'foo'
431         w.start = 'go'
432         w.autostart = false
433       end
434     EOF
435     
436     Watch.any_instance.expects(:monitor).never
437     no_stdout do
438       God.running_load(code, '/foo/bar.god')
439     end
440   end
441   
442   def test_running_load_should_return_array_of_affected_watches
443     code = <<-EOF
444       God.watch do |w|
445         w.name = 'foo'
446         w.start = 'go'
447       end
448     EOF
449     
450     w = nil
451     no_stdout do
452       w, e = *God.running_load(code, '/foo/bar.god')
453     end
454     assert_equal 1, w.size
455     assert_equal 'foo', w.first
456   end
457   
458   def test_running_load_should_clear_pending_watches
459     code = <<-EOF
460       God.watch do |w|
461         w.name = 'foo'
462         w.start = 'go'
463       end
464     EOF
465     
466     no_stdout do
467       God.running_load(code, '/foo/bar.god')
468     end
469     assert_equal 0, God.pending_watches.size
470   end
471   
472   # load
473   
474   def test_load_should_collect_and_load_globbed_path
475     Dir.expects(:[]).with('/path/to/*.thing').returns(['a', 'b'])
476     Kernel.expects(:load).with('a').once
477     Kernel.expects(:load).with('b').once
478     God.load('/path/to/*.thing')
479   end
480   
481   # start
482   
483   def test_start_should_kick_off_a_server_instance
484     God::Socket.expects(:new).returns(true)
485     God.start
486   end
487     
488   def test_start_should_start_event_handler
489     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
490     Timer.any_instance.expects(:join)
491     EventHandler.expects(:start).once
492     no_stdout do
493       God.start
494     end
495   end
496   
497   def test_start_should_begin_monitoring_autostart_watches
498     God.watch do |w|
499       w.name = 'foo'
500       w.start = 'go'
501     end
502     
503     Timer.any_instance.expects(:join)
504     Watch.any_instance.expects(:monitor).once
505     God.start
506   end
507   
508   def test_start_should_not_begin_monitoring_non_autostart_watches
509     God.watch do |w|
510       w.name = 'foo'
511       w.start = 'go'
512       w.autostart = false
513     end
514     
515     Timer.any_instance.expects(:join)
516     Watch.any_instance.expects(:monitor).never
517     God.start
518   end
519   
520   def test_start_should_get_and_join_timer
521     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
522     Timer.any_instance.expects(:join)
523     no_stdout do
524       God.start
525     end
526   end
527   
528   # at_exit
529   
530   def test_at_exit_should_call_start
531     God.expects(:start).once
532     God.at_exit
533   end
534   
535   # pattern_match
536   
537   def test_pattern_match
538     list = %w{ mongrel-3000 mongrel-3001 fuzed fuzed2 apache mysql}
539     
540     assert_equal %w{ mongrel-3000 }, God.pattern_match('m3000', list)
541     assert_equal %w{ mongrel-3001 }, God.pattern_match('m31', list)
542     assert_equal %w{ fuzed fuzed2 }, God.pattern_match('fu', list)
543     assert_equal %w{ mysql }, God.pattern_match('sql', list)
544   end
548 class TestGodOther < Test::Unit::TestCase
549   def setup
550     God::Socket.stubs(:new).returns(true)
551     God.internal_init
552     God.reset
553   end
554   
555   def teardown
556     Timer.get.timer.kill
557   end
558   
559   # setup
560   
561   def test_setup_should_create_pid_file_directory_if_it_doesnt_exist
562     God.expects(:test).returns(false)
563     FileUtils.expects(:mkdir_p).with(God.pid_file_directory)
564     God.setup
565   end
566   
567   def test_setup_should_raise_if_no_permissions_to_create_pid_file_directory
568     God.expects(:test).returns(false)
569     FileUtils.expects(:mkdir_p).raises(Errno::EACCES)
570     
571     assert_abort do
572       God.setup
573     end
574   end
575   
576   # validate
577     
578   def test_validate_should_abort_if_pid_file_directory_is_unwriteable
579     God.expects(:test).returns(false)
580     assert_abort do
581       God.validater
582     end
583   end
584   
585   def test_validate_should_not_abort_if_pid_file_directory_is_writeable
586     God.expects(:test).returns(true)
587     assert_nothing_raised do
588       God.validater
589     end
590   end