Merge pull request #318 from chef/chris-rock/cmp-matcher

matcher for less-restrictive comparison
This commit is contained in:
Dominik Richter 2015-12-11 17:58:47 +01:00
commit 494ed708d4
4 changed files with 83 additions and 20 deletions

View file

@ -64,7 +64,7 @@ One of the key differences is that InSpec targets more user groups. It is optimi
insecure SSHv1 connections anymore.
"
describe sshd_config do
its('Protocol') { should eq('2') }
its('Protocol') { should cmp 2 }
end
end

View file

@ -258,7 +258,7 @@ A ``auditd_conf`` |inspec resource| block declares configuration settings that s
.. code-block:: ruby
describe auditd_conf('path') do
its('keyword') { should eq 'value' }
its('keyword') { should cmp 'value' }
end
where
@ -269,11 +269,12 @@ where
Matchers
-----------------------------------------------------
This |inspec resource| matches any keyword that is listed in the ``auditd.conf`` configuration file:
This |inspec resource| matches any keyword that is listed in the ``auditd.conf`` configuration file. Since all option names and values are case insensitive for ``auditd_conf``, we recommend to compare values with `cmp` instead of the `eq`:
.. code-block:: ruby
its('log_format') { should eq 'raw' }
its('log_format') { should cmp 'raw' }
its('max_log_file') { should cmp 6 }
Examples
-----------------------------------------------------
@ -284,20 +285,20 @@ The following examples show how to use this InSpec audit resource.
.. code-block:: ruby
describe auditd_conf do
its('log_file') { should eq '/full/path/to/file' }
its('log_format') { should eq 'raw' }
its('flush') { should eq 'none' }
its('freq') { should eq '1' }
its('num_logs') { should eq '0' }
its('max_log_file') { should eq '6' }
its('max_log_file_action') { should eq 'email' }
its('space_left') { should eq '2' }
its('action_mail_acct') { should eq 'root' }
its('space_left_action') { should eq 'email' }
its('admin_space_left') { should eq '1' }
its('admin_space_left_action') { should eq 'halt' }
its('disk_full_action') { should eq 'halt' }
its('disk_error_action') { should eq 'halt' }
its('log_file') { should cmp '/full/path/to/file' }
its('log_format') { should cmp 'raw' }
its('flush') { should cmp 'none' }
its('freq') { should cmp 1 }
its('num_logs') { should cmp 0 }
its('max_log_file') { should cmp 6 }
its('max_log_file_action') { should cmp 'email' }
its('space_left') { should cmp 2 }
its('action_mail_acct') { should cmp 'root' }
its('space_left_action') { should cmp 'email' }
its('admin_space_left') { should cmp 1 }
its('admin_space_left_action') { should cmp 'halt' }
its('disk_full_action') { should cmp 'halt' }
its('disk_error_action') { should cmp 'halt' }
end
@ -3910,7 +3911,7 @@ The following examples show how to use this InSpec audit resource.
.. code-block:: ruby
describe sshd_config do
its('Protocol') { should eq '2' }
its('Protocol') { should cmp 2 }
end
**Test ciphers**
@ -3926,7 +3927,7 @@ The following examples show how to use this InSpec audit resource.
.. code-block:: ruby
describe sshd_config do
its('Port') { should eq '22' }
its('Port') { should cmp 22 }
its('UsePAM') { should eq 'yes' }
its('ListenAddress') { should eq nil }
its('HostKey') { should eq [

View file

@ -219,3 +219,46 @@ RSpec::Matchers.define :contain do |_rule|
fail "[UNSUPPORTED] `contain` matcher. Please use the following syntax `its('content') { should match('value') }`."
end
end
# This matcher implements a compare feature that cannot be covered by the default
# `eq` matcher
# You can use it in the following cases:
# - compare strings case-insensitive
# - you expect a number (strings will be converted if possible)
#
RSpec::Matchers.define :cmp do |expected|
def integer?(value)
return true if value =~ /\A\d+\Z/
false
end
def float?(value)
return true if Float(value)
false
rescue ArgumentError => _ex
false
end
match do |actual|
# if actual and expected are strings
if actual.is_a?(String) && expected.is_a?(String)
actual.casecmp(expected) == 0
elsif expected.is_a?(Integer) && integer?(actual)
expected == actual.to_i
elsif expected.is_a?(Float) && float?(actual)
expected == actual.to_f
# fallback to equal
else
actual == expected
end
end
failure_message do |actual|
"\nexpected: #{expected}\n got: #{actual}\n\n(compared using `cmp` matcher)\n"
end
failure_message_when_negated do |actual|
"\nexpected: value != #{expected}\n got: #{actual}\n\n(compared using `cmp` matcher)\n"
end
end

View file

@ -0,0 +1,19 @@
# encoding: utf-8
# uses the `cmp` matcher instead of the eq matcher
describe sshd_config do
its('Port') { should eq '22' }
its('Port') { should_not eq 22 }
its('Port') { should cmp '22' }
its('Port') { should cmp 22 }
its('Port') { should cmp 22.0 }
its('Port') { should_not cmp 22.1 }
its('LogLevel') { should eq 'INFO' }
its('LogLevel') { should_not eq 'info'}
its('LogLevel') { should cmp 'INFO' }
its('LogLevel') { should cmp 'info' }
its('LogLevel') { should cmp 'InfO' }
end