inspec-core 4.22.1 → 4.23.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -1
  3. data/inspec-core.gemspec +3 -5
  4. data/lib/bundles/inspec-supermarket/cli.rb +1 -1
  5. data/lib/inspec/base_cli.rb +11 -1
  6. data/lib/inspec/cli.rb +4 -2
  7. data/lib/inspec/config.rb +19 -1
  8. data/lib/inspec/input.rb +4 -3
  9. data/lib/inspec/input_registry.rb +7 -1
  10. data/lib/inspec/plugin/v2/plugin_types/reporter.rb +4 -25
  11. data/lib/inspec/reporters.rb +0 -3
  12. data/lib/inspec/reporters/automate.rb +3 -3
  13. data/lib/inspec/reporters/base.rb +7 -23
  14. data/lib/inspec/resources/apt.rb +5 -5
  15. data/lib/inspec/resources/bridge.rb +1 -1
  16. data/lib/inspec/resources/host.rb +1 -1
  17. data/lib/inspec/resources/mount.rb +1 -1
  18. data/lib/inspec/resources/mysql_session.rb +31 -8
  19. data/lib/inspec/resources/postgres.rb +1 -1
  20. data/lib/inspec/resources/postgres_session.rb +6 -4
  21. data/lib/inspec/resources/processes.rb +1 -1
  22. data/lib/inspec/resources/service.rb +1 -1
  23. data/lib/inspec/resources/users.rb +1 -1
  24. data/lib/inspec/resources/windows_firewall.rb +110 -0
  25. data/lib/inspec/resources/windows_firewall_rule.rb +137 -0
  26. data/lib/inspec/run_data/profile.rb +3 -2
  27. data/lib/inspec/schema/exec_json.rb +1 -1
  28. data/lib/inspec/shell.rb +3 -3
  29. data/lib/inspec/utils/parser.rb +1 -1
  30. data/lib/inspec/utils/run_data_filters.rb +104 -0
  31. data/lib/inspec/version.rb +1 -1
  32. data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +4 -4
  33. data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +1 -1
  34. data/lib/plugins/inspec-init/templates/profiles/aws/README.md +1 -1
  35. data/lib/plugins/inspec-reporter-html2/README.md +1 -1
  36. data/lib/plugins/inspec-reporter-junit/README.md +17 -0
  37. data/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit.rb +21 -0
  38. data/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb +155 -0
  39. data/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/version.rb +5 -0
  40. data/lib/plugins/shared/core_plugin_test_helper.rb +0 -16
  41. metadata +17 -34
  42. data/README.md +0 -474
  43. data/lib/inspec/reporters/junit.rb +0 -77
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b4f096b34b4707a39ac4392118bdeadf0ab3b15b2ebea8faf8661902dbf8409
4
- data.tar.gz: 60ed138d131e605f8257a541a655757bf819c6e72b169a2c1034a1626db7c4d1
3
+ metadata.gz: 6a065b3ed549e1beaaa211fc87e50e1f66be56a12c51c942884972d70a55fe6c
4
+ data.tar.gz: bef9a2f8e84aea96c3917119906bdd251468e4a54a69044f1122c0fbb1b340fe
5
5
  SHA512:
6
- metadata.gz: 910a8739e4f375d3d573a734f46350e3e609a72b2376d8d9e04757e06e2274da1f728b612ab11312b08f90fafd5baf68f90a179fc90edaac9366ca49701680eb
7
- data.tar.gz: 25320c374c74ee45a8ebdcfce19c7fd481a1888c7d7f3250c5a091a3e556096dd42191b570e58572ae382dea7f99661c901ae3822438c52268b76ccef286572f
6
+ metadata.gz: d985c4562718e2bbd57585f6c6b496970aeaca0aabb0d2101b5b89b22c465d99c5ce5fead723bf4478799331d9a6d3be8d9fcd1786434ebd47bdf4392af19b6e
7
+ data.tar.gz: bd144e5f250215c64aad78f41ad60804fefe093b7cf234aa09b0ace4c866b5d254ac7ce639405ff33af743f08a4376f1a41cb2f61c2faa0b5ffab4221add290a
data/Gemfile CHANGED
@@ -19,12 +19,13 @@ group :omnibus do
19
19
  end
20
20
 
21
21
  group :test do
22
- gem "chefstyle", "~> 0.13.0"
22
+ gem "chefstyle", "~> 1.2.1"
23
23
  gem "minitest", "~> 5.5"
24
24
  gem "minitest-sprint", "~> 1.0"
25
25
  gem "rake", ">= 10"
26
26
  gem "simplecov", ["~> 0.10", "<=0.18.2"]
27
27
  gem "concurrent-ruby", "~> 1.0"
28
+ gem "nokogiri", "~> 1.9"
28
29
  gem "mocha", "~> 1.1"
29
30
  gem "ruby-progressbar", "~> 1.8"
30
31
  gem "webmock", "~> 3.0"
@@ -17,14 +17,14 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  # the gemfile and gemspec are necessary for appbundler so don't remove it
19
19
  spec.files =
20
- Dir.glob("{{lib,etc}/**/*,README.md,LICENSE,Gemfile,inspec-core.gemspec}")
20
+ Dir.glob("{{lib,etc}/**/*,LICENSE,Gemfile,inspec-core.gemspec}")
21
21
  .grep_v(%r{(?<!inspec-init/templates/profiles/)(aws|azure|gcp)})
22
22
  .grep_v(%r{lib/plugins/.*/test/})
23
23
  .reject { |f| File.directory?(f) }
24
24
 
25
25
  # Implementation dependencies
26
26
  spec.add_dependency "chef-telemetry", "~> 1.0"
27
- spec.add_dependency "license-acceptance", ">= 0.2.13", "< 2.0"
27
+ spec.add_dependency "license-acceptance", ">= 0.2.13", "< 3.0"
28
28
  spec.add_dependency "thor", ">= 0.20", "< 2.0"
29
29
  spec.add_dependency "json_schemer", ">= 0.2.1", "< 0.2.12"
30
30
  spec.add_dependency "method_source", ">= 0.8", "< 2.0"
@@ -36,16 +36,14 @@ Gem::Specification.new do |spec|
36
36
  spec.add_dependency "mixlib-log", "~> 3.0"
37
37
  spec.add_dependency "sslshake", "~> 1.2"
38
38
  spec.add_dependency "parallel", "~> 1.9"
39
- spec.add_dependency "faraday", ">= 0.9.0"
39
+ spec.add_dependency "faraday", ">= 0.9.0", "< 1.1"
40
40
  spec.add_dependency "tty-table", "~> 0.10"
41
41
  spec.add_dependency "tty-prompt", "~> 0.17"
42
42
  spec.add_dependency "tomlrb", "~> 1.2.0"
43
43
  spec.add_dependency "addressable", "~> 2.4"
44
44
  spec.add_dependency "parslet", "~> 1.5"
45
45
  spec.add_dependency "semverse", "~> 3.0"
46
- spec.add_dependency "htmlentities", "~> 4.3" # TODO: remove when #4853 fixed
47
46
  spec.add_dependency "multipart-post", "~> 2.0"
48
- spec.add_dependency "term-ansicolor", "~> 1.7"
49
47
 
50
48
  spec.add_dependency "train-core", "~> 3.0"
51
49
  end
@@ -5,7 +5,7 @@ module Supermarket
5
5
  class SupermarketCLI < Inspec::BaseCLI
6
6
  namespace "supermarket"
7
7
 
8
- # TODO: find another solution, once https://github.com/erikhuda/thor/issues/261 is fixed
8
+ # TODO: find another solution, once https://github.com/erikhuda/thor/issues/261 is fixed.
9
9
  def self.banner(command, _namespace = nil, _subcommand = false)
10
10
  "#{basename} #{subcommand_prefix} #{command.usage}"
11
11
  end
@@ -60,7 +60,7 @@ module Inspec
60
60
  true
61
61
  end
62
62
 
63
- def self.target_options # rubocop:disable MethodLength
63
+ def self.target_options # rubocop:disable Metrics/MethodLength
64
64
  option :target, aliases: :t, type: :string,
65
65
  desc: "Simple targeting option using URIs, e.g. ssh://user:pass@host:port"
66
66
  option :backend, aliases: :b, type: :string,
@@ -158,6 +158,16 @@ module Inspec
158
158
  option :silence_deprecations, type: :array,
159
159
  banner: "[all]|[GROUP GROUP...]",
160
160
  desc: "Suppress deprecation warnings. See install_dir/etc/deprecations.json for list of GROUPs or use 'all'."
161
+ option :diff, type: :boolean, default: true,
162
+ desc: "Use --no-diff to suppress 'diff' output of failed textual test results."
163
+ option :sort_results_by, type: :string, default: "file", banner: "--sort-results-by=none|control|file|random",
164
+ desc: "After normal execution order, results are sorted by control ID, or by file (default), or randomly. None uses legacy unsorted mode."
165
+ end
166
+
167
+ def self.help(*args)
168
+ super(*args)
169
+ puts "\nAbout #{Inspec::Dist::PRODUCT_NAME}:"
170
+ puts " Patents: chef.io/patents\n\n"
161
171
  end
162
172
 
163
173
  def self.format_platform_info(params: {}, indent: 0, color: 39)
@@ -48,7 +48,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI
48
48
  desc: "Allow or disable user interaction"
49
49
 
50
50
  class_option :disable_core_plugins, type: :string, banner: "", # Actually a boolean, but this suppresses the creation of a --no-disable...
51
- desc: "Disable loading all plugins that are shipped in the lib/plugins directory of InSpec. Useful in development."
51
+ desc: "Disable loading all plugins that are shipped in the lib/plugins directory of InSpec. Useful in development.",
52
+ hide: true
52
53
 
53
54
  class_option :disable_user_plugins, type: :string, banner: "",
54
55
  desc: "Disable loading all plugins that the user installed."
@@ -194,7 +195,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI
194
195
  pretty_handle_exception(e)
195
196
  end
196
197
 
197
- desc "exec LOCATIONS", <<~EOT
198
+ desc "exec LOCATIONS", "Run all tests at LOCATIONS."
199
+ long_desc <<~EOT
198
200
  Run all test files at the specified LOCATIONS.
199
201
 
200
202
  Loads the given profile(s) and fetches their dependencies if needed. Then
@@ -344,7 +344,6 @@ module Inspec
344
344
  cli
345
345
  json
346
346
  json-automate
347
- junit
348
347
  yaml
349
348
  }
350
349
 
@@ -406,6 +405,18 @@ module Inspec
406
405
  @plugin_cfg = data
407
406
  end
408
407
 
408
+ def validate_sort_results_by!(option_value)
409
+ expected = %w{
410
+ none
411
+ control
412
+ file
413
+ random
414
+ }
415
+ return if expected.include? option_value
416
+
417
+ raise Inspec::ConfigError::Invalid, "--sort-results-by must be one of #{expected.join(", ")}"
418
+ end
419
+
409
420
  #-----------------------------------------------------------------------#
410
421
  # Merging Options
411
422
  #-----------------------------------------------------------------------#
@@ -436,6 +447,7 @@ module Inspec
436
447
  finalize_parse_reporters(options)
437
448
  finalize_handle_sudo(options)
438
449
  finalize_compliance_login(options)
450
+ finalize_sort_results(options)
439
451
 
440
452
  Thor::CoreExt::HashWithIndifferentAccess.new(options)
441
453
  end
@@ -510,6 +522,12 @@ module Inspec
510
522
  end
511
523
  end
512
524
 
525
+ def finalize_sort_results(options)
526
+ if options.key?("sort_results_by")
527
+ validate_sort_results_by!(options["sort_results_by"])
528
+ end
529
+ end
530
+
513
531
  class Defaults
514
532
  DEFAULTS = {
515
533
  exec: {
@@ -171,7 +171,7 @@ module Inspec
171
171
  # are free to go higher.
172
172
  DEFAULT_PRIORITY_FOR_VALUE_SET = 60
173
173
 
174
- attr_reader :description, :events, :identifier, :name, :required, :title, :type
174
+ attr_reader :description, :events, :identifier, :name, :required, :sensitive, :title, :type
175
175
 
176
176
  def initialize(name, options = {})
177
177
  @name = name
@@ -264,6 +264,7 @@ module Inspec
264
264
  @required = options[:required] if options.key?(:required)
265
265
  @identifier = options[:identifier] if options.key?(:identifier) # TODO: determine if this is ever used
266
266
  @type = options[:type] if options.key?(:type)
267
+ @sensitive = options[:sensitive] if options.key?(:sensitive)
267
268
  end
268
269
 
269
270
  def make_creation_event(options)
@@ -320,7 +321,7 @@ module Inspec
320
321
 
321
322
  def to_hash
322
323
  as_hash = { name: name, options: {} }
323
- %i{description title identifier type required value}.each do |field|
324
+ %i{description title identifier type required value sensitive}.each do |field|
324
325
  val = send(field)
325
326
  next if val.nil?
326
327
 
@@ -334,7 +335,7 @@ module Inspec
334
335
  #--------------------------------------------------------------------------#
335
336
 
336
337
  def to_s
337
- "Input #{name} with #{current_value}"
338
+ "Input #{name} with value " + (sensitive ? "*** (senstive)" : "#{current_value}")
338
339
  end
339
340
 
340
341
  #--------------------------------------------------------------------------#
@@ -29,6 +29,8 @@ module Inspec
29
29
  def_delegator :inputs_by_profile, :select
30
30
  def_delegator :profile_aliases, :key?, :profile_alias?
31
31
 
32
+ attr_accessor :cache_inputs
33
+
32
34
  def initialize
33
35
  # Keyed on String profile_name => Hash of String input_name => Input object
34
36
  @inputs_by_profile = {}
@@ -43,6 +45,9 @@ module Inspec
43
45
  activator.activate!
44
46
  activator.implementation_class.new
45
47
  end
48
+
49
+ # Activate caching for inputs by default
50
+ @cache_inputs = true
46
51
  end
47
52
 
48
53
  #-------------------------------------------------------------#
@@ -84,7 +89,7 @@ module Inspec
84
89
 
85
90
  # Find or create the input
86
91
  inputs_by_profile[profile_name] ||= {}
87
- if inputs_by_profile[profile_name].key?(input_name)
92
+ if inputs_by_profile[profile_name].key?(input_name) && cache_inputs
88
93
  inputs_by_profile[profile_name][input_name].update(options)
89
94
  else
90
95
  inputs_by_profile[profile_name][input_name] = Inspec::Input.new(input_name, options)
@@ -316,6 +321,7 @@ module Inspec
316
321
  profile_name,
317
322
  type: input_options[:type],
318
323
  required: input_options[:required],
324
+ sensitive: input_options[:sensitive],
319
325
  event: evt
320
326
  )
321
327
  end
@@ -1,18 +1,20 @@
1
1
  require_relative "../../../run_data"
2
+ require_relative "../../../utils/run_data_filters"
2
3
 
3
4
  module Inspec::Plugin::V2::PluginType
4
5
  class Reporter < Inspec::Plugin::V2::PluginBase
5
6
  register_plugin_type(:reporter)
7
+ include Inspec::Utils::RunDataFilters
6
8
 
7
9
  attr_reader :run_data
8
10
 
9
11
  def initialize(config)
10
12
  @config = config
11
13
 
12
- # Trim the run_data while still a Hash; if it is huge, this
14
+ # Filter the run_data while still a Hash; if it is huge, this
13
15
  # saves on conversion time
14
16
  @run_data = config[:run_data] || {}
15
- apply_report_resize_options
17
+ apply_run_data_filters_to_hash
16
18
 
17
19
  unless Inspec::RunData.compatible_schema?(self.class.run_data_schema_constraints)
18
20
  # Best we can do is warn here, the InSpec run has finished
@@ -24,29 +26,6 @@ module Inspec::Plugin::V2::PluginType
24
26
  @output = ""
25
27
  end
26
28
 
27
- # This is a temporary duplication of code from lib/inspec/reporters/base.rb
28
- # To be DRY'd up once the core reporters become plugins...
29
- # Apply options such as message truncation and removal of backtraces
30
- def apply_report_resize_options
31
- runtime_config = Inspec::Config.cached.respond_to?(:final_options) ? Inspec::Config.cached.final_options : {}
32
-
33
- message_truncation = runtime_config[:reporter_message_truncation] || "ALL"
34
- trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
35
- include_backtrace = runtime_config[:reporter_backtrace_inclusion].nil? ? true : runtime_config[:reporter_backtrace_inclusion]
36
-
37
- @run_data[:profiles]&.each do |p|
38
- p[:controls].each do |c|
39
- c[:results]&.map! do |r|
40
- r.delete(:backtrace) unless include_backtrace
41
- if r.key?(:message) && r[:message] != "" && trunc > -1
42
- r[:message] = r[:message][0...trunc] + "[Truncated to #{trunc} characters]"
43
- end
44
- r
45
- end
46
- end
47
- end
48
- end
49
-
50
29
  def output(str, newline = true)
51
30
  @output << str
52
31
  @output << "\n" if newline
@@ -2,7 +2,6 @@ require "inspec/reporters/base"
2
2
  require "inspec/reporters/cli"
3
3
  require "inspec/reporters/json"
4
4
  require "inspec/reporters/json_automate"
5
- require "inspec/reporters/junit"
6
5
  require "inspec/reporters/automate"
7
6
  require "inspec/reporters/yaml"
8
7
 
@@ -20,8 +19,6 @@ module Inspec::Reporters
20
19
  # right to introduce breaking changes to this reporter at any time.
21
20
  when "json-automate"
22
21
  reporter = Inspec::Reporters::JsonAutomate.new(config)
23
- when "junit"
24
- reporter = Inspec::Reporters::Junit.new(config)
25
22
  when "automate"
26
23
  reporter = Inspec::Reporters::Automate.new(config)
27
24
  when "yaml"
@@ -49,14 +49,14 @@ module Inspec::Reporters
49
49
 
50
50
  res = http.request(req)
51
51
  if res.is_a?(Net::HTTPSuccess)
52
- return true
52
+ true
53
53
  else
54
54
  Inspec::Log.error "send_report: POST to #{uri.path} returned: #{res.body}"
55
- return false
55
+ false
56
56
  end
57
57
  rescue => e
58
58
  Inspec::Log.error "send_report: POST to #{uri.path} returned: #{e.message}"
59
- return false
59
+ false
60
60
  end
61
61
  end
62
62
 
@@ -1,33 +1,17 @@
1
+ require_relative "../utils/run_data_filters"
2
+
1
3
  module Inspec::Reporters
2
4
  class Base
5
+ include Inspec::Utils::RunDataFilters
6
+
3
7
  attr_reader :run_data
4
8
 
5
9
  def initialize(config)
6
10
  @config = config
7
- @run_data = config[:run_data]
8
- apply_report_resize_options unless @run_data.nil?
9
- @output = ""
10
- end
11
+ @run_data = config[:run_data] || {}
12
+ apply_run_data_filters_to_hash
11
13
 
12
- # Apply options such as message truncation and removal of backtraces
13
- def apply_report_resize_options
14
- runtime_config = Inspec::Config.cached.respond_to?(:final_options) ? Inspec::Config.cached.final_options : {}
15
-
16
- message_truncation = runtime_config[:reporter_message_truncation] || "ALL"
17
- trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
18
- include_backtrace = runtime_config[:reporter_backtrace_inclusion].nil? ? true : runtime_config[:reporter_backtrace_inclusion]
19
-
20
- @run_data[:profiles]&.each do |p|
21
- p[:controls].each do |c|
22
- c[:results]&.map! do |r|
23
- r.delete(:backtrace) unless include_backtrace
24
- if r.key?(:message) && r[:message] != "" && trunc > -1
25
- r[:message] = r[:message][0...trunc] + "[Truncated to #{trunc} characters]"
26
- end
27
- r
28
- end
29
- end
30
- end
14
+ @output = ""
31
15
  end
32
16
 
33
17
  def output(str, newline = true)
@@ -87,13 +87,13 @@ module Inspec::Resources
87
87
  active = raw_line == line
88
88
 
89
89
  # formats:
90
- # deb "http://archive.ubuntu.com/ubuntu/" wily main restricted ...
91
- # deb http://archive.ubuntu.com/ubuntu/ wily main restricted ...
92
- # deb [trusted=yes] http://archive.ubuntu.com/ubuntu/ wily main restricted ...
90
+ # deb "http://archive.ubuntu.com/ubuntu/" wily main restricted ...
91
+ # deb http://archive.ubuntu.com/ubuntu/ wily main restricted ...
92
+ # deb [trusted=yes] http://archive.ubuntu.com/ubuntu/ wily main restricted ...
93
+ # deb [arch=amd64 trusted=yes] http://archive.ubuntu.com/ubuntu/ wily main restricted ...
93
94
  # deb cdrom:[Ubuntu 15.10 _Wily Werewolf_ - Release amd64 (20151021)]/ wily main restricted ...
94
95
 
95
- words = line.split
96
- words.delete_at 1 if words[1] && words[1].start_with?("[")
96
+ words = line.sub(/^(deb|deb-src)\s+\[.+?\]/, '\1').split
97
97
  type, url, distro, *components = words
98
98
  url = url.delete('"') if url
99
99
 
@@ -27,7 +27,7 @@ module Inspec::Resources
27
27
  elsif inspec.os.windows?
28
28
  @bridge_provider = WindowsBridge.new(inspec)
29
29
  else
30
- return skip_resource "The `bridge` resource is not supported on your OS yet."
30
+ skip_resource "The `bridge` resource is not supported on your OS yet."
31
31
  end
32
32
  end
33
33
 
@@ -71,7 +71,7 @@ module Inspec::Resources
71
71
 
72
72
  missing_requirements = @host_provider.missing_requirements(protocol)
73
73
  unless missing_requirements.empty?
74
- return skip_resource "The following requirements are not met for this resource: " \
74
+ skip_resource "The following requirements are not met for this resource: " \
75
75
  "#{missing_requirements.join(", ")}"
76
76
  end
77
77
  end
@@ -61,7 +61,7 @@ module Inspec::Resources
61
61
  os = inspec.os
62
62
  if os.linux?
63
63
  LinuxMounts.new(inspec)
64
- elsif ["freebsd"].include?(os[:family])
64
+ elsif os.bsd?
65
65
  BsdMounts.new(inspec)
66
66
  end
67
67
  end
@@ -4,6 +4,27 @@ require "inspec/resources/command"
4
4
  require "shellwords"
5
5
 
6
6
  module Inspec::Resources
7
+ class Lines
8
+ attr_reader :output, :stdout, :stderr, :exit_status
9
+
10
+ def initialize(raw, desc, exit_status)
11
+ @output = raw
12
+ @desc = desc
13
+ @exit_status = exit_status
14
+ # backwards compatibility
15
+ @stdout = raw
16
+ @stderr = raw
17
+ end
18
+
19
+ def lines
20
+ output.split("\n")
21
+ end
22
+
23
+ def to_s
24
+ @desc
25
+ end
26
+ end
27
+
7
28
  class MysqlSession < Inspec.resource(1)
8
29
  name "mysql_session"
9
30
  supports platform: "unix"
@@ -12,7 +33,7 @@ module Inspec::Resources
12
33
  example <<~EXAMPLE
13
34
  sql = mysql_session('my_user','password','host')
14
35
  describe sql.query('show databases like \'test\';') do
15
- its('stdout') { should_not match(/test/) }
36
+ its('output') { should_not match(/test/) }
16
37
  end
17
38
  EXAMPLE
18
39
 
@@ -28,15 +49,17 @@ module Inspec::Resources
28
49
 
29
50
  def query(q, db = "")
30
51
  mysql_cmd = create_mysql_cmd(q, db)
31
- cmd = inspec.command(mysql_cmd)
52
+ cmd = if !@pass.nil?
53
+ inspec.command(mysql_cmd, redact_regex: /(mysql -u\w+ -p).+(\s-(h|S).*)/)
54
+ else
55
+ inspec.command(mysql_cmd)
56
+ end
32
57
  out = cmd.stdout + "\n" + cmd.stderr
33
- if out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error /
34
- # skip this test if the server can't run the query
35
- warn("Can't connect to MySQL instance for SQL checks.")
58
+ if cmd.exit_status != 0 || out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error:.*/
59
+ Lines.new(out, "MySQL query with errors: #{q}", cmd.exit_status)
60
+ else
61
+ Lines.new(cmd.stdout.strip, "MySQL query: #{q}", cmd.exit_status)
36
62
  end
37
-
38
- # return the raw command output
39
- cmd
40
63
  end
41
64
 
42
65
  def to_s