spec/cli/helpers_spec.rb in backup-3.0.23 vs spec/cli/helpers_spec.rb in backup-3.0.24
- old
+ new
@@ -4,59 +4,194 @@
describe Backup::CLI::Helpers do
let(:helpers) { Module.new.extend(Backup::CLI::Helpers) }
describe '#run' do
- let(:stdin) { mock }
- let(:stdout) { mock }
- let(:stderr) { mock }
- let(:process_status) { mock }
+ let(:stdout_io) { stub(:read => stdout_messages) }
+ let(:stderr_io) { stub(:read => stderr_messages) }
+ let(:stdin_io) { stub(:close) }
+ let(:process_status) { stub(:success? => process_success) }
+ let(:command) { '/path/to/cmd_name arg1 arg2' }
- it 'should run the given command using POpen4' do
- Open4.expects(:popen4).with('/path/to/command args').
- returns([123, stdin, stdout, stderr])
- Process.expects(:waitpid2).with(123).returns([123, process_status])
- stdout.expects(:read).returns('stdout message')
- stderr.expects(:read).returns('stderr message')
+ context 'when the command is successful' do
+ let(:process_success) { true }
- helpers.expects(:command_name).with('/path/to/command args').
- returns('command')
- helpers.expects(:raise_if_command_failed!).with(
- 'command',
- {:status => process_status,
- :stdout => 'stdout message',
- :stderr => 'stderr message',
- :ignore_exit_codes => [0]}
- )
+ before do
+ Backup::Logger.expects(:message).with(
+ "Running system utility 'cmd_name'..."
+ )
- helpers.run('/path/to/command args').should == 'stdout message'
- end
+ Open4.expects(:popen4).with(command).yields(
+ nil, stdin_io, stdout_io, stderr_io
+ ).returns(process_status)
+ end
- it 'should accept ignore_exit_codes and add 0 to the list' do
- Open4.expects(:popen4).with('/path/to/command args').
- returns([123, stdin, stdout, stderr])
- Process.expects(:waitpid2).with(123).returns([123, process_status])
- stdout.expects(:read).returns('stdout message')
- stderr.expects(:read).returns('stderr message')
+ context 'and generates no messages' do
+ let(:stdout_messages) { '' }
+ let(:stderr_messages) { '' }
- helpers.expects(:command_name).with('/path/to/command args').
- returns('command')
- helpers.expects(:raise_if_command_failed!).with(
- 'command',
- {:status => process_status,
- :stdout => 'stdout message',
- :stderr => 'stderr message',
- :ignore_exit_codes => [1, 2, 0]}
- )
+ it 'should generate no additional log messages' do
+ helpers.run(command).should be_nil
+ end
+ end
- helpers.run(
- '/path/to/command args', :ignore_exit_codes => [1, 2]
- ).should == 'stdout message'
- end
- end
+ context 'and generates only stdout messages' do
+ let(:stdout_messages) { "out line1\nout line2\n" }
+ let(:stderr_messages) { '' }
+ it 'should log the stdout messages' do
+ Backup::Logger.expects(:message).with(
+ "cmd_name:STDOUT: out line1\ncmd_name:STDOUT: out line2"
+ )
+ helpers.run(command).should be_nil
+ end
+ end
+
+ context 'and generates only stderr messages' do
+ let(:stdout_messages) { '' }
+ let(:stderr_messages) { "err line1\nerr line2\n" }
+
+ it 'should log the stderr messages' do
+ Backup::Logger.expects(:warn).with(
+ "cmd_name:STDERR: err line1\ncmd_name:STDERR: err line2"
+ )
+ helpers.run(command).should be_nil
+ end
+ end
+
+ context 'and generates messages on both stdout and stderr' do
+ let(:stdout_messages) { "out line1\nout line2\n" }
+ let(:stderr_messages) { "err line1\nerr line2\n" }
+
+ it 'should log both stdout and stderr messages' do
+ Backup::Logger.expects(:message).with(
+ "cmd_name:STDOUT: out line1\ncmd_name:STDOUT: out line2"
+ )
+ Backup::Logger.expects(:warn).with(
+ "cmd_name:STDERR: err line1\ncmd_name:STDERR: err line2"
+ )
+ helpers.run(command).should be_nil
+ end
+ end
+ end # context 'when the command is successful'
+
+ context 'when the command is not successful' do
+ let(:process_success) { false }
+ let(:message_head) do
+ "CLI::SystemCallError: 'cmd_name' Failed on #{ RUBY_PLATFORM }\n" +
+ " The following information should help to determine the problem:\n" +
+ " Command was: /path/to/cmd_name arg1 arg2\n" +
+ " Exit Status: 1\n"
+ end
+
+ before do
+ Backup::Logger.expects(:message).with(
+ "Running system utility 'cmd_name'..."
+ )
+
+ Open4.expects(:popen4).with(command).yields(
+ nil, stdin_io, stdout_io, stderr_io
+ ).returns(process_status)
+
+ process_status.stubs(:exitstatus).returns(1)
+ end
+
+ context 'and generates no messages' do
+ let(:stdout_messages) { '' }
+ let(:stderr_messages) { '' }
+
+ it 'should raise an error reporting no messages' do
+ expect do
+ helpers.run(command)
+ end.to raise_error {|err|
+ err.message.should == message_head +
+ " STDOUT Messages: None\n" +
+ " STDERR Messages: None"
+ }
+ end
+ end
+
+ context 'and generates only stdout messages' do
+ let(:stdout_messages) { "out line1\nout line2\n" }
+ let(:stderr_messages) { '' }
+
+ it 'should raise an error and report the stdout messages' do
+ expect do
+ helpers.run(command)
+ end.to raise_error {|err|
+ err.message.should == message_head +
+ " STDOUT Messages: \n" +
+ " out line1\n" +
+ " out line2\n" +
+ " STDERR Messages: None"
+ }
+ end
+ end
+
+ context 'and generates only stderr messages' do
+ let(:stdout_messages) { '' }
+ let(:stderr_messages) { "err line1\nerr line2\n" }
+
+ it 'should raise an error and report the stderr messages' do
+ expect do
+ helpers.run(command)
+ end.to raise_error {|err|
+ err.message.should == message_head +
+ " STDOUT Messages: None\n" +
+ " STDERR Messages: \n" +
+ " err line1\n" +
+ " err line2"
+ }
+ end
+ end
+
+ context 'and generates messages on both stdout and stderr' do
+ let(:stdout_messages) { "out line1\nout line2\n" }
+ let(:stderr_messages) { "err line1\nerr line2\n" }
+
+ it 'should raise an error and report the stdout and stderr messages' do
+ expect do
+ helpers.run(command)
+ end.to raise_error {|err|
+ err.message.should == message_head +
+ " STDOUT Messages: \n" +
+ " out line1\n" +
+ " out line2\n" +
+ " STDERR Messages: \n" +
+ " err line1\n" +
+ " err line2"
+ }
+ end
+ end
+ end # context 'when the command is not successful'
+
+ context 'when the system fails to execute the command' do
+ before do
+ Backup::Logger.expects(:message).with(
+ "Running system utility 'cmd_name'..."
+ )
+
+ Open4.expects(:popen4).raises("exec call failed")
+ end
+
+ it 'should raise an error wrapping the system error raised' do
+ expect do
+ helpers.run(command)
+ end.to raise_error {|err|
+ err.message.should == "CLI::SystemCallError: " +
+ "Failed to execute system command on #{ RUBY_PLATFORM }\n" +
+ " Command was: /path/to/cmd_name arg1 arg2\n" +
+ " Reason: RuntimeError\n" +
+ " exec call failed"
+ }
+ end
+ end # context 'when the system fails to execute the command'
+ end # describe '#run'
+
describe '#utility' do
+ after { Backup::CLI::Helpers::UTILITY.clear }
+
context 'when a system path for the utility is available' do
it 'should return the system path with newline removed' do
helpers.expects(:`).with('which foo 2>/dev/null').returns("system_path\n")
helpers.utility(:foo).should == 'system_path'
end
@@ -77,38 +212,55 @@
Class.new.extend(Backup::CLI::Helpers).utility(:once_only).
should == 'cached_path'
end
end
-
context 'when a system path for the utility is not available' do
it 'should raise an error' do
helpers.expects(:`).with('which unknown 2>/dev/null').returns("\n")
expect do
helpers.utility(:unknown)
end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
- err.message.should match(/Path to 'unknown' could not be found/)
+ err.message.should match(/Could not locate 'unknown'/)
}
end
it 'should not cache any value for the utility' do
helpers.expects(:`).with('which not_cached 2>/dev/null').twice.returns("\n")
expect do
helpers.utility(:not_cached)
end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
- err.message.should match(/Path to 'not_cached' could not be found/)
+ err.message.should match(/Could not locate 'not_cached'/)
}
expect do
helpers.utility(:not_cached)
end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
- err.message.should match(/Path to 'not_cached' could not be found/)
+ err.message.should match(/Could not locate 'not_cached'/)
}
end
end
+
+ it 'should raise an error if name is nil' do
+ expect do
+ helpers.utility(nil)
+ end.to raise_error(
+ Backup::Errors::CLI::UtilityNotFoundError,
+ 'CLI::UtilityNotFoundError: Utility Name Empty'
+ )
+ end
+
+ it 'should raise an error if name is empty' do
+ expect do
+ helpers.utility(' ')
+ end.to raise_error(
+ Backup::Errors::CLI::UtilityNotFoundError,
+ 'CLI::UtilityNotFoundError: Utility Name Empty'
+ )
+ end
end # describe '#utility'
describe '#command_name' do
context 'given a command line path with no arguments' do
it 'should return the base command name' do
@@ -143,34 +295,7 @@
cmd = 'command'
helpers.command_name(cmd).should == 'command'
end
end
end # describe '#command_name'
-
- describe '#raise_if_command_failed!' do
-
- it 'returns nil if status exit code is in ignore_exit_codes' do
- process_data = { :status => '3', :ignore_exit_codes => [1,3,5] }
- helpers.raise_if_command_failed!('foo', process_data).should be_nil
- end
-
- it 'raises an error with stdout/stderr data' do
- process_data = { :status => '3', :ignore_exit_codes => [2,4,6],
- :stdout => 'stdout data', :stderr => 'stderr data' }
-
- expect do
- helpers.raise_if_command_failed!('utility_name', process_data)
- end.to raise_error(
- Backup::Errors::CLI::SystemCallError,
- "CLI::SystemCallError: Failed to run utility_name on #{RUBY_PLATFORM}\n" +
- " The following information should help to determine the problem:\n" +
- " Exit Code: 3\n" +
- " STDERR:\n" +
- " stderr data\n" +
- " STDOUT:\n" +
- " stdout data"
- )
- end
-
- end
end