inferno_core 0.4.29 → 0.4.30
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/new.rb +42 -18
- data/lib/inferno/db/migrations/010_add_validator_sessions.rb +14 -0
- data/lib/inferno/db/schema.rb +14 -0
- data/lib/inferno/dsl/fhir_client_builder.rb +1 -1
- data/lib/inferno/dsl/fhir_resource_validation.rb +21 -7
- data/lib/inferno/dsl/http_client_builder.rb +1 -1
- data/lib/inferno/entities/validator_session.rb +22 -0
- data/lib/inferno/entities.rb +1 -0
- data/lib/inferno/jobs/invoke_validator_session.rb +3 -3
- data/lib/inferno/public/175.bundle.js +1 -0
- data/lib/inferno/public/assets.json +1 -1
- data/lib/inferno/public/bundle.js +21 -21
- data/lib/inferno/public/bundle.js.LICENSE.txt +17 -5
- data/lib/inferno/repositories/validator_sessions.rb +58 -0
- data/lib/inferno/repositories.rb +1 -0
- data/lib/inferno/utils/ig_downloader.rb +57 -0
- data/lib/inferno/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4439e9a6fff9fbd72efd09c4a14342206c509151fc0b6782089bf991b1849442
|
4
|
+
data.tar.gz: f386dba398dbf37c48fd3864fa4fe21e89732abccf155c5a2002530f802c7a34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 062e5019bcd5b1ca6cf67ac9fe94719e4a9e82fe2e8243f57a928ab28df35e8d517e0b180e48f6e7c1a5555ab691009399fc7f8d509d2d02cbbe0c4cbae8a3a3
|
7
|
+
data.tar.gz: 6105c47597428f29714650ea36492892bd399bac93323178144d2ad9b52dcbf27e643d514d18de533ec7c76d63dc9c53128fab9282b50d5cf91ea069ddf2760b
|
data/lib/inferno/apps/cli/new.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'bundler'
|
3
3
|
require_relative '../../utils/named_thor_actions'
|
4
|
+
require_relative '../../utils/ig_downloader'
|
4
5
|
require_relative '../../version'
|
5
6
|
|
6
7
|
module Inferno
|
@@ -8,17 +9,27 @@ module Inferno
|
|
8
9
|
class New < Thor::Group
|
9
10
|
include Thor::Actions
|
10
11
|
include Inferno::Utils::NamedThorActions
|
12
|
+
include Inferno::Utils::IgDownloader
|
11
13
|
|
12
14
|
desc <<~HELP
|
13
15
|
Generate a new Inferno test kit for FHIR software testing
|
14
16
|
|
15
17
|
Examples:
|
16
18
|
|
17
|
-
`inferno new
|
18
|
-
=> generates an Inferno
|
19
|
+
`inferno new my_test_kit`
|
20
|
+
=> generates an Inferno test kit
|
19
21
|
|
20
|
-
`inferno new
|
21
|
-
=> generates Inferno
|
22
|
+
`inferno new test-us-core -i hl7.fhir.us.core@6.1.0`
|
23
|
+
=> generates Inferno test kit with US Core 6.1.0 implementation guide
|
24
|
+
|
25
|
+
`inferno new TestMatching -i https://build.fhir.org/ig/HL7/fhir-identity-matching-ig/`
|
26
|
+
=> generates Inferno test kit with an implementation guide from its continuous web build
|
27
|
+
|
28
|
+
`inferno new test-my-ig -a "My Name" -i file:///absolute/path/to/my/ig/package.tgz`
|
29
|
+
=> generates Inferno test kit with a local IG and specifies My Name as gem author
|
30
|
+
|
31
|
+
`inferno new test_my_igs -a "My Name" -a "Another Name" -i file:///my/first/package.tgz -i hl7.fhir.us.core@6.1.0`
|
32
|
+
=> generates Inferno test kit with multiple IGs and multiple authors
|
22
33
|
|
23
34
|
https://inferno-framework.github.io/index.html
|
24
35
|
HELP
|
@@ -45,15 +56,23 @@ module Inferno
|
|
45
56
|
type: :boolean,
|
46
57
|
aliases: '-b',
|
47
58
|
default: false,
|
48
|
-
desc: 'Do not run bundle install'
|
59
|
+
desc: 'Do not run bundle install or inferno migrate'
|
60
|
+
class_option :implementation_guide,
|
61
|
+
type: :string,
|
62
|
+
aliases: '-i',
|
63
|
+
repeatable: true,
|
64
|
+
desc: 'Load an Implementation Guide by FHIR Registry name, URL, or absolute path'
|
49
65
|
|
50
66
|
add_runtime_options!
|
51
67
|
|
52
|
-
def
|
68
|
+
def create_test_kit
|
53
69
|
directory('.', root_name, { mode: :preserve, recursive: true, verbose: !options['quiet'] })
|
54
70
|
|
55
|
-
|
56
|
-
|
71
|
+
inside(root_name) do
|
72
|
+
bundle_install
|
73
|
+
inferno_migrate
|
74
|
+
load_igs
|
75
|
+
end
|
57
76
|
|
58
77
|
say_unless_quiet "Created #{root_name} Inferno test kit!", :green
|
59
78
|
|
@@ -65,10 +84,6 @@ module Inferno
|
|
65
84
|
|
66
85
|
private
|
67
86
|
|
68
|
-
def ig_path
|
69
|
-
File.join('lib', library_name, 'igs')
|
70
|
-
end
|
71
|
-
|
72
87
|
def authors
|
73
88
|
options['author'].presence || [default_author]
|
74
89
|
end
|
@@ -80,18 +95,27 @@ module Inferno
|
|
80
95
|
def bundle_install
|
81
96
|
return if options['skip_bundle']
|
82
97
|
|
83
|
-
|
84
|
-
|
85
|
-
run 'bundle install', verbose: !options['quiet'], capture: options['quiet']
|
86
|
-
end
|
98
|
+
Bundler.with_unbundled_env do
|
99
|
+
run 'bundle install', verbose: !options['quiet'], capture: options['quiet']
|
87
100
|
end
|
88
101
|
end
|
89
102
|
|
90
103
|
def inferno_migrate
|
91
104
|
return if options['skip_bundle']
|
92
105
|
|
93
|
-
|
94
|
-
|
106
|
+
run 'bundle exec inferno migrate', verbose: !options['quiet'], capture: options['quiet']
|
107
|
+
end
|
108
|
+
|
109
|
+
def load_igs
|
110
|
+
config = { verbose: !options['quiet'] }
|
111
|
+
options['implementation_guide']&.each_with_index do |ig, idx|
|
112
|
+
uri = options['implementation_guide'].length == 1 ? load_ig(ig, nil, config) : load_ig(ig, idx, config)
|
113
|
+
say_unless_quiet "Downloaded IG from #{uri}"
|
114
|
+
rescue OpenURI::HTTPError => e
|
115
|
+
say_unless_quiet "Failed to install implementation guide #{ig}", :red
|
116
|
+
say_unless_quiet e.message, :red
|
117
|
+
rescue StandardError => e
|
118
|
+
say_unless_quiet e.message, :red
|
95
119
|
end
|
96
120
|
end
|
97
121
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Sequel.migration do
|
2
|
+
change do
|
3
|
+
create_table :validator_sessions do
|
4
|
+
column :id, String, primary_key: true, null: false, size: 36
|
5
|
+
column :validator_session_id, String, null: false, size: 255
|
6
|
+
column :test_suite_id, String, null: false, size: 255
|
7
|
+
column :validator_name, String, null: false, size: 255
|
8
|
+
column :suite_options, String, text: true
|
9
|
+
column :last_accessed, DateTime, null: false
|
10
|
+
index [:validator_session_id], unique: true
|
11
|
+
index [:test_suite_id, :validator_name, :suite_options], unique: true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/inferno/db/schema.rb
CHANGED
@@ -23,6 +23,20 @@ Sequel.migration do
|
|
23
23
|
primary_key [:id]
|
24
24
|
end
|
25
25
|
|
26
|
+
create_table(:validator_sessions, :ignore_index_errors=>true) do
|
27
|
+
String :id, :size=>36, :null=>false
|
28
|
+
String :validator_session_id, :size=>255, :null=>false
|
29
|
+
String :test_suite_id, :size=>255, :null=>false
|
30
|
+
String :validator_name, :size=>255, :null=>false
|
31
|
+
String :suite_options, :text=>true
|
32
|
+
DateTime :last_accessed, :null=>false
|
33
|
+
|
34
|
+
primary_key [:id]
|
35
|
+
|
36
|
+
index [:test_suite_id, :validator_name, :suite_options], :unique=>true
|
37
|
+
index [:validator_session_id], :unique=>true
|
38
|
+
end
|
39
|
+
|
26
40
|
create_table(:session_data, :ignore_index_errors=>true) do
|
27
41
|
String :id, :size=>255, :null=>false
|
28
42
|
foreign_key :test_session_id, :test_sessions, :type=>String, :size=>36, :null=>false, :key=>[:id]
|
@@ -27,10 +27,12 @@ module Inferno
|
|
27
27
|
|
28
28
|
class Validator
|
29
29
|
attr_reader :requirements
|
30
|
-
attr_accessor :session_id
|
30
|
+
attr_accessor :session_id, :name, :test_suite_id
|
31
31
|
|
32
32
|
# @private
|
33
|
-
def initialize(requirements = nil, &)
|
33
|
+
def initialize(name = nil, test_suite_id = nil, requirements = nil, &)
|
34
|
+
@name = name
|
35
|
+
@test_suite_id = test_suite_id
|
34
36
|
instance_eval(&)
|
35
37
|
@requirements = requirements
|
36
38
|
end
|
@@ -40,6 +42,10 @@ module Inferno
|
|
40
42
|
ENV.fetch('FHIR_RESOURCE_VALIDATOR_URL')
|
41
43
|
end
|
42
44
|
|
45
|
+
def validator_session_repo
|
46
|
+
@validator_session_repo ||= Inferno::Repositories::ValidatorSessions.new
|
47
|
+
end
|
48
|
+
|
43
49
|
# Set the url of the validator service
|
44
50
|
#
|
45
51
|
# @param validator_url [String]
|
@@ -231,6 +237,10 @@ module Inferno
|
|
231
237
|
|
232
238
|
# @private
|
233
239
|
def wrap_resource_for_hl7_wrapper(resource, profile_url)
|
240
|
+
validator_session_id =
|
241
|
+
validator_session_repo.find_validator_session_id(test_suite_id,
|
242
|
+
name.to_s, requirements)
|
243
|
+
@session_id = validator_session_id if validator_session_id
|
234
244
|
wrapped_resource = {
|
235
245
|
cliContext: {
|
236
246
|
**cli_context.definition,
|
@@ -269,8 +279,11 @@ module Inferno
|
|
269
279
|
# @private
|
270
280
|
def operation_outcome_from_hl7_wrapped_response(response)
|
271
281
|
res = JSON.parse(response)
|
272
|
-
|
273
|
-
|
282
|
+
if res['sessionId'] != @session_id
|
283
|
+
validator_session_repo.save(test_suite_id:, validator_session_id: res['sessionId'],
|
284
|
+
validator_name: name.to_s, suite_options: requirements)
|
285
|
+
@session_id = res['sessionId']
|
286
|
+
end
|
274
287
|
|
275
288
|
# assume for now that one resource -> one request
|
276
289
|
issues = res['outcomes'][0]['issues']&.map do |i|
|
@@ -287,7 +300,7 @@ module Inferno
|
|
287
300
|
else
|
288
301
|
runnable.add_message('error', "Validator Response: HTTP #{response.status}\n#{response.body}")
|
289
302
|
raise Inferno::Exceptions::ErrorInValidatorException,
|
290
|
-
'Validator response was an unexpected format. '\
|
303
|
+
'Validator response was an unexpected format. ' \
|
291
304
|
'Review Messages tab or validator service logs for more information.'
|
292
305
|
end
|
293
306
|
end
|
@@ -300,7 +313,8 @@ module Inferno
|
|
300
313
|
CLICONTEXT_DEFAULTS = {
|
301
314
|
sv: '4.0.1',
|
302
315
|
doNative: false,
|
303
|
-
extensions: ['any']
|
316
|
+
extensions: ['any'],
|
317
|
+
disableDefaultResourceFetcher: true
|
304
318
|
}.freeze
|
305
319
|
|
306
320
|
# @private
|
@@ -353,7 +367,7 @@ module Inferno
|
|
353
367
|
def fhir_resource_validator(name = :default, required_suite_options: nil, &block)
|
354
368
|
current_validators = fhir_validators[name] || []
|
355
369
|
|
356
|
-
new_validator = Inferno::DSL::FHIRResourceValidation::Validator.new(required_suite_options, &block)
|
370
|
+
new_validator = Inferno::DSL::FHIRResourceValidation::Validator.new(name, id, required_suite_options, &block)
|
357
371
|
|
358
372
|
current_validators.reject! { |validator| validator.requirements == required_suite_options }
|
359
373
|
current_validators << new_validator
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Inferno
|
2
|
+
module Entities
|
3
|
+
class ValidatorSession < Entity
|
4
|
+
ATTRIBUTES = [
|
5
|
+
:id,
|
6
|
+
:created_at,
|
7
|
+
:updated_at,
|
8
|
+
:validator_session_id,
|
9
|
+
:test_suite_id,
|
10
|
+
:validator_name,
|
11
|
+
:suite_options,
|
12
|
+
:validator_index
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
include Inferno::Entities::Attributes
|
16
|
+
|
17
|
+
def initialize(params)
|
18
|
+
super(params, ATTRIBUTES)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/inferno/entities.rb
CHANGED
@@ -11,6 +11,7 @@ require_relative 'entities/test_group'
|
|
11
11
|
require_relative 'entities/test_run'
|
12
12
|
require_relative 'entities/test_session'
|
13
13
|
require_relative 'entities/test_suite'
|
14
|
+
require_relative 'entities/validator_session'
|
14
15
|
|
15
16
|
module Inferno
|
16
17
|
# Entities are domain objects whose identity is based on an `id`. Entities
|
@@ -6,13 +6,13 @@ module Inferno
|
|
6
6
|
def perform(suite_id, validator_name, validator_index)
|
7
7
|
suite = Inferno::Repositories::TestSuites.new.find suite_id
|
8
8
|
validator = suite.fhir_validators[validator_name.to_sym][validator_index]
|
9
|
-
|
10
9
|
response_body = validator.validate(FHIR::Patient.new, 'http://hl7.org/fhir/StructureDefinition/Patient')
|
11
|
-
|
12
10
|
if response_body.start_with? '{'
|
13
11
|
res = JSON.parse(response_body)
|
14
12
|
session_id = res['sessionId']
|
15
|
-
|
13
|
+
session_repo = Inferno::Repositories::ValidatorSessions.new
|
14
|
+
session_repo.save(test_suite_id: suite_id, validator_session_id: session_id,
|
15
|
+
validator_name:, suite_options: validator.requirements)
|
16
16
|
validator.session_id = session_id
|
17
17
|
else
|
18
18
|
Inferno::Application['logger'].error("InvokeValidatorSession - error from validator: #{response_body}")
|
@@ -0,0 +1 @@
|
|
1
|
+
"use strict";(self.webpackChunkinferno_web_app=self.webpackChunkinferno_web_app||[]).push([[175],{9175:(t,e,n)=>{n.r(e),n.d(e,{getCLS:()=>d,getFCP:()=>m,getFID:()=>v,getLCP:()=>h,getTTFB:()=>S});var i,a,r=function(t){return{name:t,value:arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1,delta:0,entries:[],id:"".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),isFinal:!1}},o=function(t,e){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var n=new PerformanceObserver((function(t){return t.getEntries().map(e)}));return n.observe({type:t,buffered:!0}),n}}catch(t){}},s=!1,u=!1,c=function(t){s=!t.persisted},p=function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];u||(addEventListener("pagehide",c),addEventListener("beforeunload",(function(){})),u=!0),addEventListener("visibilitychange",(function(e){var n=e.timeStamp;"hidden"===document.visibilityState&&t({timeStamp:n,isUnloading:s})}),{capture:!0,once:e})},l=function(t,e,n,i){var a;return function(){n&&e.isFinal&&n.disconnect(),e.value>=0&&(i||e.isFinal||"hidden"===document.visibilityState)&&(e.delta=e.value-(a||0),(e.delta||e.isFinal||void 0===a)&&(t(e),a=e.value))}},d=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=r("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),e())},s=o("layout-shift",a);s&&(e=l(t,i,s,n),p((function(t){var n=t.isUnloading;s.takeRecords().map(a),n&&(i.isFinal=!0),e()})))},f=function(){return void 0===i&&(i="hidden"===document.visibilityState?0:1/0,p((function(t){var e=t.timeStamp;return i=e}),!0)),{get timeStamp(){return i}}},m=function(t){var e,n=r("FCP"),i=f(),a=o("paint",(function(t){"first-contentful-paint"===t.name&&t.startTime<i.timeStamp&&(n.value=t.startTime,n.isFinal=!0,n.entries.push(t),e())}));a&&(e=l(t,n,a))},v=function(t){var e=r("FID"),n=f(),i=function(t){t.startTime<n.timeStamp&&(e.value=t.processingStart-t.startTime,e.entries.push(t),e.isFinal=!0,s())},a=o("first-input",i),s=l(t,e,a);a?p((function(){a.takeRecords().map(i),a.disconnect()}),!0):window.perfMetrics&&window.perfMetrics.onFirstInputDelay&&window.perfMetrics.onFirstInputDelay((function(t,i){i.timeStamp<n.timeStamp&&(e.value=t,e.isFinal=!0,e.entries=[{entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+t}],s())}))},g=function(){return a||(a=new Promise((function(t){return["scroll","keydown","pointerdown"].map((function(e){addEventListener(e,t,{once:!0,passive:!0,capture:!0})}))}))),a},h=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=r("LCP"),a=f(),s=function(t){var n=t.startTime;n<a.timeStamp?(i.value=n,i.entries.push(t)):i.isFinal=!0,e()},u=o("largest-contentful-paint",s);if(u){e=l(t,i,u,n);var c=function(){i.isFinal||(u.takeRecords().map(s),i.isFinal=!0,e())};g().then(c),p(c,!0)}},S=function(t){var e,n=r("TTFB");e=function(){try{var e=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,e={entryType:"navigation",startTime:0};for(var n in t)"navigationStart"!==n&&"toJSON"!==n&&(e[n]=Math.max(t[n]-t.navigationStart,0));return e}();n.value=n.delta=e.responseStart,n.entries=[e],n.isFinal=!0,t(n)}catch(t){}},"complete"===document.readyState?setTimeout(e,0):addEventListener("pageshow",e)}}}]);
|