dtr 0.0.4 → 1.0.0
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/CHANGES +7 -0
- data/LICENSE.txt +203 -0
- data/README.rdoc +208 -0
- data/Rakefile +64 -205
- data/TODO +8 -2
- data/bin/dtr +27 -60
- data/dtr.gemspec +8 -11
- data/lib/dtr.rb +5 -94
- data/lib/dtr/agent.rb +38 -0
- data/lib/dtr/agent/brain.rb +57 -0
- data/lib/dtr/agent/herald.rb +60 -0
- data/lib/dtr/agent/runner.rb +87 -0
- data/lib/dtr/agent/sync_codebase.rb +44 -0
- data/lib/dtr/agent/sync_logger.rb +70 -0
- data/lib/dtr/agent/test_case.rb +53 -0
- data/lib/dtr/agent/test_unit.rb +40 -0
- data/lib/dtr/agent/worker.rb +89 -0
- data/lib/dtr/agent/working_env_ext.rb +47 -0
- data/lib/dtr/facade.rb +65 -0
- data/lib/dtr/master.rb +40 -0
- data/lib/dtr/monitor.rb +95 -0
- data/lib/dtr/raketasks.rb +155 -22
- data/lib/dtr/shared.rb +24 -0
- data/lib/dtr/shared/adapter.rb +115 -0
- data/lib/dtr/shared/configuration.rb +104 -0
- data/lib/dtr/shared/message_decorator.rb +28 -0
- data/lib/dtr/shared/ruby_ext.rb +129 -0
- data/lib/dtr/shared/service.rb +19 -0
- data/lib/dtr/shared/service/agent.rb +37 -0
- data/lib/dtr/shared/service/file.rb +28 -0
- data/lib/dtr/shared/service/rinda.rb +48 -0
- data/lib/dtr/shared/service/runner.rb +34 -0
- data/lib/dtr/shared/service/working_env.rb +28 -0
- data/lib/dtr/shared/sync_codebase.rb +18 -0
- data/lib/dtr/shared/sync_codebase/copiable_package.rb +40 -0
- data/lib/dtr/shared/sync_codebase/master_ext.rb +40 -0
- data/lib/dtr/shared/sync_codebase/package.rb +53 -0
- data/lib/dtr/shared/sync_codebase/sync_service.rb +36 -0
- data/lib/dtr/shared/sync_logger.rb +64 -0
- data/lib/dtr/shared/utils.rb +17 -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 +87 -0
- data/lib/dtr/shared/working_env.rb +38 -0
- data/lib/dtr/test_unit.rb +9 -275
- data/lib/dtr/test_unit/drb_test_runner.rb +48 -0
- data/lib/dtr/test_unit/injection.rb +29 -0
- data/lib/dtr/test_unit/test_case_injection.rb +37 -0
- data/lib/dtr/test_unit/test_suite_injection.rb +24 -0
- data/lib/dtr/test_unit/testrunnermediator_injection.rb +72 -0
- data/lib/dtr/test_unit/thread_safe_test_result.rb +38 -0
- data/lib/dtr/test_unit/worker_club.rb +72 -0
- data/lib/dtr/test_unit_injection.rb +1 -2
- data/test/acceptance/agent_working_env_test.rb +86 -0
- data/test/acceptance/dtr_package_task_test.rb +36 -0
- data/test/acceptance/general_test.rb +331 -0
- data/test/acceptance/raketasks_test.rb +23 -0
- data/test/acceptance/sync_codebase_test.rb +66 -0
- data/test/acceptance/sync_logger_test.rb +32 -0
- data/test/agent_helper.rb +37 -0
- data/test/logger_stub.rb +34 -0
- data/test/test_helper.rb +71 -0
- data/test/unit/adapter_test.rb +149 -0
- data/test/unit/configuration_test.rb +44 -0
- data/test/unit/facade_test.rb +41 -0
- data/test/unit/logger_test.rb +72 -0
- data/test/unit/test_unit_test.rb +26 -0
- data/test/unit/working_env_test.rb +71 -0
- data/testdata/Rakefile +11 -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/hacked_run_method_test_case.rb +15 -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/raketasks/Rakefile +7 -0
- data/testdata/raketasks/success_test_case.rb +6 -0
- data/testdata/scenario_test_case.rb +34 -0
- data/testdata/setup_agent_env_test_case.rb +9 -0
- data/testdata/sleep_3_secs_test_case.rb +9 -0
- data/testdata/verify_dir_pwd/Rakefile +6 -0
- data/testdata/verify_dir_pwd/verify_dir_pwd_test_case.rb +10 -0
- metadata +101 -34
- data/README +0 -291
- data/install.rb +0 -88
- 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,72 @@
|
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
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
|
+
require 'test/unit/testcase'
|
16
|
+
require 'test/unit/testsuite'
|
17
|
+
|
18
|
+
module DTR
|
19
|
+
module TestUnit
|
20
|
+
module TestRunnerMediatorInjection
|
21
|
+
class SuiteWrapper
|
22
|
+
def initialize(suite)
|
23
|
+
@suite = suite
|
24
|
+
end
|
25
|
+
|
26
|
+
def run(result, &block)
|
27
|
+
@suite.run(result, &block)
|
28
|
+
WorkerClub.instance.graceful_shutdown
|
29
|
+
end
|
30
|
+
|
31
|
+
def size
|
32
|
+
@suite.size
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.included(base)
|
37
|
+
base.send(:include, Master)
|
38
|
+
base.alias_method_chain :create_result, :thread_safe
|
39
|
+
base.alias_method_chain :run_suite, :dtr_injection
|
40
|
+
#have to use class_eval for adding it back after removed reject_dtr method
|
41
|
+
base.class_eval do
|
42
|
+
def self.reject_dtr
|
43
|
+
remove_method :run_suite
|
44
|
+
alias_method :run_suite, :run_suite_without_dtr_injection
|
45
|
+
remove_method :run_suite_without_dtr_injection
|
46
|
+
|
47
|
+
remove_method :create_result
|
48
|
+
alias_method :create_result, :create_result_without_thread_safe
|
49
|
+
remove_method :create_result_without_thread_safe
|
50
|
+
|
51
|
+
(class << self; self; end;).send :remove_method, :reject_dtr
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_result_with_thread_safe
|
57
|
+
ThreadSafeTestResult.new(create_result_without_thread_safe)
|
58
|
+
end
|
59
|
+
|
60
|
+
def run_suite_with_dtr_injection
|
61
|
+
DTR.logger('dtr_master_process.log')
|
62
|
+
# inject testcase&testsuite as late as possible, for it's too easy to be hacked in ruby world
|
63
|
+
Test::Unit::TestCase.send(:include, TestUnit::TestCaseInjection)
|
64
|
+
Test::Unit::TestSuite.send(:include, TestUnit::TestSuiteInjection)
|
65
|
+
@suite = SuiteWrapper.new(@suite.proxy)
|
66
|
+
with_dtr_master do
|
67
|
+
run_suite_without_dtr_injection
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
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 TestUnit
|
17
|
+
class ThreadSafeTestResult
|
18
|
+
include DRbUndumped
|
19
|
+
|
20
|
+
def initialize(rs)
|
21
|
+
@mutex = Mutex.new
|
22
|
+
@rs = rs
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
@mutex.synchronize do
|
27
|
+
@rs.to_s
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(method, *args, &block)
|
32
|
+
@mutex.synchronize do
|
33
|
+
@rs.send(method, *args, &block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
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
|
+
require 'singleton'
|
16
|
+
|
17
|
+
module DTR
|
18
|
+
module TestUnit
|
19
|
+
class WorkerClub
|
20
|
+
include Singleton
|
21
|
+
|
22
|
+
DEFAULT_RUN_TEST_TIMEOUT = 60 #seconds
|
23
|
+
|
24
|
+
def start_thread(drb_runner, remote_runner)
|
25
|
+
thread = Thread.new(drb_runner, remote_runner) do |local, remote|
|
26
|
+
local.run_test_on(remote)
|
27
|
+
end
|
28
|
+
thread[:started_on] = Time.now
|
29
|
+
workers.add(thread)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Performs a wait on all the currently running threads and kills any that take
|
33
|
+
# too long. It waits by ENV['RUN_TEST_TIMEOUT'] || 60 seconds
|
34
|
+
def graceful_shutdown
|
35
|
+
while reap_dead_workers("shutdown") > 0
|
36
|
+
DTR.info {"Waiting for #{workers.list.length} threads to finish, could take #{timeout} seconds."}
|
37
|
+
sleep timeout / 60
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def timeout
|
43
|
+
(ENV['RUN_TEST_TIMEOUT'] || DEFAULT_RUN_TEST_TIMEOUT).to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
def workers
|
47
|
+
@workers ||= ThreadGroup.new
|
48
|
+
end
|
49
|
+
|
50
|
+
# Used internally to kill off any worker threads that have taken too long
|
51
|
+
# to complete processing. It returns the count of workers still active
|
52
|
+
# after the reap is done. It only runs if there are workers to reap.
|
53
|
+
def reap_dead_workers(reason='unknown')
|
54
|
+
if workers.list.length > 0
|
55
|
+
DTR.info {"Reaping #{workers.list.length} threads because of '#{reason}'"}
|
56
|
+
error_msg = "#{Time.now}: WorkerClub timed out this thread: #{reason}"
|
57
|
+
mark = Time.now
|
58
|
+
workers.list.each do |worker|
|
59
|
+
worker[:started_on] = Time.now if not worker[:started_on]
|
60
|
+
|
61
|
+
if mark - worker[:started_on] > timeout
|
62
|
+
DTR.info {"Thread #{worker.inspect} is too old, killing."}
|
63
|
+
worker.raise(TimeoutError.new(error_msg))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
return workers.list.length
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-2008 Li Xiao
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -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
|
|
@@ -0,0 +1,86 @@
|
|
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
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
stop_agents
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_run_2_project_should_be_independence
|
17
|
+
assert_fork_process_exits_ok do
|
18
|
+
$argv_dup = ['an_error_test_case.rb']
|
19
|
+
|
20
|
+
suite = Test::Unit::TestSuite.new('test_run_2_project_should_be_independence 1')
|
21
|
+
suite << AnErrorTestCase.suite
|
22
|
+
|
23
|
+
@result = runit(suite)
|
24
|
+
|
25
|
+
assert_false @result.passed?
|
26
|
+
assert_equal 1, @result.run_count
|
27
|
+
assert_equal 0, @result.failure_count
|
28
|
+
assert_equal 1, @result.error_count
|
29
|
+
end
|
30
|
+
|
31
|
+
assert_fork_process_exits_ok do
|
32
|
+
Dir.chdir("another_project") do
|
33
|
+
$argv_dup = ['passed_test_case.rb']
|
34
|
+
require 'passed_test_case'
|
35
|
+
suite = Test::Unit::TestSuite.new('test_run_2_project_should_be_independence 2')
|
36
|
+
suite << PassedTestCase.suite
|
37
|
+
|
38
|
+
@result = runit(suite)
|
39
|
+
|
40
|
+
assert @result.passed?
|
41
|
+
assert_equal 1, @result.run_count
|
42
|
+
assert_equal 0, @result.failure_count
|
43
|
+
assert_equal 0, @result.error_count
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_run_same_project_twice_should_be_independence
|
49
|
+
assert_fork_process_exits_ok do
|
50
|
+
Dir.chdir("another_project") do
|
51
|
+
$argv_dup = ['passed_test_case.rb']
|
52
|
+
require 'passed_test_case'
|
53
|
+
suite = Test::Unit::TestSuite.new('test_run_same_project_twice_should_be_independence 1')
|
54
|
+
suite << PassedTestCase.suite
|
55
|
+
|
56
|
+
@result = runit(suite)
|
57
|
+
|
58
|
+
assert @result.passed?
|
59
|
+
assert_equal 1, @result.run_count
|
60
|
+
assert_equal 0, @result.failure_count
|
61
|
+
assert_equal 0, @result.error_count
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
assert_fork_process_exits_ok do
|
66
|
+
Dir.chdir("another_project") do
|
67
|
+
FileUtils.cp("./../an_error_test_case.rb", '.')
|
68
|
+
begin
|
69
|
+
$argv_dup = ['an_error_test_case.rb']
|
70
|
+
require 'an_error_test_case'
|
71
|
+
suite = Test::Unit::TestSuite.new('test_run_same_project_twice_should_be_independence 2')
|
72
|
+
suite << AnErrorTestCase.suite
|
73
|
+
|
74
|
+
@result = runit(suite)
|
75
|
+
|
76
|
+
assert_false @result.passed?
|
77
|
+
assert_equal 1, @result.run_count
|
78
|
+
assert_equal 0, @result.failure_count
|
79
|
+
assert_equal 1, @result.error_count
|
80
|
+
ensure
|
81
|
+
FileUtils.rm_f('an_error_test_case.rb')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,36 @@
|
|
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.zip")
|
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.zip")
|
22
|
+
end
|
23
|
+
ensure
|
24
|
+
FileUtils.rm_rf(testdata_dir + "/dtr_pkg") rescue nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_should_not_include_dtr_pkg_dir
|
28
|
+
testdata_dir = File.expand_path(File.dirname(__FILE__) + '/../../testdata')
|
29
|
+
Dir.chdir(testdata_dir) do
|
30
|
+
%x[rake dtr_repackage]
|
31
|
+
assert !File.exists?(testdata_dir + "/dtr_pkg/codebase-dump/dtr_pkg")
|
32
|
+
end
|
33
|
+
ensure
|
34
|
+
FileUtils.rm_rf(testdata_dir + "/dtr_pkg") rescue nil
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,331 @@
|
|
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
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
stop_agents
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_run_test_passed
|
16
|
+
assert_fork_process_exits_ok do
|
17
|
+
$argv_dup = ['a_test_case.rb', 'a_test_case2.rb', 'a_file_system_test_case.rb']
|
18
|
+
suite = Test::Unit::TestSuite.new('run_test_passed')
|
19
|
+
suite << ATestCase.suite
|
20
|
+
suite << ATestCase2.suite
|
21
|
+
suite << AFileSystemTestCase.suite
|
22
|
+
@result = runit(suite)
|
23
|
+
|
24
|
+
assert @result.passed?
|
25
|
+
assert_equal 3, @result.run_count
|
26
|
+
assert_equal 0, @result.failure_count
|
27
|
+
assert_equal 0, @result.error_count
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_run_test_failed
|
32
|
+
assert_fork_process_exits_ok do
|
33
|
+
$argv_dup = ['a_test_case.rb', 'a_failed_test_case.rb']
|
34
|
+
suite = Test::Unit::TestSuite.new('test_run_test_failed')
|
35
|
+
suite << ATestCase.suite
|
36
|
+
suite << AFailedTestCase.suite
|
37
|
+
@result = runit(suite)
|
38
|
+
|
39
|
+
assert !@result.passed?
|
40
|
+
assert_equal 2, @result.run_count
|
41
|
+
assert_equal 1, @result.failure_count
|
42
|
+
assert_equal 0, @result.error_count
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_run_test_error
|
47
|
+
assert_fork_process_exits_ok do
|
48
|
+
$argv_dup = ['a_test_case.rb', 'an_error_test_case.rb']
|
49
|
+
suite = Test::Unit::TestSuite.new('test_run_test_error')
|
50
|
+
suite << ATestCase.suite
|
51
|
+
suite << AnErrorTestCase.suite
|
52
|
+
|
53
|
+
@result = runit(suite)
|
54
|
+
|
55
|
+
assert_false @result.passed?
|
56
|
+
assert_equal 2, @result.run_count
|
57
|
+
assert_equal 0, @result.failure_count
|
58
|
+
assert_equal 1, @result.error_count
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_run_suite_should_be_independence
|
63
|
+
assert_fork_process_exits_ok do
|
64
|
+
$argv_dup = ['an_error_test_case.rb']
|
65
|
+
suite = Test::Unit::TestSuite.new('test_run_suite_should_be_independence 1')
|
66
|
+
suite << AnErrorTestCase.suite
|
67
|
+
|
68
|
+
@result = runit(suite)
|
69
|
+
|
70
|
+
assert_false @result.passed?
|
71
|
+
assert_equal 1, @result.run_count
|
72
|
+
assert_equal 0, @result.failure_count
|
73
|
+
assert_equal 1, @result.error_count
|
74
|
+
end
|
75
|
+
|
76
|
+
assert_fork_process_exits_ok do
|
77
|
+
$argv_dup = ['a_test_case.rb']
|
78
|
+
suite = Test::Unit::TestSuite.new('test_run_suite_should_be_independence 2')
|
79
|
+
suite << ATestCase.suite
|
80
|
+
|
81
|
+
@result = runit(suite)
|
82
|
+
|
83
|
+
assert @result.passed?
|
84
|
+
assert_equal 1, @result.run_count
|
85
|
+
assert_equal 0, @result.failure_count
|
86
|
+
assert_equal 0, @result.error_count
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_should_ignore_environment_file_not_exists
|
91
|
+
assert_fork_process_exits_ok do
|
92
|
+
$argv_dup = ['a_test_case.rb', 'test_file_not_exists.rb']
|
93
|
+
suite = Test::Unit::TestSuite.new('test_run_test_file_not_exist')
|
94
|
+
suite << ATestCase.suite
|
95
|
+
|
96
|
+
@result = runit(suite)
|
97
|
+
|
98
|
+
assert @result.passed?
|
99
|
+
assert_equal 1, @result.run_count
|
100
|
+
assert_equal 0, @result.failure_count
|
101
|
+
assert_equal 0, @result.error_count
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_run_empty_test_suite_and_no_test_files_in_environment
|
106
|
+
assert_fork_process_exits_ok do
|
107
|
+
$argv_dup = []
|
108
|
+
suite = Test::Unit::TestSuite.new('test_run_without_test_files')
|
109
|
+
|
110
|
+
@result = runit(suite)
|
111
|
+
|
112
|
+
assert @result.passed?
|
113
|
+
assert_equal 0, @result.run_count
|
114
|
+
assert_equal 0, @result.failure_count
|
115
|
+
assert_equal 0, @result.error_count
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_run_empty_test_suite_should_not_crash_agent
|
120
|
+
assert_fork_process_exits_ok do
|
121
|
+
$argv_dup = []
|
122
|
+
suite = Test::Unit::TestSuite.new('test_run_empty_test_suite_should_not_crash_agent')
|
123
|
+
|
124
|
+
@result = runit(suite)
|
125
|
+
|
126
|
+
assert @result.passed?
|
127
|
+
assert_equal 0, @result.run_count
|
128
|
+
assert_equal 0, @result.failure_count
|
129
|
+
assert_equal 0, @result.error_count
|
130
|
+
end
|
131
|
+
|
132
|
+
assert_fork_process_exits_ok do
|
133
|
+
$argv_dup = ['a_test_case.rb']
|
134
|
+
suite = Test::Unit::TestSuite.new('test_run_empty_test_suite_should_not_crash_agent')
|
135
|
+
suite << ATestCase.suite
|
136
|
+
|
137
|
+
@result = runit(suite)
|
138
|
+
|
139
|
+
assert @result.passed?
|
140
|
+
assert_equal 1, @result.run_count
|
141
|
+
assert_equal 0, @result.failure_count
|
142
|
+
assert_equal 0, @result.error_count
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_run_empty_test_suite_and_test_files_not_exist_in_environment
|
147
|
+
assert_fork_process_exits_ok do
|
148
|
+
$argv_dup = ['test_file_not_exists.rb']
|
149
|
+
suite = Test::Unit::TestSuite.new('test_run_empty_test_suite_and_test_files_not_exist_in_environment')
|
150
|
+
|
151
|
+
@result = runit(suite)
|
152
|
+
|
153
|
+
assert @result.passed?
|
154
|
+
assert_equal 0, @result.run_count
|
155
|
+
assert_equal 0, @result.failure_count
|
156
|
+
assert_equal 0, @result.error_count
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_run_test_specified_by_load_path
|
161
|
+
assert_fork_process_exits_ok do
|
162
|
+
lib_path = File.expand_path(File.dirname(__FILE__) + '/../../testdata/lib')
|
163
|
+
$LOAD_PATH.unshift lib_path
|
164
|
+
require 'lib_test_case'
|
165
|
+
$argv_dup = ['lib_test_case.rb']
|
166
|
+
suite = Test::Unit::TestSuite.new('test_run_test_specified_by_load_path')
|
167
|
+
suite << LibTestCase.suite
|
168
|
+
|
169
|
+
@result = runit(suite)
|
170
|
+
|
171
|
+
assert @result.passed?
|
172
|
+
assert_equal 1, @result.run_count
|
173
|
+
assert_equal 0, @result.failure_count
|
174
|
+
assert_equal 0, @result.error_count
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_message_of_errors_and_failures_should_include_runner_host_name
|
179
|
+
assert_fork_process_exits_ok do
|
180
|
+
$argv_dup = ['scenario_test_case.rb']
|
181
|
+
suite = Test::Unit::TestSuite.new('test_should_wrapper_errors_by_dtr_remote_exception')
|
182
|
+
suite << ScenarioTestCase.suite
|
183
|
+
|
184
|
+
@result = runit(suite)
|
185
|
+
|
186
|
+
assert !@result.passed?
|
187
|
+
assert_equal 8, @result.run_count
|
188
|
+
assert_equal 3, @result.failure_count
|
189
|
+
assert_equal 4, @result.error_count
|
190
|
+
|
191
|
+
@result.errors.each do |e|
|
192
|
+
assert e.message.include?("from #{Socket.gethostname}")
|
193
|
+
end
|
194
|
+
@result.failures.each do |e|
|
195
|
+
assert e.message.include?("from #{Socket.gethostname}")
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_setup_agent_env_from_master_process
|
201
|
+
assert_fork_process_exits_ok do
|
202
|
+
$argv_dup = ['setup_agent_env_test_case.rb']
|
203
|
+
suite = Test::Unit::TestSuite.new('setup_agent_env_from_master_process')
|
204
|
+
suite << SetupAgentEnvTestCase.suite
|
205
|
+
ENV['DTR_AGENT_ENV_SETUP_CMD'] = 'touch /tmp/test_setup_agent_env_from_master_process'
|
206
|
+
|
207
|
+
@result = runit(suite)
|
208
|
+
assert @result.passed?
|
209
|
+
assert_equal 1, @result.run_count
|
210
|
+
assert_equal 0, @result.failure_count
|
211
|
+
assert_equal 0, @result.error_count
|
212
|
+
end
|
213
|
+
ensure
|
214
|
+
File.delete('/tmp/test_setup_agent_env_from_master_process') rescue nil
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_multi_dtr_tasks_should_be_queued_and_processed_one_by_one
|
218
|
+
testdata_dir = File.expand_path(File.dirname(__FILE__) + "/../../testdata/")
|
219
|
+
process_assertion = Proc.new do |master_dir|
|
220
|
+
FileUtils.cp_r testdata_dir, master_dir
|
221
|
+
begin
|
222
|
+
Dir.chdir(master_dir) do
|
223
|
+
$argv_dup = ['a_test_case.rb', 'a_test_case2.rb', 'a_file_system_test_case.rb']
|
224
|
+
setup_test_env
|
225
|
+
suite = Test::Unit::TestSuite.new('run_test_passed')
|
226
|
+
suite << ATestCase.suite
|
227
|
+
suite << ATestCase2.suite
|
228
|
+
suite << AFileSystemTestCase.suite
|
229
|
+
with_agent_helper_group do
|
230
|
+
result = runit(suite)
|
231
|
+
assert result.passed?
|
232
|
+
assert_equal 3, result.run_count
|
233
|
+
end
|
234
|
+
end
|
235
|
+
ensure
|
236
|
+
FileUtils.rm_rf master_dir
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
@test_processes = []
|
241
|
+
4.times do |index|
|
242
|
+
@test_processes << Process.fork do
|
243
|
+
process_assertion.call("#{testdata_dir}_copy#{index}")
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
Process.waitpid @test_processes[0]
|
248
|
+
assert_equal 0, $?.exitstatus
|
249
|
+
Process.waitpid @test_processes[1]
|
250
|
+
assert_equal 0, $?.exitstatus
|
251
|
+
Process.waitpid @test_processes[2]
|
252
|
+
assert_equal 0, $?.exitstatus
|
253
|
+
Process.waitpid @test_processes[3]
|
254
|
+
assert_equal 0, $?.exitstatus
|
255
|
+
ensure
|
256
|
+
@test_processes.each do |pid|
|
257
|
+
DTR.kill_process pid
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_run_test_case_hacked_run_method
|
262
|
+
assert_fork_process_exits_ok do
|
263
|
+
require 'hacked_run_method_test_case'
|
264
|
+
|
265
|
+
$argv_dup = ['hacked_run_method_test_case.rb']
|
266
|
+
suite = Test::Unit::TestSuite.new('run_test_case_hacked_run_method')
|
267
|
+
suite << HackedRunMethodTestCase.suite
|
268
|
+
|
269
|
+
@result = runit(suite)
|
270
|
+
|
271
|
+
assert @result.passed?
|
272
|
+
assert_equal 1, @result.run_count
|
273
|
+
assert_equal 0, @result.failure_count
|
274
|
+
assert_equal 0, @result.error_count
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def test_should_not_break_heartbeat_of_master_process_when_run_with_a_test_case_sleep_long_time
|
279
|
+
assert_fork_process_exits_ok do
|
280
|
+
DTR.configuration.master_heartbeat_interval = 1
|
281
|
+
DTR.configuration.follower_listen_heartbeat_timeout = 2
|
282
|
+
|
283
|
+
require 'sleep_3_secs_test_case'
|
284
|
+
|
285
|
+
$argv_dup = ['sleep_3_secs_test_case.rb']
|
286
|
+
suite = Test::Unit::TestSuite.new('run_test_case_sleep_3_secs')
|
287
|
+
suite << Sleep3SecsTestCase.suite
|
288
|
+
|
289
|
+
@result = runit(suite)
|
290
|
+
|
291
|
+
assert @result.passed?
|
292
|
+
assert_equal 1, @result.run_count
|
293
|
+
assert_equal 0, @result.failure_count
|
294
|
+
assert_equal 0, @result.error_count
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_should_add_meaningful_error_when_runner_get_a_unknown_test
|
299
|
+
assert_fork_process_exits_ok do
|
300
|
+
$argv_dup = ['a_failed_test_case.rb']
|
301
|
+
suite = Test::Unit::TestSuite.new('should_add_meaningful_error_when_runner_get_a_unknown_test')
|
302
|
+
suite << ATestCase.suite
|
303
|
+
|
304
|
+
@result = runit(suite)
|
305
|
+
|
306
|
+
assert !@result.passed?
|
307
|
+
assert_equal 1, @result.run_count
|
308
|
+
assert_equal 0, @result.failure_count
|
309
|
+
assert_equal 1, @result.error_count
|
310
|
+
assert_equal "DTR::RemoteError: DTR::Agent::UnknownTestError from #{Socket.gethostname}: No such test loaded: ATestCase", @result.errors.first.message
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
def test_run_test_timeout
|
315
|
+
assert_fork_process_exits_ok do
|
316
|
+
require 'sleep_3_secs_test_case'
|
317
|
+
$argv_dup = ['sleep_3_secs_test_case.rb']
|
318
|
+
suite = Test::Unit::TestSuite.new('run_test_case_sleep_3_secs')
|
319
|
+
suite << Sleep3SecsTestCase.suite
|
320
|
+
|
321
|
+
ENV['RUN_TEST_TIMEOUT'] = '1'
|
322
|
+
@result = runit(suite)
|
323
|
+
|
324
|
+
assert !@result.passed?
|
325
|
+
assert_equal 1, @result.run_count
|
326
|
+
assert_equal 0, @result.failure_count
|
327
|
+
assert_equal 1, @result.error_count
|
328
|
+
assert @result.errors.first.message.include?('Timeout')
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|