inferno_core 0.0.1 → 0.0.5
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.rb +4 -0
- data/lib/inferno/apps/web/controllers/test_runs/create.rb +17 -10
- data/lib/inferno/apps/web/controllers/test_runs/show.rb +10 -0
- data/lib/inferno/apps/web/controllers/test_sessions/create.rb +1 -0
- data/lib/inferno/apps/web/controllers/test_sessions/last_test_run.rb +22 -0
- data/lib/inferno/apps/web/controllers/test_sessions/results/index.rb +6 -1
- data/lib/inferno/apps/web/controllers/test_sessions/session_data/index.rb +21 -0
- data/lib/inferno/apps/web/index.html.erb +44 -0
- data/lib/inferno/apps/web/router.rb +15 -0
- data/lib/inferno/apps/web/serializers/request.rb +1 -0
- data/lib/inferno/apps/web/serializers/result.rb +8 -0
- data/lib/inferno/apps/web/serializers/session_data.rb +10 -0
- data/lib/inferno/apps/web/serializers/test.rb +1 -3
- data/lib/inferno/apps/web/serializers/test_group.rb +2 -3
- data/lib/inferno/apps/web/serializers/test_run.rb +1 -0
- data/lib/inferno/apps/web/serializers/test_session.rb +1 -1
- data/lib/inferno/apps/web/serializers/test_suite.rb +1 -0
- data/lib/inferno/config/application.rb +4 -2
- data/lib/inferno/config/boot.rb +2 -0
- data/lib/inferno/config/boot/db.rb +10 -1
- data/lib/inferno/config/boot/sidekiq.rb +11 -0
- data/lib/inferno/db/migrations/001_create_initial_structure.rb +0 -21
- data/lib/inferno/db/migrations/002_add_wait_support.rb +7 -0
- data/lib/inferno/db/migrations/003_update_session_data.rb +18 -0
- data/lib/inferno/db/migrations/004_add_request_results_table.rb +9 -0
- data/lib/inferno/db/migrations/005_add_updated_at_index_to_results.rb +5 -0
- data/lib/inferno/db/schema.rb +154 -0
- data/lib/inferno/dsl.rb +1 -3
- data/lib/inferno/dsl/fhir_client_builder.rb +16 -0
- data/lib/inferno/dsl/request_storage.rb +12 -0
- data/lib/inferno/dsl/results.rb +49 -0
- data/lib/inferno/dsl/resume_test_route.rb +89 -0
- data/lib/inferno/dsl/runnable.rb +96 -7
- data/lib/inferno/entities.rb +1 -1
- data/lib/inferno/entities/header.rb +7 -7
- data/lib/inferno/entities/message.rb +8 -6
- data/lib/inferno/entities/request.rb +40 -14
- data/lib/inferno/entities/result.rb +34 -18
- data/lib/inferno/entities/session_data.rb +33 -0
- data/lib/inferno/entities/test.rb +20 -7
- data/lib/inferno/entities/test_run.rb +13 -6
- data/lib/inferno/entities/test_session.rb +8 -8
- data/lib/inferno/exceptions.rb +12 -0
- data/lib/inferno/jobs.rb +16 -0
- data/lib/inferno/jobs/execute_test_run.rb +14 -0
- data/lib/inferno/jobs/resume_test_run.rb +14 -0
- data/lib/inferno/public/bundle.js +1 -1
- data/lib/inferno/repositories/repository.rb +13 -0
- data/lib/inferno/repositories/requests.rb +5 -4
- data/lib/inferno/repositories/results.rb +151 -3
- data/lib/inferno/repositories/session_data.rb +47 -0
- data/lib/inferno/repositories/test_runs.rb +66 -0
- data/lib/inferno/test_runner.rb +121 -29
- data/lib/inferno/utils/middleware/request_logger.rb +16 -3
- data/lib/inferno/version.rb +1 -1
- data/spec/factories/header.rb +19 -0
- data/spec/factories/message.rb +17 -0
- data/spec/factories/request.rb +35 -0
- data/spec/factories/result.rb +45 -0
- data/spec/factories/test_run.rb +24 -0
- data/spec/factories/test_session.rb +11 -0
- data/spec/fixtures/basic_test_group.rb +9 -0
- data/spec/fixtures/basic_test_suite.rb +8 -0
- metadata +139 -89
- data/lib/inferno/dsl/fhir_manipulation.rb +0 -25
- data/lib/inferno/entities/test_input.rb +0 -20
@@ -7,13 +7,13 @@ module Inferno
|
|
7
7
|
request = self.class::Model.create(db_params(params))
|
8
8
|
|
9
9
|
request_headers = (params[:request_headers] || []).map do |header|
|
10
|
-
|
10
|
+
request.add_header(header.merge(request_id: request.index, type: 'request'))
|
11
11
|
end
|
12
12
|
response_headers = (params[:response_headers] || []).map do |header|
|
13
|
-
|
13
|
+
request.add_header(header.merge(request_id: request.index, type: 'response'))
|
14
14
|
end
|
15
15
|
|
16
|
-
headers = request_headers + response_headers
|
16
|
+
headers = (request_headers + response_headers).map { |header| headers_repo.build_entity(header.to_hash) }
|
17
17
|
|
18
18
|
build_entity(
|
19
19
|
request.to_hash
|
@@ -73,7 +73,8 @@ module Inferno
|
|
73
73
|
end
|
74
74
|
|
75
75
|
class Model < Sequel::Model(db)
|
76
|
-
|
76
|
+
many_to_many :result, class: 'Inferno::Repositories::Results::Model', join_table: :requests_results,
|
77
|
+
left_key: :request_id, right_key: :result_id
|
77
78
|
one_to_many :headers, class: 'Inferno::Repositories::Headers::Model', key: :request_id
|
78
79
|
|
79
80
|
def before_create
|
@@ -15,11 +15,43 @@ module Inferno
|
|
15
15
|
messages = params.delete(:messages) || []
|
16
16
|
requests = params.delete(:requests) || []
|
17
17
|
super(params).tap do |result|
|
18
|
+
result_model = self.class::Model.find(id: result.id)
|
18
19
|
messages.each { |message| messages_repo.create(message.merge(result_id: result.id)) }
|
19
|
-
requests.each
|
20
|
+
requests.each do |request|
|
21
|
+
request_id =
|
22
|
+
if request.id.present?
|
23
|
+
request.id
|
24
|
+
else
|
25
|
+
requests_repo.create(request.to_hash.merge(result_id: result.id)).id
|
26
|
+
end
|
27
|
+
request_model = requests_repo.class::Model.find(id: request_id)
|
28
|
+
result_model.add_request(request_model)
|
29
|
+
end
|
20
30
|
end
|
21
31
|
end
|
22
32
|
|
33
|
+
# Get the current result for a particular test/group
|
34
|
+
# @api private
|
35
|
+
# @example
|
36
|
+
# repo.current_result_for_test_session(
|
37
|
+
# test_session_id,
|
38
|
+
# test_id: 'test_id'
|
39
|
+
# )
|
40
|
+
def current_result_for_test_session(test_session_id, **params)
|
41
|
+
self.class::Model
|
42
|
+
.where({ test_session_id: test_session_id }.merge(params))
|
43
|
+
.order(Sequel.desc(:updated_at))
|
44
|
+
.limit(1)
|
45
|
+
.all
|
46
|
+
.map! do |result_hash|
|
47
|
+
build_entity(
|
48
|
+
result_hash
|
49
|
+
.to_json_data(json_serializer_options)
|
50
|
+
.deep_symbolize_keys!
|
51
|
+
)
|
52
|
+
end.first
|
53
|
+
end
|
54
|
+
|
23
55
|
def build_entity(params)
|
24
56
|
runnable =
|
25
57
|
if params[:test_id]
|
@@ -34,12 +66,85 @@ module Inferno
|
|
34
66
|
entity_class.new(params.merge(runnable))
|
35
67
|
end
|
36
68
|
|
69
|
+
def result_for_test_run(test_run_id:, **params)
|
70
|
+
result_hash =
|
71
|
+
self.class::Model
|
72
|
+
.find({ test_run_id: test_run_id }.merge(params))
|
73
|
+
&.to_hash
|
74
|
+
|
75
|
+
return nil if result_hash.nil?
|
76
|
+
|
77
|
+
build_entity(result_hash)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_run_results_after(test_run_id:, after:)
|
81
|
+
Model
|
82
|
+
.where(test_run_id: test_run_id)
|
83
|
+
.where { updated_at >= after }
|
84
|
+
.to_a
|
85
|
+
.map! do |result_hash|
|
86
|
+
build_entity(
|
87
|
+
result_hash
|
88
|
+
.to_json_data(json_serializer_options)
|
89
|
+
.deep_symbolize_keys!
|
90
|
+
)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def find_waiting_result(test_run_id:)
|
95
|
+
result_hash =
|
96
|
+
Model
|
97
|
+
.where(test_run_id: test_run_id, result: 'wait')
|
98
|
+
.where { test_id !~ nil }
|
99
|
+
.limit(1)
|
100
|
+
.to_a
|
101
|
+
.first
|
102
|
+
&.to_hash
|
103
|
+
|
104
|
+
return nil if result_hash.nil?
|
105
|
+
|
106
|
+
build_entity(result_hash)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Get all of the current results for a test session
|
110
|
+
def current_results_for_test_session(test_session_id)
|
111
|
+
self.class::Model
|
112
|
+
.current_results_for_test_session(test_session_id)
|
113
|
+
.eager(:messages)
|
114
|
+
.eager(requests: proc { |requests| requests.select(*Entities::Request::SUMMARY_FIELDS) })
|
115
|
+
.all
|
116
|
+
.map! do |result_hash|
|
117
|
+
build_entity(
|
118
|
+
result_hash
|
119
|
+
.to_json_data(json_serializer_options)
|
120
|
+
.deep_symbolize_keys!
|
121
|
+
)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Get the current results for a list of runnables
|
126
|
+
def current_results_for_test_session_and_runnables(test_session_id, runnables)
|
127
|
+
self.class::Model
|
128
|
+
.current_results_for_test_session_and_runnables(test_session_id, runnables)
|
129
|
+
.all
|
130
|
+
.map! do |result_hash|
|
131
|
+
build_entity(
|
132
|
+
result_hash
|
133
|
+
.to_json_data(json_serializer_options)
|
134
|
+
.deep_symbolize_keys!
|
135
|
+
)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def pass_waiting_result(result_id, message = nil)
|
140
|
+
update(result_id, result: 'pass', result_message: message)
|
141
|
+
end
|
142
|
+
|
37
143
|
def json_serializer_options
|
38
144
|
{
|
39
145
|
include: {
|
40
146
|
messages: {},
|
41
147
|
requests: {
|
42
|
-
include: { headers: {} },
|
43
148
|
only: Entities::Request::SUMMARY_FIELDS
|
44
149
|
}
|
45
150
|
}
|
@@ -49,8 +154,33 @@ module Inferno
|
|
49
154
|
class Model < Sequel::Model(db)
|
50
155
|
include ValidateRunnableReference
|
51
156
|
|
157
|
+
def self.current_results_sql(with_runnables_filter: false)
|
158
|
+
query = <<~SQL.gsub(/\s+/, ' ').freeze
|
159
|
+
SELECT * FROM results a
|
160
|
+
WHERE test_session_id = :test_session_id
|
161
|
+
SQL
|
162
|
+
runnables_filter = <<~SQL.gsub(/\s+/, ' ').freeze
|
163
|
+
AND (test_id IN :test_ids OR test_group_id IN :test_group_ids OR test_suite_id IN :test_suite_ids)
|
164
|
+
SQL
|
165
|
+
subquery = <<~SQL.gsub(/\s+/, ' ').freeze
|
166
|
+
AND a.id IN (
|
167
|
+
SELECT id
|
168
|
+
FROM results b
|
169
|
+
WHERE (b.test_session_id = a.test_session_id AND b.test_id = a.test_id) OR
|
170
|
+
(b.test_session_id = a.test_session_id AND b.test_group_id = a.test_group_id) OR
|
171
|
+
(b.test_session_id = a.test_session_id AND b.test_suite_id = a.test_suite_id)
|
172
|
+
ORDER BY updated_at DESC
|
173
|
+
LIMIT 1
|
174
|
+
)
|
175
|
+
SQL
|
176
|
+
return "#{query} #{runnables_filter} #{subquery}" if with_runnables_filter
|
177
|
+
|
178
|
+
"#{query} #{subquery}"
|
179
|
+
end
|
180
|
+
|
52
181
|
one_to_many :messages, class: 'Inferno::Repositories::Messages::Model', key: :result_id
|
53
|
-
|
182
|
+
many_to_many :requests, class: 'Inferno::Repositories::Requests::Model', join_table: :requests_results,
|
183
|
+
left_key: :results_id, right_key: :requests_id
|
54
184
|
many_to_one :test_run, class: 'Inferno::Repositories::TestRuns::Model', key: :test_run_id
|
55
185
|
many_to_one :test_session, class: 'Inferno::Repositories::TestSessions::Model', key: :test_session_id
|
56
186
|
|
@@ -66,6 +196,24 @@ module Inferno
|
|
66
196
|
super
|
67
197
|
errors.add(:result, "'#{result}' is not valid") unless Entities::Result::RESULT_OPTIONS.include?(result)
|
68
198
|
end
|
199
|
+
|
200
|
+
def self.current_results_for_test_session(test_session_id)
|
201
|
+
fetch(current_results_sql, test_session_id: test_session_id)
|
202
|
+
end
|
203
|
+
|
204
|
+
def self.current_results_for_test_session_and_runnables(test_session_id, runnables)
|
205
|
+
test_ids = runnables.select { |runnable| runnable < Entities::Test }.map!(&:id)
|
206
|
+
test_group_ids = runnables.select { |runnable| runnable < Entities::TestGroup }.map!(&:id)
|
207
|
+
test_suite_ids = runnables.select { |runnable| runnable < Entities::TestSuite }.map!(&:id)
|
208
|
+
|
209
|
+
fetch(
|
210
|
+
current_results_sql(with_runnables_filter: true),
|
211
|
+
test_session_id: test_session_id,
|
212
|
+
test_ids: test_ids,
|
213
|
+
test_group_ids: test_group_ids,
|
214
|
+
test_suite_ids: test_suite_ids
|
215
|
+
)
|
216
|
+
end
|
69
217
|
end
|
70
218
|
end
|
71
219
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Inferno
|
2
|
+
module Repositories
|
3
|
+
class SessionData < Repository
|
4
|
+
def save(params)
|
5
|
+
name = params[:name].to_s.downcase
|
6
|
+
test_session_id = params[:test_session_id]
|
7
|
+
db
|
8
|
+
.insert_conflict(
|
9
|
+
target: :id,
|
10
|
+
update: { value: params[:value] }
|
11
|
+
).insert(
|
12
|
+
id: "#{test_session_id}_#{name}",
|
13
|
+
name: name,
|
14
|
+
value: params[:value],
|
15
|
+
test_session_id: test_session_id
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def load(test_session_id:, name:)
|
20
|
+
self.class::Model
|
21
|
+
.find(test_session_id: test_session_id, name: name.to_s.downcase)
|
22
|
+
&.value
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_all_from_session(test_session_id)
|
26
|
+
self.class::Model
|
27
|
+
.where(test_session_id: test_session_id)
|
28
|
+
.all
|
29
|
+
.map! do |session_data_hash|
|
30
|
+
build_entity(
|
31
|
+
session_data_hash
|
32
|
+
.to_json_data
|
33
|
+
.deep_symbolize_keys!
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def entity_class_name
|
39
|
+
'SessionData'
|
40
|
+
end
|
41
|
+
|
42
|
+
class Model < Sequel::Model(db)
|
43
|
+
many_to_one :test_session, class: 'Inferno::Repositories::TestSessions::Model', key: :test_session_id
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -24,6 +24,65 @@ module Inferno
|
|
24
24
|
.map! { |result| results_repo.build_entity(result) }
|
25
25
|
end
|
26
26
|
|
27
|
+
def find_latest_waiting_by_identifier(identifier)
|
28
|
+
test_run_hash =
|
29
|
+
self.class::Model
|
30
|
+
.where(status: 'waiting')
|
31
|
+
.where(identifier: identifier)
|
32
|
+
.where { wait_timeout >= Time.now }
|
33
|
+
.order(Sequel.desc(:updated_at))
|
34
|
+
.limit(1)
|
35
|
+
.to_a
|
36
|
+
&.first
|
37
|
+
&.to_hash
|
38
|
+
|
39
|
+
return nil if test_run_hash.nil?
|
40
|
+
|
41
|
+
build_entity(test_run_hash)
|
42
|
+
end
|
43
|
+
|
44
|
+
def last_test_run(test_session_id)
|
45
|
+
test_run_hash =
|
46
|
+
self.class::Model
|
47
|
+
.where(test_session_id: test_session_id)
|
48
|
+
.order(Sequel.desc(:updated_at))
|
49
|
+
.limit(1)
|
50
|
+
.to_a
|
51
|
+
.map { |record| record.to_json_data(json_serializer_options).deep_symbolize_keys! }
|
52
|
+
&.first
|
53
|
+
&.to_hash
|
54
|
+
|
55
|
+
return nil if test_run_hash.nil?
|
56
|
+
|
57
|
+
build_entity(test_run_hash)
|
58
|
+
end
|
59
|
+
|
60
|
+
def mark_as_running(test_run_id)
|
61
|
+
update(test_run_id, status: 'running')
|
62
|
+
end
|
63
|
+
|
64
|
+
def mark_as_done(test_run_id)
|
65
|
+
update(test_run_id, status: 'done')
|
66
|
+
end
|
67
|
+
|
68
|
+
def mark_as_waiting(test_run_id, identifier, timeout)
|
69
|
+
update(
|
70
|
+
test_run_id,
|
71
|
+
status: 'waiting',
|
72
|
+
identifier: identifier,
|
73
|
+
wait_timeout: Time.now + timeout.seconds
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
def mark_as_no_longer_waiting(test_run_id)
|
78
|
+
update(
|
79
|
+
test_run_id,
|
80
|
+
status: 'queued',
|
81
|
+
identifier: nil,
|
82
|
+
wait_timeout: nil
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
27
86
|
class Model < Sequel::Model(db)
|
28
87
|
include ValidateRunnableReference
|
29
88
|
|
@@ -33,6 +92,13 @@ module Inferno
|
|
33
92
|
key: :test_run_id
|
34
93
|
many_to_one :test_session, class: 'Inferno::Repositories::TestSessions::Model', key: :test_session_id
|
35
94
|
|
95
|
+
def validate
|
96
|
+
super
|
97
|
+
if status.present? && !Entities::TestRun::STATUS_OPTIONS.include?(status) # rubocop:disable Style/GuardClause
|
98
|
+
errors.add(:status, "'#{status}' is not valid")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
36
102
|
def before_create
|
37
103
|
self.id = SecureRandom.uuid
|
38
104
|
time = Time.now
|
data/lib/inferno/test_runner.rb
CHANGED
@@ -1,73 +1,165 @@
|
|
1
1
|
module Inferno
|
2
2
|
# @api private
|
3
3
|
class TestRunner
|
4
|
-
attr_reader :test_session, :test_run
|
4
|
+
attr_reader :test_session, :test_run, :resuming
|
5
5
|
|
6
|
-
def initialize(test_session:, test_run:)
|
6
|
+
def initialize(test_session:, test_run:, resume: false)
|
7
7
|
@test_session = test_session
|
8
8
|
@test_run = test_run
|
9
|
+
@resuming = resume
|
10
|
+
end
|
11
|
+
|
12
|
+
def run_results
|
13
|
+
@run_results ||= {}
|
9
14
|
end
|
10
15
|
|
11
16
|
def results_repo
|
12
17
|
@results_repo ||= Repositories::Results.new
|
13
18
|
end
|
14
19
|
|
15
|
-
def
|
20
|
+
def test_runs_repo
|
21
|
+
@test_runs_repo ||= Repositories::TestRuns.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def session_data_repo
|
25
|
+
@session_data_repo ||= Repositories::SessionData.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def start
|
29
|
+
test_runs_repo.mark_as_running(test_run.id)
|
30
|
+
|
31
|
+
run(test_run.runnable)
|
32
|
+
|
33
|
+
test_runs_repo.mark_as_done(test_run.id) unless run_results.values.any?(&:waiting?)
|
34
|
+
|
35
|
+
run_results.values
|
36
|
+
end
|
37
|
+
|
38
|
+
def run(runnable)
|
16
39
|
if runnable < Entities::Test
|
17
|
-
run_test(runnable
|
40
|
+
return existing_test_result(runnable) || run_test(runnable) if resuming
|
41
|
+
|
42
|
+
run_test(runnable)
|
18
43
|
else
|
19
|
-
run_group(runnable
|
44
|
+
run_group(runnable)
|
20
45
|
end
|
21
46
|
end
|
22
47
|
|
23
|
-
def
|
24
|
-
|
48
|
+
def existing_test_result(runnable)
|
49
|
+
results_repo.result_for_test_run(runnable.reference_hash.merge(test_run_id: test_run.id))
|
50
|
+
end
|
51
|
+
|
52
|
+
def run_test(test)
|
53
|
+
inputs = load_inputs(test)
|
54
|
+
|
55
|
+
input_json_string = JSON.generate(inputs)
|
56
|
+
test_instance = test.new(inputs: inputs, test_session_id: test_session.id)
|
25
57
|
|
26
58
|
result = begin
|
27
|
-
inputs.merge(outputs).each do |key, value|
|
28
|
-
test_instance.instance_variable_set("@#{key}", value)
|
29
|
-
end
|
30
59
|
test_instance.load_named_requests
|
31
|
-
test_instance.instance_eval(&
|
60
|
+
test_instance.instance_eval(&test.block)
|
32
61
|
'pass'
|
33
62
|
rescue Exceptions::TestResultException => e
|
34
63
|
test_instance.result_message = e.message
|
35
64
|
e.result
|
36
65
|
rescue StandardError => e
|
66
|
+
Application['logger'].error(e.full_message)
|
37
67
|
test_instance.result_message = "Error: #{e.message}"
|
38
68
|
'error'
|
39
69
|
end
|
40
70
|
|
41
|
-
|
42
|
-
|
71
|
+
outputs = save_outputs(test_instance)
|
72
|
+
output_json_string = JSON.generate(outputs)
|
73
|
+
|
74
|
+
if result == 'wait'
|
75
|
+
test_runs_repo.mark_as_waiting(test_run.id, test_instance.identifier, test_instance.wait_timeout)
|
43
76
|
end
|
44
77
|
|
45
|
-
|
78
|
+
test_result = persist_result(
|
46
79
|
{
|
47
|
-
test_session_id: test_session.id,
|
48
|
-
test_run_id: test_run.id,
|
49
80
|
messages: test_instance.messages,
|
50
81
|
requests: test_instance.requests,
|
51
82
|
result: result,
|
52
|
-
result_message: test_instance.result_message
|
53
|
-
|
54
|
-
|
83
|
+
result_message: test_instance.result_message,
|
84
|
+
input_json: input_json_string,
|
85
|
+
output_json: output_json_string
|
86
|
+
}.merge(test.reference_hash)
|
87
|
+
)
|
88
|
+
|
89
|
+
# If running a single test, update its parents' results. If running a
|
90
|
+
# group or suite, #run_group handles updating the parents.
|
91
|
+
return test_result if test_run.test_id.blank?
|
92
|
+
|
93
|
+
update_parent_result(test.parent)
|
94
|
+
|
95
|
+
test_result
|
55
96
|
end
|
56
97
|
|
57
|
-
def run_group(
|
58
|
-
results =
|
98
|
+
def run_group(group)
|
99
|
+
results = []
|
100
|
+
group.children.each do |child|
|
101
|
+
result = run(child)
|
102
|
+
results << result
|
103
|
+
break if results.last.waiting?
|
104
|
+
end
|
59
105
|
|
60
|
-
results
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
106
|
+
results.flatten!
|
107
|
+
|
108
|
+
group_result = persist_result(group.reference_hash.merge(result: roll_up_result(results)))
|
109
|
+
|
110
|
+
update_parent_result(group.parent)
|
111
|
+
|
112
|
+
group_result
|
113
|
+
end
|
114
|
+
|
115
|
+
def update_parent_result(parent)
|
116
|
+
return if parent.nil?
|
117
|
+
|
118
|
+
children = parent.children
|
119
|
+
child_results = results_repo.current_results_for_test_session_and_runnables(test_session.id, children)
|
120
|
+
return if children.length != child_results.length
|
121
|
+
|
122
|
+
old_result = results_repo.current_result_for_test_session(test_session.id, parent.reference_hash)&.result
|
123
|
+
new_result = roll_up_result(child_results)
|
124
|
+
|
125
|
+
if new_result != old_result
|
126
|
+
persist_result(parent.reference_hash.merge(result: new_result))
|
127
|
+
|
128
|
+
update_parent_result(parent.parent)
|
129
|
+
end
|
130
|
+
|
131
|
+
new_result
|
132
|
+
end
|
133
|
+
|
134
|
+
def load_inputs(runnable)
|
135
|
+
runnable.inputs.each_with_object({}) do |input, input_hash|
|
136
|
+
name = input[:name]
|
137
|
+
input_hash[name] = session_data_repo.load(test_session_id: test_session.id, name: name)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def save_outputs(runnable_instance)
|
142
|
+
outputs =
|
143
|
+
runnable_instance.outputs.map do |output_name|
|
144
|
+
{
|
145
|
+
name: output_name,
|
146
|
+
value: runnable_instance.send(output_name)
|
147
|
+
}
|
148
|
+
end
|
149
|
+
outputs.compact!
|
150
|
+
outputs.each do |output|
|
151
|
+
session_data_repo.save(output.merge(test_session_id: test_session.id))
|
152
|
+
end
|
153
|
+
|
154
|
+
outputs
|
67
155
|
end
|
68
156
|
|
69
157
|
def persist_result(params)
|
70
|
-
results_repo.create(
|
158
|
+
result = results_repo.create(
|
159
|
+
params.merge(test_run_id: test_run.id, test_session_id: test_session.id)
|
160
|
+
)
|
161
|
+
|
162
|
+
run_results[result.runnable.id] = result
|
71
163
|
end
|
72
164
|
|
73
165
|
def roll_up_result(results)
|