Class: Inferno::CLI::Execute

Inherits:
Object
  • Object
show all
Includes:
Utils::PersistInputs, Utils::VerifyRunnable
Defined in:
lib/inferno/apps/cli/execute.rb,
lib/inferno/apps/cli/execute/console_outputter.rb

Defined Under Namespace

Classes: ConsoleOutputter

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils::PersistInputs

#persist_inputs

Methods included from Utils::VerifyRunnable

#verify_runnable

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



14
15
16
# File 'lib/inferno/apps/cli/execute.rb', line 14

def options
  @options
end

Class Method Details

.boot_full_infernoObject



27
28
29
30
31
32
33
34
# File 'lib/inferno/apps/cli/execute.rb', line 27

def self.boot_full_inferno
  ENV['NO_DB'] = 'false'

  # Inferno boot flow triggers migration and logger outputs it
  Inferno::CLI::Execute.suppress_output { require_relative '../../../inferno' }

  Inferno::Application.start(:executor)
end

.suppress_outputObject



16
17
18
19
20
21
22
23
24
25
# File 'lib/inferno/apps/cli/execute.rb', line 16

def self.suppress_output
  begin
    original_stdout = $stdout.clone
    $stdout.reopen(File.new(File::NULL, 'w+'))
    retval = yield
  ensure
    $stdout.reopen(original_stdout)
  end
  retval
end

Instance Method Details

#all_selected_groups_and_testsObject



95
96
97
# File 'lib/inferno/apps/cli/execute.rb', line 95

def all_selected_groups_and_tests
  @all_selected_groups_and_tests ||= runnables_by_short_id + groups + tests
end

#create_params(test_session, runnable) ⇒ Object



158
159
160
161
162
163
164
# File 'lib/inferno/apps/cli/execute.rb', line 158

def create_params(test_session, runnable)
  {
    test_session_id: test_session.id,
    runnable_id_key(runnable) => runnable.id,
    inputs: thor_hash_to_inputs_array(options[:inputs])
  }
end

#create_test_run(runnable) ⇒ Object



123
124
125
126
127
# File 'lib/inferno/apps/cli/execute.rb', line 123

def create_test_run(runnable)
  test_runs_repo.create(
    create_params(test_session, runnable).merge({ status: 'queued' })
  )
end

#dispatch_job(test_run) ⇒ Object



166
167
168
169
170
171
172
173
174
175
# File 'lib/inferno/apps/cli/execute.rb', line 166

def dispatch_job(test_run)
  # TODO: move suppression to outputter? better suppression?
  if options[:verbose]
    Jobs.perform(Jobs::ExecuteTestRun, test_run.id, force_synchronous: true)
  else
    Inferno::CLI::Execute.suppress_output do
      Jobs.perform(Jobs::ExecuteTestRun, test_run.id, force_synchronous: true)
    end
  end
end

#find_by_short_id(repo_symbol, short_id) ⇒ Object

Raises:

  • (StandardError)


195
196
197
198
199
200
201
202
# File 'lib/inferno/apps/cli/execute.rb', line 195

def find_by_short_id(repo_symbol, short_id)
  repo_symbol_to_array(repo_symbol).each do |repo|
    repo.all.each do |entity|
      return entity if short_id == entity.short_id && suite.id == entity.suite.id
    end
  end
  raise StandardError, "#{repo_symbol.to_s.humanize} #{short_id} not found."
end

#groupsObject



183
184
185
186
187
# File 'lib/inferno/apps/cli/execute.rb', line 183

def groups
  return [] if options[:groups].blank?

  @groups ||= options[:groups]&.map { |short_id| find_by_short_id(:group, short_id) }
end

#outputterObject



90
91
92
93
# File 'lib/inferno/apps/cli/execute.rb', line 90

def outputter
  # TODO: swap outputter based on options
  @outputter ||= Inferno::CLI::Execute::ConsoleOutputter.new
end


225
226
227
228
229
230
231
# File 'lib/inferno/apps/cli/execute.rb', line 225

def print_error_and_exit(err, code)
  outputter.print_error(options || {}, err)
rescue StandardError => e
  puts "Caught exception #{e} while printing exception #{err}. Exiting."
ensure
  exit(code)
end


85
86
87
88
# File 'lib/inferno/apps/cli/execute.rb', line 85

def print_help_and_exit
  puts `NO_DB=true bundle exec inferno help execute`
  exit(0)
end

#repo_symbol_to_array(repo_symbol) ⇒ Object



204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/inferno/apps/cli/execute.rb', line 204

def repo_symbol_to_array(repo_symbol)
  case repo_symbol
  when :group
    [test_groups_repo]
  when :test
    [tests_repo]
  when :group_or_test
    [test_groups_repo, tests_repo]
  else
    raise StandardError, "Unrecognized repo_symbol #{repo_symbol} for `find_by_short_id`"
  end
end

#results_repoObject



129
130
131
# File 'lib/inferno/apps/cli/execute.rb', line 129

def results_repo
  @results_repo ||= Inferno::Repositories::Results.new
end

#run(options) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/inferno/apps/cli/execute.rb', line 36

def run(options)
  print_help_and_exit if options[:help]

  self.options = options

  outputter.print_start_message(options)

  results = []
  outputter.print_around_run(options) do
    if all_selected_groups_and_tests.empty?
      test_run = create_test_run(suite)
      run_one(suite, test_run)

      results = test_runs_repo.results_for_test_run(test_run.id)
      results = sort_results(results)
    else
      all_selected_groups_and_tests.each do |runnable|
        test_run = create_test_run(runnable)
        run_one(runnable, test_run)

        results += sort_results(test_runs_repo.results_for_test_run(test_run.id))
      end
    end
  end

  # User may enter duplicate runnables, in which case this prevents a bug of extraneous results
  results.uniq!(&:id)

  outputter.print_results(options, results)
  outputter.print_end_message(options)

  # TODO: respect customized rollups
  exit(0) if Inferno::ResultSummarizer.new(results).summarize == 'pass'

  # exit(1) is for Thor failures
  # exit(2) is for shell builtin failures
  exit(3)
rescue Sequel::ValidationFailed => e
  print_error_and_exit(e, 4)
rescue Sequel::ForeignKeyConstraintViolation => e
  print_error_and_exit(e, 5)
rescue Inferno::Exceptions::RequiredInputsNotFound => e
  print_error_and_exit(e, 6)
rescue Inferno::Exceptions::NotUserRunnableException => e
  print_error_and_exit(e, 7)
rescue StandardError => e
  print_error_and_exit(e, 8)
end

#run_one(runnable, test_run) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/inferno/apps/cli/execute.rb', line 99

def run_one(runnable, test_run)
  verify_runnable(
    runnable,
    thor_hash_to_inputs_array(options[:inputs]),
    test_session.suite_options
  )

  persist_inputs(session_data_repo, create_params(test_session, suite), test_run)

  dispatch_job(test_run)
end

#runnable_id_key(runnable) ⇒ Object



245
246
247
248
249
250
251
252
253
254
# File 'lib/inferno/apps/cli/execute.rb', line 245

def runnable_id_key(runnable)
  case runnable_type(runnable)
  when :suite
    :test_suite_id
  when :group
    :test_group_id
  else
    :test_id
  end
end

#runnable_type(runnable) ⇒ Object



233
234
235
236
237
238
239
240
241
242
243
# File 'lib/inferno/apps/cli/execute.rb', line 233

def runnable_type(runnable)
  if runnable < Inferno::TestSuite
    :suite
  elsif runnable < Inferno::TestGroup
    :group
  elsif runnable < Inferno::Test
    :test
  else
    raise StandardError, "Unidentified runnable #{runnable}"
  end
end

#runnables_by_short_idObject



177
178
179
180
181
# File 'lib/inferno/apps/cli/execute.rb', line 177

def runnables_by_short_id
  return [] if options[:short_ids].blank?

  @runnables_by_short_id ||= options[:short_ids]&.map { |short_id| find_by_short_id(:group_or_test, short_id) }
end

#session_data_repoObject



145
146
147
# File 'lib/inferno/apps/cli/execute.rb', line 145

def session_data_repo
  @session_data_repo ||= Inferno::Repositories::SessionData.new
end

#sort_results(results) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
# File 'lib/inferno/apps/cli/execute.rb', line 256

def sort_results(results)
  results.sort do |result, other|
    if result.runnable < Inferno::TestSuite
      -1
    elsif other.runnable < Inferno::TestSuite
      1
    else
      result.runnable.short_id <=> other.runnable.short_id
    end
  end
end

#suiteObject

Raises:

  • (StandardError)


111
112
113
114
115
116
117
# File 'lib/inferno/apps/cli/execute.rb', line 111

def suite
  @suite ||= Inferno::Repositories::TestSuites.new.find(options[:suite])

  raise StandardError, "Test suite #{options[:suite]} not found" if @suite.nil?

  @suite
end

#test_groups_repoObject



133
134
135
# File 'lib/inferno/apps/cli/execute.rb', line 133

def test_groups_repo
  @test_groups_repo ||= Inferno::Repositories::TestGroups.new
end

#test_runs_repoObject



119
120
121
# File 'lib/inferno/apps/cli/execute.rb', line 119

def test_runs_repo
  @test_runs_repo ||= Inferno::Repositories::TestRuns.new
end

#test_sessionObject



149
150
151
152
153
154
155
156
# File 'lib/inferno/apps/cli/execute.rb', line 149

def test_session
  @test_session ||= test_sessions_repo.create({
                                                test_suite_id: suite.id,
                                                suite_options: thor_hash_to_suite_options_array(
                                                  options[:suite_options]
                                                )
                                              })
end

#test_sessions_repoObject



141
142
143
# File 'lib/inferno/apps/cli/execute.rb', line 141

def test_sessions_repo
  @test_sessions_repo ||= Inferno::Repositories::TestSessions.new
end

#testsObject



189
190
191
192
193
# File 'lib/inferno/apps/cli/execute.rb', line 189

def tests
  return [] if options[:tests].blank?

  @tests ||= options[:tests]&.map { |short_id| find_by_short_id(:test, short_id) }
end

#tests_repoObject



137
138
139
# File 'lib/inferno/apps/cli/execute.rb', line 137

def tests_repo
  @tests_repo ||= Inferno::Repositories::Tests.new
end

#thor_hash_to_inputs_array(hash = {}) ⇒ Object



221
222
223
# File 'lib/inferno/apps/cli/execute.rb', line 221

def thor_hash_to_inputs_array(hash = {})
  hash.to_a.map { |pair| { name: pair[0], value: pair[1] } }
end

#thor_hash_to_suite_options_array(hash = {}) ⇒ Object



217
218
219
# File 'lib/inferno/apps/cli/execute.rb', line 217

def thor_hash_to_suite_options_array(hash = {})
  hash.to_a.map { |pair| Inferno::DSL::SuiteOption.new({ id: pair[0], value: pair[1] }) }
end