inferno_core 0.4.43 → 0.4.44

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/inferno/apps/cli/execute/console_outputter.rb +152 -0
  3. data/lib/inferno/apps/cli/execute.rb +269 -0
  4. data/lib/inferno/apps/cli/main.rb +73 -4
  5. data/lib/inferno/apps/cli/templates/.env.development +2 -1
  6. data/lib/inferno/apps/cli/templates/.env.production +2 -1
  7. data/lib/inferno/apps/cli/templates/.env.test +1 -0
  8. data/lib/inferno/apps/cli/templates/.gitignore +1 -0
  9. data/lib/inferno/apps/cli/templates/config/nginx.background.conf.tt +15 -0
  10. data/lib/inferno/apps/cli/templates/docker-compose.background.yml.tt +5 -0
  11. data/lib/inferno/apps/cli/templates/docker-compose.yml.tt +4 -0
  12. data/lib/inferno/apps/cli.rb +0 -1
  13. data/lib/inferno/apps/web/controllers/test_runs/create.rb +7 -32
  14. data/lib/inferno/apps/web/serializers/serializer.rb +3 -0
  15. data/lib/inferno/config/boot/executor.rb +14 -0
  16. data/lib/inferno/dsl/auth_info.rb +77 -72
  17. data/lib/inferno/dsl/fhir_client_builder.rb +2 -2
  18. data/lib/inferno/dsl/fhir_resource_validation.rb +4 -0
  19. data/lib/inferno/dsl/http_client_builder.rb +2 -2
  20. data/lib/inferno/dsl/links.rb +100 -0
  21. data/lib/inferno/dsl/runnable.rb +6 -1
  22. data/lib/inferno/entities/has_runnable.rb +1 -1
  23. data/lib/inferno/entities/test.rb +4 -4
  24. data/lib/inferno/entities/test_group.rb +2 -2
  25. data/lib/inferno/entities/test_suite.rb +2 -24
  26. data/lib/inferno/exceptions.rb +6 -0
  27. data/lib/inferno/ext/fhir_models.rb +3 -3
  28. data/lib/inferno/jobs.rb +4 -4
  29. data/lib/inferno/public/237.bundle.js +1 -0
  30. data/lib/inferno/public/assets.json +1 -1
  31. data/lib/inferno/public/bundle.js +42 -63
  32. data/lib/inferno/public/bundle.js.LICENSE.txt +5 -33
  33. data/lib/inferno/repositories/repository.rb +1 -1
  34. data/lib/inferno/result_summarizer.rb +1 -1
  35. data/lib/inferno/test_runner.rb +2 -2
  36. data/lib/inferno/utils/middleware/request_logger.rb +1 -1
  37. data/lib/inferno/utils/persist_inputs.rb +30 -0
  38. data/lib/inferno/utils/preset_template_generator.rb +1 -1
  39. data/lib/inferno/utils/verify_runnable.rb +15 -0
  40. data/lib/inferno/version.rb +1 -1
  41. data/spec/factories/result.rb +4 -0
  42. data/spec/fixtures/basic_test_group.rb +2 -1
  43. data/spec/fixtures/run_as_group_test_group.rb +11 -0
  44. metadata +24 -170
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09f9e6a4ff6df2749650a972de54dbf8e693de38469c3ac8cb781ee99cbf6ce4'
4
- data.tar.gz: 2153922e52c9207e092526b7a0bedaca8b9333530c4c2e41515083001ba09097
3
+ metadata.gz: c185042b4e2042dc69fc734d9ecec9ee77ff98c9fe1dfd8204b9f1c648220433
4
+ data.tar.gz: 85dd03b14c444415be44ef24f4d7999465639806343845841808c80fc4d502bd
5
5
  SHA512:
6
- metadata.gz: fe29bbefe0208e36c4e9919dba3292f35779f1c9d8e9810e98b03837ef73b3538bf19bd752e659733da7bc6b646a190249a7017b44ff45a679e29b2faa3d91fe
7
- data.tar.gz: 8b43e4f565366c80930ab4150c1c1a493fc8fe8551295851ef49eef213e42a185521abd62438e5a0514f51463968bf24e84824aa72c9ef20f5880a65b5145cb1
6
+ metadata.gz: ff47ba5db1e469fdb79eb2136d43c05eb339766fe99f8ad88c32750faf65812903230a64b758e3a676cc2e6b281fffc36ad585ef9ec58573293b2a9d381bdb28
7
+ data.tar.gz: 5ffb96cda09467091258b9dc9851141470d97ad4e9e026bd198aa5a8f1253d79793dbc092c5c6ecf5e275d19d50e7660172fc0c2d7f01cc9c9357bea00507553
@@ -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
- # rubocop:disable Naming/BlockForwarding
72
- def without_bundler(&block)
142
+ def without_bundler(&)
73
143
  if defined?(Bundler) && ENV['BUNDLE_GEMFILE']
74
- Bundler.with_unbundled_env(&block)
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
@@ -1,2 +1,3 @@
1
1
  FHIR_RESOURCE_VALIDATOR_URL=http://localhost/hl7validatorapi
2
- REDIS_URL=redis://localhost:6379/0
2
+ REDIS_URL=redis://localhost:6379/0
3
+ FHIRPATH_URL=http://localhost/fhirpath
@@ -1,2 +1,3 @@
1
1
  REDIS_URL=redis://redis:6379/0
2
- FHIR_RESOURCE_VALIDATOR_URL=http://hl7_validator_service:3500
2
+ FHIR_RESOURCE_VALIDATOR_URL=http://hl7_validator_service:3500
3
+ FHIRPATH_URL=http://fhirpath:6789
@@ -1,2 +1,3 @@
1
1
  FHIR_RESOURCE_VALIDATOR_URL=https://example.com/validatorapi
2
2
  ASYNC_JOBS=false
3
+ FHIRPATH_URL=https://example.com/fhirpath
@@ -12,6 +12,7 @@
12
12
  .settings/org.eclipse.wst.jsdt.ui.superType.container
13
13
  .settings/org.eclipse.wst.jsdt.ui.superType.name
14
14
  .idea
15
+ *.gem
15
16
 
16
17
  /coverage
17
18
  /spec/examples.txt
@@ -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:
@@ -27,6 +27,10 @@ services:
27
27
  extends:
28
28
  file: docker-compose.background.yml
29
29
  service: fhir_validator_app
30
+ fhirpath:
31
+ extends:
32
+ file: docker-compose.background.yml
33
+ service: fhirpath
30
34
  nginx:
31
35
  extends:
32
36
  file: docker-compose.background.yml
@@ -1,5 +1,4 @@
1
1
  require 'thor'
2
-
3
2
  require_relative 'cli/main'
4
3
 
5
4
  module Inferno
@@ -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,
@@ -1,3 +1,6 @@
1
+ require 'oj'
2
+ require 'blueprinter'
3
+
1
4
  module Inferno
2
5
  module Web
3
6
  module Serializers