added ssh library
This commit is contained in:
parent
72b15af79f
commit
8c0359ed4c
4
Rakefile
4
Rakefile
|
@ -11,7 +11,7 @@ begin
|
|||
gem.homepage = "http://github.com/ngauthier/hydra"
|
||||
gem.authors = ["Nick Gauthier"]
|
||||
gem.add_development_dependency "shoulda", "= 2.10.3"
|
||||
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
||||
gem.add_dependency "net-ssh", "= 2.0.19"
|
||||
end
|
||||
Jeweler::GemcutterTasks.new
|
||||
rescue LoadError
|
||||
|
@ -34,7 +34,7 @@ begin
|
|||
end
|
||||
rescue LoadError
|
||||
task :rcov do
|
||||
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
||||
abort "RCov is not available. In order to run rcov, you must: gem install rcov"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# Generated by jeweler
|
||||
# DO NOT EDIT THIS FILE DIRECTLY
|
||||
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = %q{hydra}
|
||||
s.version = "0.0.0"
|
||||
|
||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||
s.authors = ["Nick Gauthier"]
|
||||
s.date = %q{2010-01-26}
|
||||
s.description = %q{TODO: longer description of your gem}
|
||||
s.email = %q{nick@smartlogicsolutions.com}
|
||||
s.extra_rdoc_files = [
|
||||
"LICENSE",
|
||||
"README.rdoc"
|
||||
]
|
||||
s.files = [
|
||||
".document",
|
||||
".gitignore",
|
||||
"LICENSE",
|
||||
"README.rdoc",
|
||||
"Rakefile",
|
||||
"VERSION",
|
||||
"lib/hydra.rb",
|
||||
"lib/hydra/pipe.rb",
|
||||
"lib/hydra/ssh.rb",
|
||||
"test/echo_the_dolphin.rb",
|
||||
"test/helper.rb",
|
||||
"test/test_pipe.rb",
|
||||
"test/test_ssh.rb"
|
||||
]
|
||||
s.homepage = %q{http://github.com/ngauthier/hydra}
|
||||
s.rdoc_options = ["--charset=UTF-8"]
|
||||
s.require_paths = ["lib"]
|
||||
s.rubygems_version = %q{1.3.5}
|
||||
s.summary = %q{Distributed testing toolkit}
|
||||
s.test_files = [
|
||||
"test/test_ssh.rb",
|
||||
"test/helper.rb",
|
||||
"test/test_pipe.rb",
|
||||
"test/echo_the_dolphin.rb"
|
||||
]
|
||||
|
||||
if s.respond_to? :specification_version then
|
||||
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
||||
s.specification_version = 3
|
||||
|
||||
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
||||
s.add_development_dependency(%q<shoulda>, ["= 2.10.3"])
|
||||
s.add_runtime_dependency(%q<net-ssh>, ["= 2.0.19"])
|
||||
else
|
||||
s.add_dependency(%q<shoulda>, ["= 2.10.3"])
|
||||
s.add_dependency(%q<net-ssh>, ["= 2.0.19"])
|
||||
end
|
||||
else
|
||||
s.add_dependency(%q<shoulda>, ["= 2.10.3"])
|
||||
s.add_dependency(%q<net-ssh>, ["= 2.0.19"])
|
||||
end
|
||||
end
|
||||
|
|
@ -1 +1,2 @@
|
|||
require 'hydra/pipe'
|
||||
require 'hydra/ssh'
|
||||
|
|
|
@ -16,8 +16,13 @@ module Hydra #:nodoc:
|
|||
#
|
||||
# A pipe is actually two pipes:
|
||||
#
|
||||
# Parent === Pipe 1 ==> Child
|
||||
# Parent <== Pipe 2 === Child
|
||||
# Parent == Pipe 1 ==> Child
|
||||
# Parent <== Pipe 2 == Child
|
||||
#
|
||||
# It's like if you had two cardboard tubes and you were using
|
||||
# them to drop balls with messages in them between processes.
|
||||
# One tube is for sending from parent to child, and the other
|
||||
# tube is for sending from child to parent.
|
||||
class Pipe
|
||||
# Creates a new uninitialized pipe pair.
|
||||
def initialize
|
||||
|
@ -43,15 +48,6 @@ module Hydra #:nodoc:
|
|||
end
|
||||
end
|
||||
|
||||
# Returns true if there is nothing to read (right now). However it is
|
||||
# not exactly eof, if the other side writes, this will return false.
|
||||
#
|
||||
# It's a good way to tell if there is anything to process right now,
|
||||
# otherwise, you can sleep.
|
||||
def eof?
|
||||
@reader.eof?
|
||||
end
|
||||
|
||||
# Identify this side of the pipe as the child.
|
||||
def identify_as_child
|
||||
@parent_write.close
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
require 'open3'
|
||||
module Hydra #:nodoc:
|
||||
# Read and write with an ssh connection. For example:
|
||||
# @ssh = Hydra::SSH.new('nick@nite')
|
||||
# @ssh.write("echo hi")
|
||||
# puts @ssh.gets
|
||||
# => hi
|
||||
#
|
||||
# You can also use this to launch an interactive process. For
|
||||
# example:
|
||||
# @ssh = Hydra::SSH.new('nick@nite')
|
||||
# @ssh.write('irb')
|
||||
# @ssh.write("5+3")
|
||||
# @ssh.gets
|
||||
# => "5+3\n" # because irb echoes commands
|
||||
# @ssh.gets
|
||||
# => "8" # the output from irb
|
||||
class SSH
|
||||
include Open3
|
||||
|
||||
# Initialize new SSH connection. The single parameters is passed
|
||||
# directly to ssh for starting a connection. So you can do:
|
||||
# Hydra::SSH.new('localhost')
|
||||
# Hydra::SSH.new('user@server.com')
|
||||
# Hydra::SSH.new('-p 3022 user@server.com')
|
||||
# etc..
|
||||
def initialize(connection_options)
|
||||
@stdin, @stdout, @stderr = popen3("ssh #{connection_options}")
|
||||
end
|
||||
|
||||
# Write a string to ssh. This method returns the string passed to
|
||||
# ssh. Note that if you do not add a newline at the end, it adds
|
||||
# one for you, and the modified string is returned
|
||||
def write(str)
|
||||
unless str =~ /\n$/
|
||||
str += "\n"
|
||||
end
|
||||
@stdin.write(str)
|
||||
return str
|
||||
end
|
||||
|
||||
# Read a line from ssh. This call blocks when there is nothing
|
||||
# to read.
|
||||
def gets
|
||||
@stdout.gets.chomp
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env ruby
|
||||
# read lines from stdin
|
||||
# echo each line back
|
||||
# on EOF, quit nicely
|
||||
|
||||
$stdout.sync = true
|
||||
|
||||
while line = $stdin.gets
|
||||
$stdout.write(line)
|
||||
end
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
require 'helper'
|
||||
require File.join(File.dirname(__FILE__), 'helper')
|
||||
|
||||
class TestPipeDream < Test::Unit::TestCase
|
||||
class TestPipe < Test::Unit::TestCase
|
||||
context "a pipe" do
|
||||
setup do
|
||||
@pipe = Hydra::Pipe.new
|
||||
|
@ -16,9 +16,7 @@ class TestPipeDream < Test::Unit::TestCase
|
|||
@pipe.identify_as_parent
|
||||
@pipe.write "Test Message\n"
|
||||
assert_equal "Message Received\n", @pipe.gets
|
||||
assert !@pipe.eof?
|
||||
assert_equal "Second Message\n", @pipe.gets
|
||||
assert @pipe.eof?
|
||||
assert_raise Hydra::PipeError::Broken do
|
||||
@pipe.write "anybody home?"
|
||||
end
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
require File.join(File.dirname(__FILE__), 'helper')
|
||||
|
||||
class TestSSH < Test::Unit::TestCase
|
||||
context "an ssh connection" do
|
||||
setup do
|
||||
@ssh = Hydra::SSH.new('localhost')
|
||||
end
|
||||
should "be able to execute a command" do
|
||||
@ssh.write "echo hi"
|
||||
assert_equal "hi", @ssh.gets
|
||||
end
|
||||
should "be able to execute a command with a newline" do
|
||||
@ssh.write "echo hi\n"
|
||||
assert_equal "hi", @ssh.gets
|
||||
end
|
||||
should "be able to communicate with a process" do
|
||||
pwd = File.dirname(__FILE__)
|
||||
echo_the_dolphin = File.expand_path(
|
||||
File.join(File.dirname(__FILE__), 'echo_the_dolphin.rb')
|
||||
)
|
||||
@ssh.write('ruby -e "puts \'Hello\'"')
|
||||
assert_equal "Hello", @ssh.gets
|
||||
|
||||
@ssh.write("ruby #{echo_the_dolphin}")
|
||||
@ssh.write("Hello Echo!")
|
||||
assert_equal "Hello Echo!", @ssh.gets
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue