up version to 0.6.0 and release
[god.git] / test / test_god.rb
blob3009ba95fad62ed9adcc46d4c7e07b5a1564cc1c
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     God.unwatch(w)
174   end
175   
176   def test_unwatch_should_unregister_watch
177     God.watch { |w| w.name = 'bar'; w.start = 'bar' }
178     w = God.watches['bar']
179     w.expects(:unregister!)
180     no_stdout do
181       God.unwatch(w)
182     end
183   end
184   
185   def test_unwatch_should_remove_same_name_watches
186     God.watch { |w| w.name = 'bar'; w.start = 'bar' }
187     w = God.watches['bar']
188     no_stdout do
189       God.unwatch(w)
190     end
191     assert_equal 0, God.watches.size
192   end
193   
194   def test_unwatch_should_remove_from_group
195     God.watch do |w|
196       w.name = 'bar'
197       w.start = 'baz'
198       w.group = 'test'
199     end
200     w = God.watches['bar']
201     no_stdout do
202       God.unwatch(w)
203     end
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 [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 2, God.contact_groups.size
230   end
231   
232   def test_contact_should_abort_on_no_name
233     no_stdout do
234       assert_abort do
235         God.contact(:fake_contact) { |c| }
236       end
237     end
238   end
239   
240   def test_contact_should_abort_on_duplicate_contact_name
241     God.contact(:fake_contact) { |c| c.name = 'tom' }
242     assert_abort do
243       God.contact(:fake_contact) { |c| c.name = 'tom' }
244     end
245   end
246   
247   def test_contact_should_abort_on_contact_with_same_name_as_group
248     God.contact(:fake_contact) { |c| c.name = 'tom'; c.group = 'devs' }
249     assert_abort do
250       God.contact(:fake_contact) { |c| c.name = 'devs' }
251     end
252   end
253   
254   def test_contact_should_abort_on_contact_with_same_group_as_name
255     God.contact(:fake_contact) { |c| c.name = 'tom' }
256     assert_abort do
257       God.contact(:fake_contact) { |c| c.name = 'chris'; c.group = 'tom' }
258     end
259   end
260   
261   def test_contact_should_abort_if_contact_is_invalid
262     assert_abort do
263       God.contact(:fake_contact) do |c|
264         c.name = 'tom'
265         c.stubs(:valid?).returns(false)
266       end
267     end
268   end
269   
270   # control
271   
272   def test_control_should_monitor_on_start
273     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
274     
275     w = God.watches['foo']
276     w.expects(:monitor)
277     God.control('foo', 'start')
278   end
279   
280   def test_control_should_move_to_restart_on_restart
281     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
282     
283     w = God.watches['foo']
284     w.expects(:move).with(:restart)
285     God.control('foo', 'restart')
286   end
287   
288   def test_control_should_unmonitor_and_stop_on_stop
289     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
290     
291     w = God.watches['foo']
292     w.state = :up
293     w.expects(:unmonitor).returns(w)
294     w.expects(:action).with(:stop)
295     God.control('foo', 'stop')
296   end
297   
298   def test_control_should_unmonitor_on_unmonitor
299     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
300     
301     w = God.watches['foo']
302     w.state = :up
303     w.expects(:unmonitor).returns(w)
304     God.control('foo', 'unmonitor')
305   end
306   
307   def test_control_should_unwatch_on_remove
308     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
309     
310     w = God.watches['foo']
311     w.state = :up
312     God.expects(:unwatch)
313     God.control('foo', 'remove')
314   end
315   
316   def test_control_should_raise_on_invalid_command
317     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
318     
319     assert_raise InvalidCommandError do
320       God.control('foo', 'invalid')
321     end
322   end
323   
324   def test_control_should_operate_on_each_watch_in_group
325     God.watch do |w|
326       w.name = 'foo1'
327       w.start = 'go'
328       w.group = 'bar'
329     end
330     
331     God.watch do |w|
332       w.name = 'foo2'
333       w.start = 'go'
334       w.group = 'bar'
335     end
336     
337     God.watches['foo1'].expects(:monitor)
338     God.watches['foo2'].expects(:monitor)
339     
340     God.control('bar', 'start')
341   end
342   
343   # stop_all
344   
345   # terminate
346   
347   def test_terminate_should_exit
348     God.pid = nil
349     FileUtils.expects(:rm_f).never
350     God.expects(:exit!)
351     God.terminate
352   end
353   
354   def test_terminate_should_delete_pid
355     God.pid = '/foo/bar'
356     FileUtils.expects(:rm_f).with("/foo/bar")
357     God.expects(:exit!)
358     God.terminate
359   end
360   
361   # status
362   
363   def test_status_should_show_state
364     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
365     
366     w = God.watches['foo']
367     w.state = :up
368     assert_equal({'foo' => {:state => :up}}, God.status)
369   end
370   
371   def test_status_should_show_unmonitored_for_nil_state
372     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
373     
374     w = God.watches['foo']
375     assert_equal({'foo' => {:state => :unmonitored}}, God.status)
376   end
377   
378   # running_log
379   
380   def test_running_log_should_call_watch_log_since_on_main_log
381     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
382     t = Time.now
383     LOG.expects(:watch_log_since).with('foo', t)
384     God.running_log('foo', t)
385   end
386   
387   def test_running_log_should_raise_on_unknown_watch
388     God.internal_init
389     assert_raise(NoSuchWatchError) do
390       God.running_log('foo', Time.now)
391     end
392   end
393   
394   # running_load
395   
396   def test_running_load_should_eval_code
397     code = <<-EOF
398       God.watch do |w|
399         w.name = 'foo'
400         w.start = 'go'
401       end
402     EOF
403     
404     no_stdout do
405       God.running_load(code, '/foo/bar.god')
406     end
407     
408     assert_equal 1, God.watches.size
409   end
410   
411   def test_running_load_should_monitor_new_watches
412     code = <<-EOF
413       God.watch do |w|
414         w.name = 'foo'
415         w.start = 'go'
416       end
417     EOF
418     
419     Watch.any_instance.expects(:monitor)
420     no_stdout do
421       God.running_load(code, '/foo/bar.god')
422     end
423   end
424   
425   def test_running_load_should_not_monitor_new_watches_with_autostart_false
426     code = <<-EOF
427       God.watch do |w|
428         w.name = 'foo'
429         w.start = 'go'
430         w.autostart = false
431       end
432     EOF
433     
434     Watch.any_instance.expects(:monitor).never
435     no_stdout do
436       God.running_load(code, '/foo/bar.god')
437     end
438   end
439   
440   def test_running_load_should_return_array_of_affected_watches
441     code = <<-EOF
442       God.watch do |w|
443         w.name = 'foo'
444         w.start = 'go'
445       end
446     EOF
447     
448     w = nil
449     no_stdout do
450       w, e = *God.running_load(code, '/foo/bar.god')
451     end
452     assert_equal 1, w.size
453     assert_equal 'foo', w.first
454   end
455   
456   def test_running_load_should_clear_pending_watches
457     code = <<-EOF
458       God.watch do |w|
459         w.name = 'foo'
460         w.start = 'go'
461       end
462     EOF
463     
464     no_stdout do
465       God.running_load(code, '/foo/bar.god')
466     end
467     assert_equal 0, God.pending_watches.size
468   end
469   
470   # load
471   
472   def test_load_should_collect_and_load_globbed_path
473     Dir.expects(:[]).with('/path/to/*.thing').returns(['a', 'b'])
474     Kernel.expects(:load).with('a').once
475     Kernel.expects(:load).with('b').once
476     God.load('/path/to/*.thing')
477   end
478   
479   # start
480   
481   def test_start_should_kick_off_a_server_instance
482     God::Socket.expects(:new).returns(true)
483     God.start
484   end
485     
486   def test_start_should_start_event_handler
487     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
488     Timer.any_instance.expects(:join)
489     EventHandler.expects(:start).once
490     no_stdout do
491       God.start
492     end
493   end
494   
495   def test_start_should_begin_monitoring_autostart_watches
496     God.watch do |w|
497       w.name = 'foo'
498       w.start = 'go'
499     end
500     
501     Timer.any_instance.expects(:join)
502     Watch.any_instance.expects(:monitor).once
503     God.start
504   end
505   
506   def test_start_should_not_begin_monitoring_non_autostart_watches
507     God.watch do |w|
508       w.name = 'foo'
509       w.start = 'go'
510       w.autostart = false
511     end
512     
513     Timer.any_instance.expects(:join)
514     Watch.any_instance.expects(:monitor).never
515     God.start
516   end
517   
518   def test_start_should_get_and_join_timer
519     God.watch { |w| w.name = 'foo'; w.start = 'bar' }
520     Timer.any_instance.expects(:join)
521     no_stdout do
522       God.start
523     end
524   end
525   
526   # at_exit
527   
528   def test_at_exit_should_call_start
529     God.expects(:start).once
530     God.at_exit
531   end
532   
533   # pattern_match
534   
535   def test_pattern_match
536     list = %w{ mongrel-3000 mongrel-3001 fuzed fuzed2 apache mysql}
537     
538     assert_equal %w{ mongrel-3000 }, God.pattern_match('m3000', list)
539     assert_equal %w{ mongrel-3001 }, God.pattern_match('m31', list)
540     assert_equal %w{ fuzed fuzed2 }, God.pattern_match('fu', list)
541     assert_equal %w{ mysql }, God.pattern_match('sql', list)
542   end
546 class TestGodOther < Test::Unit::TestCase
547   def setup
548     God::Socket.stubs(:new).returns(true)
549     God.internal_init
550     God.reset
551   end
552   
553   def teardown
554     Timer.get.timer.kill
555   end
556   
557   # setup
558   
559   def test_setup_should_create_pid_file_directory_if_it_doesnt_exist
560     God.expects(:test).returns(false)
561     FileUtils.expects(:mkdir_p).with(God.pid_file_directory)
562     God.setup
563   end
564   
565   def test_setup_should_raise_if_no_permissions_to_create_pid_file_directory
566     God.expects(:test).returns(false)
567     FileUtils.expects(:mkdir_p).raises(Errno::EACCES)
568     
569     assert_abort do
570       God.setup
571     end
572   end
573   
574   # validate
575     
576   def test_validate_should_abort_if_pid_file_directory_is_unwriteable
577     God.expects(:test).returns(false)
578     assert_abort do
579       God.validater
580     end
581   end
582   
583   def test_validate_should_not_abort_if_pid_file_directory_is_writeable
584     God.expects(:test).returns(true)
585     assert_nothing_raised do
586       God.validater
587     end
588   end