xli-dtr 0.0.4 → 0.0.5
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/README +6 -115
- data/Rakefile +22 -154
- data/TODO +16 -1
- data/bin/dtr +22 -61
- data/dtr.gemspec +7 -6
- data/lib/dtr/agent/brain.rb +66 -0
- data/lib/dtr/agent/herald.rb +50 -0
- data/lib/dtr/agent/runner.rb +100 -0
- data/lib/dtr/agent/sync_codebase.rb +44 -0
- data/lib/dtr/agent/sync_logger.rb +40 -0
- data/lib/dtr/agent/test_unit.rb +42 -0
- data/lib/dtr/agent/worker.rb +92 -0
- data/lib/dtr/agent/working_env_ext.rb +45 -0
- data/lib/dtr/agent.rb +37 -0
- data/lib/dtr/master.rb +40 -0
- data/lib/dtr/monitor.rb +37 -0
- data/lib/dtr/raketasks.rb +74 -13
- data/lib/dtr/shared/adapter.rb +112 -0
- data/lib/dtr/shared/configuration.rb +76 -0
- data/lib/dtr/shared/message_decorator.rb +28 -0
- data/lib/dtr/shared/ruby_ext.rb +153 -0
- data/lib/dtr/shared/service/agent.rb +33 -0
- data/lib/dtr/shared/service/file.rb +28 -0
- data/lib/dtr/shared/service/rinda.rb +40 -0
- data/lib/dtr/shared/service/runner.rb +33 -0
- data/lib/dtr/shared/service/working_env.rb +28 -0
- data/lib/dtr/shared/service.rb +19 -0
- data/lib/dtr/shared/sync_codebase/codebase.rb +32 -0
- data/lib/dtr/shared/sync_codebase/master_ext.rb +52 -0
- data/lib/dtr/shared/sync_codebase/package.rb +39 -0
- data/lib/dtr/shared/sync_codebase/sync_service.rb +41 -0
- data/lib/dtr/shared/sync_codebase.rb +18 -0
- data/lib/dtr/shared/sync_logger.rb +72 -0
- data/lib/dtr/shared/utils/cmd.rb +30 -0
- data/lib/dtr/shared/utils/env_store.rb +60 -0
- data/lib/dtr/shared/utils/logger.rb +71 -0
- data/lib/dtr/shared/utils.rb +17 -0
- data/lib/dtr/shared/working_env.rb +38 -0
- data/lib/dtr/shared.rb +24 -0
- data/lib/dtr/test_unit/drb_test_runner.rb +57 -0
- data/lib/dtr/test_unit/injection.rb +30 -0
- data/lib/dtr/test_unit/test_case_injection.rb +37 -0
- data/lib/dtr/test_unit/testrunnermediator_injection.rb +72 -0
- data/lib/dtr/test_unit/thread_safe_test_result.rb +40 -0
- data/lib/dtr/test_unit/worker_club.rb +72 -0
- data/lib/dtr/test_unit.rb +8 -275
- data/lib/dtr/test_unit_injection.rb +0 -1
- data/lib/dtr.rb +23 -81
- data/test/acceptance/agent_working_env_test.rb +92 -0
- data/test/acceptance/dtr_package_task_test.rb +26 -0
- data/test/acceptance/general_test.rb +275 -0
- data/test/acceptance/sync_codebase_test.rb +67 -0
- data/test/acceptance/sync_logger_test.rb +41 -0
- data/test/agent_helper.rb +39 -0
- data/test/logger_stub.rb +30 -0
- data/test/test_helper.rb +43 -0
- data/test/unit/adapter_test.rb +107 -0
- data/test/unit/test_unit_test.rb +47 -0
- data/test/unit/working_env_test.rb +71 -0
- data/testdata/Rakefile +15 -0
- data/testdata/a_failed_test_case.rb +8 -0
- data/testdata/a_file_system_test_case.rb +8 -0
- data/testdata/a_test_case.rb +13 -0
- data/testdata/a_test_case2.rb +6 -0
- data/testdata/an_error_test_case.rb +9 -0
- data/testdata/another_project/Rakefile +6 -0
- data/testdata/another_project/passed_test_case.rb +7 -0
- data/testdata/is_required_by_a_test.rb +9 -0
- data/testdata/lib/lib_test_case.rb +7 -0
- data/testdata/package_task_test_rakefile +8 -0
- data/testdata/scenario_test_case.rb +34 -0
- data/testdata/setup_agent_env_test_case.rb +9 -0
- data/testdata/should_not_sync_codebase_and_setup_working_dir_when_agent_is_in_same_dir_with_master_process/Rakefile +6 -0
- data/testdata/should_not_sync_codebase_and_setup_working_dir_when_agent_is_in_same_dir_with_master_process/verify_dir_pwd_test_case.rb +10 -0
- metadata +72 -18
- data/lib/dtr/base.rb +0 -172
- data/lib/dtr/runner.rb +0 -270
- data/lib/dtr/service_provider.rb +0 -160
@@ -0,0 +1,275 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
include DTR::AgentHelper
|
4
|
+
|
5
|
+
class GeneralTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
#start_agents first for test files loaded would be copied into sub processes
|
9
|
+
start_agents
|
10
|
+
# put these here for we don't want run them in current process
|
11
|
+
@pwd = Dir.pwd
|
12
|
+
Dir.chdir(File.expand_path(File.dirname(__FILE__) + "/../../testdata/"))
|
13
|
+
require 'a_test_case'
|
14
|
+
require 'a_test_case2'
|
15
|
+
require 'a_failed_test_case'
|
16
|
+
require 'an_error_test_case'
|
17
|
+
require 'a_file_system_test_case'
|
18
|
+
require 'scenario_test_case'
|
19
|
+
require 'setup_agent_env_test_case'
|
20
|
+
|
21
|
+
DTR.inject
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
DTR.reject
|
26
|
+
Dir.chdir(@pwd)
|
27
|
+
stop_agents
|
28
|
+
$argv_dup = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_run_test_passed
|
32
|
+
$argv_dup = ['a_test_case.rb', 'a_test_case2.rb', 'a_file_system_test_case.rb']
|
33
|
+
suite = Test::Unit::TestSuite.new('run_test_passed')
|
34
|
+
suite << ATestCase.suite
|
35
|
+
suite << ATestCase2.suite
|
36
|
+
suite << AFileSystemTestCase.suite
|
37
|
+
|
38
|
+
assert_fork_process_exits_ok do
|
39
|
+
@result = runit(suite)
|
40
|
+
|
41
|
+
assert @result.passed?
|
42
|
+
assert_equal 3, @result.run_count
|
43
|
+
assert_equal 0, @result.failure_count
|
44
|
+
assert_equal 0, @result.error_count
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_run_test_failed
|
49
|
+
$argv_dup = ['a_test_case.rb', 'a_failed_test_case.rb']
|
50
|
+
suite = Test::Unit::TestSuite.new('test_run_test_failed')
|
51
|
+
suite << ATestCase.suite
|
52
|
+
suite << AFailedTestCase.suite
|
53
|
+
|
54
|
+
assert_fork_process_exits_ok do
|
55
|
+
@result = runit(suite)
|
56
|
+
|
57
|
+
assert !@result.passed?
|
58
|
+
assert_equal 2, @result.run_count
|
59
|
+
assert_equal 1, @result.failure_count
|
60
|
+
assert_equal 0, @result.error_count
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_run_test_error
|
65
|
+
$argv_dup = ['a_test_case.rb', 'an_error_test_case.rb']
|
66
|
+
suite = Test::Unit::TestSuite.new('test_run_test_error')
|
67
|
+
suite << ATestCase.suite
|
68
|
+
suite << AnErrorTestCase.suite
|
69
|
+
|
70
|
+
assert_fork_process_exits_ok do
|
71
|
+
@result = runit(suite)
|
72
|
+
|
73
|
+
assert_false @result.passed?
|
74
|
+
assert_equal 2, @result.run_count
|
75
|
+
assert_equal 0, @result.failure_count
|
76
|
+
assert_equal 1, @result.error_count
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_run_suite_should_be_independence
|
81
|
+
$argv_dup = ['an_error_test_case.rb']
|
82
|
+
suite = Test::Unit::TestSuite.new('test_run_suite_should_be_independence 1')
|
83
|
+
suite << AnErrorTestCase.suite
|
84
|
+
|
85
|
+
assert_fork_process_exits_ok do
|
86
|
+
@result = runit(suite)
|
87
|
+
|
88
|
+
assert_false @result.passed?
|
89
|
+
assert_equal 1, @result.run_count
|
90
|
+
assert_equal 0, @result.failure_count
|
91
|
+
assert_equal 1, @result.error_count
|
92
|
+
end
|
93
|
+
|
94
|
+
$argv_dup = ['a_test_case.rb']
|
95
|
+
suite = Test::Unit::TestSuite.new('test_run_suite_should_be_independence 2')
|
96
|
+
suite << ATestCase.suite
|
97
|
+
|
98
|
+
assert_fork_process_exits_ok do
|
99
|
+
@result = runit(suite)
|
100
|
+
|
101
|
+
assert @result.passed?
|
102
|
+
assert_equal 1, @result.run_count
|
103
|
+
assert_equal 0, @result.failure_count
|
104
|
+
assert_equal 0, @result.error_count
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_should_ignore_environment_file_not_exists
|
109
|
+
$argv_dup = ['a_test_case.rb', 'test_file_not_exists.rb']
|
110
|
+
suite = Test::Unit::TestSuite.new('test_run_test_file_not_exist')
|
111
|
+
suite << ATestCase.suite
|
112
|
+
|
113
|
+
assert_fork_process_exits_ok do
|
114
|
+
@result = runit(suite)
|
115
|
+
|
116
|
+
assert @result.passed?
|
117
|
+
assert_equal 1, @result.run_count
|
118
|
+
assert_equal 0, @result.failure_count
|
119
|
+
assert_equal 0, @result.error_count
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_run_empty_test_suite_and_no_test_files_in_environment
|
124
|
+
$argv_dup = []
|
125
|
+
suite = Test::Unit::TestSuite.new('test_run_without_test_files')
|
126
|
+
|
127
|
+
assert_fork_process_exits_ok do
|
128
|
+
@result = runit(suite)
|
129
|
+
|
130
|
+
assert @result.passed?
|
131
|
+
assert_equal 0, @result.run_count
|
132
|
+
assert_equal 0, @result.failure_count
|
133
|
+
assert_equal 0, @result.error_count
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_run_empty_test_suite_should_not_crash_agent
|
138
|
+
$argv_dup = []
|
139
|
+
suite = Test::Unit::TestSuite.new('test_run_empty_test_suite_should_not_crash_agent')
|
140
|
+
|
141
|
+
assert_fork_process_exits_ok do
|
142
|
+
@result = runit(suite)
|
143
|
+
|
144
|
+
assert @result.passed?
|
145
|
+
assert_equal 0, @result.run_count
|
146
|
+
assert_equal 0, @result.failure_count
|
147
|
+
assert_equal 0, @result.error_count
|
148
|
+
end
|
149
|
+
|
150
|
+
$argv_dup = ['a_test_case.rb']
|
151
|
+
suite << ATestCase.suite
|
152
|
+
assert_fork_process_exits_ok do
|
153
|
+
@result = runit(suite)
|
154
|
+
|
155
|
+
assert @result.passed?
|
156
|
+
assert_equal 1, @result.run_count
|
157
|
+
assert_equal 0, @result.failure_count
|
158
|
+
assert_equal 0, @result.error_count
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_run_empty_test_suite_and_test_files_not_exist_in_environment
|
163
|
+
$argv_dup = ['test_file_not_exists.rb']
|
164
|
+
suite = Test::Unit::TestSuite.new('test_run_empty_test_suite_and_test_files_not_exist_in_environment')
|
165
|
+
|
166
|
+
assert_fork_process_exits_ok do
|
167
|
+
@result = runit(suite)
|
168
|
+
|
169
|
+
assert @result.passed?
|
170
|
+
assert_equal 0, @result.run_count
|
171
|
+
assert_equal 0, @result.failure_count
|
172
|
+
assert_equal 0, @result.error_count
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_run_test_specified_by_load_path
|
177
|
+
lib_path = File.expand_path(File.dirname(__FILE__) + '/../../testdata/lib')
|
178
|
+
$LOAD_PATH.unshift lib_path
|
179
|
+
require 'lib_test_case'
|
180
|
+
$argv_dup = ['lib_test_case.rb']
|
181
|
+
suite = Test::Unit::TestSuite.new('test_run_test_specified_by_load_path')
|
182
|
+
suite << LibTestCase.suite
|
183
|
+
|
184
|
+
assert_fork_process_exits_ok do
|
185
|
+
@result = runit(suite)
|
186
|
+
|
187
|
+
assert @result.passed?
|
188
|
+
assert_equal 1, @result.run_count
|
189
|
+
assert_equal 0, @result.failure_count
|
190
|
+
assert_equal 0, @result.error_count
|
191
|
+
end
|
192
|
+
ensure
|
193
|
+
$LOAD_PATH.delete lib_path
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_message_of_errors_and_failures_should_include_runner_host_name
|
197
|
+
$argv_dup = ['scenario_test_case.rb']
|
198
|
+
suite = Test::Unit::TestSuite.new('test_should_wrapper_errors_by_dtr_remote_exception')
|
199
|
+
suite << ScenarioTestCase.suite
|
200
|
+
|
201
|
+
assert_fork_process_exits_ok do
|
202
|
+
@result = runit(suite)
|
203
|
+
|
204
|
+
assert !@result.passed?
|
205
|
+
assert_equal 8, @result.run_count
|
206
|
+
assert_equal 3, @result.failure_count
|
207
|
+
assert_equal 4, @result.error_count
|
208
|
+
|
209
|
+
@result.errors.each do |e|
|
210
|
+
assert e.message.include?("from #{Socket.gethostname}")
|
211
|
+
end
|
212
|
+
@result.failures.each do |e|
|
213
|
+
assert e.message.include?("from #{Socket.gethostname}")
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_setup_agent_env_from_master_process
|
219
|
+
$argv_dup = ['setup_agent_env_test_case.rb']
|
220
|
+
suite = Test::Unit::TestSuite.new('setup_agent_env_from_master_process')
|
221
|
+
suite << SetupAgentEnvTestCase.suite
|
222
|
+
ENV['DTR_AGENT_ENV_SETUP_CMD'] = 'touch /tmp/test_setup_agent_env_from_master_process'
|
223
|
+
assert_fork_process_exits_ok do
|
224
|
+
@result = runit(suite)
|
225
|
+
assert @result.passed?
|
226
|
+
assert_equal 1, @result.run_count
|
227
|
+
assert_equal 0, @result.failure_count
|
228
|
+
assert_equal 0, @result.error_count
|
229
|
+
end
|
230
|
+
ensure
|
231
|
+
File.delete('/tmp/test_setup_agent_env_from_master_process') rescue nil
|
232
|
+
ENV['DTR_AGENT_ENV_SETUP_CMD'] = nil
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_multi_dtr_tasks_should_be_queued_and_processed_one_by_one
|
236
|
+
testdata_dir = File.expand_path('./../testdata')
|
237
|
+
$argv_dup = ['a_test_case.rb', 'a_test_case2.rb', 'a_file_system_test_case.rb']
|
238
|
+
suite = Test::Unit::TestSuite.new('run_test_passed')
|
239
|
+
suite << ATestCase.suite
|
240
|
+
suite << ATestCase2.suite
|
241
|
+
suite << AFileSystemTestCase.suite
|
242
|
+
process_assertion = Proc.new do |master_dir|
|
243
|
+
FileUtils.cp_r testdata_dir, master_dir
|
244
|
+
begin
|
245
|
+
Dir.chdir(master_dir) do
|
246
|
+
result = runit(suite)
|
247
|
+
assert result.passed?
|
248
|
+
assert_equal 3, result.run_count
|
249
|
+
end
|
250
|
+
ensure
|
251
|
+
FileUtils.rm_rf master_dir
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
@test_processes = []
|
256
|
+
4.times do |index|
|
257
|
+
@test_processes << Process.fork do
|
258
|
+
process_assertion.call("#{testdata_dir}_copy#{index}")
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
Process.waitpid @test_processes[0]
|
263
|
+
assert_equal 0, $?.exitstatus
|
264
|
+
Process.waitpid @test_processes[1]
|
265
|
+
assert_equal 0, $?.exitstatus
|
266
|
+
Process.waitpid @test_processes[2]
|
267
|
+
assert_equal 0, $?.exitstatus
|
268
|
+
Process.waitpid @test_processes[3]
|
269
|
+
assert_equal 0, $?.exitstatus
|
270
|
+
ensure
|
271
|
+
@test_processes.each do |pid|
|
272
|
+
Process.kill 'TERM', pid rescue nil
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
include DTR::AgentHelper
|
3
|
+
|
4
|
+
class SyncCodebaseTest < Test::Unit::TestCase
|
5
|
+
include DTR::Service::File
|
6
|
+
include DTR::SyncCodebase::SyncService
|
7
|
+
|
8
|
+
def test_sync_codebase
|
9
|
+
testdata_dir = File.expand_path(File.dirname(__FILE__) + '/../../testdata')
|
10
|
+
|
11
|
+
master = Process.fork do
|
12
|
+
DTR.configuration.with_rinda_server do
|
13
|
+
Dir.chdir(testdata_dir) do
|
14
|
+
DTR::Cmd.execute('rake dtr_repackage')
|
15
|
+
provide_file DTR::SyncCodebase::Codebase.new
|
16
|
+
DRb.thread.join
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
#sleep for waiting rinda server start
|
21
|
+
sleep(1)
|
22
|
+
client = Process.fork do
|
23
|
+
start_service
|
24
|
+
Dir.mkdir("test_sync_codebase")
|
25
|
+
Dir.chdir("test_sync_codebase") do
|
26
|
+
sync_codebase
|
27
|
+
end
|
28
|
+
end
|
29
|
+
Process.waitpid client
|
30
|
+
assert File.directory?("test_sync_codebase/#{package_name}")
|
31
|
+
assert !File.exists?("test_sync_codebase/#{package_copy_file}")
|
32
|
+
ensure
|
33
|
+
stop_service rescue nil
|
34
|
+
Process.kill 'TERM', master rescue nil
|
35
|
+
Process.kill 'TERM', client rescue nil
|
36
|
+
FileUtils.rm_rf("test_sync_codebase")
|
37
|
+
Dir.chdir(testdata_dir) do
|
38
|
+
DTR::Cmd.execute('rake dtr_clobber_package')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_should_not_sync_codebase_and_setup_working_dir_when_agent_is_in_same_dir_with_master_process
|
43
|
+
@master_dir = File.expand_path(File.dirname(__FILE__) + '/../../testdata/should_not_sync_codebase_and_setup_working_dir_when_agent_is_in_same_dir_with_master_process')
|
44
|
+
Dir.chdir(@master_dir) do
|
45
|
+
require 'verify_dir_pwd_test_case'
|
46
|
+
end
|
47
|
+
$argv_dup = ['verify_dir_pwd_test_case.rb']
|
48
|
+
suite = Test::Unit::TestSuite.new('test_should_not_sync_codebase_and_setup_working_dir')
|
49
|
+
suite << VerifyDirPwdTestCase.suite
|
50
|
+
@agent = start_agent_at @master_dir, 2, false
|
51
|
+
begin
|
52
|
+
DTR.inject
|
53
|
+
assert_fork_process_exits_ok do
|
54
|
+
Dir.chdir(@master_dir) do
|
55
|
+
result = runit(suite)
|
56
|
+
assert result.passed?
|
57
|
+
assert_equal 1, result.run_count
|
58
|
+
end
|
59
|
+
end
|
60
|
+
ensure
|
61
|
+
DTR.reject
|
62
|
+
Process.kill 'TERM', @agent rescue nil
|
63
|
+
Process.waitall
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
include DTR::AgentHelper
|
4
|
+
|
5
|
+
class SyncLoggerTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
start_agents
|
9
|
+
# put these here for we don't want run them in current process
|
10
|
+
@pwd = Dir.pwd
|
11
|
+
Dir.chdir(File.expand_path(File.dirname(__FILE__) + "/../../testdata/"))
|
12
|
+
require 'a_test_case'
|
13
|
+
@logger = LoggerStub.new
|
14
|
+
DTR.logger = @logger
|
15
|
+
DTR.inject
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
DTR.reject
|
20
|
+
Dir.chdir(@pwd)
|
21
|
+
stop_agents
|
22
|
+
$argv_dup = nil
|
23
|
+
DTR.logger = nil
|
24
|
+
@logger.clear
|
25
|
+
end
|
26
|
+
|
27
|
+
#todo fix random failure
|
28
|
+
def test_master_process_should_get_log_of_agents
|
29
|
+
$argv_dup = ['a_test_case.rb']
|
30
|
+
suite = Test::Unit::TestSuite.new('test_master_process_should_get_log_of_agents')
|
31
|
+
suite << ATestCase.suite
|
32
|
+
assert_fork_process_exits_ok do
|
33
|
+
runit(suite)
|
34
|
+
end
|
35
|
+
logs = @logger.logs.flatten.join("\n")
|
36
|
+
assert(/From #{Socket.gethostname}: => Herald starts off\.\.\./ =~ logs)
|
37
|
+
assert(/From #{Socket.gethostname}: runner0: test files loaded/ =~ logs)
|
38
|
+
#when use Delegator to implement UndumpedLogger, there are lots of 'nil' in the log
|
39
|
+
assert(/nil/ !~ logs)
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
module DTR
|
3
|
+
module AgentHelper
|
4
|
+
def start_agents
|
5
|
+
@agents_dir = File.join(Dir.pwd, 'agents')
|
6
|
+
@agents = []
|
7
|
+
@agents << start_agent_at(File.join(@agents_dir, 'agent1'), 3)
|
8
|
+
# @agents << start_agent_at(File.join(@agents_dir, 'agent2'), 1)
|
9
|
+
end
|
10
|
+
|
11
|
+
def start_agent_at(agent_dir, size, clean_dir=true)
|
12
|
+
FileUtils.rm_rf(agent_dir) if clean_dir
|
13
|
+
FileUtils.mkdir_p(agent_dir)
|
14
|
+
runner_names = []
|
15
|
+
size.times {|i| runner_names << "runner#{i}"}
|
16
|
+
Process.fork do
|
17
|
+
begin
|
18
|
+
Dir.chdir(agent_dir) do
|
19
|
+
DTR.launch_agent(runner_names, nil)
|
20
|
+
end
|
21
|
+
rescue Exception => e
|
22
|
+
puts e.message
|
23
|
+
puts e.backtrace.join("\n")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def stop_agents
|
29
|
+
if @agents
|
30
|
+
@agents.each do |agent|
|
31
|
+
Process.kill 'TERM', agent rescue nil
|
32
|
+
end
|
33
|
+
Process.waitall
|
34
|
+
end
|
35
|
+
ensure
|
36
|
+
FileUtils.rm_rf(@agents_dir) rescue nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/test/logger_stub.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
class LoggerStub
|
2
|
+
def initialize
|
3
|
+
@store = DTR::EnvStore.new
|
4
|
+
clear
|
5
|
+
end
|
6
|
+
def debug(message=nil, &block)
|
7
|
+
output(:debug, message, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
def info(message=nil, &block)
|
11
|
+
output(:info, message, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def error(message=nil, &block)
|
15
|
+
output(:error, message, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def output(level, msg=nil, &block)
|
19
|
+
message = block_given? ? block.call : msg.to_s
|
20
|
+
@store << [:logs, [level, message]]
|
21
|
+
end
|
22
|
+
|
23
|
+
def logs
|
24
|
+
@store[:logs]
|
25
|
+
end
|
26
|
+
|
27
|
+
def clear
|
28
|
+
@store[:logs] = []
|
29
|
+
end
|
30
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'test/unit/ui/console/testrunner'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
# require 'growling_test'
|
8
|
+
require 'dtr'
|
9
|
+
require 'dtr/test_unit'
|
10
|
+
# DTR.configuration.master_yell_interval = 2
|
11
|
+
# DTR.configuration.follower_listen_sleep_timeout = 3
|
12
|
+
|
13
|
+
require File.dirname(__FILE__) + '/agent_helper'
|
14
|
+
require File.dirname(__FILE__) + '/logger_stub'
|
15
|
+
|
16
|
+
ENV['DTR_ENV'] = 'test'
|
17
|
+
|
18
|
+
module Test
|
19
|
+
module Unit
|
20
|
+
class TestCase
|
21
|
+
def assert_false(o)
|
22
|
+
assert !o
|
23
|
+
end
|
24
|
+
def assert_fork_process_exits_ok(&block)
|
25
|
+
pid = Process.fork do
|
26
|
+
block.call
|
27
|
+
exit 0
|
28
|
+
end
|
29
|
+
Process.waitpid pid
|
30
|
+
assert_equal 0, $?.exitstatus
|
31
|
+
ensure
|
32
|
+
Process.kill 'TERM', pid rescue nil
|
33
|
+
end
|
34
|
+
def runit(suite)
|
35
|
+
Test::Unit::UI::Console::TestRunner.run(suite, Test::Unit::UI::SILENT)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Test::Unit::TestResult
|
42
|
+
attr_reader :failures, :errors
|
43
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
include DTR::AgentHelper
|
4
|
+
|
5
|
+
class AdapterTests < Test::Unit::TestCase
|
6
|
+
include DTR::Adapter::Master
|
7
|
+
include DTR::Adapter::Follower
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@timeout = false
|
11
|
+
@messages = []
|
12
|
+
DTR.configuration.follower_listen_sleep_timeout = 1
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
DTR.configuration.follower_listen_sleep_timeout = 15
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_should_be_sleep_if_never_wakeup
|
20
|
+
assert sleep?
|
21
|
+
assert !wakeup?
|
22
|
+
assert sleep?
|
23
|
+
do_wakeup_agents
|
24
|
+
assert wakeup?
|
25
|
+
do_wakeup_agents
|
26
|
+
assert !sleep?
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_wakeup_by_broadcast_message
|
30
|
+
assert !wakeup?
|
31
|
+
broadcast('address', "#{DTR::Adapter::WAKEUP_MESSAGE} #{Socket.gethostname}:4567")
|
32
|
+
assert wakeup?
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_should_be_sleep_after_hypnotized_waked_up_agents
|
36
|
+
broadcast('address', "#{DTR::Adapter::WAKEUP_MESSAGE} #{Socket.gethostname}:4567")
|
37
|
+
assert wakeup?
|
38
|
+
hypnotize_agents
|
39
|
+
assert sleep?
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_do_wakeup_agents
|
43
|
+
assert !wakeup?
|
44
|
+
do_wakeup_agents
|
45
|
+
assert wakeup?
|
46
|
+
|
47
|
+
do_wakeup_agents
|
48
|
+
assert !sleep?
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_hypnotize_agents_after_did_waked_up_agents
|
52
|
+
do_wakeup_agents
|
53
|
+
assert wakeup?
|
54
|
+
hypnotize_agents
|
55
|
+
assert sleep?
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_should_not_be_sleep_when_sleep_message_is_sent_from_different_port_with_wakeup_message
|
59
|
+
broadcast('address', "#{DTR::Adapter::WAKEUP_MESSAGE} hostname:1234")
|
60
|
+
assert wakeup?
|
61
|
+
#sleep message should be ignored
|
62
|
+
broadcast('address', "#{DTR::Adapter::SLEEP_MESSAGE} hostname:4567")
|
63
|
+
#wakup message for keep it wakeup
|
64
|
+
broadcast('address', "#{DTR::Adapter::WAKEUP_MESSAGE} hostname:1234")
|
65
|
+
assert !sleep?
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_should_not_be_sleep_when_sleep_message_is_sent_from_different_hostname_with_wakeup_message
|
69
|
+
broadcast('address', "#{DTR::Adapter::WAKEUP_MESSAGE} xli.local:1234")
|
70
|
+
assert wakeup?
|
71
|
+
#sleep message should be ignored
|
72
|
+
broadcast('address', "#{DTR::Adapter::SLEEP_MESSAGE} dtr.remote:1234")
|
73
|
+
#wakup message for keep it wakeup
|
74
|
+
broadcast('address', "#{DTR::Adapter::WAKEUP_MESSAGE} xli.local:1234")
|
75
|
+
assert !sleep?
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_should_update_rinda_server_port_parsed_from_wakeup_message
|
79
|
+
broadcast('address', "#{DTR::Adapter::WAKEUP_MESSAGE} hostname:4567")
|
80
|
+
assert wakeup?
|
81
|
+
assert_equal 4567, DTR.configuration.rinda_server_port
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_should_be_sleep_when_timeout_on_listen
|
85
|
+
do_wakeup_agents
|
86
|
+
assert wakeup?
|
87
|
+
@timeout = true
|
88
|
+
assert sleep?
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_should_be_sleep_when_timeout_on_listen_to_host_sending_wakeup_message
|
92
|
+
broadcast('address', "#{DTR::Adapter::WAKEUP_MESSAGE} xli.local:1234")
|
93
|
+
assert wakeup?
|
94
|
+
broadcast('address', "#{DTR::Adapter::WAKEUP_MESSAGE} dtr.remote:1234")
|
95
|
+
sleep(2)
|
96
|
+
assert sleep?
|
97
|
+
end
|
98
|
+
|
99
|
+
def listen
|
100
|
+
raise Timeout::Error.new('timeout') if @timeout
|
101
|
+
@messages.shift.to_s.split
|
102
|
+
end
|
103
|
+
|
104
|
+
def broadcast(it, msg)
|
105
|
+
@messages << msg
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class TestUnitTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def teardown
|
6
|
+
DTR.reject
|
7
|
+
end
|
8
|
+
|
9
|
+
# inject testcase as late as possible, for in ruby world there is lots hacks added to TestCase#run method,
|
10
|
+
# DTR should be the last one to add dtr injection chain into run method
|
11
|
+
def test_should_only_inject_test_runner_mediator_for_lauching_dtr
|
12
|
+
DTR.inject
|
13
|
+
assert Test::Unit::UI::TestRunnerMediator.respond_to?(:reject_dtr)
|
14
|
+
assert Test::Unit::UI::TestRunnerMediator.method_defined?(:run_suite_without_dtr_injection)
|
15
|
+
assert Test::Unit::UI::TestRunnerMediator.private_method_defined?(:create_result_without_thread_safe)
|
16
|
+
assert !Test::Unit::TestCase.respond_to?(:reject_dtr)
|
17
|
+
assert !Test::Unit::TestCase.method_defined?(:run_without_dtr_injection)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_inject_testcase
|
21
|
+
Test::Unit::TestCase.send(:include, DTR::TestUnit::TestCaseInjection)
|
22
|
+
begin
|
23
|
+
assert Test::Unit::TestCase.respond_to?(:reject_dtr)
|
24
|
+
assert Test::Unit::TestCase.method_defined?(:run_without_dtr_injection)
|
25
|
+
ensure
|
26
|
+
Test::Unit::TestCase.reject_dtr
|
27
|
+
end
|
28
|
+
assert !Test::Unit::TestCase.respond_to?(:reject_dtr)
|
29
|
+
assert !Test::Unit::TestCase.method_defined?(:run_without_dtr_injection)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_reject
|
33
|
+
DTR.inject
|
34
|
+
DTR.reject
|
35
|
+
test_case = Test::Unit::TestCase.new('name')
|
36
|
+
assert_false test_case.respond_to?(:run_without_dtr_injection)
|
37
|
+
assert test_case.respond_to?(:run)
|
38
|
+
|
39
|
+
assert !Test::Unit::TestCase.respond_to?(:reject_dtr)
|
40
|
+
assert !Test::Unit::UI::TestRunnerMediator.respond_to?(:reject_dtr)
|
41
|
+
|
42
|
+
assert !Test::Unit::TestCase.method_defined?(:run_without_dtr_injection)
|
43
|
+
assert !Test::Unit::UI::TestRunnerMediator.method_defined?(:run_suite_without_dtr_injection)
|
44
|
+
assert !Test::Unit::UI::TestRunnerMediator.private_method_defined?(:create_result_without_thread_safe)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|