Given a checker script deployed to my server at path /tmp/foo
with the following content...
#!/bin/bash
a=`cat /tmp/a`
b=`cat /tmp/b`
echo -n $( expr $a - $b )
...I have an InSpec test to evaluate if the difference between a and b are within an acceptable range.
describe command('/tmp/foo') do
its('stdout') { should be >= 0 }
its('stdout') { should be < 120 }
end
Sadly, the be
matcher won't coerce the input to a type that can be used with the math operators.
How can I coerce this value to an integer?
So far I've tried
('stdout').to_i
undefined method `to_i' for #<Class:0x00007f8a86b91f00> (NoMethodError) Did you mean? to_s
('stdout').to_s
and ('stdout').to_s.to_i
Command: `/tmp/foo`
↺
↺
Test Summary: 0 successful, 0 failures, 2 skipped
(('stdout').to_i)
undefined method `0' for Command: `/tmp/foo`:#<Class:0x00007f9a52b912e0>
For background, /tmp/a
and /tmp/b
are a pair of epoch outputs from a previous InSpec test.
I could check client side if the values are within the acceptable range, but if possible I would like to have this variance checked & reported by the InSpec evaluation without regex wizardry in place of human-readable math expression.
Credit to @bodumin
in the chef community slack #InSpec channel
Fuzzy typing with
cmp
matching
The simplest solution is to use the cmp
matcher instead of the be
matcher. While there are no explicit math operators given by example on [the official docs for cmp
], math operations within a cmp
match will evaluate properly
describe command('/tmp/foo') do
its('stdout') { should cmp >= 0 }
its('stdout') { should cmp < 120 }
end
Per @aaronlippold
cmp
is a logical compare that we do in the backend … aka 1 is true is TRUE is True. So in SSHD config as an example … you can set a prop using 1 or true or TRUE or True etc. Its a more forgiving matcher that we have built as much as a convince function etc.