inferno_core 0.4.43 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/inferno/apps/cli/execute/console_outputter.rb +152 -0
- data/lib/inferno/apps/cli/execute.rb +269 -0
- data/lib/inferno/apps/cli/main.rb +73 -4
- data/lib/inferno/apps/cli/templates/.env.development +2 -1
- data/lib/inferno/apps/cli/templates/.env.production +2 -1
- data/lib/inferno/apps/cli/templates/.env.test +1 -0
- data/lib/inferno/apps/cli/templates/.gitignore +1 -0
- data/lib/inferno/apps/cli/templates/config/nginx.background.conf.tt +15 -0
- data/lib/inferno/apps/cli/templates/docker-compose.background.yml.tt +5 -0
- data/lib/inferno/apps/cli/templates/docker-compose.yml.tt +4 -0
- data/lib/inferno/apps/cli.rb +0 -1
- data/lib/inferno/apps/web/controllers/test_runs/create.rb +7 -32
- data/lib/inferno/apps/web/serializers/serializer.rb +3 -0
- data/lib/inferno/config/boot/executor.rb +14 -0
- data/lib/inferno/dsl/auth_info.rb +77 -72
- data/lib/inferno/dsl/fhir_client_builder.rb +2 -2
- data/lib/inferno/dsl/fhir_resource_validation.rb +4 -0
- data/lib/inferno/dsl/http_client_builder.rb +2 -2
- data/lib/inferno/dsl/links.rb +100 -0
- data/lib/inferno/dsl/runnable.rb +6 -1
- data/lib/inferno/entities/has_runnable.rb +1 -1
- data/lib/inferno/entities/request.rb +2 -2
- data/lib/inferno/entities/test.rb +4 -4
- data/lib/inferno/entities/test_group.rb +2 -2
- data/lib/inferno/entities/test_suite.rb +2 -24
- data/lib/inferno/exceptions.rb +12 -0
- data/lib/inferno/ext/fhir_models.rb +3 -3
- data/lib/inferno/jobs.rb +4 -4
- data/lib/inferno/public/237.bundle.js +1 -0
- data/lib/inferno/public/assets.json +1 -1
- data/lib/inferno/public/bundle.js +42 -63
- data/lib/inferno/public/bundle.js.LICENSE.txt +5 -33
- data/lib/inferno/repositories/in_memory_repository.rb +5 -8
- data/lib/inferno/repositories/repository.rb +1 -1
- data/lib/inferno/result_summarizer.rb +1 -1
- data/lib/inferno/test_runner.rb +2 -2
- data/lib/inferno/utils/middleware/request_logger.rb +1 -1
- data/lib/inferno/utils/persist_inputs.rb +30 -0
- data/lib/inferno/utils/preset_template_generator.rb +1 -1
- data/lib/inferno/utils/verify_runnable.rb +15 -0
- data/lib/inferno/version.rb +1 -1
- data/spec/factories/result.rb +4 -0
- data/spec/fixtures/basic_test_group.rb +2 -1
- data/spec/fixtures/run_as_group_test_group.rb +11 -0
- metadata +24 -171
- data/lib/inferno/public/175.bundle.js +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c6ddae6726754b2036409f6765ffd3746e88a2238226655905332ac9083a907
|
4
|
+
data.tar.gz: a7f8fe7d9eedd5213bd9d825fc32075b00abf69953c29ab550c45b66fc0147b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bfbb7ef6d15895b029349446501d739b7e676cff8e0ea369c1f781ee29151187eaba602f4485cee34a19c9a492d1cdbe2e4db3454db5f33a8f7b578586c53685
|
7
|
+
data.tar.gz: 14cb75b1bbaa2dcca319348f9914cf2af5d40d36a23ab7de3d212e43555466dc5f7c6d1af9a570fcca977e16353df80bc76f891616b32f0d91a593cfb9378730
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'pastel'
|
2
|
+
require_relative '../../web/serializers/test_run'
|
3
|
+
require_relative '../../web/serializers/result'
|
4
|
+
|
5
|
+
module Inferno
|
6
|
+
module CLI
|
7
|
+
class Execute
|
8
|
+
# @private
|
9
|
+
class ConsoleOutputter
|
10
|
+
COLOR = Pastel.new
|
11
|
+
CHECKMARK = "\u2713".freeze
|
12
|
+
BAR = ('=' * 80).freeze
|
13
|
+
|
14
|
+
def print_start_message(options)
|
15
|
+
puts ''
|
16
|
+
puts BAR
|
17
|
+
puts "Testing #{options[:suite]}"
|
18
|
+
verbose_puts options, "Running Groups #{options[:groups]}" unless options[:groups].blank?
|
19
|
+
verbose_puts options, "Running Tests #{options[:tests]}" unless options[:tests].blank?
|
20
|
+
verbose_puts options, "Running Entities #{options[:short_ids]}" unless options[:short_ids].blank?
|
21
|
+
puts BAR
|
22
|
+
end
|
23
|
+
|
24
|
+
def print_around_run(_options)
|
25
|
+
puts 'Running tests. This may take a while...'
|
26
|
+
# TODO: spinner/progress bar
|
27
|
+
yield
|
28
|
+
end
|
29
|
+
|
30
|
+
def print_results(options, results)
|
31
|
+
verbose_print_json_results(options, results)
|
32
|
+
|
33
|
+
puts BAR
|
34
|
+
puts 'Test Results:'
|
35
|
+
puts BAR
|
36
|
+
results.each do |result|
|
37
|
+
print format_tag(result), ': ', format_result(result), "\n"
|
38
|
+
verbose_puts(options, "\tsummary: ", result.result_message)
|
39
|
+
verbose_puts(options, "\tmessages: ", format_messages(result))
|
40
|
+
verbose_puts(options, "\trequests: ", format_requests(result))
|
41
|
+
verbose_puts(options, "\tinputs: ", format_inputs(result))
|
42
|
+
verbose_puts(options, "\toutputs: ", format_outputs(result))
|
43
|
+
end
|
44
|
+
puts BAR
|
45
|
+
end
|
46
|
+
|
47
|
+
def print_end_message(options); end
|
48
|
+
|
49
|
+
def print_error(options, exception)
|
50
|
+
puts COLOR.red "Error: #{exception.full_message}"
|
51
|
+
verbose_print(options, exception.backtrace&.join('\n'))
|
52
|
+
end
|
53
|
+
|
54
|
+
# private
|
55
|
+
|
56
|
+
def verbose_print(options, *args)
|
57
|
+
print(COLOR.dim(*args)) if options[:verbose]
|
58
|
+
end
|
59
|
+
|
60
|
+
def verbose_puts(options, *args)
|
61
|
+
args.push("\n")
|
62
|
+
verbose_print(options, *args)
|
63
|
+
end
|
64
|
+
|
65
|
+
def format_tag(result)
|
66
|
+
if result.runnable.respond_to?(:short_id)
|
67
|
+
"#{result.runnable.short_id} #{format_tag_suffix(result)}"
|
68
|
+
else
|
69
|
+
format_tag_suffix(result)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def format_tag_suffix(result)
|
74
|
+
result.runnable.short_title.presence || result.runnable.title.presence || result.runnable.id
|
75
|
+
end
|
76
|
+
|
77
|
+
def format_messages(result)
|
78
|
+
result.messages.map do |message|
|
79
|
+
"\n\t\t#{message.type}: #{message.message}"
|
80
|
+
end.join
|
81
|
+
end
|
82
|
+
|
83
|
+
def format_requests(result)
|
84
|
+
result.requests.map do |req_res|
|
85
|
+
"\n\t\t#{req_res.status} #{req_res.verb.upcase} #{req_res.url}"
|
86
|
+
end.join
|
87
|
+
end
|
88
|
+
|
89
|
+
def format_session_data(result, attr)
|
90
|
+
json = result.send(attr)
|
91
|
+
return '' if json.nil?
|
92
|
+
|
93
|
+
JSON.parse(json).map do |hash|
|
94
|
+
"\n\t\t#{hash['name']}: #{hash['value']}"
|
95
|
+
end.join
|
96
|
+
end
|
97
|
+
|
98
|
+
def format_inputs(result)
|
99
|
+
format_session_data(result, :input_json)
|
100
|
+
end
|
101
|
+
|
102
|
+
def format_outputs(result)
|
103
|
+
format_session_data(result, :output_json)
|
104
|
+
end
|
105
|
+
|
106
|
+
def format_result(result) # rubocop:disable Metrics/CyclomaticComplexity
|
107
|
+
case result.result
|
108
|
+
when 'pass'
|
109
|
+
COLOR.bold.green(CHECKMARK, ' pass')
|
110
|
+
when 'fail'
|
111
|
+
COLOR.bold.red 'X fail'
|
112
|
+
when 'skip'
|
113
|
+
COLOR.yellow '* skip'
|
114
|
+
when 'omit'
|
115
|
+
COLOR.blue '* omit'
|
116
|
+
when 'error'
|
117
|
+
COLOR.magenta 'X error'
|
118
|
+
when 'wait'
|
119
|
+
COLOR.bold '. wait'
|
120
|
+
when 'cancel'
|
121
|
+
COLOR.red 'X cancel'
|
122
|
+
when 'running'
|
123
|
+
COLOR.bold '- running'
|
124
|
+
else
|
125
|
+
raise StandardError.new, "Unrecognized result #{result.result}"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def verbose_print_json_results(options, results)
|
130
|
+
verbose_puts(options, BAR)
|
131
|
+
verbose_puts(options, 'JSON Test Results:')
|
132
|
+
verbose_puts(options, BAR)
|
133
|
+
verbose_puts(options, serialize(results))
|
134
|
+
verbose_puts(options, BAR)
|
135
|
+
end
|
136
|
+
|
137
|
+
def serialize(entity)
|
138
|
+
case entity.class.to_s
|
139
|
+
when 'Array'
|
140
|
+
JSON.pretty_generate(entity.map { |item| JSON.parse serialize(item) })
|
141
|
+
when lambda { |x|
|
142
|
+
defined?(x.constantize) && defined?("Inferno::Web::Serializers::#{x.split('::').last}".constantize)
|
143
|
+
}
|
144
|
+
"Inferno::Web::Serializers::#{entity.class.to_s.split('::').last}".constantize.render(entity)
|
145
|
+
else
|
146
|
+
raise StandardError, "CLI does not know how to serialize #{entity.class}"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
require 'pastel'
|
2
|
+
require 'active_support'
|
3
|
+
require_relative '../../utils/verify_runnable'
|
4
|
+
require_relative '../../utils/persist_inputs'
|
5
|
+
require_relative 'execute/console_outputter'
|
6
|
+
require_relative '../../result_summarizer'
|
7
|
+
|
8
|
+
module Inferno
|
9
|
+
module CLI
|
10
|
+
class Execute
|
11
|
+
include ::Inferno::Utils::VerifyRunnable
|
12
|
+
include ::Inferno::Utils::PersistInputs
|
13
|
+
|
14
|
+
attr_accessor :options
|
15
|
+
|
16
|
+
def self.suppress_output
|
17
|
+
begin
|
18
|
+
original_stdout = $stdout.clone
|
19
|
+
$stdout.reopen(File.new(File::NULL, 'w+'))
|
20
|
+
retval = yield
|
21
|
+
ensure
|
22
|
+
$stdout.reopen(original_stdout)
|
23
|
+
end
|
24
|
+
retval
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.boot_full_inferno
|
28
|
+
ENV['NO_DB'] = 'false'
|
29
|
+
|
30
|
+
# Inferno boot flow triggers migration and logger outputs it
|
31
|
+
Inferno::CLI::Execute.suppress_output { require_relative '../../../inferno' }
|
32
|
+
|
33
|
+
Inferno::Application.start(:executor)
|
34
|
+
end
|
35
|
+
|
36
|
+
def run(options)
|
37
|
+
print_help_and_exit if options[:help]
|
38
|
+
|
39
|
+
self.options = options
|
40
|
+
|
41
|
+
outputter.print_start_message(options)
|
42
|
+
|
43
|
+
results = []
|
44
|
+
outputter.print_around_run(options) do
|
45
|
+
if all_selected_groups_and_tests.empty?
|
46
|
+
test_run = create_test_run(suite)
|
47
|
+
run_one(suite, test_run)
|
48
|
+
|
49
|
+
results = test_runs_repo.results_for_test_run(test_run.id)
|
50
|
+
results = sort_results(results)
|
51
|
+
else
|
52
|
+
all_selected_groups_and_tests.each do |runnable|
|
53
|
+
test_run = create_test_run(runnable)
|
54
|
+
run_one(runnable, test_run)
|
55
|
+
|
56
|
+
results += sort_results(test_runs_repo.results_for_test_run(test_run.id))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# User may enter duplicate runnables, in which case this prevents a bug of extraneous results
|
62
|
+
results.uniq!(&:id)
|
63
|
+
|
64
|
+
outputter.print_results(options, results)
|
65
|
+
outputter.print_end_message(options)
|
66
|
+
|
67
|
+
# TODO: respect customized rollups
|
68
|
+
exit(0) if Inferno::ResultSummarizer.new(results).summarize == 'pass'
|
69
|
+
|
70
|
+
# exit(1) is for Thor failures
|
71
|
+
# exit(2) is for shell builtin failures
|
72
|
+
exit(3)
|
73
|
+
rescue Sequel::ValidationFailed => e
|
74
|
+
print_error_and_exit(e, 4)
|
75
|
+
rescue Sequel::ForeignKeyConstraintViolation => e
|
76
|
+
print_error_and_exit(e, 5)
|
77
|
+
rescue Inferno::Exceptions::RequiredInputsNotFound => e
|
78
|
+
print_error_and_exit(e, 6)
|
79
|
+
rescue Inferno::Exceptions::NotUserRunnableException => e
|
80
|
+
print_error_and_exit(e, 7)
|
81
|
+
rescue StandardError => e
|
82
|
+
print_error_and_exit(e, 8)
|
83
|
+
end
|
84
|
+
|
85
|
+
def print_help_and_exit
|
86
|
+
puts `NO_DB=true bundle exec inferno help execute`
|
87
|
+
exit(0)
|
88
|
+
end
|
89
|
+
|
90
|
+
def outputter
|
91
|
+
# TODO: swap outputter based on options
|
92
|
+
@outputter ||= Inferno::CLI::Execute::ConsoleOutputter.new
|
93
|
+
end
|
94
|
+
|
95
|
+
def all_selected_groups_and_tests
|
96
|
+
@all_selected_groups_and_tests ||= runnables_by_short_id + groups + tests
|
97
|
+
end
|
98
|
+
|
99
|
+
def run_one(runnable, test_run)
|
100
|
+
verify_runnable(
|
101
|
+
runnable,
|
102
|
+
thor_hash_to_inputs_array(options[:inputs]),
|
103
|
+
test_session.suite_options
|
104
|
+
)
|
105
|
+
|
106
|
+
persist_inputs(session_data_repo, create_params(test_session, suite), test_run)
|
107
|
+
|
108
|
+
dispatch_job(test_run)
|
109
|
+
end
|
110
|
+
|
111
|
+
def suite
|
112
|
+
@suite ||= Inferno::Repositories::TestSuites.new.find(options[:suite])
|
113
|
+
|
114
|
+
raise StandardError, "Test suite #{options[:suite]} not found" if @suite.nil?
|
115
|
+
|
116
|
+
@suite
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_runs_repo
|
120
|
+
@test_runs_repo ||= Inferno::Repositories::TestRuns.new
|
121
|
+
end
|
122
|
+
|
123
|
+
def create_test_run(runnable)
|
124
|
+
test_runs_repo.create(
|
125
|
+
create_params(test_session, runnable).merge({ status: 'queued' })
|
126
|
+
)
|
127
|
+
end
|
128
|
+
|
129
|
+
def results_repo
|
130
|
+
@results_repo ||= Inferno::Repositories::Results.new
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_groups_repo
|
134
|
+
@test_groups_repo ||= Inferno::Repositories::TestGroups.new
|
135
|
+
end
|
136
|
+
|
137
|
+
def tests_repo
|
138
|
+
@tests_repo ||= Inferno::Repositories::Tests.new
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_sessions_repo
|
142
|
+
@test_sessions_repo ||= Inferno::Repositories::TestSessions.new
|
143
|
+
end
|
144
|
+
|
145
|
+
def session_data_repo
|
146
|
+
@session_data_repo ||= Inferno::Repositories::SessionData.new
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_session
|
150
|
+
@test_session ||= test_sessions_repo.create({
|
151
|
+
test_suite_id: suite.id,
|
152
|
+
suite_options: thor_hash_to_suite_options_array(
|
153
|
+
options[:suite_options]
|
154
|
+
)
|
155
|
+
})
|
156
|
+
end
|
157
|
+
|
158
|
+
def create_params(test_session, runnable)
|
159
|
+
{
|
160
|
+
test_session_id: test_session.id,
|
161
|
+
runnable_id_key(runnable) => runnable.id,
|
162
|
+
inputs: thor_hash_to_inputs_array(options[:inputs])
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
def dispatch_job(test_run)
|
167
|
+
# TODO: move suppression to outputter? better suppression?
|
168
|
+
if options[:verbose]
|
169
|
+
Jobs.perform(Jobs::ExecuteTestRun, test_run.id, force_synchronous: true)
|
170
|
+
else
|
171
|
+
Inferno::CLI::Execute.suppress_output do
|
172
|
+
Jobs.perform(Jobs::ExecuteTestRun, test_run.id, force_synchronous: true)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def runnables_by_short_id
|
178
|
+
return [] if options[:short_ids].blank?
|
179
|
+
|
180
|
+
@runnables_by_short_id ||= options[:short_ids]&.map { |short_id| find_by_short_id(:group_or_test, short_id) }
|
181
|
+
end
|
182
|
+
|
183
|
+
def groups
|
184
|
+
return [] if options[:groups].blank?
|
185
|
+
|
186
|
+
@groups ||= options[:groups]&.map { |short_id| find_by_short_id(:group, short_id) }
|
187
|
+
end
|
188
|
+
|
189
|
+
def tests
|
190
|
+
return [] if options[:tests].blank?
|
191
|
+
|
192
|
+
@tests ||= options[:tests]&.map { |short_id| find_by_short_id(:test, short_id) }
|
193
|
+
end
|
194
|
+
|
195
|
+
def find_by_short_id(repo_symbol, short_id)
|
196
|
+
repo_symbol_to_array(repo_symbol).each do |repo|
|
197
|
+
repo.all.each do |entity|
|
198
|
+
return entity if short_id == entity.short_id && suite.id == entity.suite.id
|
199
|
+
end
|
200
|
+
end
|
201
|
+
raise StandardError, "#{repo_symbol.to_s.humanize} #{short_id} not found."
|
202
|
+
end
|
203
|
+
|
204
|
+
def repo_symbol_to_array(repo_symbol)
|
205
|
+
case repo_symbol
|
206
|
+
when :group
|
207
|
+
[test_groups_repo]
|
208
|
+
when :test
|
209
|
+
[tests_repo]
|
210
|
+
when :group_or_test
|
211
|
+
[test_groups_repo, tests_repo]
|
212
|
+
else
|
213
|
+
raise StandardError, "Unrecognized repo_symbol #{repo_symbol} for `find_by_short_id`"
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def thor_hash_to_suite_options_array(hash = {})
|
218
|
+
hash.to_a.map { |pair| Inferno::DSL::SuiteOption.new({ id: pair[0], value: pair[1] }) }
|
219
|
+
end
|
220
|
+
|
221
|
+
def thor_hash_to_inputs_array(hash = {})
|
222
|
+
hash.to_a.map { |pair| { name: pair[0], value: pair[1] } }
|
223
|
+
end
|
224
|
+
|
225
|
+
def print_error_and_exit(err, code)
|
226
|
+
outputter.print_error(options || {}, err)
|
227
|
+
rescue StandardError => e
|
228
|
+
puts "Caught exception #{e} while printing exception #{err}. Exiting."
|
229
|
+
ensure
|
230
|
+
exit(code)
|
231
|
+
end
|
232
|
+
|
233
|
+
def runnable_type(runnable)
|
234
|
+
if runnable < Inferno::TestSuite
|
235
|
+
:suite
|
236
|
+
elsif runnable < Inferno::TestGroup
|
237
|
+
:group
|
238
|
+
elsif runnable < Inferno::Test
|
239
|
+
:test
|
240
|
+
else
|
241
|
+
raise StandardError, "Unidentified runnable #{runnable}"
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def runnable_id_key(runnable)
|
246
|
+
case runnable_type(runnable)
|
247
|
+
when :suite
|
248
|
+
:test_suite_id
|
249
|
+
when :group
|
250
|
+
:test_group_id
|
251
|
+
else
|
252
|
+
:test_id
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def sort_results(results)
|
257
|
+
results.sort do |result, other|
|
258
|
+
if result.runnable < Inferno::TestSuite
|
259
|
+
-1
|
260
|
+
elsif other.runnable < Inferno::TestSuite
|
261
|
+
1
|
262
|
+
else
|
263
|
+
result.runnable.short_id <=> other.runnable.short_id
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
@@ -5,6 +5,7 @@ require_relative 'suite'
|
|
5
5
|
require_relative 'suites'
|
6
6
|
require_relative 'new'
|
7
7
|
require_relative '../../version'
|
8
|
+
require_relative 'execute'
|
8
9
|
|
9
10
|
module Inferno
|
10
11
|
module CLI
|
@@ -65,18 +66,86 @@ module Inferno
|
|
65
66
|
puts "Inferno Core v#{Inferno::VERSION}"
|
66
67
|
end
|
67
68
|
|
69
|
+
EXECUTE_HELP = <<~END_OF_HELP.freeze
|
70
|
+
Run Inferno tests in the command line. Exits with 0 only if test entity passes.
|
71
|
+
Must be run with test kit as working directory.
|
72
|
+
|
73
|
+
You must have background services running: `bundle exec inferno services start`
|
74
|
+
|
75
|
+
You can view suite ids with: `bundle exec inferno suites`
|
76
|
+
|
77
|
+
Examples:
|
78
|
+
|
79
|
+
(These examples only work from within the inferno_core directory).
|
80
|
+
|
81
|
+
`bundle exec inferno execute --suite dev_validator \
|
82
|
+
--inputs "url:https://hapi.fhir.org/baseR4" \
|
83
|
+
patient_id:1234321`
|
84
|
+
=> Outputs test results
|
85
|
+
|
86
|
+
`bundle exec inferno execute --suite dev_validator \
|
87
|
+
--inputs "url:https://hapi.fhir.org/baseR4" \
|
88
|
+
patient_id:1234321 \
|
89
|
+
--tests 1.01 1.02`
|
90
|
+
=> Run specific tests from suite
|
91
|
+
END_OF_HELP
|
92
|
+
desc 'execute', 'Run Inferno tests in command line'
|
93
|
+
long_desc EXECUTE_HELP, wrap: false
|
94
|
+
option :suite,
|
95
|
+
aliases: ['-s'],
|
96
|
+
type: :string,
|
97
|
+
desc: 'Test suite id to run or to select groups and tests from',
|
98
|
+
banner: 'id'
|
99
|
+
option :suite_options,
|
100
|
+
aliases: ['-u'], # NOTE: -o will be for outputter
|
101
|
+
type: :hash,
|
102
|
+
desc: 'Suite options'
|
103
|
+
option :groups,
|
104
|
+
aliases: ['-g'],
|
105
|
+
type: :array,
|
106
|
+
desc: 'Series of test group short ids (AKA sequence number) to run, requires suite'
|
107
|
+
option :tests,
|
108
|
+
aliases: ['-t'],
|
109
|
+
type: :array,
|
110
|
+
desc: 'Series of test short ids (AKA sequence number) to run, requires suite'
|
111
|
+
option :short_ids,
|
112
|
+
aliases: ['-r'],
|
113
|
+
type: :array,
|
114
|
+
desc: 'Series of test or group short ids (AKA sequence number) to run, requires suite'
|
115
|
+
option :inputs,
|
116
|
+
aliases: ['-i'],
|
117
|
+
type: :hash,
|
118
|
+
desc: 'Inputs (i.e: --inputs=foo:bar goo:baz)'
|
119
|
+
option :verbose,
|
120
|
+
aliases: ['-v'],
|
121
|
+
type: :boolean,
|
122
|
+
default: false,
|
123
|
+
desc: 'Output additional information for debugging'
|
124
|
+
option :help,
|
125
|
+
aliases: ['-h'],
|
126
|
+
type: :boolean,
|
127
|
+
default: false,
|
128
|
+
desc: 'Display this message'
|
129
|
+
def execute
|
130
|
+
Execute.boot_full_inferno
|
131
|
+
Execute.new.run(options)
|
132
|
+
end
|
133
|
+
|
134
|
+
# https://github.com/rails/thor/issues/244 - Make Thor exit(1) on Errors/Exceptions
|
135
|
+
def self.exit_on_failure?
|
136
|
+
true
|
137
|
+
end
|
138
|
+
|
68
139
|
private
|
69
140
|
|
70
141
|
# https://github.com/rubocop/rubocop/issues/12571 - still affects Ruby 3.1 upto Rubocop 1.63
|
71
|
-
|
72
|
-
def without_bundler(&block)
|
142
|
+
def without_bundler(&)
|
73
143
|
if defined?(Bundler) && ENV['BUNDLE_GEMFILE']
|
74
|
-
Bundler.with_unbundled_env(&
|
144
|
+
Bundler.with_unbundled_env(&)
|
75
145
|
else
|
76
146
|
yield
|
77
147
|
end
|
78
148
|
end
|
79
|
-
# rubocop:enable Naming/BlockForwarding
|
80
149
|
end
|
81
150
|
end
|
82
151
|
end
|
@@ -98,5 +98,20 @@ http {
|
|
98
98
|
|
99
99
|
proxy_pass http://hl7_validator_service:3500/;
|
100
100
|
}
|
101
|
+
|
102
|
+
location /fhirpath/ {
|
103
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
104
|
+
proxy_set_header Host $http_host;
|
105
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
106
|
+
proxy_set_header X-Forwarded-Port $server_port;
|
107
|
+
proxy_redirect off;
|
108
|
+
proxy_set_header Connection '';
|
109
|
+
proxy_http_version 1.1;
|
110
|
+
chunked_transfer_encoding off;
|
111
|
+
proxy_buffering off;
|
112
|
+
proxy_cache off;
|
113
|
+
|
114
|
+
proxy_pass http://fhirpath:6789/;
|
115
|
+
}
|
101
116
|
}
|
102
117
|
}
|
@@ -23,6 +23,10 @@ services:
|
|
23
23
|
environment:
|
24
24
|
EXTERNAL_VALIDATOR_URL: http://localhost/validatorapi
|
25
25
|
VALIDATOR_BASE_PATH: /validator
|
26
|
+
fhirpath:
|
27
|
+
image: infernocommunity/fhirpath-service
|
28
|
+
ports:
|
29
|
+
- "6789:6789"
|
26
30
|
nginx:
|
27
31
|
image: nginx
|
28
32
|
volumes:
|
@@ -32,6 +36,7 @@ services:
|
|
32
36
|
command: [nginx, '-g', 'daemon off;']
|
33
37
|
depends_on:
|
34
38
|
- fhir_validator_app
|
39
|
+
- fhirpath
|
35
40
|
redis:
|
36
41
|
image: redis
|
37
42
|
ports:
|
data/lib/inferno/apps/cli.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
+
require_relative '../../../../utils/verify_runnable'
|
2
|
+
require_relative '../../../../utils/persist_inputs'
|
3
|
+
|
1
4
|
module Inferno
|
2
5
|
module Web
|
3
6
|
module Controllers
|
4
7
|
module TestRuns
|
5
8
|
class Create < Controller
|
9
|
+
include ::Inferno::Utils::VerifyRunnable
|
10
|
+
include ::Inferno::Utils::PersistInputs
|
11
|
+
|
6
12
|
include Import[
|
7
13
|
test_sessions_repo: 'inferno.repositories.test_sessions',
|
8
14
|
session_data_repo: 'inferno.repositories.session_data',
|
@@ -11,37 +17,6 @@ module Inferno
|
|
11
17
|
|
12
18
|
PARAMS = [:test_session_id, :test_suite_id, :test_group_id, :test_id].freeze
|
13
19
|
|
14
|
-
def verify_runnable(runnable, inputs, selected_suite_options)
|
15
|
-
missing_inputs = runnable&.missing_inputs(inputs, selected_suite_options)
|
16
|
-
user_runnable = runnable&.user_runnable?
|
17
|
-
raise Inferno::Exceptions::RequiredInputsNotFound, missing_inputs if missing_inputs&.any?
|
18
|
-
raise Inferno::Exceptions::NotUserRunnableException unless user_runnable
|
19
|
-
end
|
20
|
-
|
21
|
-
def persist_inputs(params, test_run)
|
22
|
-
available_inputs = test_run.runnable.available_inputs
|
23
|
-
params[:inputs]&.each do |input_params|
|
24
|
-
input =
|
25
|
-
available_inputs
|
26
|
-
.find { |_, runnable_input| runnable_input.name == input_params[:name] }
|
27
|
-
&.last
|
28
|
-
|
29
|
-
if input.nil?
|
30
|
-
Inferno::Application['logger'].warn(
|
31
|
-
"Unknown input `#{input_params[:name]}` for #{test_run.runnable.id}: #{test_run.runnable.title}"
|
32
|
-
)
|
33
|
-
next
|
34
|
-
end
|
35
|
-
|
36
|
-
session_data_repo.save(
|
37
|
-
test_session_id: test_run.test_session_id,
|
38
|
-
name: input.name,
|
39
|
-
value: input_params[:value],
|
40
|
-
type: input.type
|
41
|
-
)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
20
|
def handle(req, res)
|
46
21
|
test_session = test_sessions_repo.find(req.params[:test_session_id])
|
47
22
|
|
@@ -60,7 +35,7 @@ module Inferno
|
|
60
35
|
|
61
36
|
res.body = serialize(test_run, suite_options: test_session.suite_options)
|
62
37
|
|
63
|
-
persist_inputs(req.params, test_run)
|
38
|
+
persist_inputs(session_data_repo, req.params, test_run)
|
64
39
|
|
65
40
|
Jobs.perform(Jobs::ExecuteTestRun, test_run.id)
|
66
41
|
rescue Sequel::ValidationFailed, Sequel::ForeignKeyConstraintViolation,
|