From 727bdcf1b7d4af2765ca705f0f10f5b7e13870e4 Mon Sep 17 00:00:00 2001 From: Nick Gauthier Date: Fri, 29 Jan 2010 17:21:48 -0500 Subject: [PATCH] midway through making ssh workers --- TODO | 5 ++++- lib/hydra.rb | 1 + lib/hydra/master.rb | 22 ++++++++++++++++++++-- lib/hydra/messaging_io.rb | 3 +++ lib/hydra/runner.rb | 1 + test/master_test.rb | 16 ++++++++++++++++ 6 files changed, 45 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 61128d2..e17c511 100644 --- a/TODO +++ b/TODO @@ -8,9 +8,12 @@ YML configuration hydra: workers: - type: local - runners: 1 + runners: 4 - type: ssh connect: localhost + directory: /path/to/suite + [command: rake hydra:worker RUNNERS=1] + runners: 4 v0.6.0 diff --git a/lib/hydra.rb b/lib/hydra.rb index 71a4c4c..fc81862 100644 --- a/lib/hydra.rb +++ b/lib/hydra.rb @@ -1,5 +1,6 @@ require 'hydra/pipe' require 'hydra/ssh' +require 'hydra/stdio' require 'hydra/message' require 'hydra/runner' require 'hydra/worker' diff --git a/lib/hydra/master.rb b/lib/hydra/master.rb index ed66c87..173aac2 100644 --- a/lib/hydra/master.rb +++ b/lib/hydra/master.rb @@ -18,11 +18,14 @@ module Hydra #:nodoc: @files = opts.fetch(:files) { [] } @workers = [] @listeners = [] + @verbose = opts.fetch(:verbose) { false } # default is one worker that is configured to use a pipe with one runner worker_cfg = opts.fetch(:workers) { [ { :type => :local, :runners => 1} ] } + $stdout.write "MASTER| Initialized\n" if @verbose + boot_workers worker_cfg process_messages end @@ -44,26 +47,41 @@ module Hydra #:nodoc: private def boot_workers(workers) + $stdout.write "MASTER| Booting workers\n" if @verbose workers.select{|worker| worker[:type] == :local}.each do |worker| + $stdout.write "MASTER| Booting local worker\n" if @verbose boot_local_worker(worker) end workers.select{|worker| worker[:type] == :ssh}.each do |worker| + $stdout.write "MASTER| Booting ssh worker\n" if @verbose boot_ssh_worker(worker) end end def boot_local_worker(worker) + runners = worker.fetch(:runners) { raise "You must specify the number of runners" } pipe = Hydra::Pipe.new child = Process.fork do pipe.identify_as_child - Hydra::Worker.new(:io => pipe, :runners => worker[:runners]) + Hydra::Worker.new(:io => pipe, :runners => runners) end pipe.identify_as_parent @workers << { :pid => child, :io => pipe, :idle => false } end def boot_ssh_worker(worker) - raise "Don't know how to boot SSH workers yet" + runners = worker.fetch(:runners) { raise "You must specify the number of runners" } + connect = worker.fetch(:connect) { raise "You must specify SSH connection options" } + directory = worker.fetch(:directory) { raise "You must specify a remote directory" } + command = worker.fetch(:command) { + "ruby -e \"require 'rubygems'; require 'hydra'; Hydra::Worker.new(:io => Hydra::Stdio.new, :runners => #{runners});\"" + } + + ssh = nil + child = Process.fork do + ssh = Hydra::SSH.new(connect, directory, command) + end + @workers << { :pid => child, :io => ssh, :idle => false } end def process_messages diff --git a/lib/hydra/messaging_io.rb b/lib/hydra/messaging_io.rb index 95e10b9..9d34dc6 100644 --- a/lib/hydra/messaging_io.rb +++ b/lib/hydra/messaging_io.rb @@ -12,6 +12,9 @@ module Hydra #:nodoc: message = @reader.gets return nil unless message return Message.build(eval(message.chomp)) + rescue SyntaxError => ex + $stderr.write "Not a message: [#{message.inspect}]\n" + return nil end # Write a Message to the output IO object. It will automatically diff --git a/lib/hydra/runner.rb b/lib/hydra/runner.rb index c39ba13..62d57c1 100644 --- a/lib/hydra/runner.rb +++ b/lib/hydra/runner.rb @@ -1,3 +1,4 @@ +require 'test/unit' module Hydra #:nodoc: # Hydra class responsible for running test files. # diff --git a/test/master_test.rb b/test/master_test.rb index d67b18f..f7a2504 100644 --- a/test/master_test.rb +++ b/test/master_test.rb @@ -58,5 +58,21 @@ class MasterTest < Test::Unit::TestCase finish = Time.now assert (finish-start) < 15, "took #{finish-start} seconds" end + + + should "run a test via ssh" do + Hydra::Master.new( + :files => [test_file], + :workers => [{ + :type => :ssh, + :connect => 'localhost', + :directory => File.expand_path(File.join(File.dirname(__FILE__), '..')), + :runners => 1 + }], + :verbose => true + ) + assert File.exists?(target_file) + assert_equal "HYDRA", File.read(target_file) + end end end