2010-01-29 16:45:42 +00:00
require File . join ( File . dirname ( __FILE__ ) , 'test_helper' )
2011-06-01 16:45:43 +00:00
require File . join ( File . dirname ( __FILE__ ) , 'fixtures' , 'runner_listeners' )
require File . join ( File . dirname ( __FILE__ ) , 'fixtures' , 'master_listeners' )
2010-01-29 16:45:42 +00:00
class MasterTest < Test :: Unit :: TestCase
context " with a file to test and a destination to verify " do
setup do
2010-02-16 21:13:51 +00:00
# avoid having other tests interfering with us
2010-02-18 18:11:00 +00:00
sleep ( 0 . 2 )
2010-01-29 19:56:02 +00:00
FileUtils . rm_f ( target_file )
2010-01-29 16:45:42 +00:00
end
teardown do
2010-01-29 19:56:02 +00:00
FileUtils . rm_f ( target_file )
2010-01-29 16:45:42 +00:00
end
should " run a test " do
2010-01-29 20:26:32 +00:00
Hydra :: Master . new (
:files = > [ test_file ]
)
2010-01-29 19:56:02 +00:00
assert File . exists? ( target_file )
assert_equal " HYDRA " , File . read ( target_file )
2010-01-29 16:45:42 +00:00
end
2010-02-17 21:28:32 +00:00
2010-08-28 02:35:11 +00:00
# this test simulates what happens when we have 2 tests with the same
# class name but with different parent classes. This can happen when
# we have a functional and an integration test class with the same name.
2010-08-29 05:17:26 +00:00
should " run even with a test that will not require " do
class FileOutputListener < Hydra :: Listener :: Abstract
attr_accessor :output
def initialize ( & block )
self . output = { }
end
def file_end ( file , output )
self . output [ file ] = output
end
end
listener = FileOutputListener . new
2010-08-28 02:35:11 +00:00
sync_test = File . join ( File . dirname ( __FILE__ ) , 'fixtures' , 'sync_test.rb' )
Hydra :: Master . new (
# we want the actual test to run last to make sure the runner can still run tests
:files = > [ sync_test , conflicting_test_file , test_file ] ,
2010-08-29 05:17:26 +00:00
:autosort = > false ,
:listeners = > [ listener ]
2010-08-28 02:35:11 +00:00
)
2010-08-29 05:17:26 +00:00
assert_match / superclass mismatch for class SyncTest / , listener . output [ conflicting_test_file ]
assert_match conflicting_test_file , listener . output [ conflicting_test_file ]
2010-08-28 02:35:11 +00:00
assert File . exists? ( target_file )
assert_equal " HYDRA " , File . read ( target_file )
end
2010-04-20 10:33:28 +00:00
should " run a spec with pending examples " do
progress_bar = Hydra :: Listener :: ProgressBar . new ( StringIO . new )
Hydra :: Master . new (
:files = > [ rspec_file_with_pending ] ,
:listeners = > [ progress_bar ]
)
assert File . exists? ( target_file )
assert_equal " HYDRA " , File . read ( target_file )
assert_equal false , progress_bar . instance_variable_get ( '@errors' )
end
2010-02-17 21:28:32 +00:00
should " generate a report " do
2010-03-25 16:15:01 +00:00
Hydra :: Master . new ( :files = > [ test_file ] )
2010-02-17 21:28:32 +00:00
assert File . exists? ( target_file )
assert_equal " HYDRA " , File . read ( target_file )
2010-06-09 18:24:32 +00:00
report_file = File . join ( Dir . consistent_tmpdir , 'hydra_heuristics.yml' )
2010-02-17 21:28:32 +00:00
assert File . exists? ( report_file )
2010-03-25 16:15:01 +00:00
assert report = YAML . load_file ( report_file )
assert_not_nil report [ test_file ]
2010-02-17 21:28:32 +00:00
end
2010-01-29 20:26:32 +00:00
should " run a test 6 times on 1 worker with 2 runners " do
Hydra :: Master . new (
:files = > [ test_file ] * 6 ,
2010-02-04 15:33:21 +00:00
:workers = > [ { :type = > :local , :runners = > 2 } ]
2010-01-29 20:26:32 +00:00
)
assert File . exists? ( target_file )
assert_equal " HYDRA " * 6 , File . read ( target_file )
end
2010-02-04 16:18:06 +00:00
# The test being run sleeps for 5 seconds. So, if this was run in
# series, it would take at least 50 seconds. This test ensures that
2010-01-29 20:26:32 +00:00
# in runs in less than that amount of time. Since there are 10
2010-02-04 16:18:06 +00:00
# runners to run the file 10 times, it should only take 5-10 seconds
2010-01-29 20:26:32 +00:00
# based on overhead.
should " run a slow test 10 times on 1 worker with 10 runners quickly " do
start = Time . now
Hydra :: Master . new (
:files = > [ File . join ( File . dirname ( __FILE__ ) , 'fixtures' , 'slow.rb' ) ] * 10 ,
:workers = > [
{ :type = > :local , :runners = > 10 }
]
)
finish = Time . now
2010-02-04 16:18:06 +00:00
assert ( finish - start ) < 30 , " took #{ finish - start } seconds "
2010-01-29 20:27:48 +00:00
end
2010-01-29 20:26:32 +00:00
2010-01-29 20:27:48 +00:00
should " run a slow test 10 times on 2 workers with 5 runners each quickly " do
start = Time . now
Hydra :: Master . new (
:files = > [ File . join ( File . dirname ( __FILE__ ) , 'fixtures' , 'slow.rb' ) ] * 10 ,
:workers = > [
{ :type = > :local , :runners = > 5 } ,
{ :type = > :local , :runners = > 5 }
]
)
finish = Time . now
2010-01-29 20:26:32 +00:00
assert ( finish - start ) < 15 , " took #{ finish - start } seconds "
end
2010-01-29 22:21:48 +00:00
should " run a test via ssh " do
Hydra :: Master . new (
:files = > [ test_file ] ,
:workers = > [ {
:type = > :ssh ,
:connect = > 'localhost' ,
2011-05-30 17:40:44 +00:00
:directory = > remote_dir_path ,
:runners = > 1
2010-02-03 21:03:16 +00:00
} ]
2010-01-29 22:21:48 +00:00
)
assert File . exists? ( target_file )
assert_equal " HYDRA " , File . read ( target_file )
end
2010-02-04 15:33:21 +00:00
should " run a test with config from a yaml file " do
Hydra :: Master . new (
:files = > [ test_file ] ,
:config = > File . join ( File . dirname ( __FILE__ ) , 'fixtures' , 'config.yml' )
)
assert File . exists? ( target_file )
assert_equal " HYDRA " , File . read ( target_file )
end
2010-02-09 20:40:35 +00:00
should " synchronize a test file over ssh with rsync " do
2010-06-09 18:24:32 +00:00
local = File . join ( Dir . consistent_tmpdir , 'hydra' , 'local' )
remote = File . join ( Dir . consistent_tmpdir , 'hydra' , 'remote' )
2010-02-09 20:40:35 +00:00
sync_test = File . join ( File . dirname ( __FILE__ ) , 'fixtures' , 'sync_test.rb' )
[ local , remote ] . each { | f | FileUtils . rm_rf f ; FileUtils . mkdir_p f }
# setup the folders:
# local:
# - test_a
# - test_c
# remote:
# - test_b
#
# add test_c to exludes
FileUtils . cp ( sync_test , File . join ( local , 'test_a.rb' ) )
FileUtils . cp ( sync_test , File . join ( local , 'test_c.rb' ) )
FileUtils . cp ( sync_test , File . join ( remote , 'test_b.rb' ) )
# ensure a is not on remote
assert ! File . exists? ( File . join ( remote , 'test_a.rb' ) ) , " A should not be on remote "
# ensure c is not on remote
assert ! File . exists? ( File . join ( remote , 'test_c.rb' ) ) , " C should not be on remote "
# ensure b is on remote
assert File . exists? ( File . join ( remote , 'test_b.rb' ) ) , " B should be on remote "
Hydra :: Master . new (
:files = > [ 'test_a.rb' ] ,
:workers = > [ {
:type = > :ssh ,
:connect = > 'localhost' ,
:directory = > remote ,
2010-03-25 16:15:01 +00:00
:runners = > 1
2010-02-09 20:40:35 +00:00
} ] ,
:sync = > {
:directory = > local ,
:exclude = > [ 'test_c.rb' ]
}
)
# ensure a is copied
assert File . exists? ( File . join ( remote , 'test_a.rb' ) ) , " A was not copied "
# ensure c is not copied
assert ! File . exists? ( File . join ( remote , 'test_c.rb' ) ) , " C was copied, should be excluded "
# ensure b is deleted
assert ! File . exists? ( File . join ( remote , 'test_b.rb' ) ) , " B was not deleted "
end
2010-01-29 16:45:42 +00:00
end
2011-06-01 16:45:43 +00:00
context " with a runner_end event " do
setup do
# avoid having other tests interfering with us
sleep ( 0 . 2 )
FileUtils . rm_f ( target_file )
FileUtils . rm_f ( alternate_target_file )
@worker_began_flag = File . expand_path ( File . join ( Dir . consistent_tmpdir , 'worker_began_flag' ) ) #used to know when the worker is ready
FileUtils . rm_f ( @worker_began_flag )
@runner_listener = 'HydraExtension::RunnerListener::RunnerEndTest.new' # runner_end method that creates alternate_target_file
@master_listener = HydraExtension :: Listener :: WorkerBeganFlag . new #used to know when the runner is up
end
teardown do
FileUtils . rm_f ( target_file )
FileUtils . rm_f ( alternate_target_file )
end
context " running a local worker " do
setup do
@pid = Process . fork do
Hydra :: Master . new (
:files = > [ test_file ] * 6 ,
:autosort = > false ,
:listeners = > [ @master_listener ] ,
:runner_listeners = > [ @runner_listener ] ,
:verbose = > false
)
end
end
should " run runner_end on successful termination " do
Process . waitpid @pid
assert File . exists? ( target_file )
wait_for_file_for_a_while alternate_target_file , 2
assert File . exists? alternate_target_file
end
should " run runner_end after interruption signal " do
wait_for_runner_to_begin
Process . kill 'SIGINT' , @pid
Process . waitpid @pid
wait_for_file_for_a_while alternate_target_file , 2
assert File . exists? alternate_target_file # runner_end should create this file
end
end
context " running a remote worker " do
setup do
copy_worker_init_file # this method has a protection to avoid erasing an existing worker_init_file
@pid = Process . fork do
Hydra :: Master . new (
:files = > [ test_file ] * 6 ,
:autosort = > false ,
:listeners = > [ @master_listener ] ,
:runner_listeners = > [ @runner_listener ] ,
:workers = > [ {
:type = > :ssh ,
:connect = > 'localhost' ,
:directory = > remote_dir_path ,
:runners = > 1
} ] ,
:verbose = > false
)
end
end
teardown do
FileUtils . rm_f ( @remote_init_file ) unless @protect_init_file
end
should " run runner_end on successful termination " do
Process . waitpid @pid
wait_for_file_for_a_while alternate_target_file , 2
assert File . exists? target_file
assert File . exists? alternate_target_file
end
end
end
private
# this requires that a worker_begin listener creates a file named worker_began_flag in tmp directory
def wait_for_runner_to_begin
FileUtils . rm_f ( @worker_began_flag )
wait_for_file_for_a_while @worker_began_flag , 2
assert File . exists? ( @worker_began_flag ) , " The worker didn't begin!! "
end
# with a protection to avoid erasing something important in lib
def copy_worker_init_file
@remote_init_file = " #{ remote_dir_path } / #{ File . basename ( hydra_worker_init_file ) } "
if File . exists? ( @remote_init_file )
$stderr . puts " \n WARNING!!!: #{ @remote_init_file } exits and this test needs to create a new file here. Make sure there is nothing inportant in that file and remove it before running this test \n \n "
@protect_init_file = true
exit
end
# copy the hydra_worker_init to the correct location
FileUtils . cp ( hydra_worker_init_file , remote_dir_path )
end
2010-01-29 16:45:42 +00:00
end