Revision 181810b0
Added by Ivan Necas almost 7 years ago
lib/foreman_maintain/cli.rb | ||
---|---|---|
module ForemanMaintain
|
||
module Cli
|
||
class MainCommand < Base
|
||
include Concerns::Logger
|
||
|
||
subcommand 'health', 'Health related commands', HealthCommand
|
||
subcommand 'upgrade', 'Upgrade related commands', UpgradeCommand
|
||
|
||
def run(*arguments)
|
||
logger.info("Running foreman-maintain command with arguments #{arguments.inspect}")
|
||
begin
|
||
super
|
||
exit_code = 0
|
||
rescue Error::UsageError => e
|
||
puts e.message
|
||
logger.error(e)
|
||
exit_code = 1
|
||
end
|
||
return exit_code
|
||
ensure
|
||
logger.info("foreman-maintain command finished with #{exit_code}")
|
||
end
|
||
end
|
||
end
|
||
end
|
lib/foreman_maintain/cli/base.rb | ||
---|---|---|
end
|
||
|
||
def run_scenario(scenarios)
|
||
ForemanMaintain::Runner.new(reporter, scenarios, :assumeyes => assumeyes?).run
|
||
ForemanMaintain::Runner.new(reporter, scenarios,
|
||
:assumeyes => assumeyes?,
|
||
:whitelist => whitelist || []).run
|
||
end
|
||
|
||
def available_checks
|
||
... | ... | |
def self.interactive_option
|
||
option ['-y', '--assumeyes'], :flag,
|
||
'Automatically answer yes for all questions'
|
||
|
||
option ['-w', '--whitelist'], :whitelist,
|
||
'Comma-separated list of labels of steps to be ignored' do |whitelist|
|
||
raise ArgumentError, 'value not specified' if whitelist.nil? || whitelist.empty?
|
||
whitelist.split(',').map(&:strip)
|
||
end
|
||
end
|
||
end
|
||
end
|
lib/foreman_maintain/error.rb | ||
---|---|---|
ret
|
||
end
|
||
end
|
||
|
||
# Error caused by incorrect usage, usually connected to passed CLI options
|
||
class UsageError < StandardError
|
||
end
|
||
end
|
||
end
|
lib/foreman_maintain/executable.rb | ||
---|---|---|
class Executable
|
||
extend Forwardable
|
||
attr_reader :options
|
||
def_delegators :execution, :success?, :fail?, :warning?, :output, :assumeyes?
|
||
def_delegators :execution, :puts, :print, :with_spinner, :ask
|
||
def_delegators :execution,
|
||
:success?, :fail?, :warning?, :output,
|
||
:assumeyes?, :whitelisted?,
|
||
:execution, :puts, :print, :with_spinner, :ask
|
||
|
||
attr_accessor :associated_feature
|
||
|
lib/foreman_maintain/reporter/cli_reporter.rb | ||
---|---|---|
@last_line = ''
|
||
end
|
||
|
||
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
||
def before_scenario_starts(scenario, last_scenario = nil)
|
||
decision = if last_scenario && last_scenario.steps_with_error.any?
|
||
:quit
|
||
elsif last_scenario && last_scenario.steps_with_warning.any?
|
||
ask_decision("Continue with [#{scenario.description}]")
|
||
else
|
||
:yes
|
||
end
|
||
decision = :yes
|
||
if last_scenario
|
||
decision = if last_scenario.steps_with_error(:whitelisted => false).any?
|
||
:quit
|
||
elsif last_scenario.steps_with_warning(:whitelisted => false).any?
|
||
ask_decision("Continue with [#{scenario.description}]")
|
||
else
|
||
:yes
|
||
end
|
||
end
|
||
if decision == :yes
|
||
puts "Running #{scenario.description || scenario.class}"
|
||
hline('=')
|
||
... | ... | |
Scenario [#{scenario.description}] failed.
|
||
MESSAGE
|
||
recommend = []
|
||
unless scenario.steps_with_error.empty?
|
||
steps_with_error = scenario.steps_with_error(:whitelisted => false)
|
||
unless steps_with_error.empty?
|
||
message << <<-MESSAGE.strip_heredoc
|
||
The following steps ended up in failing state:
|
||
|
||
#{format_steps(scenario.steps_with_error, "\n", 2)}
|
||
#{format_steps(steps_with_error, "\n", 2)}
|
||
MESSAGE
|
||
recommend << <<-MESSAGE.strip_heredoc
|
||
Resolve the failed steps and rerun
|
||
the command. In case the failures are false positives,
|
||
use --whitelist="#{scenario.steps_with_error.map(&:label_dashed).join(',')}"
|
||
use --whitelist="#{steps_with_error.map(&:label_dashed).join(',')}"
|
||
MESSAGE
|
||
end
|
||
|
||
unless scenario.steps_with_warning.empty?
|
||
steps_with_warning = scenario.steps_with_warning(:whitelisted => false)
|
||
unless steps_with_warning.empty?
|
||
message << <<-MESSAGE.strip_heredoc
|
||
The following steps ended up in warning state:
|
||
|
||
#{format_steps(scenario.steps_with_warning, "\n", 2)}
|
||
#{format_steps(steps_with_warning, "\n", 2)}
|
||
MESSAGE
|
||
|
||
recommend << <<-MESSAGE.strip_heredoc
|
lib/foreman_maintain/runner.rb | ||
---|---|---|
class Runner
|
||
require 'foreman_maintain/runner/execution'
|
||
def initialize(reporter, scenarios, options = {})
|
||
options.validate_options!(:assumeyes)
|
||
options.validate_options!(:assumeyes, :whitelist)
|
||
@assumeyes = options.fetch(:assumeyes, false)
|
||
@whitelist = options.fetch(:whitelist, [])
|
||
@reporter = reporter
|
||
@scenarios = Array(scenarios)
|
||
@scenarios_with_dependencies = scenarios_with_dependencies
|
||
validate_whitelist!
|
||
@quit = false
|
||
end
|
||
|
||
... | ... | |
while !@quit && !@steps_to_run.empty?
|
||
step = @steps_to_run.shift
|
||
@reporter.puts('Rerunning the check after fix procedure') if rerun_check?(step)
|
||
execution = Execution.new(step, @reporter)
|
||
execution = Execution.new(step, @reporter, :whitelisted => whitelisted_step?(step))
|
||
execution.run
|
||
ask_about_offered_steps(step)
|
||
end
|
||
@reporter.after_scenario_finishes(scenario)
|
||
end
|
||
|
||
def validate_whitelist!
|
||
valid_labels = @scenarios_with_dependencies.inject([]) do |step_labels, scenario|
|
||
step_labels.concat(scenario.steps.map(&:label_dashed))
|
||
end.map(&:to_s)
|
||
invalid_whitelist_labels = @whitelist - valid_labels
|
||
unless invalid_whitelist_labels.empty?
|
||
raise Error::UsageError, "Invalid whitelist value #{invalid_whitelist_labels.join(',')}"
|
||
end
|
||
end
|
||
|
||
def whitelisted_step?(step)
|
||
@whitelist.include?(step.label_dashed.to_s)
|
||
end
|
||
|
||
def confirm_scenario(scenario)
|
||
decision = @reporter.before_scenario_starts(scenario, @last_scenario)
|
||
case decision
|
lib/foreman_maintain/runner/execution.rb | ||
---|---|---|
|
||
attr_reader :reporter
|
||
|
||
def initialize(step, reporter)
|
||
def initialize(step, reporter, options = {})
|
||
options.validate_options!(:whitelisted)
|
||
@step = step
|
||
@reporter = reporter
|
||
@status = :pending
|
||
@output = ''
|
||
@whitelisted = options[:whitelisted]
|
||
end
|
||
|
||
def name
|
||
@step.description
|
||
end
|
||
|
||
def whitelisted?
|
||
@whitelisted
|
||
end
|
||
|
||
def success?
|
||
@status == :success
|
||
end
|
lib/foreman_maintain/scenario.rb | ||
---|---|---|
end.uniq
|
||
end
|
||
|
||
def steps_with_error
|
||
steps.find_all(&:fail?)
|
||
def steps_with_error(options = {})
|
||
filter_whitelisted(steps.find_all(&:fail?), options)
|
||
end
|
||
|
||
def steps_with_warning
|
||
steps.find_all(&:warning?)
|
||
def steps_with_warning(options = {})
|
||
filter_whitelisted(steps.find_all(&:warning?), options)
|
||
end
|
||
|
||
def filter_whitelisted(steps, options)
|
||
options.validate_options!(:whitelisted)
|
||
if options.key?(:whitelisted)
|
||
steps.select do |step|
|
||
options[:whitelisted] ? step.whitelisted? : !step.whitelisted?
|
||
end
|
||
else
|
||
steps
|
||
end
|
||
end
|
||
|
||
def passed?
|
||
(steps_with_error + steps_with_warning).empty?
|
||
(steps_with_error(:whitelisted => false) + steps_with_warning(:whitelisted => false)).empty?
|
||
end
|
||
|
||
def failed?
|
test/lib/reporter_test.rb | ||
---|---|---|
MESSAGE
|
||
end
|
||
|
||
it 'informs the user about warnings and failures of the last scenario ===' do
|
||
it 'informs the user about warnings and failures of the last scenario' do
|
||
run_scenario(warn_and_fail_scenario)
|
||
reporter.after_scenario_finishes(warn_and_fail_scenario)
|
||
assert_equal <<-MESSAGE.strip_heredoc.strip, captured_out(false).strip
|
||
... | ... | |
MESSAGE
|
||
end
|
||
|
||
it 'ignores whitelisted warnings and failures of the last scenario' do
|
||
run_scenario(warn_and_fail_scenario, :whitelisted => true)
|
||
reporter.after_scenario_finishes(warn_and_fail_scenario)
|
||
assert_equal <<-MESSAGE.strip_heredoc.strip, captured_out(false).strip
|
||
check that ends up with warning: [WARNING]
|
||
this check is always causing warnings
|
||
--------------------------------------------------------------------------------
|
||
check that ends up with fail: [FAIL]
|
||
this check is always causing failure
|
||
--------------------------------------------------------------------------------
|
||
check that ends up with success: [OK]
|
||
--------------------------------------------------------------------------------
|
||
MESSAGE
|
||
end
|
||
|
||
describe 'assumeyes' do
|
||
let(:reporter) do
|
||
Reporter::CLIReporter.new(capture, fake_stdin, :assumeyes => true)
|
||
... | ... | |
out
|
||
end
|
||
|
||
def run_scenario(scenario)
|
||
def run_scenario(scenario, options = {})
|
||
scenario.steps.each do |step|
|
||
ForemanMaintain::Runner::Execution.new(step, reporter).tap(&:run)
|
||
ForemanMaintain::Runner::Execution.new(step, reporter, options).tap(&:run)
|
||
end
|
||
end
|
||
end
|
Also available in: Unified diff
Add --whitelist option
Allows to mark some steps to be ignored in the results: allows to
continue even when some checks are failing.