xli-dtr 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|