foreman_maintain 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +75 -3
- data/config/foreman_maintain.yml.example +6 -0
- data/config/foreman_maintain.yml.packaging +6 -0
- data/definitions/checks/disk_speed_minimal.rb +1 -1
- data/definitions/checks/foreman_proxy/verify_dhcp_config_syntax.rb +17 -0
- data/definitions/checks/system_registration.rb +1 -1
- data/definitions/features/downstream.rb +31 -0
- data/definitions/features/foreman_1_7_x.rb +33 -0
- data/definitions/features/foreman_proxy.rb +72 -0
- data/definitions/features/sync_plans.rb +14 -20
- data/definitions/features/upstream.rb +4 -0
- data/definitions/procedures/foreman_tasks/delete.rb +2 -1
- data/definitions/procedures/hammer_setup.rb +4 -4
- data/definitions/procedures/installer/upgrade.rb +19 -0
- data/definitions/procedures/maintenance_mode/disable.rb +13 -0
- data/definitions/procedures/maintenance_mode/enable.rb +13 -0
- data/definitions/procedures/packages/install.rb +20 -0
- data/definitions/procedures/packages/update.rb +20 -0
- data/definitions/procedures/repositories/setup.rb +18 -0
- data/definitions/procedures/sync_plans/disable.rb +4 -0
- data/definitions/procedures/sync_plans/enable.rb +5 -0
- data/definitions/scenarios/upgrade_to_satellite_6_2.rb +77 -0
- data/lib/foreman_maintain.rb +5 -2
- data/lib/foreman_maintain/check.rb +11 -4
- data/lib/foreman_maintain/cli.rb +23 -0
- data/lib/foreman_maintain/cli/advanced/procedure/abstract_by_tag_command.rb +38 -0
- data/lib/foreman_maintain/cli/advanced/procedure/abstract_procedure_command.rb +17 -0
- data/lib/foreman_maintain/cli/advanced/procedure/by_tag_command.rb +32 -0
- data/lib/foreman_maintain/cli/advanced/procedure/run_command.rb +17 -0
- data/lib/foreman_maintain/cli/advanced/procedure_command.rb +11 -0
- data/lib/foreman_maintain/cli/advanced_command.rb +9 -0
- data/lib/foreman_maintain/cli/base.rb +52 -7
- data/lib/foreman_maintain/cli/health_command.rb +0 -12
- data/lib/foreman_maintain/cli/transform_clamp_options.rb +66 -0
- data/lib/foreman_maintain/cli/upgrade_command.rb +45 -33
- data/lib/foreman_maintain/concerns/metadata.rb +28 -2
- data/lib/foreman_maintain/concerns/scenario_metadata.rb +44 -0
- data/lib/foreman_maintain/concerns/system_helpers.rb +27 -5
- data/lib/foreman_maintain/config.rb +10 -5
- data/lib/foreman_maintain/core_ext.rb +5 -1
- data/lib/foreman_maintain/csv_parser.rb +81 -0
- data/lib/foreman_maintain/dependency_graph.rb +10 -48
- data/lib/foreman_maintain/error.rb +4 -0
- data/lib/foreman_maintain/executable.rb +64 -13
- data/lib/foreman_maintain/param.rb +1 -0
- data/lib/foreman_maintain/reporter.rb +84 -3
- data/lib/foreman_maintain/reporter/cli_reporter.rb +57 -21
- data/lib/foreman_maintain/runner.rb +80 -21
- data/lib/foreman_maintain/runner/execution.rb +29 -4
- data/lib/foreman_maintain/runner/stored_execution.rb +23 -0
- data/lib/foreman_maintain/scenario.rb +90 -7
- data/lib/foreman_maintain/upgrade_runner.rb +194 -0
- data/lib/foreman_maintain/utils.rb +1 -0
- data/lib/foreman_maintain/utils/curl_response.rb +21 -0
- data/lib/foreman_maintain/version.rb +1 -1
- metadata +24 -14
- data/definitions/checks/sync_plans/with_disabled_status.rb +0 -18
- data/definitions/checks/sync_plans/with_enabled_status.rb +0 -19
- data/definitions/procedures/install_package.rb +0 -17
- data/definitions/scenarios/pre_upgrade_check_foreman_1_14.rb +0 -13
- data/definitions/scenarios/pre_upgrade_check_satellite_6_0_z.rb +0 -14
- data/definitions/scenarios/pre_upgrade_check_satellite_6_1.rb +0 -14
- data/definitions/scenarios/pre_upgrade_check_satellite_6_1_z.rb +0 -14
- data/definitions/scenarios/pre_upgrade_check_satellite_6_2.rb +0 -14
- data/definitions/scenarios/pre_upgrade_check_satellite_6_2_z.rb +0 -14
- data/definitions/scenarios/pre_upgrade_check_satellite_6_3.rb +0 -14
- data/lib/foreman_maintain/object_cache.rb +0 -34
@@ -4,12 +4,6 @@ require 'highline'
|
|
4
4
|
module ForemanMaintain
|
5
5
|
class Reporter
|
6
6
|
class CLIReporter < Reporter
|
7
|
-
DECISION_MAPPER = {
|
8
|
-
%w[y yes] => :yes,
|
9
|
-
%w[n next no] => :no,
|
10
|
-
%w[q quit] => :quit
|
11
|
-
}.freeze
|
12
|
-
|
13
7
|
# Simple spinner able to keep updating current line
|
14
8
|
class Spinner
|
15
9
|
def initialize(reporter, interval = 0.1)
|
@@ -87,7 +81,7 @@ module ForemanMaintain
|
|
87
81
|
end
|
88
82
|
|
89
83
|
def before_scenario_starts(scenario)
|
90
|
-
puts "
|
84
|
+
puts "Running #{scenario.description || scenario.class}"
|
91
85
|
hline('=')
|
92
86
|
end
|
93
87
|
|
@@ -147,33 +141,31 @@ module ForemanMaintain
|
|
147
141
|
def after_execution_finishes(execution)
|
148
142
|
puts_status(execution.status)
|
149
143
|
puts(execution.output) unless execution.output.empty?
|
144
|
+
if execution.status == :already_run
|
145
|
+
puts(<<-MESSAGE.strip_heredoc)
|
146
|
+
The step was skipped as it was already run and it is marked
|
147
|
+
as run_once. Use --force to enforce the execution.
|
148
|
+
MESSAGE
|
149
|
+
end
|
150
150
|
hline
|
151
151
|
new_line_if_needed
|
152
152
|
end
|
153
153
|
|
154
|
-
def after_scenario_finishes(
|
155
|
-
|
156
|
-
|
157
|
-
return if steps.empty?
|
158
|
-
if steps.size > 1
|
159
|
-
multiple_steps_decision(steps)
|
160
|
-
else
|
161
|
-
single_step_decision(steps.first)
|
162
|
-
end
|
154
|
+
def after_scenario_finishes(scenario)
|
155
|
+
scenario_failure_message(scenario)
|
156
|
+
puts "\n"
|
163
157
|
end
|
164
158
|
|
165
159
|
def clear_line
|
166
160
|
print "\r" + ' ' * @max_length + "\r"
|
167
161
|
end
|
168
162
|
|
169
|
-
private
|
170
|
-
|
171
163
|
def assumeyes?
|
172
164
|
@assumeyes
|
173
165
|
end
|
174
166
|
|
175
167
|
def single_step_decision(step)
|
176
|
-
answer = ask_decision("Continue with step [#{step.
|
168
|
+
answer = ask_decision("Continue with step [#{step.runtime_message}]?")
|
177
169
|
if answer == :yes
|
178
170
|
step
|
179
171
|
else
|
@@ -184,9 +176,9 @@ module ForemanMaintain
|
|
184
176
|
def multiple_steps_decision(steps)
|
185
177
|
puts 'There are multiple steps to proceed:'
|
186
178
|
steps.each_with_index do |step, index|
|
187
|
-
puts "#{index + 1}) #{step.
|
179
|
+
puts "#{index + 1}) #{step.runtime_message}"
|
188
180
|
end
|
189
|
-
ask_to_select('Select step to continue', steps, &:
|
181
|
+
ask_to_select('Select step to continue', steps, &:runtime_message)
|
190
182
|
end
|
191
183
|
|
192
184
|
def ask_decision(message)
|
@@ -260,6 +252,7 @@ module ForemanMaintain
|
|
260
252
|
:fail => { :label => '[FAIL]', :color => :red },
|
261
253
|
:running => { :label => '[RUNNING]', :color => :blue },
|
262
254
|
:skipped => { :label => '[SKIPPED]', :color => :yellow },
|
255
|
+
:already_run => { :label => '[ALREADY RUN]', :color => :yellow },
|
263
256
|
:warning => { :label => '[WARNING]', :color => :yellow } }
|
264
257
|
properties = mapping[status]
|
265
258
|
@hl.color(properties[:label], properties[:color], :bold)
|
@@ -272,6 +265,49 @@ module ForemanMaintain
|
|
272
265
|
def record_last_line(string)
|
273
266
|
@last_line = string.lines.to_a.last
|
274
267
|
end
|
268
|
+
|
269
|
+
private
|
270
|
+
|
271
|
+
def scenario_failure_message(scenario)
|
272
|
+
return if scenario.passed?
|
273
|
+
message = []
|
274
|
+
message << <<-MESSAGE.strip_heredoc
|
275
|
+
Scenario [#{scenario.description}] failed.
|
276
|
+
MESSAGE
|
277
|
+
recommend = []
|
278
|
+
steps_with_error = scenario.steps_with_error(:whitelisted => false)
|
279
|
+
unless steps_with_error.empty?
|
280
|
+
message << <<-MESSAGE.strip_heredoc
|
281
|
+
The following steps ended up in failing state:
|
282
|
+
|
283
|
+
#{format_steps(steps_with_error, "\n", 2)}
|
284
|
+
MESSAGE
|
285
|
+
recommend << <<-MESSAGE.strip_heredoc
|
286
|
+
Resolve the failed steps and rerun
|
287
|
+
the command. In case the failures are false positives,
|
288
|
+
use --whitelist="#{steps_with_error.map(&:label_dashed).join(',')}"
|
289
|
+
MESSAGE
|
290
|
+
end
|
291
|
+
|
292
|
+
steps_with_warning = scenario.steps_with_warning(:whitelisted => false)
|
293
|
+
unless steps_with_warning.empty?
|
294
|
+
message << <<-MESSAGE.strip_heredoc
|
295
|
+
The following steps ended up in warning state:
|
296
|
+
|
297
|
+
#{format_steps(steps_with_warning, "\n", 2)}
|
298
|
+
MESSAGE
|
299
|
+
|
300
|
+
recommend << <<-MESSAGE.strip_heredoc
|
301
|
+
The steps in warning state itself might not mean there is an error,
|
302
|
+
but it should be reviews to ensure the behavior is expected
|
303
|
+
MESSAGE
|
304
|
+
end
|
305
|
+
puts((message + recommend).join("\n"))
|
306
|
+
end
|
307
|
+
|
308
|
+
def format_steps(steps, join_with = ', ', indent = 0)
|
309
|
+
steps.map { |s| "#{' ' * indent}[#{s.label_dashed}]" }.join(join_with)
|
310
|
+
end
|
275
311
|
end
|
276
312
|
end
|
277
313
|
end
|
@@ -1,48 +1,73 @@
|
|
1
1
|
module ForemanMaintain
|
2
2
|
# Class responsible for running the scenario
|
3
3
|
class Runner
|
4
|
+
attr_reader :reporter, :exit_code
|
5
|
+
|
4
6
|
require 'foreman_maintain/runner/execution'
|
7
|
+
require 'foreman_maintain/runner/stored_execution'
|
5
8
|
def initialize(reporter, scenarios, options = {})
|
6
|
-
options.validate_options!(:assumeyes)
|
9
|
+
options.validate_options!(:assumeyes, :whitelist, :force)
|
7
10
|
@assumeyes = options.fetch(:assumeyes, false)
|
11
|
+
@whitelist = options.fetch(:whitelist, [])
|
12
|
+
@force = options.fetch(:force, false)
|
8
13
|
@reporter = reporter
|
9
14
|
@scenarios = Array(scenarios)
|
10
|
-
@scenarios_with_dependencies = scenarios_with_dependencies
|
11
15
|
@quit = false
|
16
|
+
@last_scenario = nil
|
17
|
+
@exit_code = 0
|
12
18
|
end
|
13
19
|
|
14
|
-
def
|
15
|
-
@
|
20
|
+
def quit?
|
21
|
+
@quit
|
16
22
|
end
|
17
23
|
|
18
|
-
def
|
19
|
-
@
|
20
|
-
scenario.before_scenarios + [scenario]
|
21
|
-
end.flatten
|
24
|
+
def assumeyes?
|
25
|
+
@assumeyes
|
22
26
|
end
|
23
27
|
|
24
28
|
def run
|
25
|
-
|
29
|
+
@scenarios.each do |scenario|
|
26
30
|
run_scenario(scenario)
|
31
|
+
break if @quit
|
27
32
|
end
|
28
33
|
end
|
29
34
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
execution = Execution.new(step, @reporter)
|
38
|
-
execution.run
|
39
|
-
ask_about_offered_steps(step)
|
35
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
|
36
|
+
def run_scenario(scenario, confirm = true)
|
37
|
+
return if scenario.steps.empty?
|
38
|
+
raise 'The runner is already in quit state' if quit?
|
39
|
+
if confirm
|
40
|
+
confirm_scenario(scenario)
|
41
|
+
return if quit?
|
40
42
|
end
|
43
|
+
scenario.before_scenarios.flatten.each { |before_scenario| run_scenario(before_scenario) }
|
44
|
+
return if quit? # the before scenarios caused the stop of the execution
|
45
|
+
@reporter.before_scenario_starts(scenario)
|
46
|
+
run_steps(scenario, scenario.steps)
|
41
47
|
@reporter.after_scenario_finishes(scenario)
|
48
|
+
ensure
|
49
|
+
@last_scenario = scenario unless scenario.steps.empty?
|
50
|
+
end
|
51
|
+
|
52
|
+
def whitelisted_step?(step)
|
53
|
+
@whitelist.include?(step.label_dashed.to_s)
|
54
|
+
end
|
55
|
+
|
56
|
+
def confirm_scenario(scenario)
|
57
|
+
return unless @last_scenario
|
58
|
+
decision = if @last_scenario.steps_with_error(:whitelisted => false).any?
|
59
|
+
:quit
|
60
|
+
elsif @last_scenario.steps_with_warning(:whitelisted => false).any?
|
61
|
+
reporter.ask_decision("Continue with [#{scenario.description}]")
|
62
|
+
end
|
63
|
+
|
64
|
+
ask_to_quit if [:quit, :no].include?(decision)
|
65
|
+
decision
|
42
66
|
end
|
43
67
|
|
44
|
-
def ask_to_quit(
|
68
|
+
def ask_to_quit(exit_code = 1)
|
45
69
|
@quit = true
|
70
|
+
@exit_code = exit_code
|
46
71
|
end
|
47
72
|
|
48
73
|
def add_steps(*steps)
|
@@ -53,9 +78,42 @@ module ForemanMaintain
|
|
53
78
|
end
|
54
79
|
end
|
55
80
|
|
81
|
+
def storage
|
82
|
+
ForemanMaintain.storage(:default)
|
83
|
+
end
|
84
|
+
|
56
85
|
private
|
57
86
|
|
58
|
-
|
87
|
+
def run_steps(scenario, steps)
|
88
|
+
@steps_to_run = ForemanMaintain::DependencyGraph.sort(steps)
|
89
|
+
while !@quit && !@steps_to_run.empty?
|
90
|
+
execution = run_step(@steps_to_run.shift)
|
91
|
+
post_step_decisions(scenario, execution)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def run_step(step)
|
96
|
+
@reporter.puts('Rerunning the check after fix procedure') if rerun_check?(step)
|
97
|
+
execution = Execution.new(step, @reporter,
|
98
|
+
:whitelisted => whitelisted_step?(step),
|
99
|
+
:storage => storage,
|
100
|
+
:force => @force)
|
101
|
+
execution.run
|
102
|
+
execution
|
103
|
+
ensure
|
104
|
+
storage.save
|
105
|
+
end
|
106
|
+
|
107
|
+
def post_step_decisions(scenario, execution)
|
108
|
+
step = execution.step
|
109
|
+
next_steps_decision = ask_about_offered_steps(step)
|
110
|
+
if next_steps_decision != :yes &&
|
111
|
+
execution.fail? && !execution.whitelisted? &&
|
112
|
+
scenario.run_strategy == :fail_fast
|
113
|
+
ask_to_quit
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
59
117
|
def ask_about_offered_steps(step)
|
60
118
|
if assumeyes? && rerun_check?(step)
|
61
119
|
@reporter.puts 'Check still failing after attempt to fix. Skipping'
|
@@ -72,6 +130,7 @@ module ForemanMaintain
|
|
72
130
|
chosen_steps = [decision]
|
73
131
|
chosen_steps << step if step.is_a?(Check)
|
74
132
|
add_steps(*chosen_steps)
|
133
|
+
:yes
|
75
134
|
end
|
76
135
|
end
|
77
136
|
end
|
@@ -4,7 +4,7 @@ module ForemanMaintain
|
|
4
4
|
class Execution
|
5
5
|
include Concerns::Logger
|
6
6
|
extend Forwardable
|
7
|
-
def_delegators
|
7
|
+
def_delegators :reporter, :with_spinner, :puts, :print, :ask, :assumeyes?
|
8
8
|
|
9
9
|
# Step performed as part of the execution
|
10
10
|
attr_reader :step
|
@@ -20,32 +20,57 @@ module ForemanMaintain
|
|
20
20
|
|
21
21
|
attr_reader :reporter
|
22
22
|
|
23
|
-
def initialize(step, reporter)
|
23
|
+
def initialize(step, reporter, options = {})
|
24
|
+
options.validate_options!(:whitelisted, :storage, :force)
|
24
25
|
@step = step
|
25
26
|
@reporter = reporter
|
26
27
|
@status = :pending
|
27
28
|
@output = ''
|
29
|
+
@whitelisted = options[:whitelisted]
|
30
|
+
@storage = options[:storage]
|
31
|
+
@force = options[:force]
|
28
32
|
end
|
29
33
|
|
30
34
|
def name
|
31
35
|
@step.description
|
32
36
|
end
|
33
37
|
|
38
|
+
def whitelisted?
|
39
|
+
@whitelisted
|
40
|
+
end
|
41
|
+
|
34
42
|
def success?
|
35
|
-
|
43
|
+
[:success, :already_run, :skipped].include?(@status)
|
36
44
|
end
|
37
45
|
|
38
46
|
def fail?
|
39
47
|
@status == :fail
|
40
48
|
end
|
41
49
|
|
50
|
+
def skipped?
|
51
|
+
@status == :skipped
|
52
|
+
end
|
53
|
+
|
54
|
+
def skip?
|
55
|
+
!@force && step.run_once? && step.executed? && step.success?
|
56
|
+
end
|
57
|
+
|
42
58
|
def warning?
|
43
59
|
@status == :warning
|
44
60
|
end
|
45
61
|
|
62
|
+
# yaml storage to preserve key/value pairs between runs.
|
63
|
+
def storage
|
64
|
+
@storage || ForemanMaintain.storage(:default)
|
65
|
+
end
|
66
|
+
|
46
67
|
def run
|
47
|
-
@status = :running
|
48
68
|
@reporter.before_execution_starts(self)
|
69
|
+
if skip?
|
70
|
+
@status = :already_run
|
71
|
+
return
|
72
|
+
end
|
73
|
+
@status = :running
|
49
74
|
with_metadata_calculation do
|
50
75
|
capture_errors do
|
51
76
|
step.__run__(self)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ForemanMaintain
|
2
|
+
class Runner
|
3
|
+
# Class representing an execution of a single step in scenario
|
4
|
+
class StoredExecution < Execution
|
5
|
+
include Concerns::Logger
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def initialize(step, hash)
|
9
|
+
@step = step
|
10
|
+
@status = hash[:status]
|
11
|
+
@output = hash[:output]
|
12
|
+
end
|
13
|
+
|
14
|
+
def reporter
|
15
|
+
raise 'Can not access reporter from stored execution'
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
raise 'Can not run stored execution'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -2,33 +2,48 @@ module ForemanMaintain
|
|
2
2
|
class Scenario
|
3
3
|
include Concerns::Logger
|
4
4
|
include Concerns::SystemHelpers
|
5
|
-
include Concerns::
|
5
|
+
include Concerns::ScenarioMetadata
|
6
6
|
include Concerns::Finders
|
7
|
+
extend Concerns::Finders
|
7
8
|
|
8
9
|
attr_reader :steps
|
9
10
|
|
10
11
|
class FilteredScenario < Scenario
|
11
|
-
metadata
|
12
|
+
metadata do
|
13
|
+
manual_detection
|
14
|
+
run_strategy :fail_slow
|
15
|
+
end
|
12
16
|
|
13
17
|
attr_reader :filter_label, :filter_tags
|
14
18
|
|
15
|
-
def initialize(filter)
|
19
|
+
def initialize(filter, definition_kinds = [:check])
|
16
20
|
@filter_tags = filter[:tags]
|
17
21
|
@filter_label = filter[:label]
|
18
|
-
@
|
22
|
+
@definition_kinds = definition_kinds
|
23
|
+
@steps = []
|
24
|
+
@steps += checks(filter) if definition_kinds.include?(:check)
|
25
|
+
@steps += procedures(filter) if definition_kinds.include?(:procedure)
|
19
26
|
@steps = DependencyGraph.sort(@steps)
|
20
27
|
end
|
21
28
|
|
22
|
-
def
|
29
|
+
def runtime_message
|
23
30
|
if @filter_label
|
24
|
-
"
|
31
|
+
"#{kind_list} with label [#{dashize(@filter_label)}]"
|
25
32
|
else
|
26
|
-
"
|
33
|
+
"#{kinds_list} with tags #{tag_string(@filter_tags)}"
|
27
34
|
end
|
28
35
|
end
|
29
36
|
|
30
37
|
private
|
31
38
|
|
39
|
+
def kinds_list
|
40
|
+
@definition_kinds.map { |kind| kind.to_s + 's' }.join(' and ')
|
41
|
+
end
|
42
|
+
|
43
|
+
def kind_list
|
44
|
+
@definition_kinds.map(&:to_s).join(' or ')
|
45
|
+
end
|
46
|
+
|
32
47
|
def tag_string(tags)
|
33
48
|
tags.map { |tag| dashize("[#{tag}]") }.join(' ')
|
34
49
|
end
|
@@ -36,12 +51,21 @@ module ForemanMaintain
|
|
36
51
|
def dashize(string)
|
37
52
|
string.to_s.tr('_', '-')
|
38
53
|
end
|
54
|
+
|
55
|
+
def checks(filter)
|
56
|
+
ForemanMaintain.available_checks(filter).map(&:ensure_instance)
|
57
|
+
end
|
58
|
+
|
59
|
+
def procedures(filter)
|
60
|
+
ForemanMaintain.available_procedures(filter).map(&:ensure_instance)
|
61
|
+
end
|
39
62
|
end
|
40
63
|
|
41
64
|
class PreparationScenario < Scenario
|
42
65
|
metadata do
|
43
66
|
manual_detection
|
44
67
|
description 'preparation steps required to run the next scenarios'
|
68
|
+
run_strategy :fail_slow
|
45
69
|
end
|
46
70
|
|
47
71
|
attr_reader :main_scenario
|
@@ -71,6 +95,37 @@ module ForemanMaintain
|
|
71
95
|
end.uniq
|
72
96
|
end
|
73
97
|
|
98
|
+
def executed_steps
|
99
|
+
steps.find_all(&:executed?)
|
100
|
+
end
|
101
|
+
|
102
|
+
def steps_with_error(options = {})
|
103
|
+
filter_whitelisted(executed_steps.find_all(&:fail?), options)
|
104
|
+
end
|
105
|
+
|
106
|
+
def steps_with_warning(options = {})
|
107
|
+
filter_whitelisted(executed_steps.find_all(&:warning?), options)
|
108
|
+
end
|
109
|
+
|
110
|
+
def filter_whitelisted(steps, options)
|
111
|
+
options.validate_options!(:whitelisted)
|
112
|
+
if options.key?(:whitelisted)
|
113
|
+
steps.select do |step|
|
114
|
+
options[:whitelisted] ? step.whitelisted? : !step.whitelisted?
|
115
|
+
end
|
116
|
+
else
|
117
|
+
steps
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def passed?
|
122
|
+
(steps_with_error(:whitelisted => false) + steps_with_warning(:whitelisted => false)).empty?
|
123
|
+
end
|
124
|
+
|
125
|
+
def failed?
|
126
|
+
!passed?
|
127
|
+
end
|
128
|
+
|
74
129
|
# scenarios to be run before this scenario
|
75
130
|
def before_scenarios
|
76
131
|
scenarios = []
|
@@ -96,5 +151,33 @@ module ForemanMaintain
|
|
96
151
|
def inspect
|
97
152
|
"#{self.class.metadata[:description]}<#{self.class.name}>"
|
98
153
|
end
|
154
|
+
|
155
|
+
def to_hash
|
156
|
+
{ :label => label,
|
157
|
+
:steps => steps.map(&:to_hash) }
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.new_from_hash(hash)
|
161
|
+
scenarios = find_scenarios(:label => hash[:label])
|
162
|
+
unless scenarios.size == 1
|
163
|
+
raise "Could not find scenario #{hash[:label]}, found #{scenarios.size} scenarios"
|
164
|
+
end
|
165
|
+
scenario = scenarios.first
|
166
|
+
scenario.load_step_states(hash[:steps])
|
167
|
+
scenario
|
168
|
+
end
|
169
|
+
|
170
|
+
def load_step_states(steps_hash)
|
171
|
+
steps = self.steps.dup
|
172
|
+
steps_hash.each do |step_hash|
|
173
|
+
until steps.empty?
|
174
|
+
step = steps.shift
|
175
|
+
if step.matches_hash?(step_hash)
|
176
|
+
step.update_from_hash(step_hash)
|
177
|
+
break
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
99
182
|
end
|
100
183
|
end
|