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.
Files changed (78) hide show
  1. data/README +6 -115
  2. data/Rakefile +22 -154
  3. data/TODO +16 -1
  4. data/bin/dtr +22 -61
  5. data/dtr.gemspec +7 -6
  6. data/lib/dtr/agent/brain.rb +66 -0
  7. data/lib/dtr/agent/herald.rb +50 -0
  8. data/lib/dtr/agent/runner.rb +100 -0
  9. data/lib/dtr/agent/sync_codebase.rb +44 -0
  10. data/lib/dtr/agent/sync_logger.rb +40 -0
  11. data/lib/dtr/agent/test_unit.rb +42 -0
  12. data/lib/dtr/agent/worker.rb +92 -0
  13. data/lib/dtr/agent/working_env_ext.rb +45 -0
  14. data/lib/dtr/agent.rb +37 -0
  15. data/lib/dtr/master.rb +40 -0
  16. data/lib/dtr/monitor.rb +37 -0
  17. data/lib/dtr/raketasks.rb +74 -13
  18. data/lib/dtr/shared/adapter.rb +112 -0
  19. data/lib/dtr/shared/configuration.rb +76 -0
  20. data/lib/dtr/shared/message_decorator.rb +28 -0
  21. data/lib/dtr/shared/ruby_ext.rb +153 -0
  22. data/lib/dtr/shared/service/agent.rb +33 -0
  23. data/lib/dtr/shared/service/file.rb +28 -0
  24. data/lib/dtr/shared/service/rinda.rb +40 -0
  25. data/lib/dtr/shared/service/runner.rb +33 -0
  26. data/lib/dtr/shared/service/working_env.rb +28 -0
  27. data/lib/dtr/shared/service.rb +19 -0
  28. data/lib/dtr/shared/sync_codebase/codebase.rb +32 -0
  29. data/lib/dtr/shared/sync_codebase/master_ext.rb +52 -0
  30. data/lib/dtr/shared/sync_codebase/package.rb +39 -0
  31. data/lib/dtr/shared/sync_codebase/sync_service.rb +41 -0
  32. data/lib/dtr/shared/sync_codebase.rb +18 -0
  33. data/lib/dtr/shared/sync_logger.rb +72 -0
  34. data/lib/dtr/shared/utils/cmd.rb +30 -0
  35. data/lib/dtr/shared/utils/env_store.rb +60 -0
  36. data/lib/dtr/shared/utils/logger.rb +71 -0
  37. data/lib/dtr/shared/utils.rb +17 -0
  38. data/lib/dtr/shared/working_env.rb +38 -0
  39. data/lib/dtr/shared.rb +24 -0
  40. data/lib/dtr/test_unit/drb_test_runner.rb +57 -0
  41. data/lib/dtr/test_unit/injection.rb +30 -0
  42. data/lib/dtr/test_unit/test_case_injection.rb +37 -0
  43. data/lib/dtr/test_unit/testrunnermediator_injection.rb +72 -0
  44. data/lib/dtr/test_unit/thread_safe_test_result.rb +40 -0
  45. data/lib/dtr/test_unit/worker_club.rb +72 -0
  46. data/lib/dtr/test_unit.rb +8 -275
  47. data/lib/dtr/test_unit_injection.rb +0 -1
  48. data/lib/dtr.rb +23 -81
  49. data/test/acceptance/agent_working_env_test.rb +92 -0
  50. data/test/acceptance/dtr_package_task_test.rb +26 -0
  51. data/test/acceptance/general_test.rb +275 -0
  52. data/test/acceptance/sync_codebase_test.rb +67 -0
  53. data/test/acceptance/sync_logger_test.rb +41 -0
  54. data/test/agent_helper.rb +39 -0
  55. data/test/logger_stub.rb +30 -0
  56. data/test/test_helper.rb +43 -0
  57. data/test/unit/adapter_test.rb +107 -0
  58. data/test/unit/test_unit_test.rb +47 -0
  59. data/test/unit/working_env_test.rb +71 -0
  60. data/testdata/Rakefile +15 -0
  61. data/testdata/a_failed_test_case.rb +8 -0
  62. data/testdata/a_file_system_test_case.rb +8 -0
  63. data/testdata/a_test_case.rb +13 -0
  64. data/testdata/a_test_case2.rb +6 -0
  65. data/testdata/an_error_test_case.rb +9 -0
  66. data/testdata/another_project/Rakefile +6 -0
  67. data/testdata/another_project/passed_test_case.rb +7 -0
  68. data/testdata/is_required_by_a_test.rb +9 -0
  69. data/testdata/lib/lib_test_case.rb +7 -0
  70. data/testdata/package_task_test_rakefile +8 -0
  71. data/testdata/scenario_test_case.rb +34 -0
  72. data/testdata/setup_agent_env_test_case.rb +9 -0
  73. data/testdata/should_not_sync_codebase_and_setup_working_dir_when_agent_is_in_same_dir_with_master_process/Rakefile +6 -0
  74. 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
  75. metadata +72 -18
  76. data/lib/dtr/base.rb +0 -172
  77. data/lib/dtr/runner.rb +0 -270
  78. data/lib/dtr/service_provider.rb +0 -160
data/lib/dtr/test_unit.rb CHANGED
@@ -12,278 +12,11 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'dtr/base'
16
- require 'dtr/service_provider'
17
- require 'test/unit/testcase'
18
- require 'test/unit/util/observable'
19
- require 'monitor'
20
- require 'drb'
21
- require 'timeout'
22
-
23
- DTROPTIONS = {} unless defined?(DTROPTIONS)
24
- DTROPTIONS[:log_file] = 'dtr_master_process.log' unless DTROPTIONS[:log_file]
25
-
26
- module DTR
27
- def reject
28
- return unless Test::Unit::TestSuite.method_defined?(:dtr_injected?)
29
- Test::Unit::TestCase.send(:include, Rejection)
30
- Test::Unit::TestSuite.send(:include, Rejection)
31
- end
32
-
33
- def inject
34
- return if Test::Unit::TestSuite.method_defined?(:dtr_injected?)
35
- Test::Unit::TestCase.send(:include, TestCaseInjection)
36
- Test::Unit::TestSuite.send(:include, TestSuiteInjection)
37
- end
38
-
39
- def service_provider
40
- $dtr_service_provider ||= DTR::ServiceProvider.new
41
- end
42
-
43
- module_function :reject, :inject, :service_provider
44
-
45
- class Counter
46
-
47
- def initialize
48
- extend MonitorMixin
49
- @start_count, @finish_count = 0, 0
50
- @complete_cond = new_cond
51
- end
52
-
53
- def add_start_count
54
- synchronize do
55
- @start_count += 1
56
- end
57
- end
58
-
59
- def add_finish_count
60
- synchronize do
61
- @finish_count += 1
62
- @complete_cond.signal
63
- end
64
- end
65
-
66
- def to_s
67
- synchronize do
68
- status
69
- end
70
- end
71
-
72
- def wait_until_complete
73
- synchronize do
74
- @complete_cond.wait_until {complete?}
75
- end
76
- end
77
-
78
- private
79
- def complete?
80
- DTR.info{ "Counter status: #{status}" }
81
- @finish_count >= @start_count
82
- end
83
-
84
- def status
85
- "finish_count => #{@finish_count}, start_count => #{@start_count}"
86
- end
87
- end
88
-
89
- class ThreadSafeTestResult
90
- include Test::Unit::Util::Observable
91
- include DRbUndumped
92
-
93
- def initialize(rs)
94
- extend MonitorMixin
95
- @rs = rs
96
- @channels = @rs.send(:channels).dup
97
- @rs.send(:channels).clear
98
- end
99
-
100
- def add_run
101
- synchronize do
102
- @rs.add_run
103
- end
104
- notify_listeners(Test::Unit::TestResult::CHANGED, self)
105
- end
106
-
107
- def add_failure(failure)
108
- synchronize do
109
- @rs.add_failure(failure)
110
- end
111
- notify_listeners(Test::Unit::TestResult::FAULT, failure)
112
- notify_listeners(Test::Unit::TestResult::CHANGED, self)
113
- end
114
-
115
- def add_error(error)
116
- synchronize do
117
- @rs.add_error(error)
118
- end
119
- notify_listeners(Test::Unit::TestResult::FAULT, error)
120
- notify_listeners(Test::Unit::TestResult::CHANGED, self)
121
- end
122
-
123
- def add_assertion
124
- synchronize do
125
- @rs.add_assertion
126
- end
127
- notify_listeners(Test::Unit::TestResult::CHANGED, self)
128
- end
129
-
130
- def to_s
131
- synchronize do
132
- @rs.to_s
133
- end
134
- end
135
-
136
- def passed?
137
- synchronize do
138
- @rs.passed?
139
- end
140
- end
141
-
142
- def failure_count
143
- synchronize do
144
- @rs.failure_count
145
- end
146
- end
147
-
148
- def error_count
149
- synchronize do
150
- @rs.error_count
151
- end
152
- end
153
- end
154
-
155
- class DRbTestRunner
156
-
157
- # because some test case will rewrite TestCase#run to ignore some tests, which
158
- # makes TestResult#run_count different with TestSuite#size, so we need to count
159
- # by ourselves.(for example: ActionController::IntegrationTest)
160
- class << self
161
- def counter
162
- @counter ||= Counter.new
163
- end
164
- end
165
-
166
- RUN_TEST_FINISHED = "::DRbTestRunner::RUN_TEST_FINISHED"
167
- DEFAULT_RUN_TEST_TIMEOUT = 60 #seconds
168
-
169
- def initialize(test, result, &progress_block)
170
- @test = test
171
- @result = result
172
- @progress_block = progress_block
173
-
174
- DRbTestRunner.counter.add_start_count
175
- end
176
-
177
- def run
178
- if runner = lookup_runner
179
- run_test_on(runner)
180
- else
181
- self.run
182
- end
183
- end
184
-
185
- def run_test_on(runner)
186
- Thread.start do
187
- begin
188
- Timeout.timeout(ENV['RUN_TEST_TIMEOUT'] || DEFAULT_RUN_TEST_TIMEOUT) do
189
- runner.run(@test, @result, &@progress_block)
190
- end
191
- @progress_block.call(RUN_TEST_FINISHED, @test.name)
192
- rescue Timeout::Error => e
193
- DTR.info {"Run test timeout(#{ENV['RUN_TEST_TIMEOUT'] || DEFAULT_RUN_TEST_TIMEOUT}), reboot runner"}
194
- runner.reboot rescue nil
195
- DTR.info {"rerun test: #{@test.name}"}
196
- self.run
197
- rescue DRb::DRbConnError => e
198
- DTR.info {"DRb::DRbConnError(#{e.message}), rerun test: #{@test.name}"}
199
- self.run
200
- rescue Exception => e
201
- DTR.info{ "#{test.name}, rescue an exception: #{e.message}, add error into result." }
202
- @result.add_error(Test::Unit::Error.new(@test.name, e))
203
- @result.add_run
204
- @progress_block.call(Test::Unit::TestCase::FINISHED, @test.name)
205
- @progress_block.call(RUN_TEST_FINISHED, @test.name)
206
- end
207
- end
208
- end
209
-
210
- def lookup_runner
211
- runner = DTR.service_provider.lookup_runner
212
- begin
213
- DTR.debug {"#{runner.name}.env ==?: #{WorkingEnv.current[:identifier] == runner.identifier}"}
214
- return runner if runner.identifier == WorkingEnv.current[:identifier]
215
- runner.shutdown
216
- rescue DRb::DRbConnError => e
217
- DTR.debug {"DRb::DRbConnError(#{e.message})"}
218
- end
219
- nil
220
- end
221
- end
222
-
223
- module TestCaseInjection
224
-
225
- def self.included(base)
226
- base.class_eval do
227
- alias_method :__run__, :run
228
-
229
- def run(result, &progress_block)
230
- DTR.debug {"start of run TestCase(#{name})"}
231
- DRbTestRunner.new(self, result, &progress_block).run
232
- DTR.debug {"end of run TestCase(#{name})"}
233
- end
234
- end
235
- end
236
- end
237
-
238
- module TestSuiteInjection
239
- def self.included(base)
240
- base.class_eval do
241
- def dtr_injected?
242
- true
243
- end
244
-
245
- alias_method :__run__, :run
246
-
247
- def run(result, &progress_block)
248
- DTR.info { "start of run suite(#{name}), size: #{size};"}
249
-
250
- if result.kind_of?(ThreadSafeTestResult)
251
- __run__(result, &progress_block)
252
- else
253
- if defined?(ActiveRecord::Base)
254
- ActiveRecord::Base.clear_active_connections! rescue nil
255
- end
256
-
257
- DTR.service_provider.setup_working_env WorkingEnv.refresh
258
-
259
- puts 'Refreshed dtr working environment, looking for runner service...' unless ENV['DTR_ENV'] == 'test'
260
- DTR.info {"Master process started at #{Time.now}"}
261
- result = ThreadSafeTestResult.new(result)
262
- __run__(result) do |channel, value|
263
- DTR.debug { "=> channel: #{channel}, value: #{value}" }
264
- progress_block.call(channel, value)
265
- if channel == DTR::DRbTestRunner::RUN_TEST_FINISHED
266
- DRbTestRunner.counter.add_finish_count
267
- end
268
- end
269
- DRbTestRunner.counter.wait_until_complete
270
- DTR.debug { "==> teardown" }
271
- DTR.service_provider.teardown_working_env
272
- end
273
- DTR.info { "end of run suite(#{name}), test result status: #{result}, counter status: #{DRbTestRunner.counter}"}
274
- end
275
- end
276
- end
277
- end
278
-
279
- module Rejection
280
- def self.included(base)
281
- base.class_eval do
282
- remove_method :dtr_injected? if base.method_defined?(:dtr_injected?)
283
- remove_method :run
284
- alias_method :run, :__run__
285
- remove_method :__run__
286
- end
287
- end
288
- end
289
- end
15
+ require 'dtr/master'
16
+
17
+ require 'dtr/test_unit/worker_club'
18
+ require 'dtr/test_unit/thread_safe_test_result'
19
+ require 'dtr/test_unit/drb_test_runner'
20
+ require 'dtr/test_unit/test_case_injection'
21
+ require 'dtr/test_unit/testrunnermediator_injection'
22
+ require 'dtr/test_unit/injection'
@@ -12,7 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'dtr/service_provider'
16
15
  require 'dtr/test_unit'
17
16
  $argv_dup = ARGV.dup.delete_if{|f| f.include?('dtr/test_unit_injection')}
18
17
 
data/lib/dtr.rb CHANGED
@@ -12,100 +12,42 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- DTRVERSION="0.0.4"
16
- DTROPTIONS = {} unless defined?(DTROPTIONS)
17
-
18
- require 'fileutils'
15
+ DTRVERSION="0.0.5"
16
+ DTR_AGENT_OPTIONS = {:runners => [], :agent_env_setup_cmd => nil}
19
17
 
20
18
  module DTR
21
19
 
22
- def start_server
23
- require 'dtr/service_provider'
24
- ServiceProvider.new.start
25
- end
26
-
27
- def start_runners
28
- launch_runners(DTROPTIONS[:names], DTROPTIONS[:setup])
20
+ def start_agent
21
+ launch_agent(DTR_AGENT_OPTIONS[:runners], DTR_AGENT_OPTIONS[:agent_env_setup_cmd])
29
22
  end
30
-
31
- def launch_runners(names, setup=nil)
32
- require 'dtr/runner'
23
+
24
+ def launch_agent(names, setup=nil)
25
+ require 'dtr/agent'
33
26
  names = names || "DTR(#{Time.now})"
34
- DTR::RunnerAgent.start(names, setup)
27
+ DTR::Agent.start(names, setup)
35
28
  end
36
-
29
+
37
30
  def lib_path
38
31
  File.expand_path(File.dirname(__FILE__))
39
32
  end
40
-
33
+
41
34
  def broadcast_list=(list)
42
- require 'dtr/service_provider'
43
- ServiceProvider.broadcast_list = list
35
+ require 'dtr/shared'
36
+ DTR.configuration.broadcast_list = list
37
+ DTR.configuration.save
44
38
  end
45
-
39
+
46
40
  def port=(port)
47
- require 'dtr/service_provider'
48
- ServiceProvider.port = port
41
+ require 'dtr/shared'
42
+ DTR.configuration.rinda_server_port = port
43
+ DTR.configuration.save
49
44
  end
50
-
51
- def runners
52
- require 'dtr/service_provider'
53
- ServiceProvider.new.runners
54
- end
55
-
45
+
56
46
  def monitor
57
- require 'dtr/service_provider'
58
- DTROPTIONS[:log_file] = 'dtr_monitor.log'
59
- ServiceProvider.new.monitor
47
+ require 'dtr/monitor'
48
+ DTR.logger('dtr_monitor.log')
49
+ Monitor.new.start
60
50
  end
61
-
62
- def stop_runners_daemon_mode
63
- with_daemon_gem do
64
- Daemons.run_proc "dtr_runners", :ARGV => ['stop']
65
- end
66
- end
67
-
68
- def start_runners_daemon_mode
69
- with_daemon_gem do
70
- FileUtils.rm_rf('dtr_runners.output')
71
- pwd = Dir.pwd
72
- Daemons.run_proc "dtr_runners", :ARGV => ['start'], :backtrace => true do
73
- Dir.chdir(pwd) do
74
- start_runners
75
- end
76
- end
77
- end
78
- end
79
-
80
- def start_server_daemon_mode
81
- with_daemon_gem do
82
- Daemons.run_proc "dtr_server", :ARGV => ['start'] do
83
- start_server
84
- end
85
- end
86
- sleep(2)
87
- end
88
-
89
- def stop_server_daemon_mode
90
- with_daemon_gem do
91
- Daemons.run_proc "dtr_server", :ARGV => ['stop']
92
- end
93
- end
94
-
95
- def with_daemon_gem
96
- require "rubygems"
97
- begin
98
- require "daemons"
99
- rescue LoadError
100
- raise "The daemons gem must be installed"
101
- end
102
- yield
103
- end
104
-
105
- def clean_server
106
- require 'dtr/service_provider'
107
- ServiceProvider.new.clear_workspace
108
- end
109
-
110
- module_function :start_server, :start_runners, :launch_runners, :lib_path, :broadcast_list=, :runners, :with_daemon_gem, :start_runners_daemon_mode, :stop_runners_daemon_mode, :start_server_daemon_mode, :stop_server_daemon_mode, :monitor, :port=, :clean_server
51
+
52
+ module_function :start_agent, :launch_agent, :lib_path, :broadcast_list=, :monitor, :port=
111
53
  end
@@ -0,0 +1,92 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ include DTR::AgentHelper
4
+
5
+ class AgentWorkingEnvTest < Test::Unit::TestCase
6
+ include DTR::Service::WorkingEnv
7
+ def setup
8
+ #start_agents first for test files loaded would be copied into sub processes
9
+ start_agents
10
+ DTR.inject
11
+ end
12
+
13
+ def teardown
14
+ DTR.reject
15
+ stop_agents
16
+ $argv_dup = nil
17
+ end
18
+
19
+ def test_run_2_project_should_be_independence
20
+ Dir.chdir(File.expand_path(File.dirname(__FILE__) + "/../../testdata/")) do
21
+ $argv_dup = ['an_error_test_case.rb']
22
+ require 'an_error_test_case'
23
+
24
+ suite = Test::Unit::TestSuite.new('test_run_2_project_should_be_independence 1')
25
+ suite << AnErrorTestCase.suite
26
+
27
+ assert_fork_process_exits_ok do
28
+ @result = runit(suite)
29
+
30
+ assert_false @result.passed?
31
+ assert_equal 1, @result.run_count
32
+ assert_equal 0, @result.failure_count
33
+ assert_equal 1, @result.error_count
34
+ end
35
+ end
36
+
37
+ Dir.chdir(File.expand_path(File.dirname(__FILE__) + "/../../testdata/another_project")) do
38
+ $argv_dup = ['passed_test_case.rb']
39
+ require 'passed_test_case'
40
+ suite = Test::Unit::TestSuite.new('test_run_2_project_should_be_independence 2')
41
+ suite << PassedTestCase.suite
42
+
43
+ assert_fork_process_exits_ok do
44
+ @result = runit(suite)
45
+
46
+ assert @result.passed?
47
+ assert_equal 1, @result.run_count
48
+ assert_equal 0, @result.failure_count
49
+ assert_equal 0, @result.error_count
50
+ end
51
+ end
52
+ end
53
+
54
+ def test_run_same_project_twice_should_be_independence
55
+ Dir.chdir(File.expand_path(File.dirname(__FILE__) + "/../../testdata/another_project")) do
56
+ $argv_dup = ['passed_test_case.rb']
57
+ require 'passed_test_case'
58
+ suite = Test::Unit::TestSuite.new('test_run_same_project_twice_should_be_independence 1')
59
+ suite << PassedTestCase.suite
60
+
61
+ assert_fork_process_exits_ok do
62
+ @result = runit(suite)
63
+
64
+ assert @result.passed?
65
+ assert_equal 1, @result.run_count
66
+ assert_equal 0, @result.failure_count
67
+ assert_equal 0, @result.error_count
68
+ end
69
+ end
70
+
71
+ Dir.chdir(File.expand_path(File.dirname(__FILE__) + "/../../testdata/another_project")) do
72
+ FileUtils.cp("./../an_error_test_case.rb", '.')
73
+ begin
74
+ $argv_dup = ['an_error_test_case.rb']
75
+ require 'an_error_test_case'
76
+ suite = Test::Unit::TestSuite.new('test_run_same_project_twice_should_be_independence 2')
77
+ suite << AnErrorTestCase.suite
78
+
79
+ assert_fork_process_exits_ok do
80
+ @result = runit(suite)
81
+
82
+ assert_false @result.passed?
83
+ assert_equal 1, @result.run_count
84
+ assert_equal 0, @result.failure_count
85
+ assert_equal 1, @result.error_count
86
+ end
87
+ ensure
88
+ FileUtils.rm_f('an_error_test_case.rb')
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'fileutils'
3
+
4
+ class DTRPackageTaskTest < Test::Unit::TestCase
5
+ def test_package
6
+ testdata_dir = File.expand_path(File.dirname(__FILE__) + '/../../testdata')
7
+ Dir.chdir(testdata_dir) do
8
+ %x[rake --rakefile package_task_test_rakefile dtr_package]
9
+ assert File.exists?(testdata_dir + "/dtr_pkg/codebase-dump/a_test_case2.rb")
10
+ assert File.exists?(testdata_dir + "/dtr_pkg/codebase-dump/lib/lib_test_case.rb")
11
+ assert File.exists?(testdata_dir + "/dtr_pkg/codebase-dump/is_required_by_a_test.rb")
12
+
13
+ assert File.exists?(testdata_dir + "/dtr_pkg/codebase-dump.tar.bz2")
14
+
15
+ %x[rake --rakefile package_task_test_rakefile dtr_clobber_package]
16
+
17
+ assert !File.exists?(testdata_dir + "/dtr_pkg/codebase-dump/a_test_case2.rb")
18
+ assert !File.exists?(testdata_dir + "/dtr_pkg/codebase-dump/lib/lib_test_case.rb")
19
+ assert !File.exists?(testdata_dir + "/dtr_pkg/codebase-dump/is_required_by_a_test.rb")
20
+
21
+ assert !File.exists?(testdata_dir + "/dtr_pkg/codebase-dump.tar.bz2")
22
+ end
23
+ ensure
24
+ FileUtils.rm_rf(testdata_dir + "/dtr_pkg") rescue nil
25
+ end
26
+ end