Project

General

Profile

Download (3.29 KB) Statistics
| Branch: | Tag: | Revision:
module ForemanMaintain
# Class responsible for running the scenario
class Runner
require 'foreman_maintain/runner/execution'
def initialize(reporter, scenarios, options = {})
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

def assumeyes?
@assumeyes
end

def scenarios_with_dependencies
@scenarios.map do |scenario|
scenario.before_scenarios + [scenario]
end.flatten
end

def run
@last_scenario = nil
scenarios_with_dependencies.each do |scenario|
next if scenario.steps.empty?
run_scenario(scenario)
@last_scenario = scenario
end
end

# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
def run_scenario(scenario)
@steps_to_run = ForemanMaintain::DependencyGraph.sort(@steps_to_run)
return unless confirm_scenario(scenario)
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, :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
when :yes
true
when :quit, :no
false
else
raise "Unexpected decision #{decision}"
end
end

def ask_to_quit(_step = nil)
@quit = true
end

def add_steps(*steps)
# we we add the steps at the beginning, but still keeping the
# order of steps passed in the arguments
steps.reverse.each do |step|
@steps_to_run.unshift(step)
end
end

private

# rubocop:disable Metrics/CyclomaticComplexity
def ask_about_offered_steps(step)
if assumeyes? && rerun_check?(step)
@reporter.puts 'Check still failing after attempt to fix. Skipping'
return :no
end
if step.next_steps && !step.next_steps.empty?
@last_decision_step = step
steps = step.next_steps.map(&:ensure_instance)
decision = @reporter.on_next_steps(steps)
case decision
when :quit
ask_to_quit
when Executable
chosen_steps = [decision]
chosen_steps << step if step.is_a?(Check)
add_steps(*chosen_steps)
end
end
end

def rerun_check?(step)
@last_decision_step == step
end
end
end
(14-14/19)