samhendley-god 0.7.13

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