spec/symphony/tasks/sshscript_spec.rb
changeset 4 3972315383b3
child 11 ffa70066522c
equal deleted inserted replaced
3:62196065e9ea 4:3972315383b3
       
     1 
       
     2 require_relative '../../helpers'
       
     3 require 'symphony/tasks/sshscript'
       
     4 
       
     5 context Symphony::Task::SSHScript do
       
     6 
       
     7 	before( :each ) do
       
     8 		described_class.configure(
       
     9 			key:  '/tmp/sekrit.rsa',
       
    10 			user: 'symphony'
       
    11 		)
       
    12 	end
       
    13 
       
    14 	it_should_behave_like "an object with Configurability"
       
    15 
       
    16 	describe 'subclassed' do
       
    17 		let( :instance ) { Class.new(described_class).new('queue') }
       
    18 		let( :payload ) {
       
    19 			{ 'template' => 'script', 'host' => 'example.com' }
       
    20 		}
       
    21 		let( :opts ) {
       
    22 			opts = described_class::DEFAULT_SSH_OPTIONS
       
    23 			opts.merge!(
       
    24 				:port    => 22,
       
    25 				:keys    => ['/tmp/sekrit.rsa']
       
    26 			)
       
    27 			opts
       
    28 		}
       
    29 		let( :template ) { Inversion::Template.new("Hi there, <?attr name?>!") }
       
    30 
       
    31 		before( :each ) do
       
    32 			allow( Inversion::Template ).to receive( :load ).and_return( template )
       
    33 			allow( Dir::Tmpname ).to receive( :make_tmpname ).and_return( "script_temp" )
       
    34 		end
       
    35 
       
    36 		it "aborts if there is no template in the payload" do
       
    37 			expect {
       
    38 				instance.work( {}, {} )
       
    39 			}.to raise_exception( ArgumentError, /missing required option 'template'/i )
       
    40 		end
       
    41 
       
    42 		it "aborts if there is no host in the payload" do
       
    43 			expect {
       
    44 				instance.work({ 'template' => 'boop' }, {} )
       
    45 			}.to raise_exception( ArgumentError, /missing required option 'host'/i )
       
    46 		end
       
    47 
       
    48 		it "adds debugging output if specified in the payload" do
       
    49 			payload[ 'debug' ] = true
       
    50 
       
    51 			options = opts.dup
       
    52 			options.merge!(
       
    53 				:logger  => Loggability[ Net::SSH ],
       
    54 				:verbose => :debug
       
    55 			)
       
    56 
       
    57 			expect( Net::SSH ).to receive( :start ).with( 'example.com', 'symphony', options )
       
    58 			instance.work( payload, {} )
       
    59 		end
       
    60 
       
    61 		it "attaches attributes to the scripts from the payload" do
       
    62 			payload[ 'attributes' ] = { :name => 'Handsome' }
       
    63 
       
    64 			conn = double( :ssh_connection )
       
    65 			expect( instance ).to receive( :upload_script ).
       
    66 				with( conn, "Hi there, Handsome!", "/tmp/script_temp" )
       
    67 			expect( conn ).to receive( :exec! ).with( "/tmp/script_temp" )
       
    68 			expect( conn ).to receive( :exec! ).with( "rm /tmp/script_temp" )
       
    69 
       
    70 			expect( Net::SSH ).to receive( :start ).
       
    71 				with( 'example.com', 'symphony', opts ).and_yield( conn )
       
    72 
       
    73 			instance.work( payload, {} )
       
    74 		end
       
    75 
       
    76 		it "uploads the file and sets it executable" do
       
    77 			conn = double( :ssh_connection )
       
    78 			sftp = double( :sftp_connection )
       
    79 			file = double( :remote_file_obj )
       
    80 			fh   = double( :remote_filehandle )
       
    81 
       
    82 			expect( conn ).to receive( :sftp ).and_return( sftp )
       
    83 			expect( sftp ).to receive( :file ).and_return( file )
       
    84 
       
    85 			expect( file ).to receive( :open ).
       
    86 				with( "/tmp/script_temp", "w", 0755 ).and_yield( fh )
       
    87 			expect( fh ).to receive( :print ).with( "Hi there, !" )
       
    88 
       
    89 			expect( conn ).to receive( :exec! ).with( "/tmp/script_temp" )
       
    90 			expect( conn ).to receive( :exec! ).with( "rm /tmp/script_temp" )
       
    91 
       
    92 			expect( Net::SSH ).to receive( :start ).
       
    93 				with( 'example.com', 'symphony', opts ).and_yield( conn )
       
    94 
       
    95 			instance.work( payload, {} )
       
    96 		end
       
    97 
       
    98 		it "leaves the remote script in place if asked" do
       
    99 			payload[ 'nocleanup' ] = true
       
   100 
       
   101 			conn = double( :ssh_connection )
       
   102 			expect( instance ).to receive( :upload_script ).
       
   103 				with( conn, "Hi there, !", "/tmp/script_temp" )
       
   104 			expect( conn ).to receive( :exec! ).with( "/tmp/script_temp" )
       
   105 			expect( conn ).to_not receive( :exec! ).with( "rm /tmp/script_temp" )
       
   106 
       
   107 			expect( Net::SSH ).to receive( :start ).
       
   108 				with( 'example.com', 'symphony', opts ).and_yield( conn )
       
   109 
       
   110 			instance.work( payload, {} )
       
   111 		end
       
   112 
       
   113 		it "remembers the output of the remote script" do
       
   114 			conn = double( :ssh_connection )
       
   115 			expect( instance ).to receive( :upload_script ).
       
   116 				with( conn, "Hi there, !", "/tmp/script_temp" )
       
   117 			expect( conn ).to receive( :exec! ).with( "/tmp/script_temp" ).and_return( "Hi there, !" )
       
   118 			expect( conn ).to receive( :exec! ).with( "rm /tmp/script_temp" )
       
   119 
       
   120 			expect( Net::SSH ).to receive( :start ).
       
   121 				with( 'example.com', 'symphony', opts ).and_yield( conn )
       
   122 
       
   123 			instance.work( payload, {} )
       
   124 			output = instance.instance_variable_get( :@output )
       
   125 			expect( output ).to eq( 'Hi there, !' )
       
   126 		end
       
   127 	end
       
   128 end
       
   129