god 0.7.17 → 0.7.18
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -0
- data/VERSION.yml +1 -1
- data/god.gemspec +3 -3
- data/lib/god/contacts/email.rb +1 -1
- data/lib/god/driver.rb +1 -1
- data/lib/god/logger.rb +2 -2
- data/lib/god/process.rb +27 -10
- data/lib/god/task.rb +9 -1
- data/lib/god/watch.rb +2 -2
- data/site/images/god_logo.png +0 -0
- data/site/index.html +12 -12
- data/site/stylesheets/layout.css +2 -2
- data/test/configs/child_polls/child_polls.god +2 -2
- data/test/helper.rb +12 -24
- data/test/test_behavior.rb +1 -4
- data/test/test_conditions_disk_usage.rb +2 -8
- data/test/test_conditions_http_response_code.rb +2 -2
- data/test/test_conditions_process_running.rb +1 -5
- data/test/test_conditions_tries.rb +1 -1
- data/test/test_god.rb +17 -45
- data/test/test_logger.rb +7 -18
- data/test/test_process.rb +28 -27
- data/test/test_socket.rb +4 -12
- data/test/test_task.rb +26 -42
- data/test/test_watch.rb +9 -9
- metadata +3 -3
- data/site/images/god_logo1.gif +0 -0
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 0.7.18 / 2009-09-09
|
2
|
+
* Minor Enhancements
|
3
|
+
* Better handling of unexpected exceptions in conditions
|
4
|
+
* Added support for running processes in a directory other than '/' [github.com/samhendley]
|
5
|
+
* Bug Fixes
|
6
|
+
* Generate an actual unique identifier for email contact [github.com/underley]
|
7
|
+
|
1
8
|
== 0.7.17 / 2009-08-25
|
2
9
|
* Bug Fixes
|
3
10
|
* Fix the glob and directory config loading for -c option
|
data/VERSION.yml
CHANGED
data/god.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{god}
|
5
|
-
s.version = "0.7.
|
5
|
+
s.version = "0.7.18"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Tom Preston-Werner"]
|
9
|
-
s.date = %q{2009-
|
9
|
+
s.date = %q{2009-09-10}
|
10
10
|
s.default_executable = %q{god}
|
11
11
|
s.description = %q{God is an easy to configure, easy to extend monitoring framework written in Ruby.}
|
12
12
|
s.email = %q{tom@mojombo.com}
|
@@ -96,7 +96,7 @@ Gem::Specification.new do |s|
|
|
96
96
|
"site/images/corner_green.gif",
|
97
97
|
"site/images/corner_green.psd",
|
98
98
|
"site/images/corner_pink.gif",
|
99
|
-
"site/images/
|
99
|
+
"site/images/god_logo.png",
|
100
100
|
"site/images/header_bg.gif",
|
101
101
|
"site/images/header_bg.jpg",
|
102
102
|
"site/images/red_dot.gif",
|
data/lib/god/contacts/email.rb
CHANGED
@@ -30,7 +30,7 @@ From: god <#{self.message_settings[:from]}>
|
|
30
30
|
To: #{name} <#{email}>
|
31
31
|
Subject: [god] #{message}
|
32
32
|
Date: #{Time.now.httpdate}
|
33
|
-
Message-Id:
|
33
|
+
Message-Id: <#{rand(1000000000).to_s(36)}.#{$$}.#{self.message_settings[:from]}>
|
34
34
|
|
35
35
|
Message: #{message}
|
36
36
|
Host: #{host}
|
data/lib/god/driver.rb
CHANGED
@@ -167,7 +167,7 @@ module God
|
|
167
167
|
rescue ThreadError => e
|
168
168
|
# queue is empty
|
169
169
|
break
|
170
|
-
rescue
|
170
|
+
rescue Object => e
|
171
171
|
message = format("Unhandled exception in driver loop - (%s): %s\n%s",
|
172
172
|
e.class, e.message, e.backtrace.join("\n"))
|
173
173
|
applog(nil, :fatal, message)
|
data/lib/god/logger.rb
CHANGED
data/lib/god/process.rb
CHANGED
@@ -2,7 +2,8 @@ module God
|
|
2
2
|
class Process
|
3
3
|
WRITES_PID = [:start, :restart]
|
4
4
|
|
5
|
-
attr_accessor :name, :uid, :gid, :log, :log_cmd, :start, :stop, :restart,
|
5
|
+
attr_accessor :name, :uid, :gid, :log, :log_cmd, :start, :stop, :restart,
|
6
|
+
:unix_socket, :chroot, :env, :dir
|
6
7
|
|
7
8
|
def initialize
|
8
9
|
self.log = '/dev/null'
|
@@ -25,13 +26,17 @@ module God
|
|
25
26
|
|
26
27
|
def file_writable?(file)
|
27
28
|
pid = fork do
|
28
|
-
|
29
|
-
|
29
|
+
begin
|
30
|
+
uid_num = Etc.getpwnam(self.uid).uid if self.uid
|
31
|
+
gid_num = Etc.getgrnam(self.gid).gid if self.gid
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
::Dir.chroot(self.chroot) if self.chroot
|
34
|
+
::Process.groups = [gid_num] if self.gid
|
35
|
+
::Process::Sys.setgid(gid_num) if self.gid
|
36
|
+
::Process::Sys.setuid(uid_num) if self.uid
|
37
|
+
rescue ArgumentError, Errno::EPERM, Errno::ENOENT
|
38
|
+
exit(1)
|
39
|
+
end
|
35
40
|
|
36
41
|
File.writable?(file_in_chroot(file)) ? exit(0) : exit(1)
|
37
42
|
end
|
@@ -72,6 +77,17 @@ module God
|
|
72
77
|
end
|
73
78
|
end
|
74
79
|
|
80
|
+
# dir must exist and be a directory if specified
|
81
|
+
if self.dir
|
82
|
+
if !File.exist?(self.dir)
|
83
|
+
valid = false
|
84
|
+
applog(self, :error, "Specified directory '#{self.dir}' does not exist")
|
85
|
+
elsif !File.directory?(self.dir)
|
86
|
+
valid = false
|
87
|
+
applog(self, :error, "Specified directory '#{self.dir}' is not a directory")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
75
91
|
# pid dir must exist if specified
|
76
92
|
if !@tracking_pid && !File.exist?(File.dirname(self.pid_file))
|
77
93
|
valid = false
|
@@ -107,12 +123,12 @@ module God
|
|
107
123
|
if self.chroot
|
108
124
|
if !File.directory?(self.chroot)
|
109
125
|
valid = false
|
110
|
-
|
126
|
+
applog(self, :error, "CHROOT directory '#{self.chroot}' does not exist")
|
111
127
|
end
|
112
128
|
|
113
129
|
if !File.exist?(File.join(self.chroot, '/dev/null'))
|
114
130
|
valid = false
|
115
|
-
|
131
|
+
applog(self, :error, "CHROOT directory '#{self.chroot}' does not contain '/dev/null'")
|
116
132
|
end
|
117
133
|
end
|
118
134
|
|
@@ -275,7 +291,8 @@ module God
|
|
275
291
|
::Process.groups = [gid_num] if self.gid
|
276
292
|
::Process::Sys.setgid(gid_num) if self.gid
|
277
293
|
::Process::Sys.setuid(uid_num) if self.uid
|
278
|
-
|
294
|
+
self.dir ||= '/'
|
295
|
+
Dir.chdir self.dir
|
279
296
|
$0 = command
|
280
297
|
STDIN.reopen "/dev/null"
|
281
298
|
if self.log_cmd
|
data/lib/god/task.rb
CHANGED
@@ -318,7 +318,15 @@ module God
|
|
318
318
|
metric = self.directory[condition]
|
319
319
|
|
320
320
|
# run the test
|
321
|
-
|
321
|
+
begin
|
322
|
+
result = condition.test
|
323
|
+
rescue Object => e
|
324
|
+
cname = condition.class.to_s.split('::').last
|
325
|
+
message = format("Unhandled exception in %s condition - (%s): %s\n%s",
|
326
|
+
cname, e.class, e.message, e.backtrace.join("\n"))
|
327
|
+
applog(self, :error, message)
|
328
|
+
result = false
|
329
|
+
end
|
322
330
|
|
323
331
|
# log
|
324
332
|
messages = self.log_line(self, metric, condition, result)
|
data/lib/god/watch.rb
CHANGED
@@ -11,8 +11,8 @@ module God
|
|
11
11
|
attr_accessor :grace, :start_grace, :stop_grace, :restart_grace
|
12
12
|
|
13
13
|
extend Forwardable
|
14
|
-
def_delegators :@process, :name, :uid, :gid, :start, :stop, :restart,
|
15
|
-
:name=, :uid=, :gid=, :start=, :stop=, :restart=,
|
14
|
+
def_delegators :@process, :name, :uid, :gid, :start, :stop, :restart, :dir,
|
15
|
+
:name=, :uid=, :gid=, :start=, :stop=, :restart=, :dir=,
|
16
16
|
:pid_file, :pid_file=, :log, :log=, :log_cmd, :log_cmd=, :alive?, :pid,
|
17
17
|
:unix_socket, :unix_socket=, :chroot, :chroot=, :env, :env=, :signal
|
18
18
|
#
|
Binary file
|
data/site/index.html
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
3
3
|
<head>
|
4
4
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
5
|
-
<title>
|
5
|
+
<title>God - A Process Monitoring Framework in Ruby</title>
|
6
6
|
<link href="stylesheets/layout.css" rel="stylesheet" type="text/css" />
|
7
7
|
<script type="text/javascript" src="javascripts/code_highlighter.js"></script>
|
8
8
|
<script type="text/javascript" src="javascripts/ruby.js"></script>
|
@@ -31,7 +31,7 @@
|
|
31
31
|
<h1>A Better Way to Monitor</h1>
|
32
32
|
<p>God is an easy to configure, easy to extend monitoring framework written in Ruby.</p>
|
33
33
|
<p>Keeping your server processes and tasks running should be a simple part of your deployment process. God aims to be the simplest, most powerful monitoring application available.</p>
|
34
|
-
<p style="text-align: right">Tom Preston-Werner<br
|
34
|
+
<p style="text-align: right">Tom Preston-Werner<br /><a href="mailto:tom@mojombo.com">tom@mojombo.com</a></p>
|
35
35
|
<p style="text-align: right">Google Group: <a href="http://groups.google.com/group/god-rb">http://groups.google.com/group/god-rb</a></p>
|
36
36
|
</div>
|
37
37
|
|
@@ -47,7 +47,7 @@
|
|
47
47
|
</ul>
|
48
48
|
</div>
|
49
49
|
|
50
|
-
<h1>Installation (v 0.7.
|
50
|
+
<h1>Installation (v 0.7.17)</h1>
|
51
51
|
<p>The best way to get god is via rubygems:</p>
|
52
52
|
<pre>$ sudo gem install god</pre>
|
53
53
|
|
@@ -69,10 +69,10 @@
|
|
69
69
|
<li>CentOS 4.5 (no events)</li>
|
70
70
|
</ul>
|
71
71
|
|
72
|
-
<h1>
|
73
|
-
<p>The easiest way to understand how god will make your life better is by looking at a sample config file. The following configuration file is what I
|
72
|
+
<h1>Config Files are Ruby Code!</h1>
|
73
|
+
<p>The easiest way to understand how god will make your life better is by looking at a sample config file. The following configuration file is what I once used at <a href="http://site.gravatar.com/">gravatar.com</a> to keep the mongrels running:</p>
|
74
74
|
|
75
|
-
<pre><code class="ruby"># run with:
|
75
|
+
<pre><code class="ruby"># run with: god -c /path/to/mongrel.god -D
|
76
76
|
#
|
77
77
|
# This is the actual config file used to keep the mongrels of
|
78
78
|
# gravatar.com running.
|
@@ -207,7 +207,7 @@ end</code></pre>
|
|
207
207
|
|
208
208
|
<p>The <code>:flapping</code> condition guards against the edge case wherein god rapidly starts or restarts your application. Things like server configuration changes or the unavailability of external services could make it impossible for my process to start. In that case, god will try to start my process over and over to no avail. The <code>:flapping</code> condition provides two levels of giving up on flapping processes. If I were to translate the options of the code above, it would be something like: If this watch is started or restarted five times withing 5 minutes, then unmonitor it...then after ten minutes, monitor it again to see if it was just a temporary problem; if the process is seen to be flapping five times within two hours, then give up completely.</p>
|
209
209
|
|
210
|
-
<p>That's it
|
210
|
+
<p>That's it!</p>
|
211
211
|
|
212
212
|
<!-- ------------------------------------------------------------------------- -->
|
213
213
|
|
@@ -462,13 +462,13 @@ God.load "/usr/local/conf/*.god"</code></pre>
|
|
462
462
|
|
463
463
|
<h1>Getting Logs for a Single Watch</h1>
|
464
464
|
|
465
|
-
<p>Sifting through the god logs for statements specific to a
|
465
|
+
<p>Sifting through the god logs for statements specific to a single Watch can be frustrating when you have many of them. You can get the realtime logs for a single Watch via the command line:</p>
|
466
466
|
|
467
467
|
<pre>$ sudo god log local-3000</pre>
|
468
468
|
|
469
|
-
<p>This will display
|
469
|
+
<p>This will display log output for the 'local-3000' Watch and update every second with new log messages.</p>
|
470
470
|
|
471
|
-
<p>You can also supply a shorthand to the log command that will match one of your watches. If it happens to match several, the
|
471
|
+
<p>You can also supply a shorthand to the log command that will match one of your watches. If it happens to match several, the shortest match will be used:</p>
|
472
472
|
|
473
473
|
<pre>$ sudo god log l3</pre>
|
474
474
|
|
@@ -536,7 +536,7 @@ end</code></pre>
|
|
536
536
|
To: tom <tom@example.com>
|
537
537
|
Subject: [god] mongrel-8600 [trigger] process exited (ProcessExits)
|
538
538
|
|
539
|
-
Message:
|
539
|
+
Message: mongrel-8600 [trigger] process exited (ProcessExits)
|
540
540
|
Host: candymountain.example.com
|
541
541
|
Priority: 1
|
542
542
|
Category: product</code></pre>
|
@@ -549,7 +549,7 @@ Category: product</code></pre>
|
|
549
549
|
|
550
550
|
</div>
|
551
551
|
<div id="footer">
|
552
|
-
<p>Brought to you by <a href="http://
|
552
|
+
<p>Brought to you by <a href="http://tom.preston-werner.com/">Tom Preston-Werner</a></p>
|
553
553
|
</div>
|
554
554
|
|
555
555
|
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
data/site/stylesheets/layout.css
CHANGED
@@ -23,7 +23,7 @@ a:active {
|
|
23
23
|
width: 307px;
|
24
24
|
height: 117px;
|
25
25
|
margin: 0 auto;
|
26
|
-
background: url(../images/
|
26
|
+
background: url(../images/god_logo.png);
|
27
27
|
}
|
28
28
|
|
29
29
|
#content {
|
@@ -90,7 +90,7 @@ a:active {
|
|
90
90
|
|
91
91
|
.columnleft {
|
92
92
|
float: left;
|
93
|
-
width:
|
93
|
+
width: 345px;
|
94
94
|
margin-bottom: 20px;
|
95
95
|
}
|
96
96
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
God.watch do |w|
|
2
2
|
w.name = 'child-polls'
|
3
|
-
w.start = File.join(GOD_ROOT, *%w[test configs child_polls simple_server.rb])
|
3
|
+
w.start = File.join(GOD_ROOT, *%w[test configs child_polls simple_server.rb]) + ' ' + ENV['RAILS_ENV']
|
4
4
|
w.interval = 5
|
5
5
|
w.grace = 2
|
6
6
|
|
@@ -34,4 +34,4 @@ God.watch do |w|
|
|
34
34
|
c.retry_within = 5.minutes
|
35
35
|
end
|
36
36
|
end
|
37
|
-
end
|
37
|
+
end
|
data/test/helper.rb
CHANGED
@@ -6,17 +6,17 @@ require 'set'
|
|
6
6
|
|
7
7
|
include God
|
8
8
|
|
9
|
-
if Process.uid != 0
|
10
|
-
|
11
|
-
\n
|
12
|
-
*********************************************************************
|
13
|
-
* *
|
14
|
-
* You need to run these tests as root *
|
15
|
-
* chroot and netlink (linux only) require it *
|
16
|
-
* *
|
17
|
-
*********************************************************************
|
18
|
-
EOF
|
19
|
-
end
|
9
|
+
# if Process.uid != 0
|
10
|
+
# abort <<-EOF
|
11
|
+
# \n
|
12
|
+
# *********************************************************************
|
13
|
+
# * *
|
14
|
+
# * You need to run these tests as root *
|
15
|
+
# * chroot and netlink (linux only) require it *
|
16
|
+
# * *
|
17
|
+
# *********************************************************************
|
18
|
+
# EOF
|
19
|
+
# end
|
20
20
|
|
21
21
|
begin
|
22
22
|
require 'mocha'
|
@@ -90,19 +90,7 @@ ensure
|
|
90
90
|
$VERBOSE = old_verbose
|
91
91
|
end
|
92
92
|
|
93
|
-
|
94
|
-
old_stdout = $stdout.dup
|
95
|
-
$stdout.reopen(File.open((PLATFORM =~ /mswin/ ? "NUL" : "/dev/null"), 'w'))
|
96
|
-
yield
|
97
|
-
$stdout.reopen(old_stdout)
|
98
|
-
end
|
99
|
-
|
100
|
-
def no_stderr
|
101
|
-
old_stderr = $stderr.dup
|
102
|
-
$stderr.reopen(File.open((PLATFORM =~ /mswin/ ? "NUL" : "/dev/null"), 'w'))
|
103
|
-
yield
|
104
|
-
$stderr.reopen(old_stderr)
|
105
|
-
end
|
93
|
+
LOG.instance_variable_set(:@io, StringIO.new('/dev/null'))
|
106
94
|
|
107
95
|
module Kernel
|
108
96
|
def abort(text)
|
data/test/test_behavior.rb
CHANGED
@@ -13,9 +13,6 @@ class TestBehavior < Test::Unit::TestCase
|
|
13
13
|
|
14
14
|
def test_complain
|
15
15
|
Syslog.expects(:err).with('foo')
|
16
|
-
|
17
|
-
no_stdout do
|
18
|
-
assert !Behavior.allocate.bypass.complain('foo')
|
19
|
-
end
|
16
|
+
assert !Behavior.allocate.bypass.complain('foo')
|
20
17
|
end
|
21
18
|
end
|
@@ -7,20 +7,14 @@ class TestConditionsDiskUsage < Test::Unit::TestCase
|
|
7
7
|
c = Conditions::DiskUsage.new
|
8
8
|
c.mount_point = '/'
|
9
9
|
c.watch = stub(:name => 'foo')
|
10
|
-
|
11
|
-
no_stdout do
|
12
|
-
assert_equal false, c.valid?
|
13
|
-
end
|
10
|
+
assert_equal false, c.valid?
|
14
11
|
end
|
15
12
|
|
16
13
|
def test_valid_should_return_false_if_no_mount_point_given
|
17
14
|
c = Conditions::DiskUsage.new
|
18
15
|
c.above = 90
|
19
16
|
c.watch = stub(:name => 'foo')
|
20
|
-
|
21
|
-
no_stdout do
|
22
|
-
assert_equal false, c.valid?
|
23
|
-
end
|
17
|
+
assert_equal false, c.valid?
|
24
18
|
end
|
25
19
|
|
26
20
|
def test_valid_should_return_true_if_required_options_all_set
|
@@ -26,14 +26,14 @@ class TestHttpResponseCode < Test::Unit::TestCase
|
|
26
26
|
c = valid_condition do |cc|
|
27
27
|
cc.code_is_not = 500
|
28
28
|
end
|
29
|
-
|
29
|
+
assert !c.valid?
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_valid_should_return_false_if_no_host_set
|
33
33
|
c = valid_condition do |cc|
|
34
34
|
cc.host = nil
|
35
35
|
end
|
36
|
-
|
36
|
+
assert !c.valid?
|
37
37
|
end
|
38
38
|
|
39
39
|
# test
|
@@ -5,12 +5,8 @@ class TestConditionsProcessRunning < Test::Unit::TestCase
|
|
5
5
|
[true, false].each do |r|
|
6
6
|
c = Conditions::ProcessRunning.new
|
7
7
|
c.running = r
|
8
|
-
|
9
8
|
c.stubs(:watch).returns(stub(:pid => 99999999, :name => 'foo'))
|
10
|
-
|
11
|
-
# no_stdout do
|
12
|
-
assert_equal !r, c.test
|
13
|
-
# end
|
9
|
+
assert_equal !r, c.test
|
14
10
|
end
|
15
11
|
end
|
16
12
|
|
data/test/test_god.rb
CHANGED
@@ -164,9 +164,7 @@ class TestGod < Test::Unit::TestCase
|
|
164
164
|
God.running = true
|
165
165
|
|
166
166
|
assert_nothing_raised do
|
167
|
-
|
168
|
-
God.watch { |w| w.name = 'foo'; w.start = 'bar' }
|
169
|
-
end
|
167
|
+
God.watch { |w| w.name = 'foo'; w.start = 'bar' }
|
170
168
|
end
|
171
169
|
end
|
172
170
|
|
@@ -177,26 +175,20 @@ class TestGod < Test::Unit::TestCase
|
|
177
175
|
w = God.watches['bar']
|
178
176
|
w.state = :up
|
179
177
|
w.expects(:unmonitor)
|
180
|
-
|
181
|
-
God.unwatch(w)
|
182
|
-
end
|
178
|
+
God.unwatch(w)
|
183
179
|
end
|
184
180
|
|
185
181
|
def test_unwatch_should_unregister_watch
|
186
182
|
God.watch { |w| w.name = 'bar'; w.start = 'bar' }
|
187
183
|
w = God.watches['bar']
|
188
184
|
w.expects(:unregister!)
|
189
|
-
|
190
|
-
God.unwatch(w)
|
191
|
-
end
|
185
|
+
God.unwatch(w)
|
192
186
|
end
|
193
187
|
|
194
188
|
def test_unwatch_should_remove_same_name_watches
|
195
189
|
God.watch { |w| w.name = 'bar'; w.start = 'bar' }
|
196
190
|
w = God.watches['bar']
|
197
|
-
|
198
|
-
God.unwatch(w)
|
199
|
-
end
|
191
|
+
God.unwatch(w)
|
200
192
|
assert_equal 0, God.watches.size
|
201
193
|
end
|
202
194
|
|
@@ -207,9 +199,7 @@ class TestGod < Test::Unit::TestCase
|
|
207
199
|
w.group = 'test'
|
208
200
|
end
|
209
201
|
w = God.watches['bar']
|
210
|
-
|
211
|
-
God.unwatch(w)
|
212
|
-
end
|
202
|
+
God.unwatch(w)
|
213
203
|
assert !God.groups[w.group].include?(w)
|
214
204
|
end
|
215
205
|
|
@@ -239,28 +229,22 @@ class TestGod < Test::Unit::TestCase
|
|
239
229
|
end
|
240
230
|
|
241
231
|
def test_contact_should_abort_on_no_name
|
242
|
-
|
243
|
-
|
244
|
-
God.contact(:fake_contact) { |c| }
|
245
|
-
end
|
232
|
+
assert_abort do
|
233
|
+
God.contact(:fake_contact) { |c| }
|
246
234
|
end
|
247
235
|
end
|
248
236
|
|
249
237
|
def test_contact_should_abort_on_duplicate_contact_name
|
250
238
|
God.contact(:fake_contact) { |c| c.name = 'tom' }
|
251
|
-
|
252
|
-
|
253
|
-
God.contact(:fake_contact) { |c| c.name = 'tom' }
|
254
|
-
end
|
239
|
+
assert_nothing_raised do
|
240
|
+
God.contact(:fake_contact) { |c| c.name = 'tom' }
|
255
241
|
end
|
256
242
|
end
|
257
243
|
|
258
244
|
def test_contact_should_abort_on_contact_with_same_name_as_group
|
259
245
|
God.contact(:fake_contact) { |c| c.name = 'tom'; c.group = 'devs' }
|
260
|
-
|
261
|
-
|
262
|
-
God.contact(:fake_contact) { |c| c.name = 'devs' }
|
263
|
-
end
|
246
|
+
assert_nothing_raised do
|
247
|
+
God.contact(:fake_contact) { |c| c.name = 'devs' }
|
264
248
|
end
|
265
249
|
end
|
266
250
|
|
@@ -422,9 +406,7 @@ class TestGod < Test::Unit::TestCase
|
|
422
406
|
end
|
423
407
|
EOF
|
424
408
|
|
425
|
-
|
426
|
-
God.running_load(code, '/foo/bar.god')
|
427
|
-
end
|
409
|
+
God.running_load(code, '/foo/bar.god')
|
428
410
|
|
429
411
|
assert_equal 1, God.watches.size
|
430
412
|
end
|
@@ -438,9 +420,7 @@ class TestGod < Test::Unit::TestCase
|
|
438
420
|
EOF
|
439
421
|
|
440
422
|
Watch.any_instance.expects(:monitor)
|
441
|
-
|
442
|
-
God.running_load(code, '/foo/bar.god')
|
443
|
-
end
|
423
|
+
God.running_load(code, '/foo/bar.god')
|
444
424
|
end
|
445
425
|
|
446
426
|
def test_running_load_should_not_monitor_new_watches_with_autostart_false
|
@@ -453,9 +433,7 @@ class TestGod < Test::Unit::TestCase
|
|
453
433
|
EOF
|
454
434
|
|
455
435
|
Watch.any_instance.expects(:monitor).never
|
456
|
-
|
457
|
-
God.running_load(code, '/foo/bar.god')
|
458
|
-
end
|
436
|
+
God.running_load(code, '/foo/bar.god')
|
459
437
|
end
|
460
438
|
|
461
439
|
def test_running_load_should_return_array_of_affected_watches
|
@@ -467,9 +445,7 @@ class TestGod < Test::Unit::TestCase
|
|
467
445
|
EOF
|
468
446
|
|
469
447
|
w = nil
|
470
|
-
|
471
|
-
w, e = *God.running_load(code, '/foo/bar.god')
|
472
|
-
end
|
448
|
+
w, e = *God.running_load(code, '/foo/bar.god')
|
473
449
|
assert_equal 1, w.size
|
474
450
|
assert_equal 'foo', w.first
|
475
451
|
end
|
@@ -482,9 +458,7 @@ class TestGod < Test::Unit::TestCase
|
|
482
458
|
end
|
483
459
|
EOF
|
484
460
|
|
485
|
-
|
486
|
-
God.running_load(code, '/foo/bar.god')
|
487
|
-
end
|
461
|
+
God.running_load(code, '/foo/bar.god')
|
488
462
|
assert_equal 0, God.pending_watches.size
|
489
463
|
end
|
490
464
|
|
@@ -527,9 +501,7 @@ class TestGod < Test::Unit::TestCase
|
|
527
501
|
|
528
502
|
def test_start_should_get_and_join_timer
|
529
503
|
God.watch { |w| w.name = 'foo'; w.start = 'bar' }
|
530
|
-
|
531
|
-
God.start
|
532
|
-
end
|
504
|
+
God.start
|
533
505
|
end
|
534
506
|
|
535
507
|
# at_exit
|
data/test/test_logger.rb
CHANGED
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/helper'
|
|
2
2
|
|
3
3
|
class TestLogger < Test::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
@log = God::Logger.new
|
5
|
+
@log = God::Logger.new(StringIO.new('/dev/null'))
|
6
6
|
end
|
7
7
|
|
8
8
|
# log
|
@@ -11,9 +11,7 @@ class TestLogger < Test::Unit::TestCase
|
|
11
11
|
@log.watch_log_since('foo', Time.now)
|
12
12
|
@log.expects(:info).with("qux")
|
13
13
|
|
14
|
-
|
15
|
-
@log.log(stub(:name => 'foo'), :info, "qux")
|
16
|
-
end
|
14
|
+
@log.log(stub(:name => 'foo'), :info, "qux")
|
17
15
|
|
18
16
|
assert_equal 1, @log.logs.size
|
19
17
|
assert_instance_of Time, @log.logs['foo'][0][0]
|
@@ -22,10 +20,7 @@ class TestLogger < Test::Unit::TestCase
|
|
22
20
|
|
23
21
|
def test_log_should_send_to_syslog
|
24
22
|
Syslog.expects(:crit).with('foo')
|
25
|
-
|
26
|
-
no_stdout do
|
27
|
-
@log.log(stub(:name => 'foo'), :fatal, "foo")
|
28
|
-
end
|
23
|
+
@log.log(stub(:name => 'foo'), :fatal, "foo")
|
29
24
|
end
|
30
25
|
|
31
26
|
# watch_log_since
|
@@ -35,18 +30,14 @@ class TestLogger < Test::Unit::TestCase
|
|
35
30
|
|
36
31
|
@log.watch_log_since('foo', t1)
|
37
32
|
|
38
|
-
|
39
|
-
|
40
|
-
@log.log(stub(:name => 'foo'), :info, "two")
|
41
|
-
end
|
33
|
+
@log.log(stub(:name => 'foo'), :info, "one")
|
34
|
+
@log.log(stub(:name => 'foo'), :info, "two")
|
42
35
|
|
43
36
|
assert_match(/one.*two/m, @log.watch_log_since('foo', t1))
|
44
37
|
|
45
38
|
t2 = Time.now
|
46
39
|
|
47
|
-
|
48
|
-
@log.log(stub(:name => 'foo'), :info, "three")
|
49
|
-
end
|
40
|
+
@log.log(stub(:name => 'foo'), :info, "three")
|
50
41
|
|
51
42
|
out = @log.watch_log_since('foo', t2)
|
52
43
|
|
@@ -58,9 +49,7 @@ class TestLogger < Test::Unit::TestCase
|
|
58
49
|
# regular methods
|
59
50
|
|
60
51
|
def test_fatal
|
61
|
-
|
62
|
-
@log.fatal('foo')
|
63
|
-
end
|
52
|
+
@log.fatal('foo')
|
64
53
|
assert_equal 0, @log.logs.size
|
65
54
|
end
|
66
55
|
end
|
data/test/test_process.rb
CHANGED
@@ -53,11 +53,7 @@ class TestProcessChild < Test::Unit::TestCase
|
|
53
53
|
@p.log = '/tmp/foo.log'
|
54
54
|
@p.uid = 'foobarbaz'
|
55
55
|
|
56
|
-
|
57
|
-
no_stderr do
|
58
|
-
assert !@p.valid?
|
59
|
-
end
|
60
|
-
end
|
56
|
+
assert !@p.valid?
|
61
57
|
end
|
62
58
|
|
63
59
|
def test_valid_should_return_true_if_gid_exists
|
@@ -73,21 +69,37 @@ class TestProcessChild < Test::Unit::TestCase
|
|
73
69
|
@p.log = '/tmp/foo.log'
|
74
70
|
@p.gid = 'foobarbaz'
|
75
71
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
72
|
+
assert !@p.valid?
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_valid_should_return_true_if_dir_exists
|
76
|
+
@p.start = 'qux'
|
77
|
+
@p.log = '/tmp/foo.log'
|
78
|
+
@p.dir = '/tmp'
|
79
|
+
|
80
|
+
assert @p.valid?
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_valid_should_return_false_if_dir_does_not_exists
|
84
|
+
@p.start = 'qux'
|
85
|
+
@p.log = '/tmp/foo.log'
|
86
|
+
@p.dir = '/tmp/doesnotexist'
|
87
|
+
|
88
|
+
assert !@p.valid?
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_valid_should_return_false_if_dir_is_not_a_dir
|
92
|
+
@p.start = 'qux'
|
93
|
+
@p.log = '/tmp/foo.log'
|
94
|
+
@p.dir = '/etc/passwd'
|
95
|
+
|
96
|
+
assert !@p.valid?
|
81
97
|
end
|
82
98
|
|
83
99
|
def test_valid_should_return_false_with_bogus_chroot
|
84
100
|
@p.chroot = '/bogusroot'
|
85
101
|
|
86
|
-
|
87
|
-
no_stderr do
|
88
|
-
assert !@p.valid?
|
89
|
-
end
|
90
|
-
end
|
102
|
+
assert !@p.valid?
|
91
103
|
end
|
92
104
|
|
93
105
|
def test_valid_should_return_true_with_chroot_and_valid_log
|
@@ -152,18 +164,7 @@ class TestProcessDaemon < Test::Unit::TestCase
|
|
152
164
|
def test_valid_should_return_false_if_no_start
|
153
165
|
@p.name = 'foo'
|
154
166
|
@p.stop = 'baz'
|
155
|
-
|
156
|
-
assert !@p.valid?
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
def test_valid_should_return_false_if_self_daemonized_and_no_stop
|
161
|
-
@p.start = 'bar'
|
162
|
-
@p.pid_file = 'foo'
|
163
|
-
|
164
|
-
no_stdout do
|
165
|
-
assert !@p.valid?
|
166
|
-
end
|
167
|
+
assert !@p.valid?
|
167
168
|
end
|
168
169
|
|
169
170
|
# pid
|
data/test/test_socket.rb
CHANGED
@@ -9,23 +9,17 @@ class TestSocket < Test::Unit::TestCase
|
|
9
9
|
|
10
10
|
def test_should_start_a_drb_server
|
11
11
|
DRb.expects(:start_service)
|
12
|
-
|
13
|
-
God::Socket.new
|
14
|
-
end
|
12
|
+
God::Socket.new
|
15
13
|
end
|
16
14
|
|
17
15
|
def test_should_use_supplied_port_and_host
|
18
16
|
DRb.expects(:start_service).with { |uri, object| uri == "drbunix:///tmp/god.9999.sock" && object.is_a?(God::Socket) }
|
19
|
-
|
20
|
-
server = God::Socket.new(9999)
|
21
|
-
end
|
17
|
+
server = God::Socket.new(9999)
|
22
18
|
end
|
23
19
|
|
24
20
|
def test_should_forward_foreign_method_calls_to_god
|
25
21
|
server = nil
|
26
|
-
|
27
|
-
server = God::Socket.new
|
28
|
-
end
|
22
|
+
server = God::Socket.new
|
29
23
|
God.expects(:send).with(:something_random)
|
30
24
|
server.something_random
|
31
25
|
end
|
@@ -34,9 +28,7 @@ class TestSocket < Test::Unit::TestCase
|
|
34
28
|
|
35
29
|
def test_ping_should_return_true
|
36
30
|
server = nil
|
37
|
-
|
38
|
-
server = God::Socket.new
|
39
|
-
end
|
31
|
+
server = God::Socket.new
|
40
32
|
assert server.ping
|
41
33
|
end
|
42
34
|
end
|
data/test/test_task.rb
CHANGED
@@ -15,23 +15,17 @@ class TestTask < Test::Unit::TestCase
|
|
15
15
|
|
16
16
|
def test_valid_should_return_false_if_no_name
|
17
17
|
@task.name = nil
|
18
|
-
|
19
|
-
assert !@task.valid?
|
20
|
-
end
|
18
|
+
assert !@task.valid?
|
21
19
|
end
|
22
20
|
|
23
21
|
def test_valid_should_return_false_if_no_valid_states
|
24
22
|
@task.valid_states = nil
|
25
|
-
|
26
|
-
assert !@task.valid?
|
27
|
-
end
|
23
|
+
assert !@task.valid?
|
28
24
|
end
|
29
25
|
|
30
26
|
def test_valid_should_return_false_if_no_initial_state
|
31
27
|
@task.initial_state = nil
|
32
|
-
|
33
|
-
assert !@task.valid?
|
34
|
-
end
|
28
|
+
assert !@task.valid?
|
35
29
|
end
|
36
30
|
|
37
31
|
# transition
|
@@ -69,14 +63,14 @@ class TestTask < Test::Unit::TestCase
|
|
69
63
|
@task.foo = 'foo'
|
70
64
|
Thread.current.stubs(:==).returns(true)
|
71
65
|
@task.expects(:system).with('foo')
|
72
|
-
|
66
|
+
@task.action(:foo, nil)
|
73
67
|
end
|
74
68
|
|
75
69
|
def test_action_should_call_lambda_commands
|
76
70
|
@task.foo = lambda { }
|
77
71
|
Thread.current.stubs(:==).returns(true)
|
78
72
|
@task.foo.expects(:call)
|
79
|
-
|
73
|
+
@task.action(:foo, nil)
|
80
74
|
end
|
81
75
|
|
82
76
|
def test_action_should_raise_not_implemented_on_non_string_or_lambda_action
|
@@ -142,10 +136,7 @@ class TestTask < Test::Unit::TestCase
|
|
142
136
|
|
143
137
|
c.expects(:test).returns(false)
|
144
138
|
@task.driver.expects(:schedule)
|
145
|
-
|
146
|
-
no_stdout do
|
147
|
-
@task.handle_poll(c)
|
148
|
-
end
|
139
|
+
@task.handle_poll(c)
|
149
140
|
end
|
150
141
|
|
151
142
|
def test_handle_poll_change_should_move
|
@@ -158,10 +149,7 @@ class TestTask < Test::Unit::TestCase
|
|
158
149
|
|
159
150
|
c.expects(:test).returns(true)
|
160
151
|
@task.expects(:move).with(:up)
|
161
|
-
|
162
|
-
no_stdout do
|
163
|
-
@task.handle_poll(c)
|
164
|
-
end
|
152
|
+
@task.handle_poll(c)
|
165
153
|
end
|
166
154
|
|
167
155
|
def test_handle_poll_should_use_overridden_transition
|
@@ -175,10 +163,7 @@ class TestTask < Test::Unit::TestCase
|
|
175
163
|
@task.directory[c] = m
|
176
164
|
|
177
165
|
@task.expects(:move).with(:start)
|
178
|
-
|
179
|
-
no_stdout do
|
180
|
-
@task.handle_poll(c)
|
181
|
-
end
|
166
|
+
@task.handle_poll(c)
|
182
167
|
end
|
183
168
|
|
184
169
|
def test_handle_poll_should_notify_if_triggering
|
@@ -192,10 +177,7 @@ class TestTask < Test::Unit::TestCase
|
|
192
177
|
|
193
178
|
c.expects(:test).returns(true)
|
194
179
|
@task.expects(:notify)
|
195
|
-
|
196
|
-
no_stdout do
|
197
|
-
@task.handle_poll(c)
|
198
|
-
end
|
180
|
+
@task.handle_poll(c)
|
199
181
|
end
|
200
182
|
|
201
183
|
def test_handle_poll_should_not_notify_if_not_triggering
|
@@ -209,10 +191,21 @@ class TestTask < Test::Unit::TestCase
|
|
209
191
|
|
210
192
|
c.expects(:test).returns(false)
|
211
193
|
@task.expects(:notify).never
|
194
|
+
@task.handle_poll(c)
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_handle_poll_unexpected_exception_should_reschedule
|
198
|
+
c = Conditions::FakePollCondition.new
|
199
|
+
c.watch = @task
|
200
|
+
c.interval = 10
|
212
201
|
|
213
|
-
|
214
|
-
|
215
|
-
|
202
|
+
m = Metric.new(@task, {true => :up})
|
203
|
+
@task.directory[c] = m
|
204
|
+
|
205
|
+
c.expects(:test).raises(StandardError)
|
206
|
+
@task.driver.expects(:schedule)
|
207
|
+
|
208
|
+
@task.handle_poll(c)
|
216
209
|
end
|
217
210
|
|
218
211
|
# handle_event
|
@@ -225,10 +218,7 @@ class TestTask < Test::Unit::TestCase
|
|
225
218
|
@task.directory[c] = m
|
226
219
|
|
227
220
|
@task.expects(:move).with(:up)
|
228
|
-
|
229
|
-
no_stdout do
|
230
|
-
@task.handle_event(c)
|
231
|
-
end
|
221
|
+
@task.handle_event(c)
|
232
222
|
end
|
233
223
|
|
234
224
|
def test_handle_event_should_notify_if_triggering
|
@@ -240,10 +230,7 @@ class TestTask < Test::Unit::TestCase
|
|
240
230
|
@task.directory[c] = m
|
241
231
|
|
242
232
|
@task.expects(:notify)
|
243
|
-
|
244
|
-
no_stdout do
|
245
|
-
@task.handle_event(c)
|
246
|
-
end
|
233
|
+
@task.handle_event(c)
|
247
234
|
end
|
248
235
|
|
249
236
|
def test_handle_event_should_not_notify_if_no_notify_set
|
@@ -254,9 +241,6 @@ class TestTask < Test::Unit::TestCase
|
|
254
241
|
@task.directory[c] = m
|
255
242
|
|
256
243
|
@task.expects(:notify).never
|
257
|
-
|
258
|
-
no_stdout do
|
259
|
-
@task.handle_event(c)
|
260
|
-
end
|
244
|
+
@task.handle_event(c)
|
261
245
|
end
|
262
246
|
end
|
data/test/test_watch.rb
CHANGED
@@ -143,7 +143,7 @@ class TestWatch < Test::Unit::TestCase
|
|
143
143
|
|
144
144
|
metric.expects(:disable).never
|
145
145
|
|
146
|
-
|
146
|
+
@watch.move(:init)
|
147
147
|
end
|
148
148
|
|
149
149
|
def test_move_should_clean_up_from_state_if_not_nil
|
@@ -162,11 +162,11 @@ class TestWatch < Test::Unit::TestCase
|
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
165
|
-
|
165
|
+
@watch.move(:init)
|
166
166
|
|
167
167
|
metric.expects(:disable)
|
168
168
|
|
169
|
-
|
169
|
+
@watch.move(:up)
|
170
170
|
end
|
171
171
|
|
172
172
|
def test_move_should_call_action
|
@@ -175,7 +175,7 @@ class TestWatch < Test::Unit::TestCase
|
|
175
175
|
|
176
176
|
@watch.expects(:action).with(:start)
|
177
177
|
|
178
|
-
|
178
|
+
@watch.move(:start)
|
179
179
|
end
|
180
180
|
|
181
181
|
def test_move_should_move_to_up_state_if_no_start_or_restart_metric
|
@@ -184,7 +184,7 @@ class TestWatch < Test::Unit::TestCase
|
|
184
184
|
|
185
185
|
[:start, :restart].each do |state|
|
186
186
|
@watch.expects(:action)
|
187
|
-
|
187
|
+
@watch.move(state)
|
188
188
|
assert_equal :up, @watch.state
|
189
189
|
end
|
190
190
|
end
|
@@ -207,7 +207,7 @@ class TestWatch < Test::Unit::TestCase
|
|
207
207
|
|
208
208
|
metric.expects(:enable)
|
209
209
|
|
210
|
-
|
210
|
+
@watch.move(:init)
|
211
211
|
end
|
212
212
|
|
213
213
|
# action
|
@@ -248,7 +248,7 @@ class TestWatch < Test::Unit::TestCase
|
|
248
248
|
def test_call_action
|
249
249
|
c = Conditions::FakePollCondition.new
|
250
250
|
God::Process.any_instance.expects(:call_action).with(:start)
|
251
|
-
|
251
|
+
@watch.call_action(c, :start)
|
252
252
|
end
|
253
253
|
|
254
254
|
def test_call_action_should_call_before_start_when_behavior_has_that
|
@@ -256,7 +256,7 @@ class TestWatch < Test::Unit::TestCase
|
|
256
256
|
c = Conditions::FakePollCondition.new
|
257
257
|
God::Process.any_instance.expects(:call_action).with(:start)
|
258
258
|
Behaviors::FakeBehavior.any_instance.expects(:before_start)
|
259
|
-
|
259
|
+
@watch.call_action(c, :start)
|
260
260
|
end
|
261
261
|
|
262
262
|
def test_call_action_should_call_after_start_when_behavior_has_that
|
@@ -264,7 +264,7 @@ class TestWatch < Test::Unit::TestCase
|
|
264
264
|
c = Conditions::FakePollCondition.new
|
265
265
|
God::Process.any_instance.expects(:call_action).with(:start)
|
266
266
|
Behaviors::FakeBehavior.any_instance.expects(:after_start)
|
267
|
-
|
267
|
+
@watch.call_action(c, :start)
|
268
268
|
end
|
269
269
|
|
270
270
|
# canonical_hash_form
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: god
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Preston-Werner
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-10 00:00:00 -07:00
|
13
13
|
default_executable: god
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -102,7 +102,7 @@ files:
|
|
102
102
|
- site/images/corner_green.gif
|
103
103
|
- site/images/corner_green.psd
|
104
104
|
- site/images/corner_pink.gif
|
105
|
-
- site/images/
|
105
|
+
- site/images/god_logo.png
|
106
106
|
- site/images/header_bg.gif
|
107
107
|
- site/images/header_bg.jpg
|
108
108
|
- site/images/red_dot.gif
|
data/site/images/god_logo1.gif
DELETED
Binary file
|