diff --git a/lib/hydra/runner.rb b/lib/hydra/runner.rb index 696a232..dd22e1e 100644 --- a/lib/hydra/runner.rb +++ b/lib/hydra/runner.rb @@ -16,16 +16,16 @@ module Hydra #:nodoc: # Boot up a runner. It takes an IO object (generally a pipe from its # parent) to send it messages on which files to execute. def initialize(opts = {}) + redirect_output + reg_trap_sighup + @io = opts.fetch(:io) { raise "No IO Object" } @verbose = opts.fetch(:verbose) { false } @event_listeners = Array( opts.fetch( :runner_listeners ) { nil } ) $stdout.sync = true - runner_begin - reg_exit_hook - trace 'Booted. Sending Request for file' @io.write RequestFile.new begin @@ -36,18 +36,19 @@ module Hydra #:nodoc: end end + def reg_trap_sighup + trap :SIGHUP do + File.open("_log_output", 'a'){ |f| f << "SIGHUP trapped"} + stop + end + @runner_began = true + end + def runner_begin trace "Firing runner_begin event" @event_listeners.each {|l| l.runner_begin( self ) } end - def reg_exit_hook - at_exit do - # NOTE: do not use trace here - stop - end - end - # Run a test file and report the results def run_file(file) trace "Running file: #{file}" @@ -71,16 +72,19 @@ module Hydra #:nodoc: # Stop running def stop - # NOTE: do not use trace here - runner_end if @running - @running = false + runner_end if @runner_began + @runner_began = @running = false end def runner_end -# trace "Firing runner_end event" + trace "Ending runner #{self.inspect}" @event_listeners.each {|l| l.runner_end( self ) } end + def format_exception(ex) + "#{ex.class.name}: #{ex.message}\n #{ex.backtrace.join("\n ")}" + end + private # The runner will continually read messages and handle them. @@ -108,10 +112,6 @@ module Hydra #:nodoc: "Error in #{file}:\n #{format_exception(ex)}" end - def format_exception(ex) - "#{ex.class.name}: #{ex.message}\n #{ex.backtrace.join("\n ")}" - end - # Run all the Test::Unit Suites in a ruby file def run_test_unit_file(file) begin @@ -288,5 +288,11 @@ module Hydra #:nodoc: end end.compact end + + def redirect_output file_name = nil + file_name = 'log/hydra.log' if !file_name and File.exists? 'log/' + file_name = 'hydra.log' unless file_name + $stderr = $stdout = File.open(file_name, 'a') + end end end diff --git a/test/fixtures/runner_listeners.rb b/test/fixtures/runner_listeners.rb index fb4b12d..1221423 100644 --- a/test/fixtures/runner_listeners.rb +++ b/test/fixtures/runner_listeners.rb @@ -8,9 +8,14 @@ module HydraExtension end class RunnerEndTest < Hydra::RunnerListener::Abstract + # Fired by the runner just before requesting the first file + def runner_begin( runner ) + FileUtils.touch File.expand_path(File.join(Dir.consistent_tmpdir, 'runner_began_flag')) #used to know when the runner is ready + end # Fired by the runner just after stoping def runner_end( runner ) # NOTE: do not use trace here + #runner.trace "Ending runner" FileUtils.touch File.expand_path(File.join(Dir.consistent_tmpdir, 'alternate_hydra_test.txt')) end end diff --git a/test/master_test.rb b/test/master_test.rb index 2d9cc21..2881ada 100644 --- a/test/master_test.rb +++ b/test/master_test.rb @@ -188,8 +188,8 @@ class MasterTest < Test::Unit::TestCase 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_began_flag = File.expand_path(File.join(Dir.consistent_tmpdir, 'runner_began_flag')) #used to know when the worker is ready + FileUtils.rm_f(@runner_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 @@ -217,13 +217,7 @@ class MasterTest < Test::Unit::TestCase end should "run runner_end after interruption signal" do - - class << @master_listener - def worker_begin( worker ) - super - sleep 1 while true #ensure the process doesn't finish before killing it - end - end + add_infinite_worker_begin_to @master_listener capture_stderr do # redirect stderr @pid = Process.fork do @@ -248,6 +242,13 @@ class MasterTest < Test::Unit::TestCase 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 + end + + teardown do + FileUtils.rm_f(@remote_init_file) unless @protect_init_file + end + + should "run runner_end on successful termination" do capture_stderr do # redirect stderr @pid = Process.fork do Hydra::Master.new( @@ -265,13 +266,6 @@ class MasterTest < Test::Unit::TestCase ) end 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 assert_file_exists alternate_target_file @@ -280,11 +274,19 @@ class MasterTest < Test::Unit::TestCase end private + + def add_infinite_worker_begin_to master_listener + class << master_listener + def worker_begin( worker ) + super + sleep 1 while true #ensure the process doesn't finish before killing it + end + end + end + # 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) - - assert_file_exists @worker_began_flag + assert_file_exists @runner_began_flag end # with a protection to avoid erasing something important in lib diff --git a/test/runner_test.rb b/test/runner_test.rb index 3b04189..381229e 100644 --- a/test/runner_test.rb +++ b/test/runner_test.rb @@ -161,7 +161,7 @@ class RunnerTest < Test::Unit::TestCase run_the_runner(pipe, [HydraExtension::RunnerListener::RunnerEndTest.new] ) Process.wait(parent) - # ensure runner_begin was fired + # ensure runner_end was fired assert File.exists?( alternate_target_file ) end end