Merge branch 'testing-testenv'

Integrate a test environment, helping to reduce or isolate code
dealing with net-ssh or net-sftp dependencies setup.
This commit is contained in:
Thibault Jouan 2014-03-04 23:42:15 +00:00
commit 65c727d5da
16 changed files with 147 additions and 46 deletions

View File

@ -4,10 +4,11 @@ module Producer
attr_reader :input, :output, :registry
attr_accessor :target
def initialize(input: $stdin, output: $stdout, registry: {})
def initialize(input: $stdin, output: $stdout, remote: nil, registry: {})
@input = input
@output = output
@registry = registry
@remote = remote
@target = nil
end

View File

@ -0,0 +1 @@
require 'producer/core/testing/mock_remote'

View File

@ -0,0 +1,25 @@
module Producer
module Core
module Testing
class MockRemote < Remote
def session
raise 'no session for mock remote!'
end
def execute(command)
tokens = command.split
program = tokens.shift
case program
when 'echo'
tokens.join ' '
when 'true'
''
when 'false'
raise RemoteCommandExecutionError
end
end
end
end
end
end

View File

@ -2,8 +2,7 @@ require 'spec_helper'
module Producer::Core
module Actions
describe Echo do
let(:env) { Env.new(output: StringIO.new) }
describe Echo, :env do
let(:text) { 'hello' }
subject(:echo) { Echo.new(env, text) }
@ -12,7 +11,7 @@ module Producer::Core
describe '#apply' do
it 'writes the given string to env output with a record separator' do
echo.apply
expect(env.output.string).to eq "hello\n"
expect(output).to eq "hello\n"
end
end
end

View File

@ -2,8 +2,7 @@ require 'spec_helper'
module Producer::Core
module Actions
describe FileWriter do
let(:env) { Env.new }
describe FileWriter, :env do
let(:path) { 'some_path' }
let(:content) { 'some_content' }
subject(:writer) { FileWriter.new(env, path, content) }
@ -12,7 +11,7 @@ module Producer::Core
describe '#apply' do
it 'writes content to file on remote filesystem' do
expect(writer.fs).to receive(:file_write).with(path, content)
expect(remote_fs).to receive(:file_write).with(path, content)
writer.apply
end
end

View File

@ -2,8 +2,7 @@ require 'spec_helper'
module Producer::Core
module Actions
describe Mkdir do
let(:env) { Env.new }
describe Mkdir, :env do
let(:path) { 'some_path' }
subject(:mkdir) { Mkdir.new(env, path) }
@ -11,7 +10,7 @@ module Producer::Core
describe '#apply' do
it 'creates directory on remote filesystem' do
expect(mkdir.fs).to receive(:mkdir).with(path)
expect(remote_fs).to receive(:mkdir).with(path)
mkdir.apply
end
end

View File

@ -2,8 +2,7 @@ require 'spec_helper'
module Producer::Core
module Actions
describe ShellCommand do
let(:env) { Env.new(output: StringIO.new) }
describe ShellCommand, :env do
let(:command_args) { 'hello from remote host' }
let(:command) { "echo #{command_args}" }
subject(:sh) { ShellCommand.new(env, command) }
@ -12,14 +11,13 @@ module Producer::Core
describe '#apply' do
it 'executes the remote command' do
expect(sh.remote).to receive(:execute).with(command)
expect_execution(command)
sh.apply
end
it 'writes the returned output with a record separator' do
allow(sh.remote).to receive(:execute) { command_args }
sh.apply
expect(sh.output.string).to eq "#{command_args}\n"
expect(output).to eq "#{command_args}\n"
end
end
end

View File

@ -38,6 +38,15 @@ module Producer::Core
expect(env.output).to be output
end
end
context 'when remote is given as argument' do
let(:remote) { double 'remote' }
subject(:env) { described_class.new(remote: remote) }
it 'assigns the given remote' do
expect(env.remote).to be remote
end
end
end
describe '#target' do

View File

@ -0,0 +1,46 @@
require 'spec_helper'
require 'producer/core/testing'
module Producer::Core
module Testing
describe MockRemote do
subject(:remote) { MockRemote.new('some_host.example') }
it 'is a remote' do
expect(remote).to be_a Remote
end
describe '#session' do
it 'raises an error to prevent real session usage' do
expect { remote.session }.to raise_error
end
end
describe '#execute' do
context 'dummy echo command' do
let(:command) { 'echo some arguments' }
it 'returns command arguments' do
expect(remote.execute(command)).to eq 'some arguments'
end
end
context 'dummy true command' do
let(:command) { 'true' }
it 'returns an empty string' do
expect(remote.execute(command)).to eq ''
end
end
context 'dummy false command' do
let(:command) { 'false' }
it 'raises a RemoteCommandExecutionError' do
expect { remote.execute(command) }.to raise_error(RemoteCommandExecutionError)
end
end
end
end
end
end

View File

@ -2,8 +2,7 @@ require 'spec_helper'
module Producer::Core
module Tests
describe FileContains do
let(:env) { Env.new }
describe FileContains, :env do
let(:filepath) { 'some_file' }
let(:content) { 'some_content' }
subject(:test) { FileContains.new(env, filepath, content) }
@ -11,13 +10,9 @@ module Producer::Core
it_behaves_like 'test'
describe '#verify' do
let(:fs) { double 'fs' }
before { allow(test).to receive(:fs) { fs } }
context 'when file contains the content' do
before do
allow(fs)
allow(remote_fs)
.to receive(:file_read).with(filepath) { "foo#{content}bar" }
end
@ -28,7 +23,7 @@ module Producer::Core
context 'when file does not contain the content' do
before do
allow(fs).to receive(:file_read).with(filepath) { 'foo bar' }
allow(remote_fs).to receive(:file_read).with(filepath) { 'foo bar' }
end
it 'returns false' do
@ -37,7 +32,9 @@ module Producer::Core
end
context 'when file does not exist' do
before { allow(fs).to receive(:file_read).with(filepath) { nil } }
before do
allow(remote_fs).to receive(:file_read).with(filepath) { nil }
end
it 'returns false' do
expect(test.verify).to be false

View File

@ -2,24 +2,21 @@ require 'spec_helper'
module Producer::Core
module Tests
describe HasDir do
let(:env) { Env.new }
describe HasDir, :env do
let(:path) { 'some_directory' }
subject(:has_dir) { HasDir.new(env, path) }
it_behaves_like 'test'
describe '#verify', :ssh do
before { sftp_story }
describe '#verify' do
it 'delegates the call on remote FS' do
expect(env.remote.fs).to receive(:dir?).with(path)
expect(remote_fs).to receive(:dir?).with(path)
has_dir.verify
end
it 'returns the dir existence' do
existence = double 'existence'
allow(env.remote.fs).to receive(:dir?) { existence }
allow(remote_fs).to receive(:dir?) { existence }
expect(has_dir.verify).to be existence
end
end

View File

@ -2,24 +2,21 @@ require 'spec_helper'
module Producer::Core
module Tests
describe HasFile do
let(:env) { Env.new }
describe HasFile, :env do
let(:filepath) { 'some_file' }
subject(:has_file) { HasFile.new(env, filepath) }
it_behaves_like 'test'
describe '#verify', :ssh do
before { sftp_story }
describe '#verify' do
it 'delegates the call on remote FS' do
expect(env.remote.fs).to receive(:file?).with(filepath)
expect(remote_fs).to receive(:file?).with(filepath)
has_file.verify
end
it 'returns the file existence' do
existence = double 'existence'
allow(env.remote.fs).to receive(:file?) { existence }
allow(remote_fs).to receive(:file?) { existence }
expect(has_file.verify).to be existence
end
end

View File

@ -6,6 +6,8 @@ Dir['spec/support/**/*.rb'].map { |e| require e.gsub 'spec/', '' }
RSpec.configure do |c|
c.treat_symbols_as_metadata_keys_with_true_values = true
c.include TestEnvHelpers, :env
c.include NetSSHStoryHelpers, :ssh
c.before(:each, :ssh) do
allow(Net::SSH).to receive(:start) { connection }

View File

@ -1,8 +1,7 @@
module Producer::Core
shared_examples 'action' do
let(:input) { StringIO.new }
let(:output) { StringIO.new }
let(:env) { Env.new(input: input, output: output) }
include TestEnvHelpers
let(:arguments) { [:some, :arguments] }
subject(:action) { described_class.new(env, *arguments) }
@ -20,25 +19,25 @@ module Producer::Core
describe '#input' do
it 'returns env input' do
expect(action.input).to be input
expect(action.input).to be env.input
end
end
describe '#output' do
it 'returns env output' do
expect(action.output).to be output
expect(action.output).to be env.output
end
end
describe '#remote' do
it 'returns env remote' do
expect(action.remote).to be action.env.remote
expect(action.remote).to be env.remote
end
end
describe '#fs' do
it 'returns env remote fs' do
expect(action.fs).to be action.env.remote.fs
expect(action.fs).to be env.remote.fs
end
end
end

View File

@ -1,6 +1,7 @@
module Producer::Core
shared_examples 'test' do
let(:env) { Env.new }
include TestEnvHelpers
let(:arguments) { [:some, :arguments] }
subject(:test) { described_class.new(env, *arguments) }

View File

@ -0,0 +1,31 @@
module TestEnvHelpers
require 'producer/core/testing'
def env
@_env ||= build_env
end
def output
env.output.string
end
def remote_fs
env.remote.fs
end
def expect_execution(command)
opts = { expected_from: caller.first }
RSpec::Mocks.expect_message(env.remote, :execute, opts).with(command)
end
private
def build_env
Producer::Core::Env.new(output: StringIO.new, remote: build_remote)
end
def build_remote
Producer::Core::Testing::MockRemote.new('some_host.test')
end
end