Fix assert that a gem is not installed #1844
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
There are some compliance situations where we want to enforce that a gem is not installed on a system. The following spec code (which is shown in the documentation) does not pass:
I originally spotted this bug in v1.18.0 which threw the following error:
Since v1.20.0, now the test is skipped completely because the
stdout
result of the gem command is blank, which is to be expected for any gem that is not installed.The gem resource is determining if a gem is installed based on the exit status of the
gem
command, however that command will return zero if the package was found or not.InSpec and Platform Version
Inspec: v1.25.1
Platform: RedHat 7 & OS/X Sierra
Looking at the code, this appears it might apply to all platforms, assuming the return code behavior of the
gem
command doesn't differ across different platforms.Replication Case
This issue can be replicated with a simple
describe
spec:Then run:
Possible Solutions
Remove support for writing tests for gems that are not installed. The documentation for the
gem
resource currently includes a sample test which suggests that this feature should be supported. This solution would just remove that test case and add a note that this feature is no longer supported.Check the return of the
gem list --local -a -q <gemname>
stdout to see if the output contains the name of the gem. If it does then the gem is installed, otherwise the gem is not installed. This check would be added in addition to the existing check for the zero return status to ensure that the command also completed successfully. This is necessary because thegem list
command will return zero if the gem exists or not.This pull request implements the second option. One thing I wasn't sure about was what should happen if the command exit status is not zero. For the time being, I left the logic in place to trigger the
skip_resource
call in the constructor, but I think the better solution should be to raise an error. I just wasn't sure what error class to use for that.