Skip to content

Commit

Permalink
Merge pull request #381 from bitglue/master
Browse files Browse the repository at this point in the history
Don't conflate stdout and stderr; run commands once
  • Loading branch information
mizzy committed Apr 4, 2014
2 parents 3bec36b + a7b0c8f commit 40554b9
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 20 deletions.
9 changes: 7 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ task :spec => 'spec:all'

namespace :spec do
oses = %w( darwin debian gentoo plamo redhat aix solaris solaris10 solaris11 smartos windows freebsd freebsd10)
backends = %w( exec ssh cmd winrm powershell )

task :all => [ oses.map {|os| "spec:#{os}" }, :exec, :ssh, :cmd, :winrm, :powershell, :helper ].flatten
task :all => [ oses.map {|os| "spec:#{os}" }, backends, :helper, :unit ].flatten

oses.each do |os|
RSpec::Core::RakeTask.new(os.to_sym) do |t|
t.pattern = "spec/#{os}/*_spec.rb"
end
end

[:exec, :ssh, :cmd, :winrm, :powershell].each do |backend|
backends.each do |backend|
RSpec::Core::RakeTask.new(backend) do |t|
t.pattern = "spec/backend/#{backend.to_s}/*_spec.rb"
end
Expand All @@ -24,4 +25,8 @@ namespace :spec do
RSpec::Core::RakeTask.new(:helper) do |t|
t.pattern = "spec/helper/*_spec.rb"
end

RSpec::Core::RakeTask.new(:unit) do |t|
t.pattern = "spec/unit/*_spec.rb"
end
end
35 changes: 17 additions & 18 deletions lib/serverspec/type/command.rb
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
module Serverspec
module Type
class Command < Base
attr_accessor :result

def return_stdout?(content)
ret = backend.run_command(@name)
if content.instance_of?(Regexp)
ret.stdout =~ content
stdout =~ content
else
ret.stdout.strip == content
stdout.strip == content
end
end

def return_stderr?(content)
ret = backend.run_command(@name)
if content.instance_of?(Regexp)
ret.stderr =~ content
stderr =~ content
else
ret.stderr.strip == content
stderr.strip == content
end
end

def return_exit_status?(status)
ret = backend.run_command(@name)
ret.exit_status.to_i == status
exit_status == status
end

def stdout
if @result.nil?
@result = backend.run_command(@name).stdout
end
@result
command_result.stdout
end

def stderr
if @result.nil?
@result = backend.run_command(@name).stderr
end
@result
command_result.stderr
end

def exit_status
command_result.exit_status.to_i
end

private

def command_result()
@command_result ||= backend.run_command(@name)
end
end
end
Expand Down
81 changes: 81 additions & 0 deletions spec/unit/command_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
require 'spec_helper'

describe Serverspec::Type::Command do
subject { command('echo banana') }

before :each do
allow(subject.backend).to receive(:run_command).and_return(
CommandResult.new({
:stdout => "banana\n",
:stderr => "split\n",
:exit_status => "42", # Command should convert this to an integer
})
)
end

it 'has stdout' do
expect(subject.stdout).to be == "banana\n"
end

it 'has stderr' do
expect(subject.stderr).to be == "split\n"
end

it 'has exit_status' do
expect(subject.exit_status).to be == 42
end

it 'does not conflate stdout and stderr' do
expect(subject.stdout).to eq("banana\n")
expect(subject.stderr).to eq("split\n")
end

it 'runs the command lazily' do
expect(subject.backend).to receive(:run_command).exactly(0).times

# Not sending any messages to the subject.
end

it 'does not run the command more than once' do
expect(subject.backend).to receive(:run_command).once

# We can send all these messages, but the command is invoked only once.
subject.stdout
subject.stderr
subject.exit_status
subject.return_stdout? 'foo'
subject.return_stderr? 'foo'
subject.return_exit_status? 0
end

describe '#return_stdout?' do
it 'matches against a string, stripping whitespace' do
expect(subject.return_stdout? 'banana').to be_true
expect(subject.return_stdout? 'pancake').to be_false
end

it 'matches against a regex' do
expect(subject.return_stdout? /anan/).to be_true
expect(subject.return_stdout? /^anan/).to be_false
end
end

describe '#return_stderr?' do
it 'matches against a string, stripping whitespace' do
expect(subject.return_stderr? 'split').to be_true
expect(subject.return_stderr? 'pancake').to be_false
end

it 'matches against a regex' do
expect(subject.return_stderr? /pli/).to be_true
expect(subject.return_stderr? /^pli/).to be_false
end
end

describe '#return_stderr?' do
it 'matches against an integer' do
expect(subject.return_exit_status? 42).to be_true
expect(subject.return_exit_status? 43).to be_false
end
end
end

0 comments on commit 40554b9

Please sign in to comment.