require File.dirname(__FILE__) + '/helper' class TestGod < Test::Unit::TestCase def setup God::Socket.stubs(:new).returns(true) God.stubs(:setup).returns(true) God.stubs(:validater).returns(true) Thread.any_instance.stubs(:join).returns(true) God.reset God.pid_file_directory = '/var/run/god' end def teardown God.main && God.main.kill if God.watches God.watches.each do |k, w| w.driver.thread.kill end end end # applog def test_applog LOG.expects(:log).with(nil, :debug, 'foo') applog(nil, :debug, 'foo') end # internal_init def test_init_should_initialize_watches_to_empty_array God.internal_init { } assert_equal Hash.new, God.watches end # init def test_pid_file_directory_should_abort_if_called_after_watch God.watch { |w| w.name = 'foo'; w.start = 'bar' } assert_abort do God.pid_file_directory = 'foo' end end # pid_file_directory def test_pid_file_directory_should_return_default_if_not_set_explicitly God.internal_init assert_equal '/var/run/god', God.pid_file_directory end def test_pid_file_directory_equals_should_set God.pid_file_directory = '/foo' God.internal_init assert_equal '/foo', God.pid_file_directory end # watch def test_watch_should_get_stored watch = nil God.watch do |w| w.name = 'foo' w.start = 'bar' watch = w end assert_equal 1, God.watches.size assert_equal watch, God.watches.values.first assert_equal 0, God.groups.size end def test_watch_should_get_stored_in_pending_watches watch = nil God.watch do |w| w.name = 'foo' w.start = 'bar' watch = w end assert_equal 1, God.pending_watches.size assert_equal watch, God.pending_watches.first end def test_watch_should_register_processes assert_nil God.registry['foo'] God.watch do |w| w.name = 'foo' w.start = 'bar' end assert_kind_of God::Process, God.registry['foo'] end def test_watch_should_get_stored_by_group a = nil God.watch do |w| a = w w.name = 'foo' w.start = 'bar' w.group = 'test' end assert_equal({'test' => [a]}, God.groups) end def test_watches_should_get_stored_by_group a = nil b = nil God.watch do |w| a = w w.name = 'foo' w.start = 'bar' w.group = 'test' end God.watch do |w| b = w w.name = 'bar' w.start = 'baz' w.group = 'test' end assert_equal({'test' => [a, b]}, God.groups) end def test_watch_should_allow_multiple_watches God.watch { |w| w.name = 'foo'; w.start = 'bar' } assert_nothing_raised do God.watch { |w| w.name = 'bar'; w.start = 'bar' } end end def test_watch_should_disallow_duplicate_watch_names God.watch { |w| w.name = 'foo'; w.start = 'bar' } assert_abort do God.watch { |w| w.name = 'foo'; w.start = 'bar' } end end def test_watch_should_disallow_identical_watch_and_group_names God.watch { |w| w.name = 'foo'; w.group = 'bar'; w.start = 'bar' } assert_abort do God.watch { |w| w.name = 'bar'; w.start = 'bar' } end end def test_watch_should_disallow_identical_watch_and_group_names_other_way God.watch { |w| w.name = 'bar'; w.start = 'bar' } assert_abort do God.watch { |w| w.name = 'foo'; w.group = 'bar'; w.start = 'bar' } end end def test_watch_should_unwatch_new_watch_if_running_and_duplicate_watch God.watch { |w| w.name = 'foo'; w.start = 'bar' } God.running = true assert_nothing_raised do no_stdout do God.watch { |w| w.name = 'foo'; w.start = 'bar' } end end end # unwatch def test_unwatch_should_unmonitor_watch God.watch { |w| w.name = 'bar'; w.start = 'bar' } w = God.watches['bar'] w.state = :up w.expects(:unmonitor) no_stdout do God.unwatch(w) end end def test_unwatch_should_unregister_watch God.watch { |w| w.name = 'bar'; w.start = 'bar' } w = God.watches['bar'] w.expects(:unregister!) no_stdout do God.unwatch(w) end end def test_unwatch_should_remove_same_name_watches God.watch { |w| w.name = 'bar'; w.start = 'bar' } w = God.watches['bar'] no_stdout do God.unwatch(w) end assert_equal 0, God.watches.size end def test_unwatch_should_remove_from_group God.watch do |w| w.name = 'bar' w.start = 'baz' w.group = 'test' end w = God.watches['bar'] no_stdout do God.unwatch(w) end assert !God.groups[w.group].include?(w) end # contact def test_contact_should_ensure_init_is_called God.contact(:fake_contact) { |c| c.name = 'tom' } assert God.inited end def test_contact_should_abort_on_invalid_contact_kind assert_abort do God.contact(:foo) { |c| c.name = 'tom' } end end def test_contact_should_create_and_store_contact contact = nil God.contact(:fake_contact) { |c| c.name = 'tom'; contact = c } assert [contact], God.contacts end def test_contact_should_add_to_group God.contact(:fake_contact) { |c| c.name = 'tom'; c.group = 'devs' } God.contact(:fake_contact) { |c| c.name = 'chris'; c.group = 'devs' } assert 2, God.contact_groups.size end def test_contact_should_abort_on_no_name no_stdout do assert_abort do God.contact(:fake_contact) { |c| } end end end def test_contact_should_abort_on_duplicate_contact_name God.contact(:fake_contact) { |c| c.name = 'tom' } no_stdout do assert_nothing_raised do God.contact(:fake_contact) { |c| c.name = 'tom' } end end end def test_contact_should_abort_on_contact_with_same_name_as_group God.contact(:fake_contact) { |c| c.name = 'tom'; c.group = 'devs' } no_stdout do assert_nothing_raised do God.contact(:fake_contact) { |c| c.name = 'devs' } end end end def test_contact_should_abort_on_contact_with_same_group_as_name God.contact(:fake_contact) { |c| c.name = 'tom' } assert_abort do God.contact(:fake_contact) { |c| c.name = 'chris'; c.group = 'tom' } end end def test_contact_should_abort_if_contact_is_invalid assert_abort do God.contact(:fake_contact) do |c| c.name = 'tom' c.stubs(:valid?).returns(false) end end end # control def test_control_should_monitor_on_start God.watch { |w| w.name = 'foo'; w.start = 'bar' } w = God.watches['foo'] w.expects(:monitor) God.control('foo', 'start') end def test_control_should_move_to_restart_on_restart God.watch { |w| w.name = 'foo'; w.start = 'bar' } w = God.watches['foo'] w.expects(:move).with(:restart) God.control('foo', 'restart') end def test_control_should_unmonitor_and_stop_on_stop God.watch { |w| w.name = 'foo'; w.start = 'bar' } w = God.watches['foo'] w.state = :up w.expects(:unmonitor).returns(w) w.expects(:action).with(:stop) God.control('foo', 'stop') end def test_control_should_unmonitor_on_unmonitor God.watch { |w| w.name = 'foo'; w.start = 'bar' } w = God.watches['foo'] w.state = :up w.expects(:unmonitor).returns(w) God.control('foo', 'unmonitor') end def test_control_should_unwatch_on_remove God.watch { |w| w.name = 'foo'; w.start = 'bar' } w = God.watches['foo'] w.state = :up God.expects(:unwatch) God.control('foo', 'remove') end def test_control_should_raise_on_invalid_command God.watch { |w| w.name = 'foo'; w.start = 'bar' } assert_raise InvalidCommandError do God.control('foo', 'invalid') end end def test_control_should_operate_on_each_watch_in_group God.watch do |w| w.name = 'foo1' w.start = 'go' w.group = 'bar' end God.watch do |w| w.name = 'foo2' w.start = 'go' w.group = 'bar' end God.watches['foo1'].expects(:monitor) God.watches['foo2'].expects(:monitor) God.control('bar', 'start') end # stop_all # terminate def test_terminate_should_exit God.pid = nil FileUtils.expects(:rm_f).never God.expects(:exit!) God.terminate end def test_terminate_should_delete_pid God.pid = '/foo/bar' FileUtils.expects(:rm_f).with("/foo/bar") God.expects(:exit!) God.terminate end # status def test_status_should_show_state God.watch { |w| w.name = 'foo'; w.start = 'bar' } w = God.watches['foo'] w.state = :up assert_equal({'foo' => {:state => :up, :group => nil}}, God.status) end def test_status_should_show_state_with_group God.watch { |w| w.name = 'foo'; w.start = 'bar'; w.group = 'g' } w = God.watches['foo'] w.state = :up assert_equal({'foo' => {:state => :up, :group => 'g'}}, God.status) end def test_status_should_show_unmonitored_for_nil_state God.watch { |w| w.name = 'foo'; w.start = 'bar' } w = God.watches['foo'] assert_equal({'foo' => {:state => :unmonitored, :group => nil}}, God.status) end # running_log def test_running_log_should_call_watch_log_since_on_main_log God.watch { |w| w.name = 'foo'; w.start = 'bar' } t = Time.now LOG.expects(:watch_log_since).with('foo', t) God.running_log('foo', t) end def test_running_log_should_raise_on_unknown_watch God.internal_init assert_raise(NoSuchWatchError) do God.running_log('foo', Time.now) end end # running_load def test_running_load_should_eval_code code = <<-EOF God.watch do |w| w.name = 'foo' w.start = 'go' end EOF no_stdout do God.running_load(code, '/foo/bar.god') end assert_equal 1, God.watches.size end def test_running_load_should_monitor_new_watches code = <<-EOF God.watch do |w| w.name = 'foo' w.start = 'go' end EOF Watch.any_instance.expects(:monitor) no_stdout do God.running_load(code, '/foo/bar.god') end end def test_running_load_should_not_monitor_new_watches_with_autostart_false code = <<-EOF God.watch do |w| w.name = 'foo' w.start = 'go' w.autostart = false end EOF Watch.any_instance.expects(:monitor).never no_stdout do God.running_load(code, '/foo/bar.god') end end def test_running_load_should_return_array_of_affected_watches code = <<-EOF God.watch do |w| w.name = 'foo' w.start = 'go' end EOF w = nil no_stdout do w, e = *God.running_load(code, '/foo/bar.god') end assert_equal 1, w.size assert_equal 'foo', w.first end def test_running_load_should_clear_pending_watches code = <<-EOF God.watch do |w| w.name = 'foo' w.start = 'go' end EOF no_stdout do God.running_load(code, '/foo/bar.god') end assert_equal 0, God.pending_watches.size end # load def test_load_should_collect_and_load_globbed_path Dir.expects(:[]).with('/path/to/*.thing').returns(['a', 'b']) Kernel.expects(:load).with('a').once Kernel.expects(:load).with('b').once God.load('/path/to/*.thing') end # start def test_start_should_kick_off_a_server_instance God::Socket.expects(:new).returns(true) God.start end def test_start_should_begin_monitoring_autostart_watches God.watch do |w| w.name = 'foo' w.start = 'go' end Watch.any_instance.expects(:monitor).once God.start end def test_start_should_not_begin_monitoring_non_autostart_watches God.watch do |w| w.name = 'foo' w.start = 'go' w.autostart = false end Watch.any_instance.expects(:monitor).never God.start end def test_start_should_get_and_join_timer God.watch { |w| w.name = 'foo'; w.start = 'bar' } no_stdout do God.start end end # at_exit def test_at_exit_should_call_start God.expects(:start).once God.at_exit end # pattern_match def test_pattern_match list = %w{ mongrel-3000 mongrel-3001 fuzed22 fuzed fuzed2 apache mysql} assert_equal %w{ mongrel-3000 }, God.pattern_match('m3000', list) assert_equal %w{ mongrel-3001 }, God.pattern_match('m31', list) assert_equal %w{ fuzed fuzed2 fuzed22}, God.pattern_match('fu', list) assert_equal %w{ mysql }, God.pattern_match('sql', list) end end # class TestGodOther < Test::Unit::TestCase # def setup # God::Socket.stubs(:new).returns(true) # God.internal_init # God.reset # end # # def teardown # God.main && God.main.kill # end # # # setup # # def test_setup_should_create_pid_file_directory_if_it_doesnt_exist # God.expects(:test).returns(false) # FileUtils.expects(:mkdir_p).with(God.pid_file_directory) # God.setup # end # # def test_setup_should_raise_if_no_permissions_to_create_pid_file_directory # God.expects(:test).returns(false) # FileUtils.expects(:mkdir_p).raises(Errno::EACCES) # # assert_abort do # God.setup # end # end # # # validate # # def test_validate_should_abort_if_pid_file_directory_is_unwriteable # God.expects(:test).returns(false) # assert_abort do # God.validater # end # end # # def test_validate_should_not_abort_if_pid_file_directory_is_writeable # God.expects(:test).returns(true) # assert_nothing_raised do # God.validater # end # end # end