scout_agent 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +4 -0
- data/CHANGELOG +3 -0
- data/COPYING +340 -0
- data/INSTALL +17 -0
- data/LICENSE +6 -0
- data/README +3 -0
- data/Rakefile +123 -0
- data/TODO +3 -0
- data/bin/scout_agent +11 -0
- data/lib/scout_agent.rb +73 -0
- data/lib/scout_agent/agent.rb +42 -0
- data/lib/scout_agent/agent/communication_agent.rb +85 -0
- data/lib/scout_agent/agent/master_agent.rb +301 -0
- data/lib/scout_agent/api.rb +241 -0
- data/lib/scout_agent/assignment.rb +105 -0
- data/lib/scout_agent/assignment/configuration.rb +30 -0
- data/lib/scout_agent/assignment/identify.rb +110 -0
- data/lib/scout_agent/assignment/queue.rb +95 -0
- data/lib/scout_agent/assignment/reset.rb +91 -0
- data/lib/scout_agent/assignment/snapshot.rb +92 -0
- data/lib/scout_agent/assignment/start.rb +149 -0
- data/lib/scout_agent/assignment/status.rb +44 -0
- data/lib/scout_agent/assignment/stop.rb +60 -0
- data/lib/scout_agent/assignment/upload_log.rb +61 -0
- data/lib/scout_agent/core_extensions.rb +260 -0
- data/lib/scout_agent/database.rb +386 -0
- data/lib/scout_agent/database/mission_log.rb +282 -0
- data/lib/scout_agent/database/queue.rb +126 -0
- data/lib/scout_agent/database/snapshots.rb +187 -0
- data/lib/scout_agent/database/statuses.rb +65 -0
- data/lib/scout_agent/dispatcher.rb +157 -0
- data/lib/scout_agent/id_card.rb +143 -0
- data/lib/scout_agent/lifeline.rb +243 -0
- data/lib/scout_agent/mission.rb +212 -0
- data/lib/scout_agent/order.rb +58 -0
- data/lib/scout_agent/order/check_in_order.rb +32 -0
- data/lib/scout_agent/order/snapshot_order.rb +33 -0
- data/lib/scout_agent/plan.rb +306 -0
- data/lib/scout_agent/server.rb +123 -0
- data/lib/scout_agent/tracked.rb +59 -0
- data/lib/scout_agent/wire_tap.rb +513 -0
- data/setup.rb +1360 -0
- data/test/tc_core_extensions.rb +89 -0
- data/test/tc_id_card.rb +115 -0
- data/test/tc_plan.rb +285 -0
- data/test/test_helper.rb +22 -0
- data/test/ts_all.rb +7 -0
- metadata +171 -0
@@ -0,0 +1,89 @@
|
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
|
5
|
+
require "scout_agent/core_extensions"
|
6
|
+
|
7
|
+
class TestCoreExtensions < Test::Unit::TestCase
|
8
|
+
def test_to_word_list
|
9
|
+
{ %w[] => "",
|
10
|
+
%w[one] => "one",
|
11
|
+
%w[one two] => "one and two",
|
12
|
+
%w[one two three] => "one, two, and three",
|
13
|
+
%w[one two three four] => "one, two, three, and four" }.each do |arr, str|
|
14
|
+
assert_equal(str, arr.to_word_list)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_to_word_list_with_custom_conjunction
|
19
|
+
assert_equal("one, two, or three", %w[one two three].to_word_list("or"))
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_string_camel_case
|
23
|
+
{ "class_name" => "ClassName",
|
24
|
+
"symbols::are/removed" => "SymbolsAreRemoved",
|
25
|
+
"spaces are removed" => "SpacesAreRemoved",
|
26
|
+
"agent_99_smart" => "Agent99Smart",
|
27
|
+
"NoChange" => "NoChange" }.each do |snake_case, camel_case|
|
28
|
+
assert_equal(camel_case, snake_case.CamelCase)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_string_camel_case_alias
|
33
|
+
str = "test_string"
|
34
|
+
assert_equal(str.CamelCase, str.camel_case)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_string_snake_case
|
38
|
+
{ "ClassName" => "class_name",
|
39
|
+
"Symbols::Are/Unified" => "symbols_are_unified",
|
40
|
+
"Spaces Are Converted" => "spaces_are_converted",
|
41
|
+
"Agent99Smart" => "agent_99_smart",
|
42
|
+
"no_change" => "no_change" }.each do |camel_case, snake_case|
|
43
|
+
assert_equal(snake_case, camel_case.snake_case)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_string_trim_with_default
|
48
|
+
heredoc = <<-END_DEFAULT.trim
|
49
|
+
I am indented on purpose.
|
50
|
+
Leading space should be removed.
|
51
|
+
|
52
|
+
but not these two spaces
|
53
|
+
END_DEFAULT
|
54
|
+
assert_match(/^I/, heredoc)
|
55
|
+
assert_match(/^Leading/, heredoc)
|
56
|
+
assert_match(/^ but/, heredoc)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_string_trim_with_width
|
60
|
+
heredoc = <<-END_WIDTH.trim(2)
|
61
|
+
I'm indented four,
|
62
|
+
but we will just trim two.
|
63
|
+
END_WIDTH
|
64
|
+
assert_match(/^ I'm/, heredoc)
|
65
|
+
assert_match(/^ but/, heredoc)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_to_question
|
69
|
+
assert_match(/\? \z/, "A simple question?\n\t ".to_question)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_word_wrap_with_default
|
73
|
+
assert_no_match(/^.{61}/, ("A short and simple string." * 1000).word_wrap)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_word_wrap_with_width
|
77
|
+
assert_no_match( /^.{11}/,
|
78
|
+
("A short and simple string." * 1000).word_wrap(10) )
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_word_wrap_skips_unbroken_content
|
82
|
+
assert_equal("0123456789", "0123456789".word_wrap(4))
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_word_wrap_strips_and_simplifes_space
|
86
|
+
assert_equal( "one two\nthree",
|
87
|
+
" \t\none\n \ttwo three\n\n \t".word_wrap(10) )
|
88
|
+
end
|
89
|
+
end
|
data/test/tc_id_card.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
require "scout_agent"
|
6
|
+
|
7
|
+
class TestIDCard < Test::Unit::TestCase
|
8
|
+
def setup
|
9
|
+
plan.prefix_path = test_prefix
|
10
|
+
plan.build_pid_dir(Process.egid)
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
id_card(:test).revoke
|
15
|
+
test_prefix.rmtree if test_prefix.exist?
|
16
|
+
plan.reset_defaults
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_authorize_creates_pid_file
|
20
|
+
@card = id_card(:test)
|
21
|
+
assert(!@card.pid_file.exist?, "PID file already existed")
|
22
|
+
assert(@card.authorize, "Failed to authorize our PID")
|
23
|
+
assert(@card.pid_file.exist?, "PID wasn't created")
|
24
|
+
assert_equal("#{Process.pid}\n", @card.pid_file.read)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_authorize_fails_for_an_existing_pid
|
28
|
+
test_authorize_creates_pid_file # make sure we already have a file
|
29
|
+
assert(!@card.authorize, "Authorized with an existing PID file")
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_authorize_will_clear_a_stale_pid_file
|
33
|
+
create_and_kill_another_process
|
34
|
+
card = id_card(:test)
|
35
|
+
assert_not_equal(Process.pid, card.pid_file.read)
|
36
|
+
assert(card.authorize, "Failed to replace stale PID file")
|
37
|
+
assert_equal("#{Process.pid}\n", card.pid_file.read)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_successful_authorize_updates_me
|
41
|
+
ScoutAgent::IDCard.me = nil
|
42
|
+
test_authorize_creates_pid_file
|
43
|
+
assert_equal(@card, ScoutAgent::IDCard.me)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_revoke_clears_a_pid_file
|
47
|
+
test_authorize_creates_pid_file # create a file
|
48
|
+
assert(@card.revoke, "Failed to clear file")
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_revoke_return_true_if_cleared_false_otherwise
|
52
|
+
test_authorize_creates_pid_file # create a file
|
53
|
+
assert(@card.revoke, "Failed to clear file")
|
54
|
+
assert(!@card.revoke, "Clear a PID file that was already cleared")
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_pid_file_is_named_file
|
58
|
+
card = id_card(:my_name)
|
59
|
+
assert_match(/my_name\.pid\z/, card.pid_file.to_s)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_pid_is_a_shorcut_for_reading_pid_file
|
63
|
+
test_authorize_creates_pid_file # create a file
|
64
|
+
assert_equal(@card.pid_file.read.to_i, @card.pid)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_pid_returns_nil_for_a_missing_pid_file
|
68
|
+
assert_nil(id_card(:does_not_exist).pid)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_signal_delivers_messages
|
72
|
+
received_message = false
|
73
|
+
trap("USR1") { received_message = true }
|
74
|
+
test_authorize_creates_pid_file
|
75
|
+
|
76
|
+
# have another process send us a signal
|
77
|
+
other_pid = fork { @card.signal("USR1") }
|
78
|
+
Process.wait(other_pid)
|
79
|
+
|
80
|
+
assert(received_message, "Didn't receive signal")
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_signal_returns_false_for_missing_pid_files
|
84
|
+
assert(!id_card(:does_not_exist).signal(0), "Signal was sent without a PID")
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_signal_errors_bubble_up_to_caller
|
88
|
+
create_and_kill_another_process
|
89
|
+
card = id_card(:test)
|
90
|
+
assert_raise(Errno::ESRCH) { card.signal("KILL") }
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_to_s_includes_process_name_and_pid
|
94
|
+
test_authorize_creates_pid_file # make an identity
|
95
|
+
assert_equal("test (#{Process.pid})", @card.to_s)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_to_s_uses_unauthorized_for_a_missing_pid
|
99
|
+
assert_equal("missing (unauthorized)", id_card(:missing).to_s)
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def id_card(*args)
|
105
|
+
ScoutAgent::IDCard.new(*args)
|
106
|
+
end
|
107
|
+
|
108
|
+
def create_and_kill_another_process
|
109
|
+
other_pid = fork do
|
110
|
+
test_authorize_creates_pid_file # make sure we claim the PID file
|
111
|
+
exit! # and exist without clearing it
|
112
|
+
end
|
113
|
+
Process.wait(other_pid)
|
114
|
+
end
|
115
|
+
end
|
data/test/tc_plan.rb
ADDED
@@ -0,0 +1,285 @@
|
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
require "tempfile"
|
5
|
+
|
6
|
+
require "scout_agent"
|
7
|
+
|
8
|
+
class TestPlan < Test::Unit::TestCase
|
9
|
+
def teardown
|
10
|
+
test_prefix.rmtree if test_prefix.exist?
|
11
|
+
end
|
12
|
+
|
13
|
+
############
|
14
|
+
### Type ###
|
15
|
+
############
|
16
|
+
|
17
|
+
def test_plan_is_a_customized_ostruct
|
18
|
+
assert_instance_of(OpenStruct, plan)
|
19
|
+
end
|
20
|
+
|
21
|
+
########################
|
22
|
+
### Loading a Config ###
|
23
|
+
########################
|
24
|
+
|
25
|
+
def test_updating_plan_from_a_config_file
|
26
|
+
c = load_config_file(<<-END_SETTINGS)
|
27
|
+
config.string_setting = "just a String"
|
28
|
+
config.integer_setting = 42
|
29
|
+
END_SETTINGS
|
30
|
+
assert_equal(plan, c)
|
31
|
+
assert_equal("just a String", c.string_setting)
|
32
|
+
assert_equal(42, c.integer_setting)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_exceptions_bubble_up_to_the_caller_from_config_file
|
36
|
+
assert_raise(RuntimeError) do
|
37
|
+
load_config_file('raise "Oops!"')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_updating_plan_from_switches
|
42
|
+
assert_nil(plan.switch_one)
|
43
|
+
assert_nil(plan.switch_two)
|
44
|
+
plan.update_from_switches(:switch_one => "One", :switch_two => "Two")
|
45
|
+
assert_equal("One", plan.switch_one)
|
46
|
+
assert_equal("Two", plan.switch_two)
|
47
|
+
end
|
48
|
+
|
49
|
+
################
|
50
|
+
### Defaults ###
|
51
|
+
################
|
52
|
+
|
53
|
+
def test_defaults_are_available_in_an_enumerable_list
|
54
|
+
assert_kind_of(Enumerable, plan.defaults)
|
55
|
+
end
|
56
|
+
|
57
|
+
# def test_agent_name_is_set
|
58
|
+
# assert_match(/\A\w+\z/, plan.agent_name)
|
59
|
+
# assert_equal( plan.agent_name.split("_"),
|
60
|
+
# plan.proper_agent_name.downcase.split(" ") )
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# def test_agent_namespace_returns_module_based_on_agent_name
|
64
|
+
# assert_equal(ScoutAgent, plan.agent_namespace)
|
65
|
+
# end
|
66
|
+
|
67
|
+
def test_all_paths_return_pathname_objects
|
68
|
+
%w[ prefix_path
|
69
|
+
os_config_path
|
70
|
+
os_db_path
|
71
|
+
os_pid_path
|
72
|
+
os_log_path
|
73
|
+
config_file
|
74
|
+
db_dir
|
75
|
+
pid_dir
|
76
|
+
log_dir ].each do |path|
|
77
|
+
assert_instance_of(Pathname, plan(path))
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_prefix_path_defaults_to_the_root_path
|
82
|
+
assert_equal(Pathname.new("/"), plan.prefix_path)
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_default_os_paths_are_set
|
86
|
+
%w[ os_config_path
|
87
|
+
os_db_path
|
88
|
+
os_pid_path
|
89
|
+
os_log_path ].each do |path|
|
90
|
+
assert_path_match(%r{\A(?:/\w+)+/?\z}, path)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_default_paths_are_set
|
95
|
+
assert_path_match(%r{\A(?:/\w+)+\.\w+\z}, :config_file)
|
96
|
+
%w[db_dir pid_dir log_dir].each do |dir|
|
97
|
+
assert_path_match(%r{\A(?:/\w+)+/?\z}, dir)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_server_url_is_set
|
102
|
+
assert_match(%r{\Ahttps://}, plan.server_url)
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_run_as_daemon_is_set
|
106
|
+
assert(plan.run_as_daemon, "Daemon mode should default to on")
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_run_as_daemon_alias
|
110
|
+
assert_equal(plan.run_as_daemon, plan.run_as_daemon?)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_user_choices_is_set
|
114
|
+
assert_equal(%w[daemon nobody], plan.user_choices)
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_group_choices_is_set
|
118
|
+
assert_equal(%w[daemon nogroup], plan.group_choices)
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_reset_defaults
|
122
|
+
current = plan.defaults.map { |name, _| [name, plan(name)] }
|
123
|
+
plan.defaults.each { |name, _| plan("#{name}=", "Junk!") }
|
124
|
+
current.each { |name, value| assert_not_equal(value, plan(name)) }
|
125
|
+
|
126
|
+
plan.reset_defaults
|
127
|
+
current.each { |name, value| assert_equal(value, plan(name)) }
|
128
|
+
end
|
129
|
+
|
130
|
+
####################
|
131
|
+
### Nested Paths ###
|
132
|
+
####################
|
133
|
+
|
134
|
+
def test_prefix_path_prepends_to_all_paths
|
135
|
+
%w[ os_config_path
|
136
|
+
os_db_path
|
137
|
+
os_pid_path
|
138
|
+
os_log_path
|
139
|
+
config_file
|
140
|
+
db_dir
|
141
|
+
pid_dir
|
142
|
+
log_dir ].each do |path|
|
143
|
+
configure(:prefix_path => test_prefix) do
|
144
|
+
assert_path_match(%r{\A#{test_prefix}/.+\z}, path)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_os_paths_prepends_to_full_paths
|
150
|
+
{ :config_file => :os_config_path,
|
151
|
+
:db_dir => :os_db_path,
|
152
|
+
:pid_dir => :os_pid_path,
|
153
|
+
:log_dir => :os_log_path }.each do |path, parent|
|
154
|
+
assert_prepends_path(path, parent)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_prefix_path_nests_with_os_paths
|
159
|
+
dir = "test_dir"
|
160
|
+
{ :config_file => :os_config_path,
|
161
|
+
:db_dir => :os_db_path,
|
162
|
+
:pid_dir => :os_pid_path,
|
163
|
+
:log_dir => :os_log_path }.each do |path, parent|
|
164
|
+
configure(:prefix_path => test_prefix, parent => dir) do
|
165
|
+
assert_path_match(%r{\A#{test_prefix}/#{dir}/.+\z}, path)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
################
|
171
|
+
### Creation ###
|
172
|
+
################
|
173
|
+
|
174
|
+
def test_write_default_config_file_creates_a_readable_ruby_configuration_file
|
175
|
+
configure(:prefix_path => test_prefix) do
|
176
|
+
assert(!File.exist?(plan.config_file), "Configuration already existed")
|
177
|
+
assert(plan.write_default_config_file, "Could not create config file")
|
178
|
+
assert(File.exist?(plan.config_file), "Configuration not created")
|
179
|
+
assert_equal("755", plan.config_file.stat.mode.to_s(8)[-3..-1])
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_write_default_config_file_wont_replace_an_existing_file
|
184
|
+
configure(:prefix_path => test_prefix) do
|
185
|
+
assert(plan.write_default_config_file, "Could not create config file")
|
186
|
+
assert(!plan.write_default_config_file, "Replaced config file")
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_builders_fails_if_they_dont_have_permission
|
191
|
+
configure(:prefix_path => test_prefix) do
|
192
|
+
{ :write_default_config_file => :os_config_path,
|
193
|
+
:build_db_dir => :os_db_path,
|
194
|
+
:build_pid_dir => :os_pid_path,
|
195
|
+
:build_log_dir => :os_log_path }.each do |builder, dir|
|
196
|
+
plan(dir).mkpath
|
197
|
+
plan(dir).chmod(0444) # read only
|
198
|
+
args = builder == :write_default_config_file ? [ ] : [Process.egid]
|
199
|
+
assert(!plan(builder, *args), "Built without permission")
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# def test_directory_builders_create_a_readable_and_writable_directory
|
205
|
+
# configure(:prefix_path => test_prefix) do
|
206
|
+
# %w[db_dir pid_dir log_dir].each do |dir|
|
207
|
+
# assert(!File.exist?(plan(dir)), "Directory already existed")
|
208
|
+
# assert(plan("build_#{dir}", Process.egid), "Could not create directory")
|
209
|
+
# assert(File.exist?(plan(dir)), "Directory not created")
|
210
|
+
# assert_equal("775", plan(dir).stat.mode.to_s(8)[-3..-1])
|
211
|
+
# end
|
212
|
+
# end
|
213
|
+
# end
|
214
|
+
|
215
|
+
###################
|
216
|
+
### Validations ###
|
217
|
+
###################
|
218
|
+
|
219
|
+
# def test_plan_is_present
|
220
|
+
# configure(:prefix_path => test_prefix) do
|
221
|
+
# assert(!plan.present?, "Card was present when missing")
|
222
|
+
# # add some config
|
223
|
+
# %w[db_dir log_dir].each do |dir|
|
224
|
+
# assert(plan("build_#{dir}", Process.egid), "Could not create directory")
|
225
|
+
# end
|
226
|
+
# assert(!plan.present?, "Card was present when partially build")
|
227
|
+
# # complete config
|
228
|
+
# assert(plan.write_default_config_file, "Could not create config file")
|
229
|
+
# assert(plan.present?, "Complete card was not present")
|
230
|
+
# end
|
231
|
+
# end
|
232
|
+
#
|
233
|
+
# def test_plan_is_valid
|
234
|
+
# configure(:prefix_path => test_prefix) do
|
235
|
+
# assert(!plan.valid?, "Card was valid when missing")
|
236
|
+
# # add config
|
237
|
+
# %w[db_dir log_dir].each do |dir|
|
238
|
+
# assert(plan("build_#{dir}", Process.egid), "Could not create directory")
|
239
|
+
# end
|
240
|
+
# assert(plan.write_default_config_file, "Could not create config file")
|
241
|
+
# assert(plan.valid?, "Complete card was not valid")
|
242
|
+
# # break premissions
|
243
|
+
# plan.db_dir.chmod(0444) # read only
|
244
|
+
# assert(!plan.valid?, "Card was valid when read only")
|
245
|
+
# end
|
246
|
+
# end
|
247
|
+
|
248
|
+
#######
|
249
|
+
private
|
250
|
+
#######
|
251
|
+
|
252
|
+
# Creates a Tempfile, dumps configuration to it, and loads it.
|
253
|
+
def load_config_file(content = String.new)
|
254
|
+
cf = Tempfile.new("agent_config_test")
|
255
|
+
cf << content
|
256
|
+
cf.flush
|
257
|
+
plan.update_from_config_file(cf.path)
|
258
|
+
end
|
259
|
+
|
260
|
+
#
|
261
|
+
# Applies +settings+ to the configuaration, runs the passed block, then resets
|
262
|
+
# configuaration defaults.
|
263
|
+
#
|
264
|
+
def configure(settings)
|
265
|
+
settings.each { |name, value| plan("#{name}=", value) }
|
266
|
+
begin
|
267
|
+
yield
|
268
|
+
ensure
|
269
|
+
plan.reset_defaults
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# Checks a Pathname +path+ against a +regexp+.
|
274
|
+
def assert_path_match(regexp, path)
|
275
|
+
assert_match(regexp, plan(path).to_s)
|
276
|
+
end
|
277
|
+
|
278
|
+
# Sets the +parent+ dir and ensures that +path+ is updated as a result.
|
279
|
+
def assert_prepends_path(path, parent)
|
280
|
+
dir = "test_dir"
|
281
|
+
configure(parent => dir) do
|
282
|
+
assert_path_match(%r{\A/#{dir}/.+\z}, path)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|