deep_test 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +0 -0
- data/README +23 -0
- data/Rakefile +58 -0
- data/lib/deep_test/extensions/error.rb +14 -0
- data/lib/deep_test/extensions/object_extension.rb +12 -0
- data/lib/deep_test/extensions/testresult.rb +17 -0
- data/lib/deep_test/loader.rb +26 -0
- data/lib/deep_test/rake_tasks.rb +2 -0
- data/lib/deep_test/rinda_blackboard.rb +29 -0
- data/lib/deep_test/server.rb +16 -0
- data/lib/deep_test/simple_test_blackboard.rb +24 -0
- data/lib/deep_test/start_workers.rb +23 -0
- data/lib/deep_test/supervised_test_suite.rb +19 -0
- data/lib/deep_test/supervisor.rb +27 -0
- data/lib/deep_test/tasks/rinda.rake +37 -0
- data/lib/deep_test/test_task.rb +39 -0
- data/lib/deep_test/worker.rb +31 -0
- data/lib/deep_test.rb +18 -0
- data/test/deep_test/loader_test.rb +7 -0
- data/test/simple_test_blackboard_test.rb +33 -0
- data/test/supervised_test_suite_test.rb +57 -0
- data/test/supervisor_test.rb +74 -0
- data/test/test_helper.rb +80 -0
- data/test/test_task_test.rb +41 -0
- data/test/testresult_test.rb +71 -0
- data/test/worker_test.rb +54 -0
- metadata +84 -0
data/CHANGELOG
ADDED
File without changes
|
data/README
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
= DeepTest
|
2
|
+
|
3
|
+
DeepTest enables tests to run in multiple processes.
|
4
|
+
|
5
|
+
== Authors
|
6
|
+
|
7
|
+
anonymous z, Dan[http://www.dcmanges.com/blog] Manges[http://www.dcmanges.com/blog], David Vollbracht
|
8
|
+
|
9
|
+
== Usage
|
10
|
+
|
11
|
+
In your Rakefile:
|
12
|
+
|
13
|
+
require "rubygems"
|
14
|
+
require "deep_test/rake_tasks"
|
15
|
+
|
16
|
+
# sample DeepTest task
|
17
|
+
DeepTest::TestTask.new "task_name" do |t|
|
18
|
+
t.pattern = "test/**/*_test.rb"
|
19
|
+
t.processes = 2 # optional, defaults to 2
|
20
|
+
end
|
21
|
+
|
22
|
+
== License
|
23
|
+
Released under Ruby's[http://www.ruby-lang.org/en/LICENSE.txt] license[http://www.ruby-lang.org/en/LICENSE.txt]
|
data/Rakefile
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/contrib/sshpublisher'
|
6
|
+
$LOAD_PATH << File.dirname(__FILE__) + "/lib"
|
7
|
+
require "deep_test/rake_tasks"
|
8
|
+
|
9
|
+
task :default => :test
|
10
|
+
|
11
|
+
Rake::TestTask.new do |t|
|
12
|
+
t.pattern = "test/**/*_test.rb"
|
13
|
+
t.libs += ['test', 'lib']
|
14
|
+
end
|
15
|
+
|
16
|
+
DeepTest::TestTask.new :deep_test do |t|
|
17
|
+
t.pattern = "test/**/*_test.rb"
|
18
|
+
t.processes = 2
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Generate documentation"
|
22
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
23
|
+
rdoc.rdoc_dir = "doc"
|
24
|
+
rdoc.title = "DeepTest"
|
25
|
+
rdoc.options << '--line-numbers'
|
26
|
+
rdoc.rdoc_files.include('README', 'CHANGELOG')
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "Upload RDoc to RubyForge"
|
30
|
+
task :publish_rdoc => [:rdoc] do
|
31
|
+
Rake::SshDirPublisher.new("dcmanges@rubyforge.org", "/var/www/gforge-projects/deep-test", "doc").upload
|
32
|
+
end
|
33
|
+
|
34
|
+
Gem::manage_gems
|
35
|
+
|
36
|
+
specification = Gem::Specification.new do |s|
|
37
|
+
s.name = "deep_test"
|
38
|
+
s.summary = "DeepTest runs tests in multiple processes."
|
39
|
+
s.version = "1.0.0"
|
40
|
+
s.author = "anonymous z, Dan Manges, David Vollbracht"
|
41
|
+
s.description = s.summary
|
42
|
+
s.email = "daniel.manges@gmail.com"
|
43
|
+
s.homepage = "http://deep-test.rubyforge.org"
|
44
|
+
s.rubyforge_project = "deep-test"
|
45
|
+
s.add_dependency "daemons", ">= 1.0.7"
|
46
|
+
|
47
|
+
s.has_rdoc = true
|
48
|
+
s.extra_rdoc_files = ['README', 'CHANGELOG']
|
49
|
+
s.rdoc_options << '--title' << "DeepTest" << '--main' << 'README' << '--line-numbers'
|
50
|
+
|
51
|
+
s.autorequire = "deep_test"
|
52
|
+
s.files = FileList['{lib,test}/**/*.{rb,rake}', 'CHANGELOG', 'README', 'Rakefile'].to_a
|
53
|
+
end
|
54
|
+
|
55
|
+
Rake::GemPackageTask.new(specification) do |package|
|
56
|
+
package.need_zip = true
|
57
|
+
package.need_tar = true
|
58
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Test
|
2
|
+
module Unit
|
3
|
+
class Error
|
4
|
+
def initialize_with_exception_wrapping(test_name, exception)
|
5
|
+
wrap = Exception.new "#{exception.class}: #{exception.message}"
|
6
|
+
wrap.set_backtrace exception.backtrace
|
7
|
+
@test_name = test_name
|
8
|
+
@exception = wrap
|
9
|
+
end
|
10
|
+
alias_method :initialize_without_exception_wrapping, :initialize
|
11
|
+
alias_method :initialize, :initialize_with_exception_wrapping
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Test
|
2
|
+
module Unit
|
3
|
+
class TestResult
|
4
|
+
attr_accessor :output
|
5
|
+
def add_to(result)
|
6
|
+
@failures.each {|e| result.add_failure(e)}
|
7
|
+
@errors.each {|e| result.add_error(e)}
|
8
|
+
assertion_count.times {result.add_assertion}
|
9
|
+
run_count.times {result.add_run}
|
10
|
+
end
|
11
|
+
|
12
|
+
def failed_due_to_deadlock?
|
13
|
+
@errors.any? && !@errors.last.message.to_s.match(/Deadlock found when trying to get lock/).nil?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DeepTest
|
2
|
+
class Loader
|
3
|
+
NO_FILTERS = Object.new.instance_eval do
|
4
|
+
def filters; []; end;
|
5
|
+
self
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.run(args)
|
9
|
+
require "deep_test"
|
10
|
+
ENV["RAILS_ENV"] = "test"
|
11
|
+
Object.const_set "RAILS_ENV", "test"
|
12
|
+
Dir.glob(ARGV.first).each { |file| load file }
|
13
|
+
suite = Test::Unit::AutoRunner::COLLECTORS[:objectspace].call NO_FILTERS
|
14
|
+
blackboard = DeepTest::RindaBlackboard.new
|
15
|
+
supervisor = DeepTest::Supervisor.new blackboard
|
16
|
+
supervised_suite = DeepTest::SupervisedTestSuite.new(suite, supervisor)
|
17
|
+
require 'test/unit/ui/console/testrunner'
|
18
|
+
Test::Unit::UI::Console::TestRunner.run(supervised_suite, Test::Unit::UI::NORMAL)
|
19
|
+
Test::Unit.run = true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
if __FILE__ == $0
|
25
|
+
DeepTest::Loader.run ARGV
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module DeepTest
|
2
|
+
class RindaBlackboard
|
3
|
+
def initialize
|
4
|
+
require "rinda/ring"
|
5
|
+
DRb.start_service
|
6
|
+
ring_server = Rinda::RingFinger.primary
|
7
|
+
ts = ring_server.read([:name, :TupleSpace, nil, nil])[2]
|
8
|
+
@tuple_space = Rinda::TupleSpaceProxy.new ts
|
9
|
+
end
|
10
|
+
|
11
|
+
def take_result
|
12
|
+
result = @tuple_space.take ["test_result", nil], 3
|
13
|
+
result[1]
|
14
|
+
end
|
15
|
+
|
16
|
+
def take_test
|
17
|
+
tuple = @tuple_space.take(["run_test", nil, nil])
|
18
|
+
eval(tuple[1]).new(tuple[2])
|
19
|
+
end
|
20
|
+
|
21
|
+
def write_result(result)
|
22
|
+
@tuple_space.write ["test_result", result]
|
23
|
+
end
|
24
|
+
|
25
|
+
def write_test(test_case)
|
26
|
+
@tuple_space.write ["run_test", test_case.class.to_s, test_case.method_name]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module DeepTest
|
2
|
+
class Server
|
3
|
+
def self.start
|
4
|
+
require 'rinda/ring'
|
5
|
+
require 'rinda/tuplespace'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'test/unit/testresult'
|
8
|
+
require 'deep_test'
|
9
|
+
DRb.start_service
|
10
|
+
ts = Rinda::TupleSpace.new
|
11
|
+
Rinda::RingServer.new(ts)
|
12
|
+
Rinda::RingProvider.new(:TupleSpace, ts, 'Tuple Space').provide
|
13
|
+
DRb.thread.join
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module DeepTest
|
2
|
+
class SimpleTestBlackboard
|
3
|
+
def initialize
|
4
|
+
@test_cases = []
|
5
|
+
@test_results = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def take_result
|
9
|
+
@test_results.shift
|
10
|
+
end
|
11
|
+
|
12
|
+
def take_test
|
13
|
+
@test_cases.shift
|
14
|
+
end
|
15
|
+
|
16
|
+
def write_result(result)
|
17
|
+
@test_results.push result
|
18
|
+
end
|
19
|
+
|
20
|
+
def write_test(test_case)
|
21
|
+
@test_cases.push test_case
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DeepTest
|
2
|
+
module StartWorkers
|
3
|
+
def self.run(args)
|
4
|
+
processes, pattern = args
|
5
|
+
1.to_i.times do
|
6
|
+
Daemons.run_proc "deep_test_worker", :multiple => true, :ARGV => ["start"], :backtrace => true, :log_output => true do
|
7
|
+
require "deep_test"
|
8
|
+
ENV["RAILS_ENV"] = "test"
|
9
|
+
Object.const_set "RAILS_ENV", "test"
|
10
|
+
Dir.glob(pattern).each { |file| load file }
|
11
|
+
blackboard = DeepTest::RindaBlackboard.new
|
12
|
+
DeepTest::Worker.new(blackboard).run
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
if __FILE__ == $0
|
20
|
+
require "rubygems"
|
21
|
+
require "daemons"
|
22
|
+
DeepTest::StartWorkers.run ARGV
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DeepTest
|
2
|
+
class SupervisedTestSuite
|
3
|
+
def initialize(suite, supervisor)
|
4
|
+
@suite = suite
|
5
|
+
@supervisor = supervisor
|
6
|
+
end
|
7
|
+
|
8
|
+
def run(result, &progress_block)
|
9
|
+
yield Test::Unit::TestSuite::STARTED, @suite.name
|
10
|
+
@supervisor.add_tests @suite
|
11
|
+
@supervisor.read_results result, &progress_block
|
12
|
+
yield Test::Unit::TestSuite::FINISHED, @suite.name
|
13
|
+
end
|
14
|
+
|
15
|
+
def size
|
16
|
+
@suite.size
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module DeepTest
|
2
|
+
class Supervisor
|
3
|
+
def initialize(blackboard)
|
4
|
+
@blackboard = blackboard
|
5
|
+
@count = 0
|
6
|
+
end
|
7
|
+
|
8
|
+
def add_tests(test_suite)
|
9
|
+
if test_suite.respond_to? :tests
|
10
|
+
test_suite.tests.each {|test| add_tests(test)}
|
11
|
+
else
|
12
|
+
@count += 1
|
13
|
+
@blackboard.write_test test_suite
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def read_results(result)
|
18
|
+
while (@count > 0 && remote_result = @blackboard.take_result)
|
19
|
+
@count -= 1
|
20
|
+
remote_result.add_to result
|
21
|
+
# TODO: is this the right place for this next line? -Dan
|
22
|
+
print remote_result.output if remote_result.output
|
23
|
+
yield Test::Unit::TestCase::FINISHED, nil if block_given?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
begin
|
3
|
+
require "daemons"
|
4
|
+
rescue LoadError
|
5
|
+
raise "The daemons gem must be installed"
|
6
|
+
end
|
7
|
+
|
8
|
+
namespace :deep_test do
|
9
|
+
namespace :server do
|
10
|
+
desc "Starts the server"
|
11
|
+
task :start do
|
12
|
+
Daemons.run_proc "deep_test_server", :ARGV => ["start"] do
|
13
|
+
require "deep_test"
|
14
|
+
ENV["RAILS_ENV"] = "test"
|
15
|
+
Object.const_set "RAILS_ENV", "test"
|
16
|
+
DeepTest::Server.start
|
17
|
+
end
|
18
|
+
sleep 0.25
|
19
|
+
end
|
20
|
+
desc "Stops the server"
|
21
|
+
task :stop do
|
22
|
+
Daemons.run("deep_test_server", :ARGV => ["stop"])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
namespace :workers do
|
27
|
+
desc "Starts the workers"
|
28
|
+
task :start do
|
29
|
+
raise "deprecated -dan"
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Stops the workers"
|
33
|
+
task :stop do
|
34
|
+
Daemons.run("deep_test_worker", :ARGV => ["stop"])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module DeepTest
|
2
|
+
class TestTask
|
3
|
+
attr_writer :pattern, :processes
|
4
|
+
|
5
|
+
def initialize(name = :deep_test)
|
6
|
+
@name = name
|
7
|
+
yield self if block_given?
|
8
|
+
define
|
9
|
+
end
|
10
|
+
|
11
|
+
def define
|
12
|
+
desc "Run '#{@name}' suite using DeepTest"
|
13
|
+
task @name => %w[deep_test:server:start] do
|
14
|
+
begin
|
15
|
+
deep_test_lib = File.expand_path(File.dirname(__FILE__) + "/..")
|
16
|
+
|
17
|
+
# workers
|
18
|
+
starter = File.expand_path(File.dirname(__FILE__) + "/start_workers.rb")
|
19
|
+
ruby "-I#{deep_test_lib} #{starter} '#{processes}' '#{pattern}'"
|
20
|
+
|
21
|
+
# loader
|
22
|
+
loader = File.expand_path(File.dirname(__FILE__) + "/loader.rb")
|
23
|
+
ruby "-I#{deep_test_lib} #{loader} '#{pattern}'"
|
24
|
+
ensure
|
25
|
+
Rake::Task["deep_test:workers:stop"].invoke
|
26
|
+
Rake::Task["deep_test:server:stop"].invoke
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def pattern
|
32
|
+
Dir.pwd + "/" + (@pattern || "test/**/*_test.rb")
|
33
|
+
end
|
34
|
+
|
35
|
+
def processes
|
36
|
+
@processes ? @processes.to_i : 2
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DeepTest
|
2
|
+
class Worker
|
3
|
+
def initialize(blackboard)
|
4
|
+
@blackboard = blackboard
|
5
|
+
end
|
6
|
+
|
7
|
+
def run
|
8
|
+
while test_case = @blackboard.take_test
|
9
|
+
result = run_test_case test_case
|
10
|
+
result = run_test_case test_case if result.failed_due_to_deadlock?
|
11
|
+
if result.failed_due_to_deadlock?
|
12
|
+
result = Test::Unit::TestResult.new
|
13
|
+
result.add_run
|
14
|
+
result.output = "-deadlock-"
|
15
|
+
end
|
16
|
+
@blackboard.write_result result
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def run_test_case(test_case)
|
23
|
+
result = Test::Unit::TestResult.new
|
24
|
+
output = capture_stdout do
|
25
|
+
test_case.run(result) {|channel,event|}
|
26
|
+
end
|
27
|
+
result.output = output
|
28
|
+
result
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/deep_test.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module DeepTest
|
2
|
+
end
|
3
|
+
|
4
|
+
require "test/unit/testresult"
|
5
|
+
require "test/unit/error"
|
6
|
+
|
7
|
+
require "deep_test/extensions/testresult"
|
8
|
+
require "deep_test/extensions/error"
|
9
|
+
require "deep_test/extensions/object_extension"
|
10
|
+
|
11
|
+
# require "deep_test/loader"
|
12
|
+
require "deep_test/rinda_blackboard"
|
13
|
+
require "deep_test/server"
|
14
|
+
require "deep_test/simple_test_blackboard"
|
15
|
+
require "deep_test/supervised_test_suite"
|
16
|
+
require "deep_test/supervisor"
|
17
|
+
require "deep_test/test_task"
|
18
|
+
require "deep_test/worker"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/test_helper"
|
2
|
+
|
3
|
+
unit_tests do
|
4
|
+
test "a test that is put on can be taken off later" do
|
5
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
6
|
+
test_case = TestFactory.passing_test
|
7
|
+
blackboard.write_test test_case
|
8
|
+
assert_equal test_case, blackboard.take_test
|
9
|
+
end
|
10
|
+
|
11
|
+
test "taking a test when all have been taken returns nil" do
|
12
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
13
|
+
test_case = TestFactory.passing_test
|
14
|
+
blackboard.write_test test_case
|
15
|
+
blackboard.take_test
|
16
|
+
assert_nil blackboard.take_test
|
17
|
+
end
|
18
|
+
|
19
|
+
test "a result that is put on can be taken off later" do
|
20
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
21
|
+
result = TestFactory.passed_result
|
22
|
+
blackboard.write_result result
|
23
|
+
assert_equal result, blackboard.take_result
|
24
|
+
end
|
25
|
+
|
26
|
+
test "taking a result when all have been taken returns nil" do
|
27
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
28
|
+
result = TestFactory.passed_result
|
29
|
+
blackboard.write_result result
|
30
|
+
blackboard.take_result
|
31
|
+
assert_nil blackboard.take_result
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/test_helper"
|
2
|
+
|
3
|
+
unit_tests do
|
4
|
+
test "run yields name for start and finished of underlying suite" do
|
5
|
+
suite = Test::Unit::TestSuite.new("name")
|
6
|
+
supervised_suite = DeepTest::SupervisedTestSuite.new(suite, stub_everything)
|
7
|
+
|
8
|
+
yielded = []
|
9
|
+
supervised_suite.run(stub_everything) do |channel,name|
|
10
|
+
yielded << [channel,name]
|
11
|
+
end
|
12
|
+
|
13
|
+
assert_equal [[Test::Unit::TestSuite::STARTED, "name"],
|
14
|
+
[Test::Unit::TestSuite::FINISHED, "name"]], yielded
|
15
|
+
end
|
16
|
+
|
17
|
+
test "run adds test suite to supervisor" do
|
18
|
+
suite = Test::Unit::TestSuite.new("name")
|
19
|
+
supervisor = stub_everything
|
20
|
+
supervised_suite = DeepTest::SupervisedTestSuite.new(suite, supervisor)
|
21
|
+
supervisor.expects(:add_tests).with(suite)
|
22
|
+
supervised_suite.run(stub_everything) {|channel,name|}
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
test "run tells supervisor to read resuts with passed in results" do
|
27
|
+
suite = Test::Unit::TestSuite.new("name")
|
28
|
+
results = stub_everything
|
29
|
+
supervisor = stub_everything
|
30
|
+
supervised_suite = DeepTest::SupervisedTestSuite.new(suite, supervisor)
|
31
|
+
supervisor.expects(:read_results).with(results)
|
32
|
+
supervised_suite.run(results) {|channel,name|}
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
test "run passes progress block on to supervisor" do
|
37
|
+
suite = Test::Unit::TestSuite.new("name")
|
38
|
+
supervisor = stub_everything
|
39
|
+
supervised_suite = DeepTest::SupervisedTestSuite.new(suite, supervisor)
|
40
|
+
supervisor.stubs(:read_results).yields("from_supervisor", "event")
|
41
|
+
yielded = []
|
42
|
+
supervised_suite.run(stub_everything) do |channel,name|
|
43
|
+
yielded << [channel, name]
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_equal true, yielded.include?(["from_supervisor", "event"])
|
47
|
+
end
|
48
|
+
|
49
|
+
test "has same size as underlyng suite" do
|
50
|
+
suite = Test::Unit::TestSuite.new("name")
|
51
|
+
suite << "test"
|
52
|
+
supervisor = stub_everything
|
53
|
+
supervised_suite = DeepTest::SupervisedTestSuite.new(suite, supervisor)
|
54
|
+
|
55
|
+
assert_equal suite.size, supervised_suite.size
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/test_helper"
|
2
|
+
|
3
|
+
unit_tests do
|
4
|
+
test "add_tests adds single test to blackboard" do
|
5
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
6
|
+
supervisor = DeepTest::Supervisor.new(blackboard)
|
7
|
+
test_case = TestFactory.passing_test
|
8
|
+
supervisor.add_tests test_case
|
9
|
+
assert_equal test_case, blackboard.take_test
|
10
|
+
end
|
11
|
+
|
12
|
+
test "add_tests adds entire suite to blackboard" do
|
13
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
14
|
+
supervisor = DeepTest::Supervisor.new(blackboard)
|
15
|
+
test_suite = TestFactory.suite
|
16
|
+
test_suite << (test_case_1 = TestFactory.passing_test)
|
17
|
+
test_suite << (test_case_2 = TestFactory.passing_test)
|
18
|
+
|
19
|
+
supervisor.add_tests test_suite
|
20
|
+
|
21
|
+
actual_tests = [blackboard.take_test, blackboard.take_test]
|
22
|
+
|
23
|
+
assert_equal true, actual_tests.member?(test_case_1),
|
24
|
+
"First test case is not on blackboard"
|
25
|
+
|
26
|
+
assert_equal true, actual_tests.member?(test_case_2),
|
27
|
+
"Second test case is not on blackboard"
|
28
|
+
end
|
29
|
+
|
30
|
+
test "read_results adds blackboard result to local result" do
|
31
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
32
|
+
supervisor = DeepTest::Supervisor.new(blackboard)
|
33
|
+
|
34
|
+
supervisor.add_tests TestFactory.passing_test
|
35
|
+
|
36
|
+
blackboard_result = Test::Unit::TestResult.new
|
37
|
+
blackboard_result.add_run
|
38
|
+
|
39
|
+
blackboard.write_result blackboard_result
|
40
|
+
|
41
|
+
local_result = Test::Unit::TestResult.new
|
42
|
+
supervisor.read_results local_result
|
43
|
+
|
44
|
+
assert_equal 1, local_result.run_count
|
45
|
+
end
|
46
|
+
|
47
|
+
test "read_results yields TestCase::Finished event when reading a result" do
|
48
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
49
|
+
supervisor = DeepTest::Supervisor.new(blackboard)
|
50
|
+
|
51
|
+
supervisor.add_tests TestFactory.passing_test
|
52
|
+
|
53
|
+
blackboard.write_result Test::Unit::TestResult.new
|
54
|
+
yielded = nil
|
55
|
+
|
56
|
+
supervisor.read_results Test::Unit::TestResult.new do |channel,name|
|
57
|
+
yielded = [channel,name]
|
58
|
+
end
|
59
|
+
|
60
|
+
assert_equal [Test::Unit::TestCase::FINISHED, nil], yielded
|
61
|
+
end
|
62
|
+
|
63
|
+
test "read_results prints output if any" do
|
64
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
65
|
+
supervisor = DeepTest::Supervisor.new(blackboard)
|
66
|
+
supervisor.add_tests stub
|
67
|
+
result = Test::Unit::TestResult.new
|
68
|
+
result.output = "output"
|
69
|
+
blackboard.write_result result
|
70
|
+
supervisor.expects(:print).with("output")
|
71
|
+
supervisor.read_results Test::Unit::TestResult.new do |channel,name|
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'dust'
|
4
|
+
require 'mocha'
|
5
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/lib")
|
6
|
+
require "deep_test"
|
7
|
+
|
8
|
+
module TestFactory
|
9
|
+
def self.failing_test
|
10
|
+
test_class = Class.new(Test::Unit::TestCase) do
|
11
|
+
def test_failing
|
12
|
+
assert_equal 1, 0
|
13
|
+
end
|
14
|
+
end
|
15
|
+
test_class.new(:test_failing)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.passed_result
|
19
|
+
result = Test::Unit::TestResult.new
|
20
|
+
result.add_run
|
21
|
+
result.add_assertion
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.passing_test
|
26
|
+
test_class = Class.new(Test::Unit::TestCase) do
|
27
|
+
def test_passing
|
28
|
+
assert_equal 0, 0
|
29
|
+
end
|
30
|
+
end
|
31
|
+
test_class.new(:test_passing)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.passing_test_with_stdout
|
35
|
+
test_class = Class.new(Test::Unit::TestCase) do
|
36
|
+
def test_passing_with_stdout
|
37
|
+
print "message printed to stdout"
|
38
|
+
assert true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
test_class.new :test_passing_with_stdout
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.deadlock_once_test
|
45
|
+
test_class = Class.new(Test::Unit::TestCase) do
|
46
|
+
def test_deadlock_once
|
47
|
+
if @deadlocked
|
48
|
+
assert true
|
49
|
+
else
|
50
|
+
@deadlocked = true
|
51
|
+
raise ActiveRecord::StatementInvalid.new("Deadlock found when trying to get lock")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
test_class.new :test_deadlock_once
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.deadlock_always_test
|
59
|
+
test_class = Class.new(Test::Unit::TestCase) do
|
60
|
+
def test_deadlock_always
|
61
|
+
raise ActiveRecord::StatementInvalid.new("Deadlock found when trying to get lock")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
test_class.new :test_deadlock_always
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.suite
|
68
|
+
Test::Unit::TestSuite.new
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class SomeCustomException < RuntimeError
|
73
|
+
end
|
74
|
+
|
75
|
+
unless defined?(ActiveRecord::StatementInvalid)
|
76
|
+
module ActiveRecord
|
77
|
+
class StatementInvalid < StandardError
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/test_helper"
|
2
|
+
|
3
|
+
unit_tests do
|
4
|
+
test "defines a rake task with the name passed to the constructor" do
|
5
|
+
DeepTest::TestTask.any_instance.stubs(:desc)
|
6
|
+
DeepTest::TestTask.any_instance.expects(:task).with { |hash| hash.keys == [:my_task_name] }
|
7
|
+
DeepTest::TestTask.new :my_task_name do
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
test "setting pattern" do
|
12
|
+
pattern = "test/**/x*_test.rb"
|
13
|
+
task = DeepTest::TestTask.new do |t|
|
14
|
+
t.stubs(:define)
|
15
|
+
t.pattern = pattern
|
16
|
+
end
|
17
|
+
assert_equal pattern, task.pattern[-pattern.size..-1]
|
18
|
+
end
|
19
|
+
|
20
|
+
test "default pattern is test/**/*_test.rb" do
|
21
|
+
task = DeepTest::TestTask.new do |t|
|
22
|
+
t.stubs(:define)
|
23
|
+
end
|
24
|
+
assert_equal "test/**/*_test.rb", task.pattern[-"test/**/*_test.rb".size..-1]
|
25
|
+
end
|
26
|
+
|
27
|
+
test "processes defaults to 2" do
|
28
|
+
task = DeepTest::TestTask.new do |t|
|
29
|
+
t.stubs(:define)
|
30
|
+
end
|
31
|
+
assert_equal 2, task.processes
|
32
|
+
end
|
33
|
+
|
34
|
+
test "processes can be set" do
|
35
|
+
task = DeepTest::TestTask.new do |t|
|
36
|
+
t.processes = 42
|
37
|
+
t.stubs(:define)
|
38
|
+
end
|
39
|
+
assert_equal 42, task.processes
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/test_helper"
|
2
|
+
|
3
|
+
unit_tests do
|
4
|
+
test "add_to adds correct run_count" do
|
5
|
+
result_1 = Test::Unit::TestResult.new
|
6
|
+
result_1.add_run
|
7
|
+
result_1.add_run
|
8
|
+
|
9
|
+
result_2 = Test::Unit::TestResult.new
|
10
|
+
result_1.add_to result_2
|
11
|
+
|
12
|
+
assert_equal 2, result_2.run_count
|
13
|
+
end
|
14
|
+
|
15
|
+
test "add_to adds correct assertion_count" do
|
16
|
+
result_1 = Test::Unit::TestResult.new
|
17
|
+
result_1.add_assertion
|
18
|
+
result_1.add_assertion
|
19
|
+
|
20
|
+
result_2 = Test::Unit::TestResult.new
|
21
|
+
result_1.add_to result_2
|
22
|
+
|
23
|
+
assert_equal 2, result_2.assertion_count
|
24
|
+
end
|
25
|
+
|
26
|
+
test "add_to adds correct errors" do
|
27
|
+
result_1 = Test::Unit::TestResult.new
|
28
|
+
result_1.add_error(:error)
|
29
|
+
|
30
|
+
result_2 = Test::Unit::TestResult.new
|
31
|
+
result_1.add_to result_2
|
32
|
+
|
33
|
+
assert_equal [:error], result_2.instance_variable_get(:@errors)
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
test "add_to adds correct failures" do
|
38
|
+
result_1 = Test::Unit::TestResult.new
|
39
|
+
result_1.add_failure(:failure)
|
40
|
+
|
41
|
+
result_2 = Test::Unit::TestResult.new
|
42
|
+
result_1.add_to result_2
|
43
|
+
|
44
|
+
assert_equal [:failure], result_2.instance_variable_get(:@failures)
|
45
|
+
end
|
46
|
+
|
47
|
+
test "wraps exceptions" do
|
48
|
+
result = Test::Unit::TestResult.new
|
49
|
+
begin
|
50
|
+
raise SomeCustomException.new("the exception message")
|
51
|
+
rescue => ex
|
52
|
+
result.add_error Test::Unit::Error.new("test_wraps_exceptions", ex)
|
53
|
+
end
|
54
|
+
error = result.instance_variable_get("@errors").last
|
55
|
+
# TODO: add this assertion
|
56
|
+
# assert_equal "SomeCustomException: the exception message", error.message
|
57
|
+
assert_equal "SomeCustomException: the exception message", error.exception.message
|
58
|
+
assert_equal Exception, error.exception.class
|
59
|
+
assert_equal ex.backtrace, error.exception.backtrace
|
60
|
+
end
|
61
|
+
|
62
|
+
test "failed due to deadlock" do
|
63
|
+
result = Test::Unit::TestResult.new
|
64
|
+
begin
|
65
|
+
raise ActiveRecord::StatementInvalid.new("Deadlock found when trying to get lock")
|
66
|
+
rescue => ex
|
67
|
+
result.add_error Test::Unit::Error.new("test_", ex)
|
68
|
+
end
|
69
|
+
assert_equal true, result.failed_due_to_deadlock?
|
70
|
+
end
|
71
|
+
end
|
data/test/worker_test.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/test_helper"
|
2
|
+
|
3
|
+
unit_tests do
|
4
|
+
test "puts result on blackboard" do
|
5
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
6
|
+
blackboard.write_test TestFactory.passing_test
|
7
|
+
|
8
|
+
DeepTest::Worker.new(blackboard).run
|
9
|
+
|
10
|
+
assert_kind_of Test::Unit::TestResult, blackboard.take_result
|
11
|
+
end
|
12
|
+
|
13
|
+
test "puts passing and failing tests on blackboard for each test" do
|
14
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
15
|
+
blackboard.write_test TestFactory.passing_test
|
16
|
+
blackboard.write_test TestFactory.failing_test
|
17
|
+
|
18
|
+
DeepTest::Worker.new(blackboard).run
|
19
|
+
|
20
|
+
result_1 = blackboard.take_result
|
21
|
+
result_2 = blackboard.take_result
|
22
|
+
|
23
|
+
assert_equal true, (result_1.passed? || result_2.passed?)
|
24
|
+
assert_equal false, (result_1.passed? && result_2.passed?)
|
25
|
+
end
|
26
|
+
|
27
|
+
test "capturing stdout" do
|
28
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
29
|
+
blackboard.write_test TestFactory.passing_test_with_stdout
|
30
|
+
DeepTest::Worker.new(blackboard).run
|
31
|
+
result = blackboard.take_result
|
32
|
+
assert_equal "message printed to stdout", result.output
|
33
|
+
end
|
34
|
+
|
35
|
+
test "retry on deadlock" do
|
36
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
37
|
+
blackboard.write_test TestFactory.deadlock_once_test
|
38
|
+
DeepTest::Worker.new(blackboard).run
|
39
|
+
result = blackboard.take_result
|
40
|
+
assert_equal 0, result.error_count
|
41
|
+
assert_equal 0, result.failure_count
|
42
|
+
assert_equal 1, result.assertion_count
|
43
|
+
end
|
44
|
+
|
45
|
+
test "skip on deadlock twice" do
|
46
|
+
blackboard = DeepTest::SimpleTestBlackboard.new
|
47
|
+
blackboard.write_test TestFactory.deadlock_always_test
|
48
|
+
DeepTest::Worker.new(blackboard).run
|
49
|
+
result = blackboard.take_result
|
50
|
+
assert_equal 0, result.error_count
|
51
|
+
assert_equal 0, result.failure_count
|
52
|
+
assert_equal 0, result.assertion_count
|
53
|
+
end
|
54
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.3
|
3
|
+
specification_version: 1
|
4
|
+
name: deep_test
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.0.0
|
7
|
+
date: 2007-09-04 00:00:00 -04:00
|
8
|
+
summary: DeepTest runs tests in multiple processes.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: daniel.manges@gmail.com
|
12
|
+
homepage: http://deep-test.rubyforge.org
|
13
|
+
rubyforge_project: deep-test
|
14
|
+
description: DeepTest runs tests in multiple processes.
|
15
|
+
autorequire: deep_test
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- anonymous z, Dan Manges, David Vollbracht
|
31
|
+
files:
|
32
|
+
- lib/deep_test.rb
|
33
|
+
- lib/deep_test/loader.rb
|
34
|
+
- lib/deep_test/rake_tasks.rb
|
35
|
+
- lib/deep_test/rinda_blackboard.rb
|
36
|
+
- lib/deep_test/server.rb
|
37
|
+
- lib/deep_test/simple_test_blackboard.rb
|
38
|
+
- lib/deep_test/start_workers.rb
|
39
|
+
- lib/deep_test/supervised_test_suite.rb
|
40
|
+
- lib/deep_test/supervisor.rb
|
41
|
+
- lib/deep_test/test_task.rb
|
42
|
+
- lib/deep_test/worker.rb
|
43
|
+
- lib/deep_test/extensions/error.rb
|
44
|
+
- lib/deep_test/extensions/object_extension.rb
|
45
|
+
- lib/deep_test/extensions/testresult.rb
|
46
|
+
- lib/deep_test/tasks/rinda.rake
|
47
|
+
- test/simple_test_blackboard_test.rb
|
48
|
+
- test/supervised_test_suite_test.rb
|
49
|
+
- test/supervisor_test.rb
|
50
|
+
- test/test_helper.rb
|
51
|
+
- test/test_task_test.rb
|
52
|
+
- test/testresult_test.rb
|
53
|
+
- test/worker_test.rb
|
54
|
+
- test/deep_test/loader_test.rb
|
55
|
+
- CHANGELOG
|
56
|
+
- README
|
57
|
+
- Rakefile
|
58
|
+
test_files: []
|
59
|
+
|
60
|
+
rdoc_options:
|
61
|
+
- --title
|
62
|
+
- DeepTest
|
63
|
+
- --main
|
64
|
+
- README
|
65
|
+
- --line-numbers
|
66
|
+
extra_rdoc_files:
|
67
|
+
- README
|
68
|
+
- CHANGELOG
|
69
|
+
executables: []
|
70
|
+
|
71
|
+
extensions: []
|
72
|
+
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
dependencies:
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: daemons
|
78
|
+
version_requirement:
|
79
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 1.0.7
|
84
|
+
version:
|