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
data/README
CHANGED
@@ -3,20 +3,18 @@
|
|
3
3
|
Supporting DTR version: 0.0.x
|
4
4
|
|
5
5
|
This package contains DTR, a distributed test runner program for decreasing
|
6
|
-
time of running ruby tests, only supporting Test::Unit ruby testing framework
|
7
|
-
|
6
|
+
time of running ruby tests, only supporting Test::Unit ruby testing framework
|
7
|
+
currently.
|
8
8
|
|
9
9
|
DTR has the following features:
|
10
10
|
|
11
11
|
* Run tests in mutli processes or on distributed machines.
|
12
12
|
|
13
|
-
* Hot plug distributed
|
13
|
+
* Hot plug distributed agents.
|
14
14
|
|
15
15
|
* Runtime injection, all tests run in same environment.
|
16
16
|
|
17
|
-
DTR works in
|
18
|
-
|
19
|
-
* DTR Server is a Rinda Server which allows DRb services and clients to automatically find each other without knowing where they live.
|
17
|
+
DTR works in two parts: Runner Agent and DTR Master.
|
20
18
|
|
21
19
|
* Runner Agent is a DRb service hosting on distributed machines to run tests. For using 'fork' to create runner process, Runner Agent can't run on Windows directly.
|
22
20
|
|
@@ -103,118 +101,16 @@ options would be cached in the directory running the test or any other dtr proce
|
|
103
101
|
|
104
102
|
== Run tests in multi-processes on one machine
|
105
103
|
|
106
|
-
For running Runner in multi-processes
|
104
|
+
For running Runner in multi-processes.
|
107
105
|
The following is the test task example in the rake file:
|
108
106
|
|
109
107
|
require 'dtr/raketasks'
|
110
108
|
|
111
|
-
DTR::
|
109
|
+
DTR::TestTask.new :test do |t|
|
112
110
|
t.test_files = FileList['test/*test.rb']
|
113
111
|
t.processes = 2 #default is 2
|
114
112
|
end
|
115
113
|
|
116
|
-
== Setup a development build grid
|
117
|
-
|
118
|
-
This example is a build grid shared within developers to run unit tests
|
119
|
-
before commit code. We'll use Mercurial to synchronize code between Runner
|
120
|
-
Agent machines and developer machine.
|
121
|
-
|
122
|
-
=== Background
|
123
|
-
|
124
|
-
Suppose I am a developer working on a rails project pet_store checked out
|
125
|
-
at '~/pet_store'. I have a MacBook called M1 and another 2 Mac-minis called
|
126
|
-
M2 and M3. My plan is distributing tests running on M1 to M2 and M3 before
|
127
|
-
commit code. M3 also will be DTR Server. All machines are accessable in
|
128
|
-
local network and IPs are M1_IP, M2_IP and M3_IP. Mercurial and DTR are
|
129
|
-
installed on all machines. And for running dtr runner agent in daemons mode,
|
130
|
-
you need install gem daemons. The test environment will be running on Mysql.
|
131
|
-
All machines are installed Mysql accessed by the following database.yml
|
132
|
-
configuration:
|
133
|
-
|
134
|
-
development:
|
135
|
-
database: pet_store_development
|
136
|
-
adapter: mysql
|
137
|
-
username: root
|
138
|
-
password:
|
139
|
-
host: localhost
|
140
|
-
test:
|
141
|
-
database: pet_store_test
|
142
|
-
adapter: mysql
|
143
|
-
username: root
|
144
|
-
password:
|
145
|
-
host: localhost
|
146
|
-
|
147
|
-
=== DTR Server
|
148
|
-
|
149
|
-
* Start DTR Server on M3: dtr -s -a M3_IP.
|
150
|
-
|
151
|
-
=== Setup Mercurial repository on M1
|
152
|
-
|
153
|
-
* Init Mercurial repository in '~/pet_store' directory: hg init
|
154
|
-
* Edit .hgignore file to ignore files don't need while running tests. In this example, we will ignore files: db/schema.rb, .dtr_env_pstore, dtr_runners.pid and dtr_server*; and directories: public, tmp and log.
|
155
|
-
* Commit .hgignore and then commit code into Mercurial repository.
|
156
|
-
* Start 'hg serve' in '~/pet_store', the default port would be 8000. We'll use the default port in this example.
|
157
|
-
* We'll clone the repository to M2 and M3 later.
|
158
|
-
|
159
|
-
=== Build Script
|
160
|
-
|
161
|
-
* Add an environment variable on all machines: export DEV_BUILD_SERVER=M3_IP
|
162
|
-
* Add an environment variable on development machine M1: export DTR_MASTER_ENV=http: //M1_IP:8000/pet_store. The environment variable DTR_MASTER_ENV would be copied to all DTR Runner Agent for sharing information between DTR Master machine and DTR Runner Agents.
|
163
|
-
* Create a rake file at '~/pet_store' directory called: dtr_tasks.rake
|
164
|
-
|
165
|
-
DEV_BUILD_SERVER = ENV['DEV_BUILD_SERVER']
|
166
|
-
DEV_REPOSITORY_URL = ENV['DTR_MASTER_ENV']
|
167
|
-
|
168
|
-
task :dtr => ['hg:check', 'dtr:uf']
|
169
|
-
|
170
|
-
namespace :hg do
|
171
|
-
task :reinit do
|
172
|
-
Dir.glob("*").each do |f|
|
173
|
-
#remove all files except files start with 'dtr_' including dtr runner pid file and current file dtr_tasks.rake
|
174
|
-
next if f =~ /^dtr_/
|
175
|
-
FileUtils.rm_rf(f)
|
176
|
-
end
|
177
|
-
FileUtils.rm_rf(".hg")
|
178
|
-
FileUtils.rm_rf(".hgignore")
|
179
|
-
puts %x[hg init]
|
180
|
-
puts %x[hg pull -u -y #{DEV_REPOSITORY_URL}]
|
181
|
-
puts %x[mkdir tmp]
|
182
|
-
puts %x[mkdir log]
|
183
|
-
end
|
184
|
-
task :check do
|
185
|
-
http = Net::HTTP.new("localhost", "8000")
|
186
|
-
begin
|
187
|
-
http.get("/")
|
188
|
-
rescue Exception
|
189
|
-
raise "Mercurial server is not running!"
|
190
|
-
end
|
191
|
-
|
192
|
-
raise "Please commit changes into Mercurial repository" if %x[hg st] =~ /.+/
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
namespace :dtr do
|
197
|
-
task :runner_agent do
|
198
|
-
puts %x[dtr -R;dtr -r runner -a '#{DEV_BUILD_SERVER}' -i 'rake --rakefile dtr_tasks.rake hg:reinit;rake db:migrate db:test:prepare' -D]
|
199
|
-
end
|
200
|
-
|
201
|
-
require 'dtr'
|
202
|
-
|
203
|
-
DTR.broadcast_list = [DEV_BUILD_SERVER]
|
204
|
-
|
205
|
-
DTR::MPTask.new(:uf) do |t|
|
206
|
-
t.libs << "test"
|
207
|
-
t.test_files = FileList['test/unit/**/*test.rb', 'test/functional/**/*test.rb']
|
208
|
-
t.processes = ENV['P'] || 1
|
209
|
-
t.runner_options = "-a '#{DEV_BUILD_SERVER}' -i 'rake db:migrate db:test:prepare'"
|
210
|
-
t.start_server = false
|
211
|
-
t.verbose = false
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
* The script above can re-init Mercurial repository. Runner Agent will run the 'hg:reinit' task before start Runner(see the 'runner_agent' task in the script above), so that Runner Agent can support any developer's codebase to run tests.
|
216
|
-
* Commit dtr_tasks.rake into Mercurial repository.
|
217
|
-
|
218
114
|
=== Runner Agent
|
219
115
|
|
220
116
|
* Clone repository from M1 to M2 in home directory: hg clone http: //M1_IP:8000/pet_store
|
@@ -263,12 +159,7 @@ DTR client is invoked from the command line using:
|
|
263
159
|
-a, --server_address ADDRESS Specify dtr server address, domain name or ip address, e.g. 192.168.0.1. Default is 'localhost'.
|
264
160
|
-i, --setup COMMAND Set command for initializing test runner test environment, e.g. 'rake db:test:prepare'. Default is do nothing.
|
265
161
|
-m, --monitor Monitor the status of the dtr rinda server, e.g. dtr -a 10.11.1.2 -m
|
266
|
-
-c, --clean_server Clean server environment, shutdown all runners registered.
|
267
162
|
-b, --be_silent Only show error messages
|
268
|
-
-s, --server Start DTR service server. There must be a DTR server running.
|
269
|
-
-D, --daemon Start server/runners in daemon mode. Gem 'daemons' must be installed
|
270
|
-
-S, --stop_server Stop server run in daemon mode.
|
271
|
-
-R, --stop_runners Stop runners run in daemon mode.
|
272
163
|
-d, --debug output debug log
|
273
164
|
-v, --version Show version
|
274
165
|
-h, --help Show this help doc
|
data/Rakefile
CHANGED
@@ -48,37 +48,21 @@ end
|
|
48
48
|
|
49
49
|
task :test_all => [:test_units, :tf]
|
50
50
|
task :tu => :test_units
|
51
|
-
task :tf => [:
|
51
|
+
task :tf => [:test_functionals]
|
52
52
|
task :test => :test_units
|
53
53
|
|
54
54
|
Rake::TestTask.new(:test_units) do |t|
|
55
|
-
t.test_files = FileList['test/*
|
55
|
+
t.test_files = FileList['test/unit/*_test.rb']
|
56
56
|
t.warning = true
|
57
57
|
t.verbose = false
|
58
58
|
end
|
59
59
|
|
60
60
|
Rake::TestTask.new(:test_functionals) do |t|
|
61
|
-
t.test_files = FileList['test/
|
62
|
-
t.warning =
|
61
|
+
t.test_files = FileList['test/acceptance/*_test.rb']
|
62
|
+
t.warning = false
|
63
63
|
t.verbose = false
|
64
64
|
end
|
65
65
|
|
66
|
-
task :start_dtr_server do
|
67
|
-
ruby "-I#{File.dirname(__FILE__) + "/lib"} #{File.dirname(__FILE__) + "/bin/dtr"} -s -D"
|
68
|
-
end
|
69
|
-
|
70
|
-
task :start_dtr_runners do
|
71
|
-
ruby "-I#{File.dirname(__FILE__) + "/lib"} #{File.dirname(__FILE__) + "/bin/dtr"} -r r1,r2,r3 -D"
|
72
|
-
end
|
73
|
-
|
74
|
-
task :stop_dtr_runners do
|
75
|
-
ruby "-I#{File.dirname(__FILE__) + "/lib"} #{File.dirname(__FILE__) + "/bin/dtr"} -R"
|
76
|
-
end
|
77
|
-
|
78
|
-
task :stop_dtr_server do
|
79
|
-
ruby "-I#{File.dirname(__FILE__) + "/lib"} #{File.dirname(__FILE__) + "/bin/dtr"} -S"
|
80
|
-
end
|
81
|
-
|
82
66
|
begin
|
83
67
|
require 'rcov/rcovtask'
|
84
68
|
|
@@ -134,7 +118,9 @@ if ! defined?(Gem)
|
|
134
118
|
puts "Package Target requires RubyGEMs"
|
135
119
|
else
|
136
120
|
File.open(File.dirname(__FILE__) + '/dtr.gemspec') do |f|
|
137
|
-
|
121
|
+
data = f.read
|
122
|
+
spec = nil
|
123
|
+
Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
|
138
124
|
package_task = Rake::GemPackageTask.new(spec) do |pkg|
|
139
125
|
#pkg.need_zip = true
|
140
126
|
#pkg.need_tar = true
|
@@ -176,11 +162,6 @@ task :lines do
|
|
176
162
|
show_line("TOTAL", total_lines, total_code)
|
177
163
|
end
|
178
164
|
|
179
|
-
# Define an optional publish target in an external file. If the
|
180
|
-
# publish.rf file is not found, the publish targets won't be defined.
|
181
|
-
|
182
|
-
load "publish.rf" if File.exist? "publish.rf"
|
183
|
-
|
184
165
|
# Support Tasks ------------------------------------------------------
|
185
166
|
|
186
167
|
RUBY_FILES = FileList['**/*.rb'].exclude('pkg')
|
@@ -219,155 +200,42 @@ task :update_site do
|
|
219
200
|
puts %x[scp -r html/* lixiao@rubyforge.org:/var/www/gforge-projects/dtr/]
|
220
201
|
end
|
221
202
|
|
222
|
-
task :noop
|
223
|
-
|
224
|
-
desc "[rel, reuse, reltest] Make a new release"
|
225
|
-
task :release => [
|
226
|
-
:prerelease,
|
227
|
-
:clobber,
|
228
|
-
:test_all,
|
229
|
-
:update_version,
|
230
|
-
:package,
|
231
|
-
:tag] do
|
232
|
-
|
233
|
-
announce
|
234
|
-
announce "**************************************************************"
|
235
|
-
announce "* Release #{$package_version} Complete."
|
236
|
-
announce "* Packages ready to upload."
|
237
|
-
announce "**************************************************************"
|
238
|
-
announce
|
239
|
-
end
|
240
|
-
|
241
|
-
# Validate that everything is ready to go for a release.
|
242
|
-
desc "[rel, reuse, reltest]"
|
243
|
-
task :prerelease do |t, rel, reuse, reltest|
|
244
|
-
$package_version = rel
|
245
|
-
announce
|
246
|
-
announce "**************************************************************"
|
247
|
-
announce "* Making RubyGem Release #{$package_version}"
|
248
|
-
announce "* (current version #{CURRENT_VERSION})"
|
249
|
-
announce "**************************************************************"
|
250
|
-
announce
|
251
|
-
|
252
|
-
# Is a release number supplied?
|
253
|
-
unless rel
|
254
|
-
fail "Usage: rake release[X.Y.Z] [REUSE=tag_suffix]"
|
255
|
-
end
|
256
|
-
|
257
|
-
# Is the release different than the current release.
|
258
|
-
# (or is REUSE set?)
|
259
|
-
if $package_version == CURRENT_VERSION && ! reuse
|
260
|
-
fail "Current version is #{$package_version}, must specify REUSE=tag_suffix to reuse version"
|
261
|
-
end
|
262
|
-
|
263
|
-
# Are all source files checked in?
|
264
|
-
if reltest
|
265
|
-
announce "Release Task Testing, skipping checked-in file test"
|
266
|
-
else
|
267
|
-
announce "Checking for unchecked-in files..."
|
268
|
-
data = `svn st`
|
269
|
-
unless data =~ /^$/
|
270
|
-
abort "svn status is not clean ... do you have unchecked-in files?"
|
271
|
-
end
|
272
|
-
announce "No outstanding checkins found ... OK"
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
desc "[rel, reuse, reltest]"
|
277
|
-
task :update_version => [:prerelease] do |t, rel, reuse, reltest|
|
278
|
-
if rel == CURRENT_VERSION
|
279
|
-
announce "No version change ... skipping version update"
|
280
|
-
else
|
281
|
-
announce "Updating DTR version to #{rel}"
|
282
|
-
open("lib/dtr.rb") do |dtrin|
|
283
|
-
open("lib/dtr.rb.new", "w") do |dtrout|
|
284
|
-
dtrin.each do |line|
|
285
|
-
if line =~ /^DTRVERSION\s*=\s*/
|
286
|
-
dtrout.puts "DTRVERSION = '#{rel}'"
|
287
|
-
else
|
288
|
-
dtrout.puts line
|
289
|
-
end
|
290
|
-
end
|
291
|
-
end
|
292
|
-
end
|
293
|
-
mv "lib/dtr.rb.new", "lib/dtr.rb"
|
294
|
-
if reltest
|
295
|
-
announce "Release Task Testing, skipping commiting of new version"
|
296
|
-
else
|
297
|
-
sh %{svn commit -m "Updated to version #{rel}" lib/dtr.rb} # "
|
298
|
-
end
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
desc "[rel, reuse, reltest] Tag all the CVS files with the latest release number (REL=x.y.z)"
|
303
|
-
task :tag => [:prerelease] do |t, rel, reuse, reltest|
|
304
|
-
reltag = "REL_#{rel.gsub(/\./, '_')}"
|
305
|
-
reltag << reuse.gsub(/\./, '_') if reuse
|
306
|
-
announce "Tagging Repository with [#{reltag}]"
|
307
|
-
if reltest
|
308
|
-
announce "Release Task Testing, skipping CVS tagging"
|
309
|
-
else
|
310
|
-
sh %{svn copy svn+ssh://rubyforge.org/var/svn/dtr/trunk svn+ssh://rubyforge.org/var/svn/dtr/tags/#{reltag} -m 'Commiting release #{reltag}'}
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
desc "Install the jamis RDoc template"
|
315
|
-
task :install_jamis_template do
|
316
|
-
require 'rbconfig'
|
317
|
-
dest_dir = File.join(Config::CONFIG['rubylibdir'], "rdoc/generators/template/html")
|
318
|
-
fail "Unabled to write to #{dest_dir}" unless File.writable?(dest_dir)
|
319
|
-
install "doc/jamis.rb", dest_dir, :verbose => true
|
320
|
-
end
|
321
|
-
|
322
203
|
task :c1 do
|
323
|
-
|
324
|
-
DTR.launch_runners(['c1'], nil)
|
325
|
-
end
|
204
|
+
DTR.launch_agent(['c1'], nil)
|
326
205
|
end
|
327
206
|
|
328
207
|
task :c3 do
|
329
|
-
|
330
|
-
DTR.launch_runners(['c1', 'c2', 'c3'], nil)
|
331
|
-
end
|
208
|
+
DTR.launch_agent(['c1', 'c2', 'c3'], nil)
|
332
209
|
end
|
333
210
|
task :c10 do
|
334
|
-
|
335
|
-
DTR.launch_runners(['c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'c10'], nil)
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
task :runners do
|
340
|
-
runners = DTR.runners
|
341
|
-
if runners.empty?
|
342
|
-
puts "No runner available!"
|
343
|
-
else
|
344
|
-
puts runners.collect{|r| r.name}.join(", ")
|
345
|
-
end
|
211
|
+
DTR.launch_agent(['c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'c10'], nil)
|
346
212
|
end
|
347
213
|
|
348
214
|
task :c2 do
|
349
|
-
|
350
|
-
|
215
|
+
DTR_AGENT_OPTIONS[:runners] = ['c1', 'c2']
|
216
|
+
DTR_AGENT_OPTIONS[:agent_env_setup_cmd] = nil
|
351
217
|
Dir.chdir('testdata') do
|
352
|
-
DTR.
|
218
|
+
DTR.start_agent
|
353
219
|
end
|
354
220
|
end
|
355
221
|
|
356
|
-
task :server do
|
357
|
-
DTR.start_server
|
358
|
-
end
|
359
|
-
|
360
222
|
Rake::TestTask.new(:dtr) do |t|
|
361
|
-
t.libs
|
362
|
-
t.test_files = FileList['dtr/
|
223
|
+
t.libs.unshift DTR.lib_path
|
224
|
+
t.test_files = FileList['dtr/test_unit_injection.rb', 'testdata/*.rb']
|
363
225
|
t.warning = true
|
364
226
|
t.verbose = false
|
365
227
|
end
|
366
228
|
|
367
229
|
require 'dtr/raketasks'
|
368
230
|
|
369
|
-
DTR::
|
231
|
+
DTR::TestTask.new :mt do |t|
|
370
232
|
t.test_files = FileList['testdata/*.rb']
|
371
233
|
t.processes = 2
|
372
234
|
end
|
373
235
|
|
236
|
+
DTR::PackageTask.new do |p|
|
237
|
+
p.package_files.include("**/*")
|
238
|
+
p.package_files.exclude("tmp")
|
239
|
+
p.package_files.exclude("log")
|
240
|
+
end
|
241
|
+
|
data/TODO
CHANGED
@@ -3,6 +3,21 @@
|
|
3
3
|
Send suggestions for this list to iam@li-xiao.com
|
4
4
|
|
5
5
|
=== To Do
|
6
|
-
|
6
|
+
clean Process.fork and rescue Exception inside and its log
|
7
|
+
change to use zip instead of tar for easy use dtr master in windows
|
8
|
+
add a test for problem of injecting dtr early
|
9
|
+
master process log doesn't have time label in mingle
|
10
|
+
sleep in test would cause yelling delayed? add a test for it
|
11
|
+
auto mkdir log&tmp for agent?
|
12
|
+
update help doc
|
13
|
+
should trigger started on runner in agent runner, for some tools is using this hook(e.g. inbrowser_test)
|
14
|
+
|
15
|
+
???? agent brain should wakeup when worker is dead
|
16
|
+
problem: when agent can't find test files, drb can't undump test object, the error would be: undefined method `run' for #<DRb::DRbUnknown:0x318800>
|
17
|
+
* tell Master this error that agent can't know what's item sent from Master
|
18
|
+
|
19
|
+
monitor dtr rinda server status
|
20
|
+
monitor acceptance test
|
21
|
+
|
7
22
|
|
8
23
|
(moved DONE list to CHANGES file)
|
data/bin/dtr
CHANGED
@@ -11,10 +11,12 @@ end
|
|
11
11
|
NOTES = <<-NOTES
|
12
12
|
----------------
|
13
13
|
Notes:
|
14
|
-
* The default value of
|
14
|
+
* The default value of broadcast address is 'localhost'.
|
15
15
|
* Runners specified by -r option will be started in different processes by the runner agent.
|
16
|
-
*
|
17
|
-
|
16
|
+
* DTR master environment options:
|
17
|
+
* DTR_MASTER_ENV: this variable would be copied into runner process for sharing info between master and agents
|
18
|
+
* DTR_AGENT_ENV_SETUP_CMD: this variable would be applied as agent setup environment command when agent have no setup environment command specified.
|
19
|
+
* DTR_LOG_LEVEL: master process logger level, e.g. ENV['DTR_LOG_LEVEL'] = Logger::DEBUG
|
18
20
|
|
19
21
|
DTR is a distributed test runner program for decreasing time of running ruby tests based on ruby 'test/unit' package.
|
20
22
|
For additional information, see http://dtr.rubyforge.org/
|
@@ -24,62 +26,41 @@ opts = OptionParser.new do |opts|
|
|
24
26
|
opts.banner = "DTR usage: #{$0} [options]"
|
25
27
|
opts.separator ""
|
26
28
|
opts.separator "Synopsis:"
|
27
|
-
opts.separator "dtr -s"
|
28
29
|
opts.separator "dtr -r runner1_name,runner2_name"
|
29
|
-
opts.separator "dtr -a
|
30
|
+
opts.separator "dtr -a broadcast_ip -m"
|
30
31
|
opts.separator ""
|
31
32
|
opts.separator "Options:"
|
32
33
|
|
33
|
-
opts.on_tail("-m", "--monitor", "Monitor the status of the dtr
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
opts.on_tail("-c", "--clean_server", "Clean server environment, shutdown all runners registered.") do
|
38
|
-
DTR.clean_server
|
39
|
-
end
|
40
|
-
|
41
|
-
opts.on_tail("-b", "--be_silent", "Only show error messages") do
|
42
|
-
DTROPTIONS[:log_level] = Logger::ERROR
|
34
|
+
opts.on_tail("-m", "--monitor", "Monitor the status of the dtr agents.") do
|
35
|
+
DTR.monitor
|
43
36
|
end
|
44
37
|
|
45
|
-
opts.
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
opts.on("-p", "--port PORT", "Port number DTR will listen to. Default is 3344.") do |port|
|
50
|
-
DTR.port = port
|
38
|
+
opts.on("-p", "--port PORT", "Port number of DTR rinda server. Default is 3344.") do |port|
|
39
|
+
DTR.port = port
|
51
40
|
end
|
52
41
|
|
53
42
|
opts.on("-r runner1_name,runner2_name", Array, "Start DTR test runner agent with unique runner names.") do |names|
|
54
|
-
|
43
|
+
DTR_AGENT_OPTIONS[:runners] = names.collect{|name| name.untaint}
|
55
44
|
end
|
56
45
|
|
57
|
-
opts.on("-a", "--
|
46
|
+
opts.on("-a", "--broadcast_address ADDRESS", "Specify broadcast address for looking up dtr rinda server, e.g. 192.168.255.255. Default is 'localhost'.") do |address|
|
58
47
|
if (!address.nil?) && (!address.empty?)
|
59
48
|
DTR.broadcast_list = [address]
|
60
49
|
end
|
61
50
|
end
|
62
51
|
|
63
52
|
opts.on("-i", "--setup COMMAND", "Set command for initializing test runner test environment, e.g. 'rake db:test:prepare'. Default is do nothing.") do |command|
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
opts.on_tail("-D", "--daemon", "Start server/runners in daemon mode. Gem 'daemons' must be installed") do
|
68
|
-
DTROPTIONS[:daemon] = true
|
69
|
-
end
|
70
|
-
|
71
|
-
opts.on_tail("-S", "--stop_server", "Stop server run in daemon mode.") do
|
72
|
-
DTR.stop_server_daemon_mode
|
73
|
-
end
|
74
|
-
|
75
|
-
opts.on_tail("-R", "--stop_runners", "Stop runners run in daemon mode.") do
|
76
|
-
DTR.stop_runners_daemon_mode
|
53
|
+
DTR_AGENT_OPTIONS[:agent_env_setup_cmd] = command.untaint
|
77
54
|
end
|
78
|
-
|
55
|
+
|
79
56
|
opts.on_tail("-d", "--debug", "output debug log") do
|
80
|
-
|
57
|
+
DTR.logger.log_level = Logger::DEBUG
|
81
58
|
end
|
82
|
-
|
59
|
+
|
60
|
+
opts.on_tail("-b", "--be_silent", "Only show error messages") do
|
61
|
+
DTR.logger.log_level = Logger::ERROR
|
62
|
+
end
|
63
|
+
|
83
64
|
opts.on_tail("-v", "--version", "Show version") do
|
84
65
|
puts "dtr, version " + DTRVERSION
|
85
66
|
end
|
@@ -99,26 +80,6 @@ if no_argv
|
|
99
80
|
puts NOTES
|
100
81
|
end
|
101
82
|
|
102
|
-
if
|
103
|
-
|
104
|
-
DTR.start_runners_daemon_mode
|
105
|
-
else
|
106
|
-
DTR.start_runners
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
if DTROPTIONS[:start_server]
|
111
|
-
if DTROPTIONS[:daemon]
|
112
|
-
DTR.start_server_daemon_mode
|
113
|
-
else
|
114
|
-
DTR.start_server
|
115
|
-
end
|
83
|
+
if DTR_AGENT_OPTIONS[:runners] && !DTR_AGENT_OPTIONS[:runners].empty?
|
84
|
+
DTR.start_agent
|
116
85
|
end
|
117
|
-
|
118
|
-
if DTROPTIONS[:monitor]
|
119
|
-
if DTROPTIONS[:daemon]
|
120
|
-
puts "Can't start monitor with daemon mode."
|
121
|
-
else
|
122
|
-
DTR.monitor
|
123
|
-
end
|
124
|
-
end
|
data/dtr.gemspec
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = 'dtr'
|
3
|
-
spec.version = "0.0.
|
3
|
+
spec.version = "0.0.5"
|
4
4
|
spec.summary = "DTR is a distributed test runner to run tests on distributed computers for decreasing build time."
|
5
5
|
|
6
6
|
#### Dependencies and requirements.
|
7
7
|
|
8
|
-
spec.add_dependency('daemons', '> 1.0.7')
|
9
8
|
#s.requirements << ""
|
9
|
+
# p Dir.glob("lib/**/*.rb") + ["bin/dtr", "CHANGES", "dtr.gemspec", "install.rb", "lib", "LICENSE.TXT", "Rakefile", "README", "TODO"]
|
10
|
+
# puts '------------'
|
11
|
+
# p Dir.glob("test/**/*.rb") + Dir.glob("testdata/**/*")
|
12
|
+
|
13
|
+
spec.files = ["lib/dtr/agent/brain.rb", "lib/dtr/agent/herald.rb", "lib/dtr/agent/runner.rb", "lib/dtr/agent/sync_codebase.rb", "lib/dtr/agent/sync_logger.rb", "lib/dtr/agent/test_unit.rb", "lib/dtr/agent/worker.rb", "lib/dtr/agent/working_env_ext.rb", "lib/dtr/agent.rb", "lib/dtr/master.rb", "lib/dtr/monitor.rb", "lib/dtr/raketasks.rb", "lib/dtr/shared/adapter.rb", "lib/dtr/shared/configuration.rb", "lib/dtr/shared/message_decorator.rb", "lib/dtr/shared/ruby_ext.rb", "lib/dtr/shared/service/agent.rb", "lib/dtr/shared/service/file.rb", "lib/dtr/shared/service/rinda.rb", "lib/dtr/shared/service/runner.rb", "lib/dtr/shared/service/working_env.rb", "lib/dtr/shared/service.rb", "lib/dtr/shared/sync_codebase/codebase.rb", "lib/dtr/shared/sync_codebase/master_ext.rb", "lib/dtr/shared/sync_codebase/package.rb", "lib/dtr/shared/sync_codebase/sync_service.rb", "lib/dtr/shared/sync_codebase.rb", "lib/dtr/shared/sync_logger.rb", "lib/dtr/shared/utils/cmd.rb", "lib/dtr/shared/utils/env_store.rb", "lib/dtr/shared/utils/logger.rb", "lib/dtr/shared/utils.rb", "lib/dtr/shared/working_env.rb", "lib/dtr/shared.rb", "lib/dtr/test_unit/drb_test_runner.rb", "lib/dtr/test_unit/injection.rb", "lib/dtr/test_unit/test_case_injection.rb", "lib/dtr/test_unit/testrunnermediator_injection.rb", "lib/dtr/test_unit/thread_safe_test_result.rb", "lib/dtr/test_unit/worker_club.rb", "lib/dtr/test_unit.rb", "lib/dtr/test_unit_injection.rb", "lib/dtr.rb", "bin/dtr", "CHANGES", "dtr.gemspec", "install.rb", "lib", "LICENSE.TXT", "Rakefile", "README", "TODO"]
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
spec.files = ["lib/dtr/base.rb", "lib/dtr/raketasks.rb", "lib/dtr/runner.rb", "lib/dtr/service_provider.rb", "lib/dtr/test_unit.rb", "lib/dtr/test_unit_injection.rb", "lib/dtr.rb", "bin/dtr", "bin", "CHANGES", "doc", "dtr.gemspec", "install.rb", "lib", "LICENSE.TXT", "Rakefile", "README", "TODO"]
|
14
|
-
|
15
|
+
spec.test_files = ["test/acceptance/agent_working_env_test.rb", "test/acceptance/dtr_package_task_test.rb", "test/acceptance/general_test.rb", "test/acceptance/sync_codebase_test.rb", "test/acceptance/sync_logger_test.rb", "test/agent_helper.rb", "test/logger_stub.rb", "test/test_helper.rb", "test/unit/adapter_test.rb", "test/unit/test_unit_test.rb", "test/unit/working_env_test.rb", "testdata/a_failed_test_case.rb", "testdata/a_file_system_test_case.rb", "testdata/a_test_case.rb", "testdata/a_test_case2.rb", "testdata/an_error_test_case.rb", "testdata/another_project", "testdata/another_project/passed_test_case.rb", "testdata/another_project/Rakefile", "testdata/is_required_by_a_test.rb", "testdata/lib", "testdata/lib/lib_test_case.rb", "testdata/package_task_test_rakefile", "testdata/Rakefile", "testdata/scenario_test_case.rb", "testdata/setup_agent_env_test_case.rb", "testdata/should_not_sync_codebase_and_setup_working_dir_when_agent_is_in_same_dir_with_master_process", "testdata/should_not_sync_codebase_and_setup_working_dir_when_agent_is_in_same_dir_with_master_process/Rakefile", "testdata/should_not_sync_codebase_and_setup_working_dir_when_agent_is_in_same_dir_with_master_process/verify_dir_pwd_test_case.rb"]
|
15
16
|
#### Load-time details: library and application (you will need one or both).
|
16
17
|
|
17
18
|
spec.require_path = 'lib' # Use these for libraries.
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module DTR
|
16
|
+
module Agent
|
17
|
+
|
18
|
+
class Brain
|
19
|
+
include Adapter::Follower
|
20
|
+
|
21
|
+
def initialize(runner_names, agent_env_setup_cmd)
|
22
|
+
raise 'No runner? What can I do for you?' if runner_names.blank?
|
23
|
+
@runner_names = runner_names
|
24
|
+
@agent_env_setup_cmd = agent_env_setup_cmd
|
25
|
+
DTR.info ""
|
26
|
+
DTR.info "--------------------beautiful line--------------------------"
|
27
|
+
DTR.info "=> Agent environment setup cmd: #{@agent_env_setup_cmd}"
|
28
|
+
DTR.info "=> Runner names: #{@runner_names.join(', ')}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def hypnotize
|
32
|
+
loop do
|
33
|
+
if wakeup?
|
34
|
+
DTR.info {"Agent brain wakes up"}
|
35
|
+
work(wakeup_worker)
|
36
|
+
DTR.info {"Agent brain is going to sleep"}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
rescue Exception => e
|
40
|
+
DTR.info {"Agent brain is stopped by Exception => #{e.class.name}, message => #{e.message}"}
|
41
|
+
DTR.debug {e.backtrace.join("\n")}
|
42
|
+
end
|
43
|
+
|
44
|
+
def work(worker)
|
45
|
+
until sleep?
|
46
|
+
#keep worker working :D
|
47
|
+
end
|
48
|
+
ensure
|
49
|
+
DTR.info {"Killing worker"}
|
50
|
+
Process.kill 'TERM', worker
|
51
|
+
end
|
52
|
+
|
53
|
+
def wakeup_worker
|
54
|
+
Process.fork do
|
55
|
+
begin
|
56
|
+
Worker.new(@runner_names, @agent_env_setup_cmd).launch
|
57
|
+
rescue Interrupt, SystemExit, SignalException
|
58
|
+
rescue Exception => e
|
59
|
+
DTR.error {"Worker is stopped by Exception => #{e.class.name}, message => #{e.message}"}
|
60
|
+
DTR.debug {e.backtrace.join("\n")}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|