dosire-god 0.7.9
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.
- data/History.txt +261 -0
- data/Manifest.txt +107 -0
- data/README.txt +59 -0
- data/Rakefile +35 -0
- data/bin/god +127 -0
- data/examples/events.god +84 -0
- data/examples/gravatar.god +54 -0
- data/examples/single.god +66 -0
- data/ext/god/extconf.rb +55 -0
- data/ext/god/kqueue_handler.c +123 -0
- data/ext/god/netlink_handler.c +167 -0
- data/init/god +42 -0
- data/lib/god/behavior.rb +52 -0
- data/lib/god/behaviors/clean_pid_file.rb +21 -0
- data/lib/god/behaviors/clean_unix_socket.rb +21 -0
- data/lib/god/behaviors/notify_when_flapping.rb +51 -0
- data/lib/god/cli/command.rb +206 -0
- data/lib/god/cli/run.rb +177 -0
- data/lib/god/cli/version.rb +23 -0
- data/lib/god/condition.rb +96 -0
- data/lib/god/conditions/always.rb +23 -0
- data/lib/god/conditions/complex.rb +86 -0
- data/lib/god/conditions/cpu_usage.rb +80 -0
- data/lib/god/conditions/degrading_lambda.rb +52 -0
- data/lib/god/conditions/disk_usage.rb +27 -0
- data/lib/god/conditions/flapping.rb +128 -0
- data/lib/god/conditions/http_response_code.rb +168 -0
- data/lib/god/conditions/lambda.rb +25 -0
- data/lib/god/conditions/memory_usage.rb +82 -0
- data/lib/god/conditions/process_exits.rb +72 -0
- data/lib/god/conditions/process_running.rb +74 -0
- data/lib/god/conditions/tries.rb +44 -0
- data/lib/god/configurable.rb +57 -0
- data/lib/god/contact.rb +106 -0
- data/lib/god/contacts/email.rb +95 -0
- data/lib/god/dependency_graph.rb +41 -0
- data/lib/god/diagnostics.rb +37 -0
- data/lib/god/driver.rb +206 -0
- data/lib/god/errors.rb +24 -0
- data/lib/god/event_handler.rb +111 -0
- data/lib/god/event_handlers/dummy_handler.rb +13 -0
- data/lib/god/event_handlers/kqueue_handler.rb +17 -0
- data/lib/god/event_handlers/netlink_handler.rb +13 -0
- data/lib/god/logger.rb +120 -0
- data/lib/god/metric.rb +59 -0
- data/lib/god/process.rb +327 -0
- data/lib/god/registry.rb +32 -0
- data/lib/god/simple_logger.rb +53 -0
- data/lib/god/socket.rb +96 -0
- data/lib/god/sugar.rb +47 -0
- data/lib/god/system/portable_poller.rb +42 -0
- data/lib/god/system/process.rb +42 -0
- data/lib/god/system/slash_proc_poller.rb +82 -0
- data/lib/god/task.rb +487 -0
- data/lib/god/timeline.rb +25 -0
- data/lib/god/trigger.rb +43 -0
- data/lib/god/watch.rb +183 -0
- data/lib/god.rb +644 -0
- data/test/configs/child_events/child_events.god +44 -0
- data/test/configs/child_events/simple_server.rb +3 -0
- data/test/configs/child_polls/child_polls.god +37 -0
- data/test/configs/child_polls/simple_server.rb +12 -0
- data/test/configs/complex/complex.god +59 -0
- data/test/configs/complex/simple_server.rb +3 -0
- data/test/configs/contact/contact.god +74 -0
- data/test/configs/contact/simple_server.rb +3 -0
- data/test/configs/daemon_events/daemon_events.god +37 -0
- data/test/configs/daemon_events/simple_server.rb +8 -0
- data/test/configs/daemon_events/simple_server_stop.rb +11 -0
- data/test/configs/daemon_polls/daemon_polls.god +17 -0
- data/test/configs/daemon_polls/simple_server.rb +6 -0
- data/test/configs/degrading_lambda/degrading_lambda.god +31 -0
- data/test/configs/degrading_lambda/tcp_server.rb +15 -0
- data/test/configs/matias/matias.god +50 -0
- data/test/configs/real.rb +59 -0
- data/test/configs/running_load/running_load.god +16 -0
- data/test/configs/stress/simple_server.rb +3 -0
- data/test/configs/stress/stress.god +15 -0
- data/test/configs/task/logs/.placeholder +0 -0
- data/test/configs/task/task.god +26 -0
- data/test/configs/test.rb +61 -0
- data/test/helper.rb +151 -0
- data/test/suite.rb +6 -0
- data/test/test_behavior.rb +21 -0
- data/test/test_condition.rb +50 -0
- data/test/test_conditions_disk_usage.rb +56 -0
- data/test/test_conditions_http_response_code.rb +109 -0
- data/test/test_conditions_process_running.rb +44 -0
- data/test/test_conditions_tries.rb +67 -0
- data/test/test_contact.rb +109 -0
- data/test/test_dependency_graph.rb +62 -0
- data/test/test_driver.rb +11 -0
- data/test/test_event_handler.rb +80 -0
- data/test/test_god.rb +598 -0
- data/test/test_handlers_kqueue_handler.rb +16 -0
- data/test/test_logger.rb +63 -0
- data/test/test_metric.rb +72 -0
- data/test/test_process.rb +246 -0
- data/test/test_registry.rb +15 -0
- data/test/test_socket.rb +42 -0
- data/test/test_sugar.rb +42 -0
- data/test/test_system_portable_poller.rb +17 -0
- data/test/test_system_process.rb +30 -0
- data/test/test_task.rb +262 -0
- data/test/test_timeline.rb +37 -0
- data/test/test_trigger.rb +59 -0
- data/test/test_watch.rb +279 -0
- metadata +186 -0
data/test/helper.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. lib god])
|
2
|
+
God::EventHandler.load
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
require 'set'
|
6
|
+
|
7
|
+
include God
|
8
|
+
|
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
|
+
|
21
|
+
begin
|
22
|
+
require 'mocha'
|
23
|
+
rescue LoadError
|
24
|
+
unless gems ||= false
|
25
|
+
require 'rubygems'
|
26
|
+
gems = true
|
27
|
+
retry
|
28
|
+
else
|
29
|
+
abort "=> You need the Mocha gem to run these tests."
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module God
|
34
|
+
module Conditions
|
35
|
+
class FakeCondition < Condition
|
36
|
+
def test
|
37
|
+
true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class FakePollCondition < PollCondition
|
42
|
+
def test
|
43
|
+
true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class FakeEventCondition < EventCondition
|
48
|
+
def register
|
49
|
+
end
|
50
|
+
def deregister
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module Behaviors
|
56
|
+
class FakeBehavior < Behavior
|
57
|
+
def before_start
|
58
|
+
'foo'
|
59
|
+
end
|
60
|
+
def after_start
|
61
|
+
'bar'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
module Contacts
|
67
|
+
class FakeContact < Contact
|
68
|
+
end
|
69
|
+
|
70
|
+
class InvalidContact
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.reset
|
75
|
+
self.watches = nil
|
76
|
+
self.groups = nil
|
77
|
+
self.server = nil
|
78
|
+
self.inited = nil
|
79
|
+
self.host = nil
|
80
|
+
self.port = nil
|
81
|
+
self.pid_file_directory = nil
|
82
|
+
self.registry.reset
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def silence_warnings
|
87
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
88
|
+
yield
|
89
|
+
ensure
|
90
|
+
$VERBOSE = old_verbose
|
91
|
+
end
|
92
|
+
|
93
|
+
def no_stdout
|
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
|
106
|
+
|
107
|
+
module Kernel
|
108
|
+
def abort(text)
|
109
|
+
raise SystemExit
|
110
|
+
end
|
111
|
+
def exit(code)
|
112
|
+
raise SystemExit
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
module Test::Unit::Assertions
|
117
|
+
def assert_abort
|
118
|
+
assert_raise SystemExit do
|
119
|
+
yield
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# This allows you to be a good OOP citizen and honor encapsulation, but
|
125
|
+
# still make calls to private methods (for testing) by doing
|
126
|
+
#
|
127
|
+
# obj.bypass.private_thingie(arg1, arg2)
|
128
|
+
#
|
129
|
+
# Which is easier on the eye than
|
130
|
+
#
|
131
|
+
# obj.send(:private_thingie, arg1, arg2)
|
132
|
+
#
|
133
|
+
class Object
|
134
|
+
class Bypass
|
135
|
+
instance_methods.each do |m|
|
136
|
+
undef_method m unless m =~ /^__/
|
137
|
+
end
|
138
|
+
|
139
|
+
def initialize(ref)
|
140
|
+
@ref = ref
|
141
|
+
end
|
142
|
+
|
143
|
+
def method_missing(sym, *args)
|
144
|
+
@ref.__send__(sym, *args)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def bypass
|
149
|
+
Bypass.new(self)
|
150
|
+
end
|
151
|
+
end
|
data/test/suite.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestBehavior < Test::Unit::TestCase
|
4
|
+
def test_generate_should_return_an_object_corresponding_to_the_given_type
|
5
|
+
assert_equal Behaviors::FakeBehavior, Behavior.generate(:fake_behavior, nil).class
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_generate_should_raise_on_invalid_type
|
9
|
+
assert_raise NoSuchBehaviorError do
|
10
|
+
Behavior.generate(:foo, nil)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_complain
|
15
|
+
Syslog.expects(:err).with('foo')
|
16
|
+
# Kernel.expects(:puts).with('foo')
|
17
|
+
no_stdout do
|
18
|
+
assert !Behavior.allocate.bypass.complain('foo')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class BadlyImplementedCondition < PollCondition
|
4
|
+
end
|
5
|
+
|
6
|
+
class TestCondition < Test::Unit::TestCase
|
7
|
+
|
8
|
+
# generate
|
9
|
+
|
10
|
+
def test_generate_should_return_an_object_corresponding_to_the_given_type
|
11
|
+
assert_equal Conditions::ProcessRunning, Condition.generate(:process_running, nil).class
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_generate_should_raise_on_invalid_type
|
15
|
+
assert_raise NoSuchConditionError do
|
16
|
+
Condition.generate(:foo, nil)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_generate_should_abort_on_event_condition_without_loaded_event_system
|
21
|
+
God::EventHandler.stubs(:operational?).returns(false)
|
22
|
+
assert_abort do
|
23
|
+
God::EventHandler.start
|
24
|
+
Condition.generate(:process_exits, nil).class
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_generate_should_return_a_good_error_message_for_invalid_types
|
29
|
+
emsg = "No Condition found with the class name God::Conditions::FooBar"
|
30
|
+
rmsg = nil
|
31
|
+
|
32
|
+
begin
|
33
|
+
Condition.generate(:foo_bar, nil)
|
34
|
+
rescue => e
|
35
|
+
rmsg = e.message
|
36
|
+
end
|
37
|
+
|
38
|
+
assert_equal emsg, rmsg
|
39
|
+
end
|
40
|
+
|
41
|
+
# test
|
42
|
+
|
43
|
+
def test_test_should_raise_if_not_defined_in_subclass
|
44
|
+
c = BadlyImplementedCondition.new
|
45
|
+
|
46
|
+
assert_raise AbstractMethodNotOverriddenError do
|
47
|
+
c.test
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestConditionsDiskUsage < Test::Unit::TestCase
|
4
|
+
# valid?
|
5
|
+
|
6
|
+
def test_valid_should_return_false_if_no_above_given
|
7
|
+
c = Conditions::DiskUsage.new
|
8
|
+
c.mount_point = '/'
|
9
|
+
c.watch = stub(:name => 'foo')
|
10
|
+
|
11
|
+
no_stdout do
|
12
|
+
assert_equal false, c.valid?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_valid_should_return_false_if_no_mount_point_given
|
17
|
+
c = Conditions::DiskUsage.new
|
18
|
+
c.above = 90
|
19
|
+
c.watch = stub(:name => 'foo')
|
20
|
+
|
21
|
+
no_stdout do
|
22
|
+
assert_equal false, c.valid?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_valid_should_return_true_if_required_options_all_set
|
27
|
+
c = Conditions::DiskUsage.new
|
28
|
+
c.above = 90
|
29
|
+
c.mount_point = '/'
|
30
|
+
c.watch = stub(:name => 'foo')
|
31
|
+
|
32
|
+
assert_equal true, c.valid?
|
33
|
+
end
|
34
|
+
|
35
|
+
# test
|
36
|
+
|
37
|
+
def test_test_should_return_true_if_above_limit
|
38
|
+
c = Conditions::DiskUsage.new
|
39
|
+
c.above = 90
|
40
|
+
c.mount_point = '/'
|
41
|
+
|
42
|
+
c.expects(:`).returns('91')
|
43
|
+
|
44
|
+
assert_equal true, c.test
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_test_should_return_false_if_below_limit
|
48
|
+
c = Conditions::DiskUsage.new
|
49
|
+
c.above = 90
|
50
|
+
c.mount_point = '/'
|
51
|
+
|
52
|
+
c.expects(:`).returns('90')
|
53
|
+
|
54
|
+
assert_equal false, c.test
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestHttpResponseCode < Test::Unit::TestCase
|
4
|
+
def valid_condition
|
5
|
+
c = Conditions::HttpResponseCode.new()
|
6
|
+
c.watch = stub(:name => 'foo')
|
7
|
+
c.host = 'localhost'
|
8
|
+
c.port = 8080
|
9
|
+
c.path = '/'
|
10
|
+
c.timeout = 10
|
11
|
+
c.code_is = 200
|
12
|
+
c.times = 1
|
13
|
+
yield(c) if block_given?
|
14
|
+
c.prepare
|
15
|
+
c
|
16
|
+
end
|
17
|
+
|
18
|
+
# valid?
|
19
|
+
|
20
|
+
def test_valid_condition_is_valid
|
21
|
+
c = valid_condition
|
22
|
+
assert c.valid?
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_valid_should_return_false_if_both_code_is_and_code_is_not_are_set
|
26
|
+
c = valid_condition do |cc|
|
27
|
+
cc.code_is_not = 500
|
28
|
+
end
|
29
|
+
no_stdout { assert !c.valid? }
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_valid_should_return_false_if_no_host_set
|
33
|
+
c = valid_condition do |cc|
|
34
|
+
cc.host = nil
|
35
|
+
end
|
36
|
+
no_stdout { assert !c.valid? }
|
37
|
+
end
|
38
|
+
|
39
|
+
# test
|
40
|
+
|
41
|
+
def test_test_should_return_false_if_code_is_is_set_to_200_but_response_is_500
|
42
|
+
c = valid_condition
|
43
|
+
Net::HTTP.expects(:start).yields(stub(:read_timeout= => nil, :get => stub(:code => 500)))
|
44
|
+
assert_equal false, c.test
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_test_should_return_false_if_code_is_not_is_set_to_200_and_response_is_200
|
48
|
+
c = valid_condition do |cc|
|
49
|
+
cc.code_is = nil
|
50
|
+
cc.code_is_not = [200]
|
51
|
+
end
|
52
|
+
Net::HTTP.expects(:start).yields(stub(:read_timeout= => nil, :get => stub(:code => 200)))
|
53
|
+
assert_equal false, c.test
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_test_should_return_true_if_code_is_is_set_to_200_and_response_is_200
|
57
|
+
c = valid_condition
|
58
|
+
Net::HTTP.expects(:start).yields(stub(:read_timeout= => nil, :get => stub(:code => 200)))
|
59
|
+
assert_equal true, c.test
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_test_should_return_false_if_code_is_not_is_set_to_200_but_response_is_500
|
63
|
+
c = valid_condition do |cc|
|
64
|
+
cc.code_is = nil
|
65
|
+
cc.code_is_not = [200]
|
66
|
+
end
|
67
|
+
Net::HTTP.expects(:start).yields(stub(:read_timeout= => nil, :get => stub(:code => 500)))
|
68
|
+
assert_equal true, c.test
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_test_should_return_false_if_code_is_is_set_to_200_but_response_times_out
|
72
|
+
c = valid_condition
|
73
|
+
Net::HTTP.expects(:start).raises(Timeout::Error, '')
|
74
|
+
assert_equal false, c.test
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_test_should_return_true_if_code_is_not_is_set_to_200_and_response_times_out
|
78
|
+
c = valid_condition do |cc|
|
79
|
+
cc.code_is = nil
|
80
|
+
cc.code_is_not = [200]
|
81
|
+
end
|
82
|
+
Net::HTTP.expects(:start).raises(Timeout::Error, '')
|
83
|
+
assert_equal true, c.test
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_test_should_return_false_if_code_is_is_set_to_200_but_cant_connect
|
87
|
+
c = valid_condition
|
88
|
+
Net::HTTP.expects(:start).raises(Errno::ECONNREFUSED, '')
|
89
|
+
assert_equal false, c.test
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_test_should_return_true_if_code_is_not_is_set_to_200_and_cant_connect
|
93
|
+
c = valid_condition do |cc|
|
94
|
+
cc.code_is = nil
|
95
|
+
cc.code_is_not = [200]
|
96
|
+
end
|
97
|
+
Net::HTTP.expects(:start).raises(Errno::ECONNREFUSED, '')
|
98
|
+
assert_equal true, c.test
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_test_should_return_true_if_code_is_is_set_to_200_and_response_is_200_twice_for_times_two_of_two
|
102
|
+
c = valid_condition do |cc|
|
103
|
+
cc.times = [2, 2]
|
104
|
+
end
|
105
|
+
Net::HTTP.expects(:start).yields(stub(:read_timeout= => nil, :get => stub(:code => 200))).times(2)
|
106
|
+
assert_equal false, c.test
|
107
|
+
assert_equal true, c.test
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestConditionsProcessRunning < Test::Unit::TestCase
|
4
|
+
def test_missing_pid_file_returns_opposite
|
5
|
+
[true, false].each do |r|
|
6
|
+
c = Conditions::ProcessRunning.new
|
7
|
+
c.running = r
|
8
|
+
|
9
|
+
c.stubs(:watch).returns(stub(:pid => 123, :name => 'foo'))
|
10
|
+
|
11
|
+
# no_stdout do
|
12
|
+
assert_equal !r, c.test
|
13
|
+
# end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_not_running_returns_opposite
|
18
|
+
[true, false].each do |r|
|
19
|
+
c = Conditions::ProcessRunning.new
|
20
|
+
c.running = r
|
21
|
+
|
22
|
+
File.stubs(:exist?).returns(true)
|
23
|
+
c.stubs(:watch).returns(stub(:pid => 123))
|
24
|
+
File.stubs(:read).returns('5')
|
25
|
+
System::Process.any_instance.stubs(:exists?).returns(false)
|
26
|
+
|
27
|
+
assert_equal !r, c.test
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_running_returns_same
|
32
|
+
[true, false].each do |r|
|
33
|
+
c = Conditions::ProcessRunning.new
|
34
|
+
c.running = r
|
35
|
+
|
36
|
+
File.stubs(:exist?).returns(true)
|
37
|
+
c.stubs(:watch).returns(stub(:pid => 123))
|
38
|
+
File.stubs(:read).returns('5')
|
39
|
+
System::Process.any_instance.stubs(:exists?).returns(true)
|
40
|
+
|
41
|
+
assert_equal r, c.test
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestConditionsTries < Test::Unit::TestCase
|
4
|
+
# valid?
|
5
|
+
|
6
|
+
def test_valid_should_return_false_if_times_not_set
|
7
|
+
c = Conditions::Tries.new
|
8
|
+
c.watch = stub(:name => 'foo')
|
9
|
+
no_stdout { assert !c.valid? }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
class TestConditionsTries < Test::Unit::TestCase
|
15
|
+
def setup
|
16
|
+
@c = Conditions::Tries.new
|
17
|
+
@c.times = 3
|
18
|
+
@c.prepare
|
19
|
+
end
|
20
|
+
|
21
|
+
# prepare
|
22
|
+
|
23
|
+
def test_prepare_should_create_timeline
|
24
|
+
assert 3, @c.instance_variable_get(:@timeline).instance_variable_get(:@max_size)
|
25
|
+
end
|
26
|
+
|
27
|
+
# test
|
28
|
+
|
29
|
+
def test_test_should_return_true_if_called_three_times_within_one_second
|
30
|
+
assert !@c.test
|
31
|
+
assert !@c.test
|
32
|
+
assert @c.test
|
33
|
+
end
|
34
|
+
|
35
|
+
# reset
|
36
|
+
|
37
|
+
def test_test_should_return_false_on_fourth_call_if_called_three_times_within_one_second
|
38
|
+
3.times { @c.test }
|
39
|
+
@c.reset
|
40
|
+
assert !@c.test
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
class TestConditionsTriesWithin < Test::Unit::TestCase
|
46
|
+
def setup
|
47
|
+
@c = Conditions::Tries.new
|
48
|
+
@c.times = 3
|
49
|
+
@c.within = 1.seconds
|
50
|
+
@c.prepare
|
51
|
+
end
|
52
|
+
|
53
|
+
# test
|
54
|
+
|
55
|
+
def test_test_should_return_true_if_called_three_times_within_one_second
|
56
|
+
assert !@c.test
|
57
|
+
assert !@c.test
|
58
|
+
assert @c.test
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_test_should_return_false_if_called_three_times_within_two_seconds
|
62
|
+
assert !@c.test
|
63
|
+
assert !@c.test
|
64
|
+
assert sleep(1.1)
|
65
|
+
assert !@c.test
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestContact < Test::Unit::TestCase
|
4
|
+
def test_exists
|
5
|
+
God::Contact
|
6
|
+
end
|
7
|
+
|
8
|
+
# generate
|
9
|
+
|
10
|
+
def test_generate_should_raise_on_invalid_kind
|
11
|
+
assert_raise(NoSuchContactError) do
|
12
|
+
Contact.generate(:invalid)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_generate_should_abort_on_invalid_contact
|
17
|
+
assert_abort do
|
18
|
+
Contact.generate(:invalid_contact)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# normalize
|
23
|
+
|
24
|
+
def test_normalize_should_accept_a_string
|
25
|
+
input = 'tom'
|
26
|
+
output = {:contacts => ['tom']}
|
27
|
+
assert_equal(output, Contact.normalize(input))
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_normalize_should_accept_an_array_of_strings
|
31
|
+
input = ['tom', 'kevin']
|
32
|
+
output = {:contacts => ['tom', 'kevin']}
|
33
|
+
assert_equal(output, Contact.normalize(input))
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_normalize_should_accept_a_hash_with_contacts_string
|
37
|
+
input = {:contacts => 'tom'}
|
38
|
+
output = {:contacts => ['tom']}
|
39
|
+
assert_equal(output, Contact.normalize(input))
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_normalize_should_accept_a_hash_with_contacts_array_of_strings
|
43
|
+
input = {:contacts => ['tom', 'kevin']}
|
44
|
+
output = {:contacts => ['tom', 'kevin']}
|
45
|
+
assert_equal(output, Contact.normalize(input))
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_normalize_should_stringify_priority
|
49
|
+
input = {:contacts => 'tom', :priority => 1}
|
50
|
+
output = {:contacts => ['tom'], :priority => '1'}
|
51
|
+
assert_equal(output, Contact.normalize(input))
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_normalize_should_stringify_category
|
55
|
+
input = {:contacts => 'tom', :category => :product}
|
56
|
+
output = {:contacts => ['tom'], :category => 'product'}
|
57
|
+
assert_equal(output, Contact.normalize(input))
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_normalize_should_raise_on_non_string_array_hash
|
61
|
+
input = 1
|
62
|
+
assert_raise ArgumentError do
|
63
|
+
Contact.normalize(input)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_normalize_should_raise_on_non_string_array_contacts_key
|
68
|
+
input = {:contacts => 1}
|
69
|
+
assert_raise ArgumentError do
|
70
|
+
Contact.normalize(input)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_normalize_should_raise_on_non_string_containing_array
|
75
|
+
input = [1]
|
76
|
+
assert_raise ArgumentError do
|
77
|
+
Contact.normalize(input)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_normalize_should_raise_on_non_string_containing_array_contacts_key
|
82
|
+
input = {:contacts => [1]}
|
83
|
+
assert_raise ArgumentError do
|
84
|
+
Contact.normalize(input)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_normalize_should_raise_on_absent_contacts_key
|
89
|
+
input = {}
|
90
|
+
assert_raise ArgumentError do
|
91
|
+
Contact.normalize(input)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_normalize_should_raise_on_extra_keys
|
96
|
+
input = {:contacts => ['tom'], :priority => 1, :category => 'product', :extra => 'foo'}
|
97
|
+
assert_raise ArgumentError do
|
98
|
+
Contact.normalize(input)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# notify
|
103
|
+
|
104
|
+
def test_notify_should_be_abstract
|
105
|
+
assert_raise(AbstractMethodNotOverriddenError) do
|
106
|
+
Contact.new.notify(:a, :b, :c, :d, :e)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -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
|