inferno_core 0.1.0 → 0.1.2
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/lib/inferno/apps/web/controllers/test_runs/destroy.rb +39 -0
- data/lib/inferno/apps/web/router.rb +1 -1
- data/lib/inferno/apps/web/serializers/result.rb +1 -0
- data/lib/inferno/apps/web/serializers/test.rb +4 -0
- data/lib/inferno/apps/web/serializers/test_group.rb +4 -0
- data/lib/inferno/apps/web/serializers/test_suite.rb +3 -0
- data/lib/inferno/dsl/configurable.rb +4 -0
- data/lib/inferno/dsl/fhir_client.rb +14 -0
- data/lib/inferno/dsl/http_client.rb +62 -0
- data/lib/inferno/dsl/runnable.rb +67 -1
- data/lib/inferno/entities/has_runnable.rb +26 -0
- data/lib/inferno/entities/result.rb +8 -4
- data/lib/inferno/entities/test_group.rb +4 -6
- data/lib/inferno/entities/test_run.rb +2 -19
- data/lib/inferno/entities/test_suite.rb +3 -4
- data/lib/inferno/entities.rb +1 -0
- data/lib/inferno/public/bundle.js +9 -9
- data/lib/inferno/repositories/results.rb +4 -0
- data/lib/inferno/repositories/session_data.rb +1 -1
- data/lib/inferno/repositories/test_runs.rb +8 -0
- data/lib/inferno/result_summarizer.rb +40 -0
- data/lib/inferno/test_runner.rb +13 -7
- data/lib/inferno/version.rb +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b15a9d2a0905bfb338974e70ceb0045a096b76dcc1cf795490f2f8b90231016b
|
4
|
+
data.tar.gz: 86d7bb32e8ca9a5e56983be39f3e4d7b177237b59624d2c7ac2e45d7cc7f0725
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '090c15c98e9d555cf8ca4c17d7ac246d74effed1463f87ffe6ff3aa1f9f415798a7758b9d8df45713f46bfb586e81c78e87fa32535426372c3a4ee952c5fb353'
|
7
|
+
data.tar.gz: b76a85e0633115721f1033724c62e6910a6666bd5f47510f454666da7aff744970b871ea25f7fa216837d14c42fdc94c563cd22a4a6e9d151a36d92af7211bee
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Inferno
|
2
|
+
module Web
|
3
|
+
module Controllers
|
4
|
+
module TestRuns
|
5
|
+
class Destroy < Controller
|
6
|
+
include Import[
|
7
|
+
test_runs_repo: 'repositories.test_runs',
|
8
|
+
results_repo: 'repositories.results'
|
9
|
+
]
|
10
|
+
|
11
|
+
def call(params)
|
12
|
+
test_run = test_runs_repo.find(params[:id])
|
13
|
+
|
14
|
+
if test_run.nil? || ['done', 'cancelling'].include?(test_run.status)
|
15
|
+
# If it doesn't exist, already finished, or currently being cancelled
|
16
|
+
self.status = 204
|
17
|
+
return
|
18
|
+
end
|
19
|
+
|
20
|
+
test_run_is_waiting = (test_run.status == 'waiting')
|
21
|
+
test_runs_repo.mark_as_cancelling(params[:id])
|
22
|
+
|
23
|
+
if test_run_is_waiting
|
24
|
+
waiting_result = results_repo.find_waiting_result(test_run_id: test_run.id)
|
25
|
+
results_repo.cancel_waiting_result(waiting_result.id, 'Test cancelled by user')
|
26
|
+
Jobs.perform(Jobs::ResumeTestRun, test_run.id)
|
27
|
+
end
|
28
|
+
|
29
|
+
self.status = 204
|
30
|
+
rescue StandardError => e
|
31
|
+
Application['logger'].error(e.full_message)
|
32
|
+
self.body = { errors: e.message }.to_json
|
33
|
+
self.status = 500
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -7,7 +7,7 @@ module Inferno
|
|
7
7
|
|
8
8
|
Router = Hanami::Router.new(namespace: Inferno::Web::Controllers) do
|
9
9
|
namespace 'api' do
|
10
|
-
resources 'test_runs', only: [:create, :show] do
|
10
|
+
resources 'test_runs', only: [:create, :show, :destroy] do
|
11
11
|
resources 'results', only: [:index]
|
12
12
|
end
|
13
13
|
|
@@ -4,10 +4,14 @@ module Inferno
|
|
4
4
|
class Test < Serializer
|
5
5
|
identifier :id
|
6
6
|
field :title
|
7
|
+
field :short_title
|
7
8
|
field :input_definitions, name: :inputs, extractor: HashValueExtractor, blueprint: Input
|
8
9
|
field :output_definitions, name: :outputs, extractor: HashValueExtractor
|
9
10
|
field :description
|
11
|
+
field :short_description
|
12
|
+
field :input_instructions
|
10
13
|
field :user_runnable?, name: :user_runnable
|
14
|
+
field :optional?, name: :optional
|
11
15
|
end
|
12
16
|
end
|
13
17
|
end
|
@@ -5,10 +5,14 @@ module Inferno
|
|
5
5
|
identifier :id
|
6
6
|
|
7
7
|
field :title
|
8
|
+
field :short_title
|
8
9
|
field :description
|
10
|
+
field :short_description
|
11
|
+
field :input_instructions
|
9
12
|
field :test_count
|
10
13
|
field :run_as_group?, name: :run_as_group
|
11
14
|
field :user_runnable?, name: :user_runnable
|
15
|
+
field :optional?, name: :optional
|
12
16
|
|
13
17
|
association :groups, name: :test_groups, blueprint: TestGroup
|
14
18
|
association :tests, blueprint: Test
|
@@ -131,6 +131,20 @@ module Inferno
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
+
# Perform a FHIR delete interaction.
|
135
|
+
#
|
136
|
+
# @param resource_type [String, Symbol, Class]
|
137
|
+
# @param id [String]
|
138
|
+
# @param client [Symbol]
|
139
|
+
# @param name [Symbol] Name for this request to allow it to be used by
|
140
|
+
# other tests
|
141
|
+
# @return [Inferno::Entities::Request]
|
142
|
+
def fhir_delete(resource_type, id, client: :default, name: nil)
|
143
|
+
store_request('outgoing', name) do
|
144
|
+
fhir_client(client).destroy(fhir_class_from_resource_type(resource_type), id)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
134
148
|
# @todo Make this a FHIR class method? Something like
|
135
149
|
# FHIR.class_for(resource_type)
|
136
150
|
# @api private
|
@@ -103,6 +103,68 @@ module Inferno
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
+
# Perform an HTTP DELETE request
|
107
|
+
#
|
108
|
+
# @param url [String] if this request is using a defined client, this will
|
109
|
+
# be appended to the client's url. Must be an absolute url for requests
|
110
|
+
# made without a defined client
|
111
|
+
# @param client [Symbol]
|
112
|
+
# @param name [Symbol] Name for this request to allow it to be used by
|
113
|
+
# other tests
|
114
|
+
# @return [Inferno::Entities::Request]
|
115
|
+
def delete(url = '', client: :default, name: :nil, **options)
|
116
|
+
store_request('outgoing', name) do
|
117
|
+
client = http_client(client)
|
118
|
+
|
119
|
+
if client
|
120
|
+
client.delete(url, nil, options[:headers])
|
121
|
+
elsif url.match?(%r{\Ahttps?://})
|
122
|
+
Faraday.delete(url, nil, options[:headers])
|
123
|
+
else
|
124
|
+
raise StandardError, 'Must use an absolute url or define an HTTP client with a base url'
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Perform an HTTP GET request and stream the response
|
130
|
+
#
|
131
|
+
# @param block [Proc] A Proc object whose input will be the string chunks
|
132
|
+
# received while streaming response to the get request.
|
133
|
+
# @param url [String] If this request is using a defined client, this will
|
134
|
+
# be appended to the client's url. Must be an absolute url for requests
|
135
|
+
# made without a defined client
|
136
|
+
# @param limit [Integer] The number of streamed-in chunks to be stored in
|
137
|
+
# the response body. This optional input defaults to 100.
|
138
|
+
# @param client [Symbol]
|
139
|
+
# @param name [Symbol] Name for this request to allow it to be used by
|
140
|
+
# other tests
|
141
|
+
# @option options [Hash] Input headers here - headers are optional and
|
142
|
+
# must be entered as the last piece of input to this method
|
143
|
+
# @return [Inferno::Entities::Request]
|
144
|
+
def stream(block, url = '', limit = 100, client: :default, name: nil, **options)
|
145
|
+
streamed = []
|
146
|
+
|
147
|
+
collector = proc do |chunk, bytes|
|
148
|
+
streamed << chunk if limit.positive?
|
149
|
+
limit -= 1
|
150
|
+
block.call(chunk, bytes)
|
151
|
+
end
|
152
|
+
|
153
|
+
store_request('outgoing', name) do
|
154
|
+
client = http_client(client)
|
155
|
+
|
156
|
+
if client
|
157
|
+
response = client.get(url, nil, options[:headers]) { |req| req.options.on_data = collector }
|
158
|
+
elsif url.match?(%r{\Ahttps?://})
|
159
|
+
response = Faraday.get(url, nil, options[:headers]) { |req| req.options.on_data = collector }
|
160
|
+
else
|
161
|
+
raise StandardError, 'Must use an absolute url or define an HTTP client with a base url'
|
162
|
+
end
|
163
|
+
response.env.body = streamed.join
|
164
|
+
response
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
106
168
|
module ClassMethods
|
107
169
|
# @private
|
108
170
|
def http_client_definitions
|
data/lib/inferno/dsl/runnable.rb
CHANGED
@@ -85,7 +85,6 @@ module Inferno
|
|
85
85
|
|
86
86
|
klass.parent = self
|
87
87
|
|
88
|
-
child_metadata[:collection] << klass
|
89
88
|
children << klass
|
90
89
|
|
91
90
|
configure_child_class(klass, hash_args)
|
@@ -164,6 +163,8 @@ module Inferno
|
|
164
163
|
|
165
164
|
klass.config(config)
|
166
165
|
|
166
|
+
klass.children.select!(&:required?) if hash_args.delete(:exclude_optional)
|
167
|
+
|
167
168
|
hash_args.each do |key, value|
|
168
169
|
if value.is_a? Array
|
169
170
|
klass.send(key, *value)
|
@@ -212,6 +213,16 @@ module Inferno
|
|
212
213
|
@title = new_title
|
213
214
|
end
|
214
215
|
|
216
|
+
# Set/Get a runnable's short title
|
217
|
+
#
|
218
|
+
# @param new_short_title [String]
|
219
|
+
# @return [String] the short title
|
220
|
+
def short_title(new_short_title = nil)
|
221
|
+
return @short_title if new_short_title.nil?
|
222
|
+
|
223
|
+
@short_title = new_short_title
|
224
|
+
end
|
225
|
+
|
215
226
|
# Set/Get a runnable's description
|
216
227
|
#
|
217
228
|
# @param new_description [String]
|
@@ -222,6 +233,26 @@ module Inferno
|
|
222
233
|
@description = format_markdown(new_description)
|
223
234
|
end
|
224
235
|
|
236
|
+
# Set/Get a runnable's short one-sentence description
|
237
|
+
#
|
238
|
+
# @param new_short_description [String]
|
239
|
+
# @return [String] the one-sentence description
|
240
|
+
def short_description(new_short_description = nil)
|
241
|
+
return @short_description if new_short_description.nil?
|
242
|
+
|
243
|
+
@short_description = format_markdown(new_short_description)
|
244
|
+
end
|
245
|
+
|
246
|
+
# Set/Get a runnable's input instructions
|
247
|
+
#
|
248
|
+
# @param new_input_instructions [String]
|
249
|
+
# @return [String] the input instructions
|
250
|
+
def input_instructions(new_input_instructions = nil)
|
251
|
+
return @input_instructions if new_input_instructions.nil?
|
252
|
+
|
253
|
+
@input_instructions = format_markdown(new_input_instructions)
|
254
|
+
end
|
255
|
+
|
225
256
|
# Define inputs
|
226
257
|
#
|
227
258
|
# @param identifier [Symbol] identifier for the input
|
@@ -252,6 +283,40 @@ module Inferno
|
|
252
283
|
end
|
253
284
|
end
|
254
285
|
|
286
|
+
# Mark as optional. Tests are required by default.
|
287
|
+
#
|
288
|
+
# @param optional [Boolean]
|
289
|
+
# @return [void]
|
290
|
+
#
|
291
|
+
def optional(optional = true) # rubocop:disable Style/OptionalBooleanParameter
|
292
|
+
@optional = optional
|
293
|
+
end
|
294
|
+
|
295
|
+
# Mark as required
|
296
|
+
#
|
297
|
+
# Tests are required by default. This method is provided to make an
|
298
|
+
# existing optional test required.
|
299
|
+
#
|
300
|
+
# @param required[Boolean]
|
301
|
+
# @return [void]
|
302
|
+
def required(required = true) # rubocop:disable Style/OptionalBooleanParameter
|
303
|
+
@optional = !required
|
304
|
+
end
|
305
|
+
|
306
|
+
# The test or group is optional if true
|
307
|
+
#
|
308
|
+
# @return [Boolean]
|
309
|
+
def optional?
|
310
|
+
!!@optional
|
311
|
+
end
|
312
|
+
|
313
|
+
# The test or group is required if true
|
314
|
+
#
|
315
|
+
# @return [Boolean]
|
316
|
+
def required?
|
317
|
+
!optional?
|
318
|
+
end
|
319
|
+
|
255
320
|
# Define outputs
|
256
321
|
#
|
257
322
|
# @param identifier [Symbol] identifier for the output
|
@@ -407,6 +472,7 @@ module Inferno
|
|
407
472
|
required_inputs.map(&:to_s) - submitted_inputs.map { |input| input[:name] }
|
408
473
|
end
|
409
474
|
|
475
|
+
# @private
|
410
476
|
def user_runnable?
|
411
477
|
@user_runnable ||= parent.nil? ||
|
412
478
|
!parent.respond_to?(:run_as_group?) ||
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Inferno
|
2
|
+
module Entities
|
3
|
+
module HasRunnable
|
4
|
+
# Returns the Test, TestGroup, or TestSuite associated with this entity
|
5
|
+
#
|
6
|
+
# @return [Inferno::Entities::Test, Inferno::Entities::TestGroup, Inferno::Entities::TestSuite]
|
7
|
+
def runnable
|
8
|
+
return @runnable if @runnable
|
9
|
+
|
10
|
+
@runnable = (test || test_group || test_suite || load_runnable)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def load_runnable
|
16
|
+
if test_id.present?
|
17
|
+
@test = Inferno::Repositories::Tests.new.find(test_id)
|
18
|
+
elsif test_group_id.present?
|
19
|
+
@test_group = Inferno::Repositories::TestGroups.new.find(test_group_id)
|
20
|
+
elsif test_suite_id.present?
|
21
|
+
@test_suite = Inferno::Repositories::TestSuites.new.find(test_suite_id)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -47,9 +47,10 @@ module Inferno
|
|
47
47
|
:test_session_id, :result, :result_message, :messages, :requests,
|
48
48
|
:input_json, :output_json
|
49
49
|
].freeze
|
50
|
-
RESULT_OPTIONS = ['cancel', 'wait', 'running', 'error', 'fail', 'skip', '
|
50
|
+
RESULT_OPTIONS = ['cancel', 'wait', 'running', 'error', 'fail', 'skip', 'pass', 'omit'].freeze
|
51
51
|
|
52
52
|
include Inferno::Entities::Attributes
|
53
|
+
include Inferno::Entities::HasRunnable
|
53
54
|
|
54
55
|
def initialize(params)
|
55
56
|
super(params, ATTRIBUTES - [:messages, :requests])
|
@@ -58,9 +59,12 @@ module Inferno
|
|
58
59
|
@requests = (params[:requests] || []).map { |request| Request.new(request) }
|
59
60
|
end
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
def optional?
|
63
|
+
runnable.optional?
|
64
|
+
end
|
65
|
+
|
66
|
+
def required?
|
67
|
+
!optional?
|
64
68
|
end
|
65
69
|
|
66
70
|
# @return [Boolean]
|
@@ -32,11 +32,11 @@ module Inferno
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def groups
|
35
|
-
|
35
|
+
children.select { |child| child < Inferno::Entities::TestGroup }
|
36
36
|
end
|
37
37
|
|
38
38
|
def tests
|
39
|
-
|
39
|
+
children.select { |child| child < Inferno::Entities::Test }
|
40
40
|
end
|
41
41
|
|
42
42
|
# Methods to configure Inferno::DSL::Runnable
|
@@ -54,16 +54,14 @@ module Inferno
|
|
54
54
|
def group_metadata
|
55
55
|
{
|
56
56
|
class: TestGroup,
|
57
|
-
repo: repository
|
58
|
-
collection: groups
|
57
|
+
repo: repository
|
59
58
|
}
|
60
59
|
end
|
61
60
|
|
62
61
|
def test_metadata
|
63
62
|
{
|
64
63
|
class: Test,
|
65
|
-
repo: Inferno::Repositories::Tests.new
|
66
|
-
collection: tests
|
64
|
+
repo: Inferno::Repositories::Tests.new
|
67
65
|
}
|
68
66
|
end
|
69
67
|
|
@@ -32,7 +32,7 @@ module Inferno
|
|
32
32
|
# @return [String, nil] identfier for a waiting `TestRun`
|
33
33
|
# @!attribute wait_timeout
|
34
34
|
class TestRun < Entity
|
35
|
-
STATUS_OPTIONS = ['queued', 'running', 'waiting', 'done'].freeze
|
35
|
+
STATUS_OPTIONS = ['queued', 'running', 'waiting', 'cancelling', 'done'].freeze
|
36
36
|
ATTRIBUTES = [
|
37
37
|
:id,
|
38
38
|
:test_session_id,
|
@@ -52,6 +52,7 @@ module Inferno
|
|
52
52
|
].freeze
|
53
53
|
|
54
54
|
include Inferno::Entities::Attributes
|
55
|
+
include Inferno::Entities::HasRunnable
|
55
56
|
|
56
57
|
attr_accessor :test_session
|
57
58
|
|
@@ -63,12 +64,6 @@ module Inferno
|
|
63
64
|
@test_session = params[:test_session]
|
64
65
|
end
|
65
66
|
|
66
|
-
def runnable
|
67
|
-
return @runnable if @runnable
|
68
|
-
|
69
|
-
@runnable = (test || test_group || test_suite || load_runnable)
|
70
|
-
end
|
71
|
-
|
72
67
|
def to_hash
|
73
68
|
super.merge(test_session: test_session).compact
|
74
69
|
end
|
@@ -76,18 +71,6 @@ module Inferno
|
|
76
71
|
def test_count
|
77
72
|
@test_count ||= runnable.test_count
|
78
73
|
end
|
79
|
-
|
80
|
-
private
|
81
|
-
|
82
|
-
def load_runnable
|
83
|
-
if test_id.present?
|
84
|
-
@test = Inferno::Repositories::Tests.new.find(test_id)
|
85
|
-
elsif test_group_id.present?
|
86
|
-
@test_group = Inferno::Repositories::TestGroups.new.find(test_group_id)
|
87
|
-
elsif test_suite_id.present?
|
88
|
-
@test_suite = Inferno::Repositories::TestSuites.new.find(test_suite_id)
|
89
|
-
end
|
90
|
-
end
|
91
74
|
end
|
92
75
|
end
|
93
76
|
end
|
@@ -22,7 +22,7 @@ module Inferno
|
|
22
22
|
return @default_group if @default_group
|
23
23
|
|
24
24
|
@default_group = Class.new(TestGroup)
|
25
|
-
|
25
|
+
children << @default_group
|
26
26
|
@default_group
|
27
27
|
end
|
28
28
|
|
@@ -31,7 +31,7 @@ module Inferno
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def groups
|
34
|
-
|
34
|
+
children.select { |child| child < Inferno::Entities::TestGroup }
|
35
35
|
end
|
36
36
|
|
37
37
|
# Methods to configure Inferno::DSL::Runnable
|
@@ -44,8 +44,7 @@ module Inferno
|
|
44
44
|
def group_metadata
|
45
45
|
{
|
46
46
|
class: TestGroup,
|
47
|
-
repo: Inferno::Repositories::TestGroups.new
|
48
|
-
collection: groups
|
47
|
+
repo: Inferno::Repositories::TestGroups.new
|
49
48
|
}
|
50
49
|
end
|
51
50
|
|