god 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. data/History.txt +26 -0
  2. data/Manifest.txt +15 -1
  3. data/Rakefile +2 -7
  4. data/bin/god +104 -16
  5. data/lib/god.rb +169 -37
  6. data/lib/god/behaviors/notify_when_flapping.rb +51 -0
  7. data/lib/god/condition.rb +1 -0
  8. data/lib/god/conditions/degrading_lambda.rb +47 -0
  9. data/lib/god/conditions/process_exits.rb +6 -2
  10. data/lib/god/conditions/tries.rb +33 -0
  11. data/lib/god/dependency_graph.rb +41 -0
  12. data/lib/god/errors.rb +6 -0
  13. data/lib/god/hub.rb +43 -20
  14. data/lib/god/logger.rb +44 -0
  15. data/lib/god/process.rb +91 -19
  16. data/lib/god/registry.rb +4 -0
  17. data/lib/god/server.rb +12 -2
  18. data/lib/god/timeline.rb +36 -0
  19. data/lib/god/watch.rb +27 -8
  20. data/test/configs/child_events/child_events.god +7 -2
  21. data/test/configs/child_polls/child_polls.god +3 -1
  22. data/test/configs/child_polls/simple_server.rb +1 -1
  23. data/test/configs/daemon_events/daemon_events.god +7 -3
  24. data/test/configs/daemon_polls/daemon_polls.god +17 -0
  25. data/test/configs/daemon_polls/simple_server.rb +6 -0
  26. data/test/configs/degrading_lambda/degrading_lambda.god +33 -0
  27. data/test/configs/degrading_lambda/tcp_server.rb +15 -0
  28. data/test/configs/real.rb +1 -1
  29. data/test/configs/running_load/running_load.god +16 -0
  30. data/test/configs/stress/simple_server.rb +3 -0
  31. data/test/configs/stress/stress.god +15 -0
  32. data/test/configs/test.rb +14 -2
  33. data/test/helper.rb +12 -2
  34. data/test/test_conditions_tries.rb +46 -0
  35. data/test/test_dependency_graph.rb +62 -0
  36. data/test/test_god.rb +289 -33
  37. data/test/test_handlers_kqueue_handler.rb +11 -7
  38. data/test/test_hub.rb +18 -0
  39. data/test/test_logger.rb +55 -0
  40. data/test/test_process.rb +135 -17
  41. data/test/test_registry.rb +2 -1
  42. data/test/test_server.rb +35 -4
  43. data/test/test_timeline.rb +14 -2
  44. data/test/test_watch.rb +7 -0
  45. metadata +21 -4
  46. data/lib/god/conditions/timeline.rb +0 -17
@@ -1,12 +1,16 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
- class TestHandlersKqueueHandler < Test::Unit::TestCase
4
- def test_register_process
5
- KQueueHandler.expects(:monitor_process).with(1234, 2147483648)
6
- KQueueHandler.register_process(1234, [:proc_exit])
7
- end
3
+ if God::EventHandler.event_system == "kqueue"
4
+
5
+ class TestHandlersKqueueHandler < Test::Unit::TestCase
6
+ def test_register_process
7
+ KQueueHandler.expects(:monitor_process).with(1234, 2147483648)
8
+ KQueueHandler.register_process(1234, [:proc_exit])
9
+ end
8
10
 
9
- def test_events_mask
10
- assert_equal 2147483648, KQueueHandler.events_mask([:proc_exit])
11
+ def test_events_mask
12
+ assert_equal 2147483648, KQueueHandler.events_mask([:proc_exit])
13
+ end
11
14
  end
15
+
12
16
  end
data/test/test_hub.rb CHANGED
@@ -7,6 +7,7 @@ class TestHub < Test::Unit::TestCase
7
7
 
8
8
  God.watch do |w|
9
9
  w.name = 'foo'
10
+ w.start = 'bar'
10
11
  w.interval = 10
11
12
  end
12
13
 
@@ -139,6 +140,23 @@ class TestHub < Test::Unit::TestCase
139
140
  end
140
141
  end
141
142
 
143
+ def test_handle_poll_should_use_overridden_transition
144
+ c = Conditions::Tries.new
145
+ c.times = 1
146
+ c.transition = :start
147
+ c.prepare
148
+
149
+ m = Metric.new(@watch, {true => :up})
150
+ Hub.attach(c, m)
151
+
152
+ @watch.expects(:move).with(:start)
153
+
154
+ no_stdout do
155
+ t = Hub.handle_poll(c)
156
+ t.join
157
+ end
158
+ end
159
+
142
160
  # handle_event
143
161
 
144
162
  def test_handle_event_should_move
@@ -0,0 +1,55 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestLogger < Test::Unit::TestCase
4
+ def setup
5
+ @log = God::Logger.new
6
+ end
7
+
8
+ # log
9
+
10
+ def test_log
11
+ @log.expects(:info).with("qux")
12
+
13
+ no_stdout do
14
+ @log.log(stub(:name => 'foo'), :info, "qux")
15
+ end
16
+
17
+ assert_equal 1, @log.logs.size
18
+ assert_instance_of Time, @log.logs['foo'][0][0]
19
+ assert_match(/qux/, @log.logs['foo'][0][1])
20
+ end
21
+
22
+ # watch_log_since
23
+
24
+ def test_watch_log_since
25
+ t1 = Time.now
26
+
27
+ no_stdout do
28
+ @log.log(stub(:name => 'foo'), :info, "one")
29
+ @log.log(stub(:name => 'foo'), :info, "two")
30
+ end
31
+
32
+ assert_match(/one.*two/m, @log.watch_log_since('foo', t1))
33
+
34
+ t2 = Time.now
35
+
36
+ no_stdout do
37
+ @log.log(stub(:name => 'foo'), :info, "three")
38
+ end
39
+
40
+ out = @log.watch_log_since('foo', t2)
41
+
42
+ assert_no_match(/one/, out)
43
+ assert_no_match(/two/, out)
44
+ assert_match(/three/, out)
45
+ end
46
+
47
+ # regular methods
48
+
49
+ def test_fatal
50
+ no_stdout do
51
+ @log.fatal('foo')
52
+ end
53
+ assert_equal 0, @log.logs.size
54
+ end
55
+ end
data/test/test_process.rb CHANGED
@@ -12,14 +12,134 @@ module God
12
12
  end
13
13
  end
14
14
 
15
- class TestProcess < Test::Unit::TestCase
15
+ class TestProcessChild < Test::Unit::TestCase
16
16
  def setup
17
- @p = God::Process.new(:name => 'foo', :pid_file => 'blah.pid')
17
+ God.internal_init
18
+ @p = God::Process.new
19
+ @p.name = 'foo'
18
20
  @p.stubs(:test).returns true # so we don't try to mkdir_p
19
21
  Process.stubs(:detach) # because we stub fork
20
22
  end
21
23
 
24
+ # valid?
25
+
26
+ def test_valid_should_return_true_if_auto_daemonized_and_log
27
+ @p.start = 'qux'
28
+ @p.log = 'bar'
29
+
30
+ assert @p.valid?
31
+ end
32
+
33
+ def test_valid_should_return_true_if_auto_daemonized_and_no_stop
34
+ @p.start = 'qux'
35
+ @p.log = 'bar'
36
+
37
+ assert @p.valid?
38
+ end
39
+
40
+ def test_valid_should_return_true_if_uid_exists
41
+ @p.start = 'qux'
42
+ @p.log = 'bar'
43
+ @p.uid = 'root'
44
+
45
+ assert @p.valid?
46
+ end
47
+
48
+ def test_valid_should_return_true_if_uid_does_not_exists
49
+ @p.start = 'qux'
50
+ @p.log = 'bar'
51
+ @p.uid = 'foobarbaz'
52
+
53
+ no_stdout do
54
+ assert !@p.valid?
55
+ end
56
+ end
57
+
58
+ def test_valid_should_return_true_if_gid_exists
59
+ @p.start = 'qux'
60
+ @p.log = 'bar'
61
+ @p.gid = 'wheel'
62
+
63
+ assert @p.valid?
64
+ end
65
+
66
+ def test_valid_should_return_true_if_gid_does_not_exists
67
+ @p.start = 'qux'
68
+ @p.log = 'bar'
69
+ @p.gid = 'foobarbaz'
70
+
71
+ no_stdout do
72
+ assert !@p.valid?
73
+ end
74
+ end
75
+ end
76
+
77
+ class TestProcessDaemon < Test::Unit::TestCase
78
+ def setup
79
+ God.internal_init
80
+ @p = God::Process.new
81
+ @p.name = 'foo'
82
+ @p.pid_file = 'blah.pid'
83
+ @p.stubs(:test).returns true # so we don't try to mkdir_p
84
+ Process.stubs(:detach) # because we stub fork
85
+ end
86
+
87
+ # alive?
88
+
89
+ def test_alive_should_call_system_process_exists
90
+ File.expects(:read).with('blah.pid').returns('1234')
91
+ System::Process.any_instance.expects(:exists?).returns(false)
92
+ assert !@p.alive?
93
+ end
94
+
95
+ # valid?
96
+
97
+ def test_valid_should_return_false_if_no_name
98
+ @p.name = nil
99
+ @p.start = 'bar'
100
+ @p.stop = 'baz'
101
+ no_stdout do
102
+ assert !@p.valid?
103
+ end
104
+ end
105
+
106
+ def test_valid_should_return_false_if_no_start
107
+ @p.name = 'foo'
108
+ @p.stop = 'baz'
109
+ no_stdout do
110
+ assert !@p.valid?
111
+ end
112
+ end
113
+
114
+ def test_valid_should_return_false_if_self_daemonized_and_no_stop
115
+ @p.start = 'bar'
116
+ @p.pid_file = 'foo'
117
+
118
+ no_stdout do
119
+ assert !@p.valid?
120
+ end
121
+ end
122
+
123
+ def test_valid_should_return_false_if_self_daemonized_and_log
124
+ @p.pid_file = 'foo'
125
+ @p.start = 'baz'
126
+ @p.stop = 'qux'
127
+ @p.log = 'bar'
128
+
129
+ no_stdout do
130
+ assert !@p.valid?
131
+ end
132
+ end
133
+
134
+ # defaul_pid_file
135
+
136
+ def test_default_pid_file
137
+ assert_equal File.join(God.pid_file_directory, 'foo.pid'), @p.default_pid_file
138
+ end
139
+
140
+ # call_action
22
141
  # These actually excercise call_action in the back at this point - Kev
142
+
23
143
  def test_call_action_with_string_should_fork_exec
24
144
  @p.start = "do something"
25
145
  IO.expects(:pipe).returns([StringIO.new('1234'), StringIO.new])
@@ -34,15 +154,12 @@ class TestProcess < Test::Unit::TestCase
34
154
  @p.start = cmd
35
155
  @p.call_action(:start)
36
156
  end
37
-
38
- def test_default_pid_file
39
- assert_equal File.join(God.pid_file_directory, 'foo.pid'), @p.default_pid_file
40
- end
41
157
 
42
158
  def test_call_action_without_pid_should_write_pid
43
159
  # Only for start, restart
44
160
  [:start, :restart].each do |action|
45
- @p = God::Process.new(:name => 'foo')
161
+ @p = God::Process.new
162
+ @p.name = 'foo'
46
163
  @p.stubs(:test).returns true
47
164
  IO.expects(:pipe).returns([StringIO.new('1234'), StringIO.new])
48
165
  @p.expects(:fork)
@@ -63,18 +180,19 @@ class TestProcess < Test::Unit::TestCase
63
180
  @p.call_action(:stop)
64
181
  end
65
182
 
66
- def test_call_action_should_mkdir_p_if_pid_file_dir_existence_test_fails
67
- @p.pid_file = nil
68
- IO.expects(:pipe).returns([StringIO.new('1234'), StringIO.new])
69
- @p.expects(:fork)
70
- Process.expects(:waitpid)
71
- @p.expects(:test).returns(false, true)
72
- FileUtils.expects(:mkdir_p).with(God.pid_file_directory)
73
- File.expects(:open)
74
- @p.start = "starting"
75
- @p.call_action(:start)
183
+ def test_call_action_with_invalid_command_class_should_raise
184
+ @p.start = 5
185
+ @p.stop = 'baz'
186
+
187
+ assert @p.valid?
188
+
189
+ assert_raise NotImplementedError do
190
+ @p.call_action(:start)
191
+ end
76
192
  end
77
193
 
194
+ # start!/stop!/restart!
195
+
78
196
  def test_start_stop_restart_bang
79
197
  [:start, :stop, :restart].each do |x|
80
198
  @p.expects(:call_action).with(x)
@@ -6,7 +6,8 @@ class TestRegistry < Test::Unit::TestCase
6
6
  end
7
7
 
8
8
  def test_add
9
- foo = God::Process.new(:name => 'foo')
9
+ foo = God::Process.new
10
+ foo.name = 'foo'
10
11
  God.registry.add(foo)
11
12
  assert_equal 1, God.registry.size
12
13
  assert_equal foo, God.registry['foo']
data/test/test_server.rb CHANGED
@@ -9,17 +9,48 @@ class TestServer < Test::Unit::TestCase
9
9
 
10
10
  def test_should_start_a_drb_server
11
11
  DRb.expects(:start_service)
12
- Server.new
12
+ no_stdout do
13
+ Server.new
14
+ end
13
15
  end
14
16
 
15
17
  def test_should_use_supplied_port_and_host
16
18
  DRb.expects(:start_service).with { |uri, object| uri == "druby://host:port" && object.is_a?(Server) }
17
- server = Server.new('host', 'port')
19
+ no_stdout do
20
+ server = Server.new('host', 'port')
21
+ end
18
22
  end
19
23
 
20
- def test_should_forward_foreign_method_calls_to_meddle
21
- server = Server.new
24
+ def test_should_forward_foreign_method_calls_to_god
25
+ server = nil
26
+ no_stdout do
27
+ server = Server.new
28
+ end
22
29
  God.expects(:send).with(:something_random)
23
30
  server.something_random
24
31
  end
32
+
33
+ def test_should_install_deny_all_by_default
34
+ ACL.expects(:new).with(%w{deny all})
35
+ no_stdout do
36
+ Server.new
37
+ end
38
+ end
39
+
40
+ def test_should_install_pass_through_acl
41
+ ACL.expects(:new).with(%w{deny all allow 127.0.0.1 allow 0.0.0.0})
42
+ no_stdout do
43
+ Server.new(nil, 17165, %w{127.0.0.1 0.0.0.0})
44
+ end
45
+ end
46
+
47
+ # ping
48
+
49
+ def test_ping_should_return_true
50
+ server = nil
51
+ no_stdout do
52
+ server = Server.new
53
+ end
54
+ assert server.ping
55
+ end
25
56
  end
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/helper'
2
2
 
3
3
  class TestTimeline < Test::Unit::TestCase
4
4
  def setup
5
- @timeline = Conditions::Timeline.new(5)
5
+ @timeline = Timeline.new(5)
6
6
  end
7
7
 
8
8
  def test_new_should_be_empty
@@ -14,11 +14,23 @@ class TestTimeline < Test::Unit::TestCase
14
14
  @timeline.push(i)
15
15
  end
16
16
 
17
- assert_equal [10, 9, 8, 7, 6], @timeline
17
+ assert_equal [6, 7, 8, 9, 10], @timeline
18
18
  end
19
19
 
20
20
  def test_clear_should_clear_array
21
21
  @timeline.push(1)
22
22
  assert_equal [], @timeline.clear
23
23
  end
24
+
25
+ # def test_benchmark
26
+ # require 'benchmark'
27
+ #
28
+ # count = 1_000_000
29
+ #
30
+ # t = Timeline.new(10)
31
+ #
32
+ # Benchmark.bmbm do |x|
33
+ # x.report("go") { count.times { t.push(5) } }
34
+ # end
35
+ # end
24
36
  end
data/test/test_watch.rb CHANGED
@@ -41,6 +41,13 @@ class TestWatch < Test::Unit::TestCase
41
41
  assert_equal @watch.mutex, @watch.mutex
42
42
  end
43
43
 
44
+ # valid?
45
+
46
+ def test_valid?
47
+ God::Process.any_instance.expects(:valid?)
48
+ @watch.valid?
49
+ end
50
+
44
51
  # behavior
45
52
 
46
53
  def test_behavior_should_record_behavior
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: god
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.3.0
7
- date: 2007-08-17 00:00:00 -07:00
6
+ version: 0.4.0
7
+ date: 2007-09-10 00:00:00 -07:00
8
8
  summary: Like monit, only awesome
9
9
  require_paths:
10
10
  - lib
@@ -43,20 +43,24 @@ files:
43
43
  - lib/god.rb
44
44
  - lib/god/behavior.rb
45
45
  - lib/god/behaviors/clean_pid_file.rb
46
+ - lib/god/behaviors/notify_when_flapping.rb
46
47
  - lib/god/condition.rb
47
48
  - lib/god/conditions/always.rb
48
49
  - lib/god/conditions/cpu_usage.rb
50
+ - lib/god/conditions/degrading_lambda.rb
49
51
  - lib/god/conditions/lambda.rb
50
52
  - lib/god/conditions/memory_usage.rb
51
53
  - lib/god/conditions/process_exits.rb
52
54
  - lib/god/conditions/process_running.rb
53
- - lib/god/conditions/timeline.rb
55
+ - lib/god/conditions/tries.rb
56
+ - lib/god/dependency_graph.rb
54
57
  - lib/god/errors.rb
55
58
  - lib/god/event_handler.rb
56
59
  - lib/god/event_handlers/dummy_handler.rb
57
60
  - lib/god/event_handlers/kqueue_handler.rb
58
61
  - lib/god/event_handlers/netlink_handler.rb
59
62
  - lib/god/hub.rb
63
+ - lib/god/logger.rb
60
64
  - lib/god/metric.rb
61
65
  - lib/god/process.rb
62
66
  - lib/god/registry.rb
@@ -64,6 +68,7 @@ files:
64
68
  - lib/god/server.rb
65
69
  - lib/god/sugar.rb
66
70
  - lib/god/system/process.rb
71
+ - lib/god/timeline.rb
67
72
  - lib/god/timer.rb
68
73
  - lib/god/watch.rb
69
74
  - test/configs/child_events/child_events.god
@@ -72,17 +77,26 @@ files:
72
77
  - test/configs/child_polls/simple_server.rb
73
78
  - test/configs/daemon_events/daemon_events.god
74
79
  - test/configs/daemon_events/simple_server.rb
80
+ - test/configs/daemon_polls/daemon_polls.god
81
+ - test/configs/daemon_polls/simple_server.rb
82
+ - test/configs/degrading_lambda/degrading_lambda.god
83
+ - test/configs/degrading_lambda/tcp_server.rb
75
84
  - test/configs/real.rb
85
+ - test/configs/running_load/running_load.god
86
+ - test/configs/stress/simple_server.rb
87
+ - test/configs/stress/stress.god
76
88
  - test/configs/test.rb
77
89
  - test/helper.rb
78
90
  - test/suite.rb
79
91
  - test/test_behavior.rb
80
92
  - test/test_condition.rb
81
93
  - test/test_conditions_process_running.rb
94
+ - test/test_dependency_graph.rb
82
95
  - test/test_event_handler.rb
83
96
  - test/test_god.rb
84
97
  - test/test_handlers_kqueue_handler.rb
85
98
  - test/test_hub.rb
99
+ - test/test_logger.rb
86
100
  - test/test_metric.rb
87
101
  - test/test_process.rb
88
102
  - test/test_registry.rb
@@ -97,10 +111,13 @@ test_files:
97
111
  - test/test_behavior.rb
98
112
  - test/test_condition.rb
99
113
  - test/test_conditions_process_running.rb
114
+ - test/test_conditions_tries.rb
115
+ - test/test_dependency_graph.rb
100
116
  - test/test_event_handler.rb
101
117
  - test/test_god.rb
102
118
  - test/test_handlers_kqueue_handler.rb
103
119
  - test/test_hub.rb
120
+ - test/test_logger.rb
104
121
  - test/test_metric.rb
105
122
  - test/test_process.rb
106
123
  - test/test_registry.rb
@@ -132,5 +149,5 @@ dependencies:
132
149
  requirements:
133
150
  - - ">="
134
151
  - !ruby/object:Gem::Version
135
- version: 1.2.1
152
+ version: 1.3.0
136
153
  version: