diff --git a/lib/producer/core/remote.rb b/lib/producer/core/remote.rb index 579c2b2..aa14a10 100644 --- a/lib/producer/core/remote.rb +++ b/lib/producer/core/remote.rb @@ -13,6 +13,15 @@ module Producer def session @session ||= Net::SSH.start(@hostname, Etc.getlogin) end + + def execute(command) + output = '' + session.exec command do |ch, stream, data| + output << data + end + session.loop + output + end end end end diff --git a/spec/producer/core/remote_spec.rb b/spec/producer/core/remote_spec.rb index 0856d96..5f8d6c3 100644 --- a/spec/producer/core/remote_spec.rb +++ b/spec/producer/core/remote_spec.rb @@ -2,6 +2,9 @@ require 'spec_helper' module Producer::Core describe Remote do + require 'net/ssh/test' + include Net::SSH::Test + let(:hostname) { 'some_host.example' } subject(:remote) { Remote.new(hostname) } @@ -28,5 +31,45 @@ module Producer::Core expect(remote.session).to be remote.session end end + + describe '#execute' do + let(:args) { 'some remote command'} + let(:command) { "echo #{args}" } + + # FIXME: refactor this with helpers, expectations and/or matchers. + def with_new_channel_story + story do |session| + ch = session.opens_channel + yield ch + ch.gets_close + ch.sends_close + end + end + + def story_completed? + socket.script.events.empty? + end + + before do + allow(remote).to receive(:session) { connection } + end + + it 'executes the given command in a new channel' do + with_new_channel_story do |ch| + ch.sends_exec command + ch.gets_data args + end + remote.execute command + expect(story_completed?).to be + end + + it 'returns the output' do + with_new_channel_story do |ch| + ch.sends_exec command + ch.gets_data args + end + expect(remote.execute(command)).to eq args + end + end end end