Ran chefstyle -a

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
This commit is contained in:
Clinton Wolfe 2021-05-09 23:59:04 -04:00
parent f44a909687
commit 02e8e9cc9c
26 changed files with 162 additions and 163 deletions

View file

@ -31,7 +31,7 @@ module Inspec::Fetcher
target = target.gsub(%r{^file://}, "") target = target.gsub(%r{^file://}, "")
else else
# support for windows paths # support for windows paths
target = target.tr('\\', "/") target = target.tr("\\", "/")
end end
target if File.exist?(File.expand_path(target)) target if File.exist?(File.expand_path(target))

View file

@ -58,7 +58,7 @@ module Inspec::Resources
end end
def query(q) # rubocop:disable Metrics/PerceivedComplexity def query(q) # rubocop:disable Metrics/PerceivedComplexity
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '""').gsub(/\$/, '\\$') escaped_query = q.gsub(/\\/, "\\\\").gsub(/"/, '""').gsub(/\$/, '\\$')
# surpress 'x rows affected' in SQLCMD with 'set nocount on;' # surpress 'x rows affected' in SQLCMD with 'set nocount on;'
cmd_string = "sqlcmd -Q \"set nocount on; #{escaped_query}\" -W -w 1024 -s ','" cmd_string = "sqlcmd -Q \"set nocount on; #{escaped_query}\" -W -w 1024 -s ','"
cmd_string += " -U '#{@user}' -P '#{@password}'" unless @user.nil? || @password.nil? cmd_string += " -U '#{@user}' -P '#{@password}'" unless @user.nil? || @password.nil?

View file

@ -75,7 +75,7 @@ module Inspec::Resources
def create_mysql_cmd(q, db = "") def create_mysql_cmd(q, db = "")
# TODO: simple escape, must be handled by a library # TODO: simple escape, must be handled by a library
# that does this securely # that does this securely
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$') escaped_query = q.gsub(/\\/, "\\\\").gsub(/"/, '\\"').gsub(/\$/, '\\$')
# construct the query # construct the query
command = "mysql" command = "mysql"

View file

@ -117,7 +117,7 @@ module Inspec::Resources
if defined?(windows_paths["Python"]) && pipcmd.nil? if defined?(windows_paths["Python"]) && pipcmd.nil?
return nil if windows_paths["Pip"].nil? return nil if windows_paths["Pip"].nil?
pipdir = windows_paths["Python"].split('\\') pipdir = windows_paths["Python"].split("\\")
# remove python.exe # remove python.exe
pipdir.pop pipdir.pop
pipcmd = pipdir.push("Scripts").push("pip.exe").join("/") pipcmd = pipdir.push("Scripts").push("pip.exe").join("/")

View file

@ -281,7 +281,7 @@ module Inspec::Resources
key = @options[:key] key = @options[:key]
return "" unless key return "" unless key
key.start_with?('\\') ? key : "\\#{key}" key.start_with?("\\") ? key : "\\#{key}"
end end
end end

View file

@ -611,7 +611,7 @@ module Inspec::Resources
# @see https://msdn.microsoft.com/en-us/library/aa394153(v=vs.85).aspx # @see https://msdn.microsoft.com/en-us/library/aa394153(v=vs.85).aspx
class WindowsUser < UserInfo class WindowsUser < UserInfo
def parse_windows_account(username) def parse_windows_account(username)
account = username.split('\\') account = username.split("\\")
name = account.pop name = account.pop
domain = account.pop unless account.empty? domain = account.pop unless account.empty?
[name, domain] [name, domain]

View file

@ -243,7 +243,7 @@ module Inspec
# to provide access to local profiles that add resources. # to provide access to local profiles that add resources.
@depends.each do |dep| @depends.each do |dep|
# support for windows paths # support for windows paths
dep = dep.tr('\\', "/") dep = dep.tr("\\", "/")
Inspec::Profile.for_path(dep, { profile_context: ctx }).load_libraries Inspec::Profile.for_path(dep, { profile_context: ctx }).load_libraries
end end

View file

@ -52,13 +52,13 @@ class ErlangParser < Parslet::Parser
rule(:stringS) do rule(:stringS) do
str("'") >> ( str("'") >> (
str('\\') >> any | str("'").absent? >> any str("\\") >> any | str("'").absent? >> any
).repeat.as(:string) >> str("'") >> filler? ).repeat.as(:string) >> str("'") >> filler?
end end
rule(:stringD) do rule(:stringD) do
str('"') >> ( str('"') >> (
str('\\') >> any | str('"').absent? >> any str("\\") >> any | str('"').absent? >> any
).repeat.as(:string) >> str('"') >> filler? ).repeat.as(:string) >> str('"') >> filler?
end end

View file

@ -375,13 +375,13 @@ module FilterTable
methods_to_install_on_resource_class = @filter_methods + @custom_properties.keys methods_to_install_on_resource_class = @filter_methods + @custom_properties.keys
methods_to_install_on_resource_class.each do |method_name| methods_to_install_on_resource_class.each do |method_name|
resource_class.send(:define_method, method_name) do |*args, &block| resource_class.send(:define_method, method_name) do |*args, &block|
begin
# self here is the resource instance # self here is the resource instance
filter_table_instance = table_class.new(self, send(raw_data_fetcher_method_name), " with") filter_table_instance = table_class.new(self, send(raw_data_fetcher_method_name), " with")
filter_table_instance.send(method_name, *args, &block) filter_table_instance.send(method_name, *args, &block)
rescue Inspec::Exceptions::ResourceFailed, Inspec::Exceptions::ResourceSkipped => e rescue Inspec::Exceptions::ResourceFailed, Inspec::Exceptions::ResourceSkipped => e
FilterTable::ExceptionCatcher.new(resource_class, e) FilterTable::ExceptionCatcher.new(resource_class, e)
end
end end
end end
end end

View file

@ -31,19 +31,19 @@ class NginxParser < Parslet::Parser
rule(:standard_value) do rule(:standard_value) do
((match(/[#;{'"]/).absent? >> any) >> ( ((match(/[#;{'"]/).absent? >> any) >> (
str('\\') >> any | match('[#;{]|\s').absent? >> any str("\\") >> any | match('[#;{]|\s').absent? >> any
).repeat).as(:value) >> space.repeat ).repeat).as(:value) >> space.repeat
end end
rule(:single_quoted_value) do rule(:single_quoted_value) do
str("'") >> ( str("'") >> (
str('\\') >> any | str("'").absent? >> any str("\\") >> any | str("'").absent? >> any
).repeat.as(:value) >> str("'") >> space.repeat ).repeat.as(:value) >> str("'") >> space.repeat
end end
rule(:double_quoted_value) do rule(:double_quoted_value) do
str('"') >> ( str('"') >> (
str('\\') >> any | str('"').absent? >> any str("\\") >> any | str('"').absent? >> any
).repeat.as(:value) >> str('"') >> space.repeat ).repeat.as(:value) >> str('"') >> space.repeat
end end

View file

@ -36,12 +36,12 @@ class AwsCloudTrailTrail < Inspec.resource(1)
def delivered_logs_days_ago def delivered_logs_days_ago
query = { name: @trail_name } query = { name: @trail_name }
catch_aws_errors do catch_aws_errors do
begin
resp = BackendFactory.create(inspec_runner).get_trail_status(query).to_h resp = BackendFactory.create(inspec_runner).get_trail_status(query).to_h
((Time.now - resp[:latest_cloud_watch_logs_delivery_time]) / (24 * 60 * 60)).to_i unless resp[:latest_cloud_watch_logs_delivery_time].nil? ((Time.now - resp[:latest_cloud_watch_logs_delivery_time]) / (24 * 60 * 60)).to_i unless resp[:latest_cloud_watch_logs_delivery_time].nil?
rescue Aws::CloudTrail::Errors::TrailNotFoundException rescue Aws::CloudTrail::Errors::TrailNotFoundException
nil nil
end
end end
end end

View file

@ -101,27 +101,27 @@ class AwsIamAccessKeys < Inspec.resource(1)
access_key_data = [] access_key_data = []
user_details.each_key do |username| user_details.each_key do |username|
begin
user_keys = iam_client.list_access_keys(user_name: username)
.access_key_metadata
user_keys = user_keys.map do |metadata|
{
access_key_id: metadata.access_key_id,
username: username,
status: metadata.status,
create_date: metadata.create_date, # DateTime.parse(metadata.create_date),
}
end
# Copy in from user data user_keys = iam_client.list_access_keys(user_name: username)
# Synthetics .access_key_metadata
user_keys.each do |key_info| user_keys = user_keys.map do |metadata|
add_synthetic_fields(key_info, user_details[username]) {
end access_key_id: metadata.access_key_id,
access_key_data.concat(user_keys) username: username,
rescue Aws::IAM::Errors::NoSuchEntity # rubocop:disable Lint/HandleExceptions status: metadata.status,
# Swallow - a miss on search results should return an empty table create_date: metadata.create_date, # DateTime.parse(metadata.create_date),
}
end end
# Copy in from user data
# Synthetics
user_keys.each do |key_info|
add_synthetic_fields(key_info, user_details[username])
end
access_key_data.concat(user_keys)
rescue Aws::IAM::Errors::NoSuchEntity # rubocop:disable Lint/HandleExceptions
# Swallow - a miss on search results should return an empty table
end end
access_key_data access_key_data
end end

View file

@ -20,19 +20,19 @@ class AwsIamPasswordPolicy < Inspec.resource(1)
# TODO: rewrite to avoid direct injection, match other resources, use AwsSingularResourceMixin # TODO: rewrite to avoid direct injection, match other resources, use AwsSingularResourceMixin
def initialize(conn = nil) def initialize(conn = nil)
catch_aws_errors do catch_aws_errors do
begin
if conn if conn
# We're in a mocked unit test. # We're in a mocked unit test.
@policy = conn.iam_resource.account_password_policy @policy = conn.iam_resource.account_password_policy
else else
# Don't use the resource approach. It's a CRUD operation # Don't use the resource approach. It's a CRUD operation
# - if the policy does not exist, you get back a blank object to populate and save. # - if the policy does not exist, you get back a blank object to populate and save.
# Using the Client will throw an exception if no policy exists. # Using the Client will throw an exception if no policy exists.
@policy = inspec_runner.backend.aws_client(Aws::IAM::Client).get_account_password_policy.password_policy @policy = inspec_runner.backend.aws_client(Aws::IAM::Client).get_account_password_policy.password_policy
end
rescue Aws::IAM::Errors::NoSuchEntity
@policy = nil
end end
rescue Aws::IAM::Errors::NoSuchEntity
@policy = nil
end end
end end

View file

@ -56,30 +56,30 @@ class AwsKmsKey < Inspec.resource(1)
query = { key_id: @key_id } query = { key_id: @key_id }
catch_aws_errors do catch_aws_errors do
begin
resp = backend.describe_key(query)
@exists = true resp = backend.describe_key(query)
@key = resp.key_metadata.to_h
@key_id = @key[:key_id] @exists = true
@arn = @key[:arn] @key = resp.key_metadata.to_h
@creation_date = @key[:creation_date] @key_id = @key[:key_id]
@enabled = @key[:enabled] @arn = @key[:arn]
@description = @key[:description] @creation_date = @key[:creation_date]
@key_usage = @key[:key_usage] @enabled = @key[:enabled]
@key_state = @key[:key_state] @description = @key[:description]
@deletion_date = @key[:deletion_date] @key_usage = @key[:key_usage]
@valid_to = @key[:valid_to] @key_state = @key[:key_state]
@external = @key[:origin] == "EXTERNAL" @deletion_date = @key[:deletion_date]
@has_key_expiration = @key[:expiration_model] == "KEY_MATERIAL_EXPIRES" @valid_to = @key[:valid_to]
@managed_by_aws = @key[:key_manager] == "AWS" @external = @key[:origin] == "EXTERNAL"
@has_key_expiration = @key[:expiration_model] == "KEY_MATERIAL_EXPIRES"
@managed_by_aws = @key[:key_manager] == "AWS"
resp = backend.get_key_rotation_status(query)
@has_rotation_enabled = resp.key_rotation_enabled unless resp.empty?
rescue Aws::KMS::Errors::NotFoundException
@exists = false
return
resp = backend.get_key_rotation_status(query)
@has_rotation_enabled = resp.key_rotation_enabled unless resp.empty?
rescue Aws::KMS::Errors::NotFoundException
@exists = false
return
end
end end
end end

View file

@ -43,13 +43,13 @@ class AwsRdsInstance < Inspec.resource(1)
backend = BackendFactory.create(inspec_runner) backend = BackendFactory.create(inspec_runner)
dsg_response = nil dsg_response = nil
catch_aws_errors do catch_aws_errors do
begin
dsg_response = backend.describe_db_instances(db_instance_identifier: db_instance_identifier) dsg_response = backend.describe_db_instances(db_instance_identifier: db_instance_identifier)
@exists = true @exists = true
rescue Aws::RDS::Errors::DBInstanceNotFound rescue Aws::RDS::Errors::DBInstanceNotFound
@exists = false @exists = false
return return
end
end end
if dsg_response.db_instances.empty? if dsg_response.db_instances.empty?

View file

@ -85,30 +85,29 @@ class AwsS3Bucket < Inspec.resource(1)
def fetch_bucket_policy def fetch_bucket_policy
backend = BackendFactory.create(inspec_runner) backend = BackendFactory.create(inspec_runner)
catch_aws_errors do catch_aws_errors do
begin
# AWS SDK returns a StringIO, we have to read() # AWS SDK returns a StringIO, we have to read()
raw_policy = backend.get_bucket_policy(bucket: bucket_name).policy raw_policy = backend.get_bucket_policy(bucket: bucket_name).policy
return JSON.parse(raw_policy.read)["Statement"].map do |statement| return JSON.parse(raw_policy.read)["Statement"].map do |statement|
lowercase_hash = {} lowercase_hash = {}
statement.each_key { |k| lowercase_hash[k.downcase] = statement[k] } statement.each_key { |k| lowercase_hash[k.downcase] = statement[k] }
@bucket_policy = OpenStruct.new(lowercase_hash) @bucket_policy = OpenStruct.new(lowercase_hash)
end
rescue Aws::S3::Errors::NoSuchBucketPolicy
@bucket_policy = []
end end
rescue Aws::S3::Errors::NoSuchBucketPolicy
@bucket_policy = []
end end
end end
def fetch_bucket_encryption_configuration def fetch_bucket_encryption_configuration
@has_default_encryption_enabled ||= catch_aws_errors do @has_default_encryption_enabled ||= catch_aws_errors do
begin !BackendFactory.create(inspec_runner)
!BackendFactory.create(inspec_runner) .get_bucket_encryption(bucket: bucket_name)
.get_bucket_encryption(bucket: bucket_name) .server_side_encryption_configuration
.server_side_encryption_configuration .nil?
.nil? rescue Aws::S3::Errors::ServerSideEncryptionConfigurationNotFoundError
rescue Aws::S3::Errors::ServerSideEncryptionConfigurationNotFoundError false
false
end
end end
end end

View file

@ -55,16 +55,16 @@ class AwsS3BucketObject < Inspec.resource(1)
def fetch_from_api def fetch_from_api
backend = BackendFactory.create(inspec_runner) backend = BackendFactory.create(inspec_runner)
catch_aws_errors do catch_aws_errors do
begin
# Just use get_object to detect if the bucket exists # Just use get_object to detect if the bucket exists
backend.get_object(bucket: bucket_name, key: key) backend.get_object(bucket: bucket_name, key: key)
rescue Aws::S3::Errors::NoSuchBucket rescue Aws::S3::Errors::NoSuchBucket
@exists = false @exists = false
return return
rescue Aws::S3::Errors::NoSuchKey rescue Aws::S3::Errors::NoSuchKey
@exists = false @exists = false
return return
end
end end
@exists = true @exists = true
end end

View file

@ -53,19 +53,19 @@ class AwsSnsSubscription < Inspec.resource(1)
def fetch_from_api def fetch_from_api
backend = BackendFactory.create(inspec_runner) backend = BackendFactory.create(inspec_runner)
catch_aws_errors do catch_aws_errors do
begin
aws_response = backend.get_subscription_attributes(subscription_arn: @subscription_arn).attributes aws_response = backend.get_subscription_attributes(subscription_arn: @subscription_arn).attributes
@exists = true @exists = true
@owner = aws_response["Owner"] @owner = aws_response["Owner"]
@raw_message_delivery = aws_response["RawMessageDelivery"].eql?("true") @raw_message_delivery = aws_response["RawMessageDelivery"].eql?("true")
@topic_arn = aws_response["TopicArn"] @topic_arn = aws_response["TopicArn"]
@endpoint = aws_response["Endpoint"] @endpoint = aws_response["Endpoint"]
@protocol = aws_response["Protocol"] @protocol = aws_response["Protocol"]
@confirmation_was_authenticated = aws_response["ConfirmationWasAuthenticated"].eql?("true") @confirmation_was_authenticated = aws_response["ConfirmationWasAuthenticated"].eql?("true")
rescue Aws::SNS::Errors::NotFound rescue Aws::SNS::Errors::NotFound
@exists = false @exists = false
return return
end
end end
end end

View file

@ -61,16 +61,16 @@ describe "inspec exec with json formatter" do
it "properly validates all (valid) unit tests against the schema" do it "properly validates all (valid) unit tests against the schema" do
schema = JSONSchemer.schema(JSON.parse(inspec("schema exec-json").stdout)) schema = JSONSchemer.schema(JSON.parse(inspec("schema exec-json").stdout))
all_profile_folders.first(1).each do |folder| all_profile_folders.first(1).each do |folder|
begin
out = inspec("exec " + folder + " --reporter json --no-create-lockfile") out = inspec("exec " + folder + " --reporter json --no-create-lockfile")
# Ensure it parses properly # Ensure it parses properly
out = JSON.parse(out.stdout) out = JSON.parse(out.stdout)
failures = schema.validate(out).to_a failures = schema.validate(out).to_a
_(failures).must_equal [] _(failures).must_equal []
rescue JSON::ParserError rescue JSON::ParserError
# We don't actually care about these; cannot validate if parsing fails! # We don't actually care about these; cannot validate if parsing fails!
nil nil
end
end end
end end

View file

@ -37,16 +37,16 @@ describe "inspec exec" do
it "properly validates all (valid) unit tests against the schema" do it "properly validates all (valid) unit tests against the schema" do
schema = JSONSchemer.schema(JSON.parse(inspec("schema exec-jsonmin").stdout)) schema = JSONSchemer.schema(JSON.parse(inspec("schema exec-jsonmin").stdout))
all_profile_folders.first(1).each do |folder| all_profile_folders.first(1).each do |folder|
begin
out = inspec("exec " + folder + " --reporter json-min --no-create-lockfile") out = inspec("exec " + folder + " --reporter json-min --no-create-lockfile")
# Ensure it parses properly; discard the result # Ensure it parses properly; discard the result
out = JSON.parse(out.stdout) out = JSON.parse(out.stdout)
failures = schema.validate(out).to_a failures = schema.validate(out).to_a
_(failures).must_equal [] _(failures).must_equal []
rescue JSON::ParserError rescue JSON::ParserError
# We don't actually care about these; cannot validate if parsing fails! # We don't actually care about these; cannot validate if parsing fails!
nil nil
end
end end
end end

View file

@ -196,16 +196,16 @@ describe "inspec json" do
it "properly validates all (valid) unit tests against the schema" do it "properly validates all (valid) unit tests against the schema" do
schema = JSONSchemer.schema(JSON.parse(inspec("schema profile-json").stdout)) schema = JSONSchemer.schema(JSON.parse(inspec("schema profile-json").stdout))
all_profile_folders.first(1).each do |folder| all_profile_folders.first(1).each do |folder|
begin
out = inspec("json " + folder) out = inspec("json " + folder)
# Ensure it parses properly; discard the result # Ensure it parses properly; discard the result
out = JSON.parse(out.stdout) out = JSON.parse(out.stdout)
failures = schema.validate(out).to_a failures = schema.validate(out).to_a
_(failures).must_equal [] _(failures).must_equal []
rescue JSON::ParserError rescue JSON::ParserError
# We don't actually care about these; cannot validate if parsing fails! # We don't actually care about these; cannot validate if parsing fails!
nil nil
end
end end
end end
end end

View file

@ -9,7 +9,7 @@ describe "inspec shell tests" do
describe "cmd" do describe "cmd" do
def assert_shell_c(code, exit_status, json = false, stderr = "") def assert_shell_c(code, exit_status, json = false, stderr = "")
json_suffix = " --reporter 'json'" if json json_suffix = " --reporter 'json'" if json
command = "shell -c '#{code.tr("'", '\\\'')}'#{json_suffix}" command = "shell -c '#{code.tr("'", "\\'")}'#{json_suffix}"
# On darwin this value is: # On darwin this value is:
# shell -c 'describe file(\"/Users/nickschwaderer/Documents/inspec/inspec/test/functional/inspec_shell_test.rb\") do it { should exist } end' --reporter 'json'" # shell -c 'describe file(\"/Users/nickschwaderer/Documents/inspec/inspec/test/functional/inspec_shell_test.rb\") do it { should exist } end' --reporter 'json'"
# appears to break in windows. # appears to break in windows.
@ -25,7 +25,7 @@ describe "inspec shell tests" do
def assert_shell_c_with_inputs(code, input_cmd, input, exit_status, json = false, stderr = "") def assert_shell_c_with_inputs(code, input_cmd, input, exit_status, json = false, stderr = "")
json_suffix = " --reporter 'json'" if json json_suffix = " --reporter 'json'" if json
command = "shell -c '#{code.tr("'", '\\\'')}'#{input_cmd} #{input}#{json_suffix}" command = "shell -c '#{code.tr("'", "\\'")}'#{input_cmd} #{input}#{json_suffix}"
# On darwin this value is: # On darwin this value is:
# shell -c 'describe file(\"/Users/nickschwaderer/Documents/inspec/inspec/test/functional/inspec_shell_test.rb\") do it { should exist } end' --reporter 'json'" # shell -c 'describe file(\"/Users/nickschwaderer/Documents/inspec/inspec/test/functional/inspec_shell_test.rb\") do it { should exist } end' --reporter 'json'"
# appears to break in windows. # appears to break in windows.
@ -226,7 +226,7 @@ describe "inspec shell tests" do
end end
def do_shell(code, exit_status = 0, stderr = "") def do_shell(code, exit_status = 0, stderr = "")
cmd = "echo '#{code.tr("'", '\\\'')}' | #{exec_inspec} shell" cmd = "echo '#{code.tr("'", "\\'")}' | #{exec_inspec} shell"
self.out = CMD.run_command(cmd) self.out = CMD.run_command(cmd)
assert_exit_code exit_status, out assert_exit_code exit_status, out

View file

@ -40,7 +40,7 @@ describe "example inheritance profile" do
return unless is_windows? return unless is_windows?
prepare_examples("inheritance") do |dir| prepare_examples("inheritance") do |dir|
dir_with_backslash = File.join(dir, '..\\', File.basename(dir)) dir_with_backslash = File.join(dir, "..\\", File.basename(dir))
out = inspec("vendor " + dir_with_backslash + " --overwrite") out = inspec("vendor " + dir_with_backslash + " --overwrite")
_(File.exist?(File.join(dir, "vendor"))).must_equal true _(File.exist?(File.join(dir, "vendor"))).must_equal true

View file

@ -37,7 +37,7 @@ describe "Inspec::Fetcher" do
it "is able to handle Windows paths" do it "is able to handle Windows paths" do
# simulate a local windows path # simulate a local windows path
file = __FILE__ file = __FILE__
file.tr!("/", '\\') file.tr!("/", "\\")
res = Inspec::Fetcher::Registry.resolve(file) res = Inspec::Fetcher::Registry.resolve(file)
_(res).must_be_kind_of Inspec::Fetcher::Local _(res).must_be_kind_of Inspec::Fetcher::Local
_(res.target).must_equal __FILE__ _(res.target).must_equal __FILE__

View file

@ -39,7 +39,7 @@ describe ErlangParser do
end end
it "parses a root array with a single quoted string" do it "parses a root array with a single quoted string" do
_(parsestr('[\'st\\\'r\'].')).must_equal '{:array=>[{:string=>"st\\\\\'r"@2}]}' _(parsestr("['st\\'r'].")).must_equal '{:array=>[{:string=>"st\\\\\'r"@2}]}'
end end
it "parses a root array with an empty binary" do it "parses a root array with an empty binary" do

View file

@ -47,7 +47,7 @@ describe FindFiles do
it "builds the correct command when an escaped single quote is used" do it "builds the correct command when an escaped single quote is used" do
inspec.expects(:command).with('sh -c "find /a/\\\'b/"').returns(result) inspec.expects(:command).with('sh -c "find /a/\\\'b/"').returns(result)
helper.find_files('/a/\\\'b/') helper.find_files("/a/\\'b/")
end end
it "builds the correct command when an escaped double quote is used" do it "builds the correct command when an escaped double quote is used" do