god 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/Announce.txt +6 -6
  2. data/Gemfile +2 -0
  3. data/History.txt +19 -2
  4. data/{README.txt → LICENSE} +0 -37
  5. data/README.md +31 -0
  6. data/Rakefile +80 -38
  7. data/bin/god +21 -21
  8. data/doc/god.asciidoc +1487 -0
  9. data/doc/intro.asciidoc +20 -0
  10. data/ext/god/extconf.rb +3 -3
  11. data/ext/god/kqueue_handler.c +18 -18
  12. data/ext/god/netlink_handler.c +31 -31
  13. data/god.gemspec +24 -16
  14. data/lib/god.rb +261 -204
  15. data/lib/god/behavior.rb +14 -14
  16. data/lib/god/behaviors/clean_pid_file.rb +5 -5
  17. data/lib/god/behaviors/clean_unix_socket.rb +10 -10
  18. data/lib/god/behaviors/notify_when_flapping.rb +12 -12
  19. data/lib/god/cli/command.rb +59 -46
  20. data/lib/god/cli/run.rb +33 -37
  21. data/lib/god/cli/version.rb +6 -6
  22. data/lib/god/compat19.rb +1 -4
  23. data/lib/god/condition.rb +21 -21
  24. data/lib/god/conditions/always.rb +19 -6
  25. data/lib/god/conditions/complex.rb +18 -18
  26. data/lib/god/conditions/cpu_usage.rb +14 -14
  27. data/lib/god/conditions/degrading_lambda.rb +8 -8
  28. data/lib/god/conditions/disk_usage.rb +5 -5
  29. data/lib/god/conditions/flapping.rb +23 -23
  30. data/lib/god/conditions/http_response_code.rb +35 -19
  31. data/lib/god/conditions/lambda.rb +2 -2
  32. data/lib/god/conditions/memory_usage.rb +13 -13
  33. data/lib/god/conditions/process_exits.rb +14 -20
  34. data/lib/god/conditions/process_running.rb +16 -25
  35. data/lib/god/conditions/socket_responding.rb +132 -0
  36. data/lib/god/conditions/tries.rb +10 -10
  37. data/lib/god/configurable.rb +10 -10
  38. data/lib/god/contact.rb +20 -20
  39. data/lib/god/contacts/email.rb +7 -4
  40. data/lib/god/contacts/jabber.rb +1 -1
  41. data/lib/god/driver.rb +96 -64
  42. data/lib/god/errors.rb +9 -9
  43. data/lib/god/event_handler.rb +19 -19
  44. data/lib/god/event_handlers/dummy_handler.rb +4 -4
  45. data/lib/god/event_handlers/kqueue_handler.rb +3 -3
  46. data/lib/god/event_handlers/netlink_handler.rb +2 -2
  47. data/lib/god/logger.rb +13 -13
  48. data/lib/god/metric.rb +50 -22
  49. data/lib/god/process.rb +53 -52
  50. data/lib/god/registry.rb +7 -7
  51. data/lib/god/simple_logger.rb +14 -14
  52. data/lib/god/socket.rb +11 -11
  53. data/lib/god/sugar.rb +30 -15
  54. data/lib/god/sys_logger.rb +2 -2
  55. data/lib/god/system/portable_poller.rb +8 -8
  56. data/lib/god/system/process.rb +8 -8
  57. data/lib/god/system/slash_proc_poller.rb +13 -13
  58. data/lib/god/task.rb +237 -188
  59. data/lib/god/timeline.rb +5 -5
  60. data/lib/god/trigger.rb +11 -11
  61. data/lib/god/watch.rb +205 -53
  62. data/test/configs/child_events/child_events.god +5 -5
  63. data/test/configs/child_events/simple_server.rb +1 -1
  64. data/test/configs/child_polls/child_polls.god +4 -4
  65. data/test/configs/child_polls/simple_server.rb +4 -4
  66. data/test/configs/complex/complex.god +7 -7
  67. data/test/configs/complex/simple_server.rb +1 -1
  68. data/test/configs/contact/contact.god +1 -1
  69. data/test/configs/contact/simple_server.rb +1 -1
  70. data/test/configs/daemon_events/daemon_events.god +5 -5
  71. data/test/configs/daemon_events/simple_server.rb +1 -1
  72. data/test/configs/daemon_events/simple_server_stop.rb +1 -1
  73. data/test/configs/daemon_polls/daemon_polls.god +3 -3
  74. data/test/configs/daemon_polls/simple_server.rb +1 -1
  75. data/test/configs/degrading_lambda/degrading_lambda.god +3 -3
  76. data/test/configs/keepalive/keepalive.god +9 -0
  77. data/test/configs/keepalive/keepalive.rb +12 -0
  78. data/test/configs/lifecycle/lifecycle.god +2 -2
  79. data/test/configs/matias/matias.god +6 -6
  80. data/test/configs/real.rb +7 -7
  81. data/test/configs/running_load/running_load.god +2 -2
  82. data/test/configs/stop_options/simple_server.rb +1 -1
  83. data/test/configs/stress/simple_server.rb +1 -1
  84. data/test/configs/stress/stress.god +2 -2
  85. data/test/configs/task/task.god +5 -5
  86. data/test/configs/test.rb +7 -7
  87. data/test/helper.rb +8 -8
  88. data/test/test_behavior.rb +3 -3
  89. data/test/test_campfire.rb +1 -2
  90. data/test/test_condition.rb +10 -10
  91. data/test/test_conditions_disk_usage.rb +12 -12
  92. data/test/test_conditions_http_response_code.rb +24 -24
  93. data/test/test_conditions_process_running.rb +7 -7
  94. data/test/test_conditions_socket_responding.rb +122 -0
  95. data/test/test_conditions_tries.rb +12 -12
  96. data/test/test_contact.rb +19 -19
  97. data/test/test_driver.rb +17 -3
  98. data/test/test_event_handler.rb +12 -12
  99. data/test/test_god.rb +195 -117
  100. data/test/test_handlers_kqueue_handler.rb +4 -4
  101. data/test/test_jabber.rb +1 -1
  102. data/test/test_logger.rb +17 -17
  103. data/test/test_metric.rb +16 -16
  104. data/test/test_process.rb +47 -41
  105. data/test/test_prowl.rb +1 -1
  106. data/test/test_registry.rb +2 -2
  107. data/test/test_socket.rb +3 -3
  108. data/test/test_sugar.rb +7 -7
  109. data/test/test_system_portable_poller.rb +1 -1
  110. data/test/test_system_process.rb +5 -5
  111. data/test/test_task.rb +57 -57
  112. data/test/test_timeline.rb +8 -8
  113. data/test/test_trigger.rb +16 -16
  114. data/test/test_watch.rb +69 -62
  115. metadata +182 -69
  116. data/lib/god/dependency_graph.rb +0 -41
  117. data/lib/god/diagnostics.rb +0 -37
  118. data/test/test_dependency_graph.rb +0 -62
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/helper'
2
2
 
3
3
  class TestConditionsTries < Test::Unit::TestCase
4
4
  # valid?
5
-
5
+
6
6
  def test_valid_should_return_false_if_times_not_set
7
7
  c = Conditions::Tries.new
8
8
  c.watch = stub(:name => 'foo')
@@ -17,23 +17,23 @@ class TestConditionsTries < Test::Unit::TestCase
17
17
  @c.times = 3
18
18
  @c.prepare
19
19
  end
20
-
20
+
21
21
  # prepare
22
-
22
+
23
23
  def test_prepare_should_create_timeline
24
- assert 3, @c.instance_variable_get(:@timeline).instance_variable_get(:@max_size)
24
+ assert_equal 3, @c.instance_variable_get(:@timeline).instance_variable_get(:@max_size)
25
25
  end
26
-
26
+
27
27
  # test
28
-
28
+
29
29
  def test_test_should_return_true_if_called_three_times_within_one_second
30
30
  assert !@c.test
31
31
  assert !@c.test
32
32
  assert @c.test
33
33
  end
34
-
34
+
35
35
  # reset
36
-
36
+
37
37
  def test_test_should_return_false_on_fourth_call_if_called_three_times_within_one_second
38
38
  3.times { @c.test }
39
39
  @c.reset
@@ -49,19 +49,19 @@ class TestConditionsTriesWithin < Test::Unit::TestCase
49
49
  @c.within = 1.seconds
50
50
  @c.prepare
51
51
  end
52
-
52
+
53
53
  # test
54
-
54
+
55
55
  def test_test_should_return_true_if_called_three_times_within_one_second
56
56
  assert !@c.test
57
57
  assert !@c.test
58
58
  assert @c.test
59
59
  end
60
-
60
+
61
61
  def test_test_should_return_false_if_called_three_times_within_two_seconds
62
62
  assert !@c.test
63
63
  assert !@c.test
64
64
  assert sleep(1.1)
65
65
  assert !@c.test
66
66
  end
67
- end
67
+ end
@@ -4,106 +4,106 @@ class TestContact < Test::Unit::TestCase
4
4
  def test_exists
5
5
  God::Contact
6
6
  end
7
-
7
+
8
8
  # generate
9
-
9
+
10
10
  def test_generate_should_raise_on_invalid_kind
11
11
  assert_raise(NoSuchContactError) do
12
12
  Contact.generate(:invalid)
13
13
  end
14
14
  end
15
-
15
+
16
16
  def test_generate_should_abort_on_invalid_contact
17
17
  assert_abort do
18
18
  Contact.generate(:invalid_contact)
19
19
  end
20
20
  end
21
-
21
+
22
22
  # normalize
23
-
23
+
24
24
  def test_normalize_should_accept_a_string
25
25
  input = 'tom'
26
26
  output = {:contacts => ['tom']}
27
27
  assert_equal(output, Contact.normalize(input))
28
28
  end
29
-
29
+
30
30
  def test_normalize_should_accept_an_array_of_strings
31
31
  input = ['tom', 'kevin']
32
32
  output = {:contacts => ['tom', 'kevin']}
33
33
  assert_equal(output, Contact.normalize(input))
34
34
  end
35
-
35
+
36
36
  def test_normalize_should_accept_a_hash_with_contacts_string
37
37
  input = {:contacts => 'tom'}
38
38
  output = {:contacts => ['tom']}
39
39
  assert_equal(output, Contact.normalize(input))
40
40
  end
41
-
41
+
42
42
  def test_normalize_should_accept_a_hash_with_contacts_array_of_strings
43
43
  input = {:contacts => ['tom', 'kevin']}
44
44
  output = {:contacts => ['tom', 'kevin']}
45
45
  assert_equal(output, Contact.normalize(input))
46
46
  end
47
-
47
+
48
48
  def test_normalize_should_stringify_priority
49
49
  input = {:contacts => 'tom', :priority => 1}
50
50
  output = {:contacts => ['tom'], :priority => '1'}
51
51
  assert_equal(output, Contact.normalize(input))
52
52
  end
53
-
53
+
54
54
  def test_normalize_should_stringify_category
55
55
  input = {:contacts => 'tom', :category => :product}
56
56
  output = {:contacts => ['tom'], :category => 'product'}
57
57
  assert_equal(output, Contact.normalize(input))
58
58
  end
59
-
59
+
60
60
  def test_normalize_should_raise_on_non_string_array_hash
61
61
  input = 1
62
62
  assert_raise ArgumentError do
63
63
  Contact.normalize(input)
64
64
  end
65
65
  end
66
-
66
+
67
67
  def test_normalize_should_raise_on_non_string_array_contacts_key
68
68
  input = {:contacts => 1}
69
69
  assert_raise ArgumentError do
70
70
  Contact.normalize(input)
71
71
  end
72
72
  end
73
-
73
+
74
74
  def test_normalize_should_raise_on_non_string_containing_array
75
75
  input = [1]
76
76
  assert_raise ArgumentError do
77
77
  Contact.normalize(input)
78
78
  end
79
79
  end
80
-
80
+
81
81
  def test_normalize_should_raise_on_non_string_containing_array_contacts_key
82
82
  input = {:contacts => [1]}
83
83
  assert_raise ArgumentError do
84
84
  Contact.normalize(input)
85
85
  end
86
86
  end
87
-
87
+
88
88
  def test_normalize_should_raise_on_absent_contacts_key
89
89
  input = {}
90
90
  assert_raise ArgumentError do
91
91
  Contact.normalize(input)
92
92
  end
93
93
  end
94
-
94
+
95
95
  def test_normalize_should_raise_on_extra_keys
96
96
  input = {:contacts => ['tom'], :priority => 1, :category => 'product', :extra => 'foo'}
97
97
  assert_raise ArgumentError do
98
98
  Contact.normalize(input)
99
99
  end
100
100
  end
101
-
101
+
102
102
  # notify
103
-
103
+
104
104
  def test_notify_should_be_abstract
105
105
  assert_raise(AbstractMethodNotOverriddenError) do
106
106
  Contact.new.notify(:a, :b, :c, :d, :e)
107
107
  end
108
108
  end
109
- end
109
+ end
@@ -2,10 +2,24 @@ require File.dirname(__FILE__) + '/helper'
2
2
 
3
3
  class TestDriver < Test::Unit::TestCase
4
4
  def setup
5
-
5
+
6
6
  end
7
7
 
8
- def test_
9
-
8
+ def test_push_pop_wait
9
+ eq = God::DriverEventQueue.new
10
+
11
+ MonitorMixin::ConditionVariable.any_instance.expects(:wait).times(1)
12
+
13
+ eq.push(God::TimedEvent.new(0))
14
+ eq.push(God::TimedEvent.new(0.1))
15
+ t = Thread.new do
16
+ # This pop will see an event immediately available, so no wait.
17
+ assert_equal TimedEvent, eq.pop.class
18
+
19
+ # This pop will happen before the next event is due, so wait.
20
+ assert_equal TimedEvent, eq.pop.class
21
+ end
22
+
23
+ t.join
10
24
  end
11
25
  end
@@ -2,15 +2,15 @@ require File.dirname(__FILE__) + '/helper'
2
2
 
3
3
  module God
4
4
  class EventHandler
5
-
5
+
6
6
  def self.actions=(value)
7
7
  @@actions = value
8
8
  end
9
-
9
+
10
10
  def self.actions
11
11
  @@actions
12
12
  end
13
-
13
+
14
14
  def self.handler=(value)
15
15
  @@handler = value
16
16
  end
@@ -21,40 +21,40 @@ class TestEventHandler < Test::Unit::TestCase
21
21
  def setup
22
22
  @h = God::EventHandler
23
23
  end
24
-
24
+
25
25
  def test_register_one_event
26
26
  pid = 4445
27
27
  event = :proc_exit
28
28
  block = lambda {
29
29
  puts "Hi"
30
30
  }
31
-
31
+
32
32
  mock_handler = mock()
33
33
  mock_handler.expects(:register_process).with(pid, [event])
34
34
  @h.handler = mock_handler
35
-
35
+
36
36
  @h.register(pid, event, &block)
37
37
  assert_equal @h.actions, {pid => {event => block}}
38
38
  end
39
-
39
+
40
40
  def test_register_multiple_events_per_process
41
41
  pid = 4445
42
42
  exit_block = lambda { puts "Hi" }
43
43
  @h.actions = {pid => {:proc_exit => exit_block}}
44
-
44
+
45
45
  mock_handler = mock()
46
46
  mock_handler.expects(:register_process).with do |a, b|
47
47
  a == pid &&
48
48
  b.to_set == [:proc_exit, :proc_fork].to_set
49
49
  end
50
50
  @h.handler = mock_handler
51
-
51
+
52
52
  fork_block = lambda { puts "Forking" }
53
53
  @h.register(pid, :proc_fork, &fork_block)
54
54
  assert_equal @h.actions, {pid => {:proc_exit => exit_block,
55
55
  :proc_fork => fork_block }}
56
56
  end
57
-
57
+
58
58
  # JIRA PLATFORM-75
59
59
  def test_call_should_check_for_pid_and_action_before_executing
60
60
  exit_block = mock()
@@ -64,7 +64,7 @@ class TestEventHandler < Test::Unit::TestCase
64
64
  @h.call(4445, :proc_fork) # shouldn't call, bad event
65
65
  @h.call(4445, :proc_exit) # should call
66
66
  end
67
-
67
+
68
68
  def teardown
69
69
  # Reset handler
70
70
  @h.actions = {}
@@ -77,4 +77,4 @@ class TestEventHandlerOperational < Test::Unit::TestCase
77
77
  God::EventHandler.start
78
78
  assert God::EventHandler.loaded?
79
79
  end
80
- end
80
+ end
@@ -5,11 +5,10 @@ class TestGod < Test::Unit::TestCase
5
5
  God::Socket.stubs(:new).returns(true)
6
6
  God.stubs(:setup).returns(true)
7
7
  God.stubs(:validater).returns(true)
8
- Thread.any_instance.stubs(:join).returns(true)
9
8
  God.reset
10
9
  God.pid_file_directory = '/var/run/god'
11
10
  end
12
-
11
+
13
12
  def teardown
14
13
  God.main && God.main.kill
15
14
  if God.watches
@@ -18,46 +17,46 @@ class TestGod < Test::Unit::TestCase
18
17
  end
19
18
  end
20
19
  end
21
-
20
+
22
21
  # applog
23
-
22
+
24
23
  def test_applog
25
24
  LOG.expects(:log).with(nil, :debug, 'foo')
26
25
  applog(nil, :debug, 'foo')
27
26
  end
28
-
27
+
29
28
  # internal_init
30
-
29
+
31
30
  def test_init_should_initialize_watches_to_empty_array
32
31
  God.internal_init { }
33
32
  assert_equal Hash.new, God.watches
34
33
  end
35
-
34
+
36
35
  # init
37
-
36
+
38
37
  def test_pid_file_directory_should_abort_if_called_after_watch
39
38
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
40
-
39
+
41
40
  assert_abort do
42
41
  God.pid_file_directory = 'foo'
43
42
  end
44
43
  end
45
-
44
+
46
45
  # pid_file_directory
47
-
46
+
48
47
  def test_pid_file_directory_should_return_default_if_not_set_explicitly
49
48
  God.internal_init
50
49
  assert_equal '/var/run/god', God.pid_file_directory
51
50
  end
52
-
51
+
53
52
  def test_pid_file_directory_equals_should_set
54
53
  God.pid_file_directory = '/foo'
55
54
  God.internal_init
56
55
  assert_equal '/foo', God.pid_file_directory
57
56
  end
58
-
57
+
59
58
  # watch
60
-
59
+
61
60
  def test_watch_should_get_stored
62
61
  watch = nil
63
62
  God.watch do |w|
@@ -65,13 +64,13 @@ class TestGod < Test::Unit::TestCase
65
64
  w.start = 'bar'
66
65
  watch = w
67
66
  end
68
-
67
+
69
68
  assert_equal 1, God.watches.size
70
69
  assert_equal watch, God.watches.values.first
71
-
70
+
72
71
  assert_equal 0, God.groups.size
73
72
  end
74
-
73
+
75
74
  def test_watch_should_get_stored_in_pending_watches
76
75
  watch = nil
77
76
  God.watch do |w|
@@ -79,11 +78,11 @@ class TestGod < Test::Unit::TestCase
79
78
  w.start = 'bar'
80
79
  watch = w
81
80
  end
82
-
81
+
83
82
  assert_equal 1, God.pending_watches.size
84
83
  assert_equal watch, God.pending_watches.first
85
84
  end
86
-
85
+
87
86
  def test_watch_should_register_processes
88
87
  assert_nil God.registry['foo']
89
88
  God.watch do |w|
@@ -92,84 +91,84 @@ class TestGod < Test::Unit::TestCase
92
91
  end
93
92
  assert_kind_of God::Process, God.registry['foo']
94
93
  end
95
-
94
+
96
95
  def test_watch_should_get_stored_by_group
97
96
  a = nil
98
-
97
+
99
98
  God.watch do |w|
100
99
  a = w
101
100
  w.name = 'foo'
102
101
  w.start = 'bar'
103
102
  w.group = 'test'
104
103
  end
105
-
104
+
106
105
  assert_equal({'test' => [a]}, God.groups)
107
106
  end
108
-
107
+
109
108
  def test_watches_should_get_stored_by_group
110
109
  a = nil
111
110
  b = nil
112
-
111
+
113
112
  God.watch do |w|
114
113
  a = w
115
114
  w.name = 'foo'
116
115
  w.start = 'bar'
117
116
  w.group = 'test'
118
117
  end
119
-
118
+
120
119
  God.watch do |w|
121
120
  b = w
122
121
  w.name = 'bar'
123
122
  w.start = 'baz'
124
123
  w.group = 'test'
125
124
  end
126
-
125
+
127
126
  assert_equal({'test' => [a, b]}, God.groups)
128
127
  end
129
-
128
+
130
129
  def test_watch_should_allow_multiple_watches
131
130
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
132
-
131
+
133
132
  assert_nothing_raised do
134
133
  God.watch { |w| w.name = 'bar'; w.start = 'bar' }
135
134
  end
136
135
  end
137
-
136
+
138
137
  def test_watch_should_disallow_duplicate_watch_names
139
138
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
140
-
139
+
141
140
  assert_abort do
142
141
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
143
142
  end
144
143
  end
145
-
144
+
146
145
  def test_watch_should_disallow_identical_watch_and_group_names
147
146
  God.watch { |w| w.name = 'foo'; w.group = 'bar'; w.start = 'bar' }
148
-
147
+
149
148
  assert_abort do
150
149
  God.watch { |w| w.name = 'bar'; w.start = 'bar' }
151
150
  end
152
151
  end
153
-
152
+
154
153
  def test_watch_should_disallow_identical_watch_and_group_names_other_way
155
154
  God.watch { |w| w.name = 'bar'; w.start = 'bar' }
156
-
155
+
157
156
  assert_abort do
158
157
  God.watch { |w| w.name = 'foo'; w.group = 'bar'; w.start = 'bar' }
159
158
  end
160
159
  end
161
-
160
+
162
161
  def test_watch_should_unwatch_new_watch_if_running_and_duplicate_watch
163
162
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
164
163
  God.running = true
165
-
164
+
166
165
  assert_nothing_raised do
167
166
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
168
167
  end
169
168
  end
170
-
169
+
171
170
  # unwatch
172
-
171
+
173
172
  def test_unwatch_should_unmonitor_watch
174
173
  God.watch { |w| w.name = 'bar'; w.start = 'bar' }
175
174
  w = God.watches['bar']
@@ -177,21 +176,21 @@ class TestGod < Test::Unit::TestCase
177
176
  w.expects(:unmonitor)
178
177
  God.unwatch(w)
179
178
  end
180
-
179
+
181
180
  def test_unwatch_should_unregister_watch
182
181
  God.watch { |w| w.name = 'bar'; w.start = 'bar' }
183
182
  w = God.watches['bar']
184
183
  w.expects(:unregister!)
185
184
  God.unwatch(w)
186
185
  end
187
-
186
+
188
187
  def test_unwatch_should_remove_same_name_watches
189
188
  God.watch { |w| w.name = 'bar'; w.start = 'bar' }
190
189
  w = God.watches['bar']
191
190
  God.unwatch(w)
192
191
  assert_equal 0, God.watches.size
193
192
  end
194
-
193
+
195
194
  def test_unwatch_should_remove_from_group
196
195
  God.watch do |w|
197
196
  w.name = 'bar'
@@ -202,59 +201,60 @@ class TestGod < Test::Unit::TestCase
202
201
  God.unwatch(w)
203
202
  assert !God.groups[w.group].include?(w)
204
203
  end
205
-
204
+
206
205
  # contact
207
-
206
+
208
207
  def test_contact_should_ensure_init_is_called
209
208
  God.contact(:fake_contact) { |c| c.name = 'tom' }
210
209
  assert God.inited
211
210
  end
212
-
211
+
213
212
  def test_contact_should_abort_on_invalid_contact_kind
214
213
  assert_abort do
215
214
  God.contact(:foo) { |c| c.name = 'tom' }
216
215
  end
217
216
  end
218
-
217
+
219
218
  def test_contact_should_create_and_store_contact
220
219
  contact = nil
221
220
  God.contact(:fake_contact) { |c| c.name = 'tom'; contact = c }
222
- assert [contact], God.contacts
221
+ assert_equal({"tom" => contact}, God.contacts)
223
222
  end
224
-
223
+
225
224
  def test_contact_should_add_to_group
226
225
  God.contact(:fake_contact) { |c| c.name = 'tom'; c.group = 'devs' }
227
226
  God.contact(:fake_contact) { |c| c.name = 'chris'; c.group = 'devs' }
228
- assert 2, God.contact_groups.size
227
+ assert_equal 2, God.contacts.size
228
+ assert_equal 1, God.contact_groups.size
229
229
  end
230
-
230
+
231
231
  def test_contact_should_abort_on_no_name
232
232
  assert_abort do
233
233
  God.contact(:fake_contact) { |c| }
234
234
  end
235
235
  end
236
-
236
+
237
237
  def test_contact_should_abort_on_duplicate_contact_name
238
238
  God.contact(:fake_contact) { |c| c.name = 'tom' }
239
239
  assert_nothing_raised do
240
240
  God.contact(:fake_contact) { |c| c.name = 'tom' }
241
241
  end
242
242
  end
243
-
243
+
244
244
  def test_contact_should_abort_on_contact_with_same_name_as_group
245
245
  God.contact(:fake_contact) { |c| c.name = 'tom'; c.group = 'devs' }
246
246
  assert_nothing_raised do
247
247
  God.contact(:fake_contact) { |c| c.name = 'devs' }
248
248
  end
249
249
  end
250
-
250
+
251
251
  def test_contact_should_abort_on_contact_with_same_group_as_name
252
252
  God.contact(:fake_contact) { |c| c.name = 'tom' }
253
253
  assert_abort do
254
254
  God.contact(:fake_contact) { |c| c.name = 'chris'; c.group = 'tom' }
255
255
  end
256
256
  end
257
-
257
+
258
258
  def test_contact_should_abort_if_contact_is_invalid
259
259
  assert_abort do
260
260
  God.contact(:fake_contact) do |c|
@@ -263,111 +263,111 @@ class TestGod < Test::Unit::TestCase
263
263
  end
264
264
  end
265
265
  end
266
-
266
+
267
267
  # control
268
-
268
+
269
269
  def test_control_should_monitor_on_start
270
270
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
271
-
271
+
272
272
  w = God.watches['foo']
273
273
  w.expects(:monitor)
274
274
  God.control('foo', 'start')
275
275
  end
276
-
276
+
277
277
  def test_control_should_move_to_restart_on_restart
278
278
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
279
-
279
+
280
280
  w = God.watches['foo']
281
281
  w.expects(:move).with(:restart)
282
282
  God.control('foo', 'restart')
283
283
  end
284
-
284
+
285
285
  def test_control_should_unmonitor_and_stop_on_stop
286
286
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
287
-
287
+
288
288
  w = God.watches['foo']
289
289
  w.state = :up
290
290
  w.expects(:unmonitor).returns(w)
291
291
  w.expects(:action).with(:stop)
292
292
  God.control('foo', 'stop')
293
293
  end
294
-
294
+
295
295
  def test_control_should_unmonitor_on_unmonitor
296
296
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
297
-
297
+
298
298
  w = God.watches['foo']
299
299
  w.state = :up
300
300
  w.expects(:unmonitor).returns(w)
301
301
  God.control('foo', 'unmonitor')
302
302
  end
303
-
303
+
304
304
  def test_control_should_unwatch_on_remove
305
305
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
306
-
306
+
307
307
  w = God.watches['foo']
308
308
  w.state = :up
309
309
  God.expects(:unwatch)
310
310
  God.control('foo', 'remove')
311
311
  end
312
-
312
+
313
313
  def test_control_should_raise_on_invalid_command
314
314
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
315
-
315
+
316
316
  assert_raise InvalidCommandError do
317
317
  God.control('foo', 'invalid')
318
318
  end
319
319
  end
320
-
320
+
321
321
  def test_control_should_operate_on_each_watch_in_group
322
322
  God.watch do |w|
323
323
  w.name = 'foo1'
324
324
  w.start = 'go'
325
325
  w.group = 'bar'
326
326
  end
327
-
327
+
328
328
  God.watch do |w|
329
329
  w.name = 'foo2'
330
330
  w.start = 'go'
331
331
  w.group = 'bar'
332
332
  end
333
-
333
+
334
334
  God.watches['foo1'].expects(:monitor)
335
335
  God.watches['foo2'].expects(:monitor)
336
-
336
+
337
337
  God.control('bar', 'start')
338
338
  end
339
-
339
+
340
340
  # stop_all
341
-
341
+
342
342
  # terminate
343
-
343
+
344
344
  def test_terminate_should_exit
345
345
  God.pid = nil
346
346
  FileUtils.expects(:rm_f).never
347
347
  God.expects(:exit!)
348
348
  God.terminate
349
349
  end
350
-
350
+
351
351
  def test_terminate_should_delete_pid
352
352
  God.pid = '/foo/bar'
353
353
  FileUtils.expects(:rm_f).with("/foo/bar")
354
354
  God.expects(:exit!)
355
355
  God.terminate
356
356
  end
357
-
357
+
358
358
  # status
359
-
359
+
360
360
  def test_status_should_show_state
361
361
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
362
-
362
+
363
363
  w = God.watches['foo']
364
364
  w.state = :up
365
365
  assert_equal({'foo' => {:state => :up, :group => nil}}, God.status)
366
366
  end
367
-
367
+
368
368
  def test_status_should_show_state_with_group
369
369
  God.watch { |w| w.name = 'foo'; w.start = 'bar'; w.group = 'g' }
370
-
370
+
371
371
  w = God.watches['foo']
372
372
  w.state = :up
373
373
  assert_equal({'foo' => {:state => :up, :group => 'g'}}, God.status)
@@ -375,29 +375,29 @@ class TestGod < Test::Unit::TestCase
375
375
 
376
376
  def test_status_should_show_unmonitored_for_nil_state
377
377
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
378
-
378
+
379
379
  w = God.watches['foo']
380
380
  assert_equal({'foo' => {:state => :unmonitored, :group => nil}}, God.status)
381
381
  end
382
-
382
+
383
383
  # running_log
384
-
384
+
385
385
  def test_running_log_should_call_watch_log_since_on_main_log
386
386
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
387
387
  t = Time.now
388
388
  LOG.expects(:watch_log_since).with('foo', t)
389
389
  God.running_log('foo', t)
390
390
  end
391
-
391
+
392
392
  def test_running_log_should_raise_on_unknown_watch
393
393
  God.internal_init
394
394
  assert_raise(NoSuchWatchError) do
395
395
  God.running_log('foo', Time.now)
396
396
  end
397
397
  end
398
-
398
+
399
399
  # running_load
400
-
400
+
401
401
  def test_running_load_should_eval_code
402
402
  code = <<-EOF
403
403
  God.watch do |w|
@@ -405,12 +405,12 @@ class TestGod < Test::Unit::TestCase
405
405
  w.start = 'go'
406
406
  end
407
407
  EOF
408
-
408
+
409
409
  God.running_load(code, '/foo/bar.god')
410
-
410
+
411
411
  assert_equal 1, God.watches.size
412
412
  end
413
-
413
+
414
414
  def test_running_load_should_monitor_new_watches
415
415
  code = <<-EOF
416
416
  God.watch do |w|
@@ -418,11 +418,11 @@ class TestGod < Test::Unit::TestCase
418
418
  w.start = 'go'
419
419
  end
420
420
  EOF
421
-
421
+
422
422
  Watch.any_instance.expects(:monitor)
423
423
  God.running_load(code, '/foo/bar.god')
424
424
  end
425
-
425
+
426
426
  def test_running_load_should_not_monitor_new_watches_with_autostart_false
427
427
  code = <<-EOF
428
428
  God.watch do |w|
@@ -431,11 +431,11 @@ class TestGod < Test::Unit::TestCase
431
431
  w.autostart = false
432
432
  end
433
433
  EOF
434
-
434
+
435
435
  Watch.any_instance.expects(:monitor).never
436
436
  God.running_load(code, '/foo/bar.god')
437
437
  end
438
-
438
+
439
439
  def test_running_load_should_return_array_of_affected_watches
440
440
  code = <<-EOF
441
441
  God.watch do |w|
@@ -443,13 +443,13 @@ class TestGod < Test::Unit::TestCase
443
443
  w.start = 'go'
444
444
  end
445
445
  EOF
446
-
446
+
447
447
  w = nil
448
448
  w, e = *God.running_load(code, '/foo/bar.god')
449
449
  assert_equal 1, w.size
450
450
  assert_equal 'foo', w.first
451
451
  end
452
-
452
+
453
453
  def test_running_load_should_clear_pending_watches
454
454
  code = <<-EOF
455
455
  God.watch do |w|
@@ -457,65 +457,143 @@ class TestGod < Test::Unit::TestCase
457
457
  w.start = 'go'
458
458
  end
459
459
  EOF
460
-
460
+
461
461
  God.running_load(code, '/foo/bar.god')
462
462
  assert_equal 0, God.pending_watches.size
463
463
  end
464
-
464
+
465
+ def test_running_load_with_stop
466
+ code_one = <<-EOF
467
+ God.watch do |w|
468
+ w.name = 'foo'
469
+ w.start = 'go'
470
+ end
471
+ EOF
472
+
473
+ code_two = <<-EOF
474
+ God.watch do |w|
475
+ w.name = 'bar'
476
+ w.start = 'go'
477
+ end
478
+ EOF
479
+
480
+ a, e, r = *God.running_load(code_one, '/foo/one.god', 'stop')
481
+
482
+ assert_equal 1, a.size
483
+ assert_equal 0, r.size
484
+
485
+ a, e, r = *God.running_load(code_two, '/foo/two.god', 'stop')
486
+
487
+ assert_equal 1, a.size
488
+ assert_equal 1, r.size
489
+ end
490
+
491
+ def test_running_load_with_remove
492
+ code_one = <<-EOF
493
+ God.watch do |w|
494
+ w.name = 'foo'
495
+ w.start = 'go'
496
+ end
497
+ EOF
498
+
499
+ code_two = <<-EOF
500
+ God.watch do |w|
501
+ w.name = 'bar'
502
+ w.start = 'go'
503
+ end
504
+ EOF
505
+
506
+ a, e, r = *God.running_load(code_one, '/foo/one.god', 'remove')
507
+
508
+ assert_equal 1, a.size
509
+ assert_equal 0, r.size
510
+
511
+ a, e, r = *God.running_load(code_two, '/foo/two.god', 'remove')
512
+
513
+ assert_equal 1, a.size
514
+ assert_equal 1, r.size
515
+ end
516
+
517
+ def test_running_load_with_leave
518
+ code_one = <<-EOF
519
+ God.watch do |w|
520
+ w.name = 'foo'
521
+ w.start = 'go'
522
+ end
523
+ EOF
524
+
525
+ code_two = <<-EOF
526
+ God.watch do |w|
527
+ w.name = 'bar'
528
+ w.start = 'go'
529
+ end
530
+ EOF
531
+
532
+ a, e, r = *God.running_load(code_one, '/foo/one.god', 'leave')
533
+
534
+ assert_equal 1, a.size
535
+ assert_equal 0, r.size
536
+
537
+ a, e, r = *God.running_load(code_two, '/foo/two.god', 'leave')
538
+
539
+ assert_equal 1, a.size
540
+ assert_equal 0, r.size
541
+ end
542
+
465
543
  # load
466
-
544
+
467
545
  def test_load_should_collect_and_load_globbed_path
468
546
  Dir.expects(:[]).with('/path/to/*.thing').returns(['a', 'b'])
469
547
  Kernel.expects(:load).with('a').once
470
548
  Kernel.expects(:load).with('b').once
471
549
  God.load('/path/to/*.thing')
472
550
  end
473
-
551
+
474
552
  # start
475
-
553
+
476
554
  def test_start_should_kick_off_a_server_instance
477
555
  God::Socket.expects(:new).returns(true)
478
556
  God.start
479
557
  end
480
-
558
+
481
559
  def test_start_should_begin_monitoring_autostart_watches
482
560
  God.watch do |w|
483
561
  w.name = 'foo'
484
562
  w.start = 'go'
485
563
  end
486
-
564
+
487
565
  Watch.any_instance.expects(:monitor).once
488
566
  God.start
489
567
  end
490
-
568
+
491
569
  def test_start_should_not_begin_monitoring_non_autostart_watches
492
570
  God.watch do |w|
493
571
  w.name = 'foo'
494
572
  w.start = 'go'
495
573
  w.autostart = false
496
574
  end
497
-
575
+
498
576
  Watch.any_instance.expects(:monitor).never
499
577
  God.start
500
578
  end
501
-
579
+
502
580
  def test_start_should_get_and_join_timer
503
581
  God.watch { |w| w.name = 'foo'; w.start = 'bar' }
504
582
  God.start
505
583
  end
506
-
584
+
507
585
  # at_exit
508
-
586
+
509
587
  def test_at_exit_should_call_start
510
588
  God.expects(:start).once
511
589
  God.at_exit
512
590
  end
513
-
591
+
514
592
  # pattern_match
515
-
593
+
516
594
  def test_pattern_match
517
595
  list = %w{ mongrel-3000 mongrel-3001 fuzed22 fuzed fuzed2 apache mysql}
518
-
596
+
519
597
  assert_equal %w{ mongrel-3000 }, God.pattern_match('m3000', list)
520
598
  assert_equal %w{ mongrel-3001 }, God.pattern_match('m31', list)
521
599
  assert_equal %w{ fuzed fuzed2 fuzed22}, God.pattern_match('fu', list)
@@ -530,37 +608,37 @@ end
530
608
  # God.internal_init
531
609
  # God.reset
532
610
  # end
533
- #
611
+ #
534
612
  # def teardown
535
613
  # God.main && God.main.kill
536
614
  # end
537
- #
615
+ #
538
616
  # # setup
539
- #
617
+ #
540
618
  # def test_setup_should_create_pid_file_directory_if_it_doesnt_exist
541
619
  # God.expects(:test).returns(false)
542
620
  # FileUtils.expects(:mkdir_p).with(God.pid_file_directory)
543
621
  # God.setup
544
622
  # end
545
- #
623
+ #
546
624
  # def test_setup_should_raise_if_no_permissions_to_create_pid_file_directory
547
625
  # God.expects(:test).returns(false)
548
626
  # FileUtils.expects(:mkdir_p).raises(Errno::EACCES)
549
- #
627
+ #
550
628
  # assert_abort do
551
629
  # God.setup
552
630
  # end
553
631
  # end
554
- #
632
+ #
555
633
  # # validate
556
- #
634
+ #
557
635
  # def test_validate_should_abort_if_pid_file_directory_is_unwriteable
558
636
  # God.expects(:test).returns(false)
559
637
  # assert_abort do
560
638
  # God.validater
561
639
  # end
562
640
  # end
563
- #
641
+ #
564
642
  # def test_validate_should_not_abort_if_pid_file_directory_is_writeable
565
643
  # God.expects(:test).returns(true)
566
644
  # assert_nothing_raised do