Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FI-2330: Request tags #407

Merged
merged 12 commits into from
Dec 4, 2023
15 changes: 15 additions & 0 deletions dev_suites/dev_demo_ig_stu1/groups/demo_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -330,5 +330,20 @@ class DemoGroup < Inferno::TestGroup
test 'read from scratch' do
run { assert scratch[:abc] == 'xyz' }
end

test 'tag a request' do
run do
fhir_read :patient, patient_id, client: :this_client_name, tags: ['example_tag_1', 'example_tag_2']
end
end

test 'load a tagged request' do
run do
tagged_requests = load_tagged_requests('example_tag_1', 'example_tag_2')

assert tagged_requests.length == 1, 'Incorrect number of requests loaded'
assert request.id == tagged_requests.first.id, 'Incorrect request loaded'
end
end
end
end
18 changes: 18 additions & 0 deletions lib/inferno/db/migrations/009_add_request_tags.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Sequel.migration do
change do
create_table :tags do
column :id, String, primary_key: true, null: false, size: 36
column :name, String, size: 255, null: false

index :name, unique: true
end

create_table :requests_tags do
foreign_key :tags_id, :tags, index: true, type: String, null: false, size: 36, key: [:id]
foreign_key :requests_id, :requests, index: true, type: Integer, null: false, key: [:index]

index [:tags_id, :requests_id], unique: true
index [:requests_id, :tags_id], unique: true
end
end
end
19 changes: 19 additions & 0 deletions lib/inferno/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@
Integer :version, :default=>0, :null=>false
end

create_table(:tags, :ignore_index_errors=>true) do
String :id, :size=>36, :null=>false
String :name, :size=>255, :null=>false

primary_key [:id]

index [:name], :unique=>true
end

create_table(:test_sessions) do
String :id, :size=>36, :null=>false
String :test_suite_id, :size=>255, :null=>false
Expand Down Expand Up @@ -121,5 +130,15 @@
index [:requests_id]
index [:results_id]
end

create_table(:requests_tags, :ignore_index_errors=>true) do
foreign_key :tags_id, :tags, :type=>String, :size=>36, :null=>false, :key=>[:id]
foreign_key :requests_id, :requests, :null=>false, :key=>[:index]

index [:requests_id]
index [:requests_id, :tags_id], :unique=>true
index [:tags_id]
index [:tags_id, :requests_id], :unique=>true
end
end
end
74 changes: 50 additions & 24 deletions lib/inferno/dsl/fhir_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,18 @@ def body_to_path(body)
# other tests
# @param headers [Hash] custom headers for this operation
# @param operation_method [Symbol] indicates which request type to use for the operation
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def fhir_operation(path, body: nil, client: :default, name: nil, headers: {}, operation_method: :post)
store_request_and_refresh_token(fhir_client(client), name) do
def fhir_operation(
path,
body: nil,
client: :default,
name: nil,
headers: {},
operation_method: :post,
tags: []
)
store_request_and_refresh_token(fhir_client(client), name, tags) do
tcp_exception_handler do
operation_headers = fhir_client(client).fhir_headers
operation_headers.merge!('Content-Type' => 'application/fhir+json') if body.present?
Expand All @@ -127,9 +136,10 @@ def fhir_operation(path, body: nil, client: :default, name: nil, headers: {}, op
# @param client [Symbol]
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def fhir_get_capability_statement(client: :default, name: nil)
store_request_and_refresh_token(fhir_client(client), name) do
def fhir_get_capability_statement(client: :default, name: nil, tags: [])
store_request_and_refresh_token(fhir_client(client), name, tags) do
tcp_exception_handler do
fhir_client(client).conformance_statement
fhir_client(client).reply
Expand All @@ -143,9 +153,10 @@ def fhir_get_capability_statement(client: :default, name: nil)
# @param client [Symbol]
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def fhir_create(resource, client: :default, name: nil)
store_request_and_refresh_token(fhir_client(client), name) do
def fhir_create(resource, client: :default, name: nil, tags: [])
store_request_and_refresh_token(fhir_client(client), name, tags) do
tcp_exception_handler do
fhir_client(client).create(resource)
end
Expand All @@ -159,9 +170,10 @@ def fhir_create(resource, client: :default, name: nil)
# @param client [Symbol]
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def fhir_read(resource_type, id, client: :default, name: nil)
store_request_and_refresh_token(fhir_client(client), name) do
def fhir_read(resource_type, id, client: :default, name: nil, tags: [])
store_request_and_refresh_token(fhir_client(client), name, tags) do
tcp_exception_handler do
fhir_client(client).read(fhir_class_from_resource_type(resource_type), id)
end
Expand All @@ -176,9 +188,10 @@ def fhir_read(resource_type, id, client: :default, name: nil)
# @param client [Symbol]
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def fhir_vread(resource_type, id, version_id, client: :default, name: nil)
store_request_and_refresh_token(fhir_client(client), name) do
def fhir_vread(resource_type, id, version_id, client: :default, name: nil, tags: [])
store_request_and_refresh_token(fhir_client(client), name, tags) do
tcp_exception_handler do
fhir_client(client).vread(fhir_class_from_resource_type(resource_type), id, version_id)
end
Expand All @@ -192,9 +205,10 @@ def fhir_vread(resource_type, id, version_id, client: :default, name: nil)
# @param client [Symbol]
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def fhir_update(resource, id, client: :default, name: nil)
store_request_and_refresh_token(fhir_client(client), name) do
def fhir_update(resource, id, client: :default, name: nil, tags: [])
store_request_and_refresh_token(fhir_client(client), name, tags) do
tcp_exception_handler do
fhir_client(client).update(resource, id)
end
Expand All @@ -209,9 +223,10 @@ def fhir_update(resource, id, client: :default, name: nil)
# @param client [Symbol]
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def fhir_patch(resource_type, id, patchset, client: :default, name: nil)
store_request_and_refresh_token(fhir_client(client), name) do
def fhir_patch(resource_type, id, patchset, client: :default, name: nil, tags: [])
store_request_and_refresh_token(fhir_client(client), name, tags) do
tcp_exception_handler do
fhir_client(client).partial_update(fhir_class_from_resource_type(resource_type), id, patchset)
end
Expand All @@ -225,9 +240,10 @@ def fhir_patch(resource_type, id, patchset, client: :default, name: nil)
# @param client [Symbol]
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def fhir_history(resource_type = nil, id = nil, client: :default, name: nil)
store_request_and_refresh_token(fhir_client(client), name) do
def fhir_history(resource_type = nil, id = nil, client: :default, name: nil, tags: [])
store_request_and_refresh_token(fhir_client(client), name, tags) do
tcp_exception_handler do
if id
fhir_client(client).resource_instance_history(fhir_class_from_resource_type(resource_type), id)
Expand All @@ -248,16 +264,24 @@ def fhir_history(resource_type = nil, id = nil, client: :default, name: nil)
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param search_method [Symbol] Use `:post` to search via POST
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def fhir_search(resource_type = nil, client: :default, params: {}, name: nil, search_method: :get)
def fhir_search(
resource_type = nil,
client: :default,
params: {},
name: nil,
search_method: :get,
tags: []
)
search =
if search_method == :post
{ body: params }
else
{ parameters: params }
end

store_request_and_refresh_token(fhir_client(client), name) do
store_request_and_refresh_token(fhir_client(client), name, tags) do
tcp_exception_handler do
if resource_type
fhir_client(client)
Expand All @@ -276,9 +300,10 @@ def fhir_search(resource_type = nil, client: :default, params: {}, name: nil, se
# @param client [Symbol]
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def fhir_delete(resource_type, id, client: :default, name: nil)
store_request('outgoing', name) do
def fhir_delete(resource_type, id, client: :default, name: nil, tags: [])
store_request('outgoing', name, tags) do
tcp_exception_handler do
fhir_client(client).destroy(fhir_class_from_resource_type(resource_type), id)
end
Expand All @@ -291,9 +316,10 @@ def fhir_delete(resource_type, id, client: :default, name: nil)
# @param client [Symbol]
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def fhir_transaction(bundle = nil, client: :default, name: nil)
store_request('outgoing', name) do
def fhir_transaction(bundle = nil, client: :default, name: nil, tags: [])
store_request('outgoing', name, tags) do
tcp_exception_handler do
fhir_client(client).transaction_bundle = bundle if bundle.present?
fhir_client(client).end_transaction
Expand All @@ -312,8 +338,8 @@ def fhir_class_from_resource_type(resource_type)
# expired. It's combined with `store_request` so that all of the fhir
# request methods don't have to be wrapped twice.
# @private
def store_request_and_refresh_token(client, name, &block)
store_request('outgoing', name) do
def store_request_and_refresh_token(client, name, tags, &block)
store_request('outgoing', name, tags) do
perform_refresh(client) if client.need_to_refresh? && client.able_to_refresh?
block.call
end
Expand Down
20 changes: 12 additions & 8 deletions lib/inferno/dsl/http_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ def http_clients
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param headers [Hash] Input headers here
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def get(url = '', client: :default, name: nil, headers: nil)
store_request('outgoing', name) do
def get(url = '', client: :default, name: nil, headers: nil, tags: [])
store_request('outgoing', name, tags) do
tcp_exception_handler do
client = http_client(client)

Expand Down Expand Up @@ -103,9 +104,10 @@ def connection
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param headers [Hash] Input headers here
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def post(url = '', body: nil, client: :default, name: nil, headers: nil)
store_request('outgoing', name) do
def post(url = '', body: nil, client: :default, name: nil, headers: nil, tags: [])
store_request('outgoing', name, tags) do
tcp_exception_handler do
client = http_client(client)

Expand All @@ -129,9 +131,10 @@ def post(url = '', body: nil, client: :default, name: nil, headers: nil)
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param headers [Hash] Input headers here
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def delete(url = '', client: :default, name: :nil, headers: nil)
store_request('outgoing', name) do
def delete(url = '', client: :default, name: :nil, headers: nil, tags: [])
store_request('outgoing', name, tags) do
tcp_exception_handler do
client = http_client(client)

Expand Down Expand Up @@ -159,8 +162,9 @@ def delete(url = '', client: :default, name: :nil, headers: nil)
# @param name [Symbol] Name for this request to allow it to be used by
# other tests
# @param headers [Hash] Input headers here
# @param tags [Array<String>] a list of tags to assign to the request
# @return [Inferno::Entities::Request]
def stream(block, url = '', limit = 100, client: :default, name: nil, headers: nil)
def stream(block, url = '', limit = 100, client: :default, name: nil, headers: nil, tags: [])
streamed = []

collector = proc do |chunk, bytes|
Expand All @@ -169,7 +173,7 @@ def stream(block, url = '', limit = 100, client: :default, name: nil, headers: n
block.call(chunk, bytes)
end

store_request('outgoing', name) do
store_request('outgoing', name, tags) do
tcp_exception_handler do
client = http_client(client)

Expand Down
18 changes: 15 additions & 3 deletions lib/inferno/dsl/request_storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,36 @@ def resource
request&.resource
end

# Returns requests which match all of the given tags
#
# @param tags [String]
# @return [Inferno::Entities::Request]
def load_tagged_requests(*tags)
return [] if tags.blank?

Repositories::Requests.new.tagged_requests(test_session_id, tags).tap do |tagged_requests|
requests.concat(tagged_requests)
end
end

# @private
def named_request(name)
requests.find { |request| request.name == self.class.config.request_name(name.to_sym) }
end

# @private
def store_request(direction, name = nil, &block)
def store_request(direction, name, tags, &block)
response = block.call

name = self.class.config.request_name(name)
request =
if response.is_a? FHIR::ClientReply
Entities::Request.from_fhir_client_reply(
response, direction:, name:, test_session_id:
response, direction:, name:, test_session_id:, tags:
)
else
Entities::Request.from_http_response(
response, direction:, name:, test_session_id:
response, direction:, name:, test_session_id:, tags:
)
end

Expand Down
8 changes: 7 additions & 1 deletion lib/inferno/dsl/resume_test_route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ def test_run_identifier_block
self.class.singleton_class.instance_variable_get(:@test_run_identifier_block)
end

# @private
def tags
self.class.singleton_class.instance_variable_get(:@tags)
end

# @private
def find_test_run(test_run_identifier)
test_runs_repo.find_latest_waiting_by_identifier(test_run_identifier)
Expand All @@ -44,7 +49,8 @@ def persist_request(request, test_run, waiting_result, test)
request.to_hash.merge(
test_session_id: test_run.test_session_id,
result_id: waiting_result.id,
name: test.config.request_name(test.incoming_request_name)
name: test.config.request_name(test.incoming_request_name),
tags:
)
)
end
Expand Down
6 changes: 4 additions & 2 deletions lib/inferno/dsl/runnable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ def suite
#
# @see Inferno::DSL::Results#wait
# @example
# resume_test_route :get, '/launch' do
# resume_test_route :get, '/launch', tags: ['launch'] do
# request.query_parameters['iss']
# end
#
Expand All @@ -341,15 +341,17 @@ def suite
# [Any of the path options available in Hanami
# Router](https://github.com/hanami/router/tree/f41001d4c3ee9e2d2c7bb142f74b43f8e1d3a265#a-beautiful-dsl)
# can be used here.
# @param tags [Array<String>] a list of tags to assign to the request
# @yield This method takes a block which must return the identifier
# defined when a test was set to wait for the test run that hit this
# route. The block has access to the `request` method which returns a
# {Inferno::Entities::Request} object with the information for the
# incoming request.
# @return [void]
def resume_test_route(method, path, &block)
def resume_test_route(method, path, tags: [], &block)
route_class = Class.new(ResumeTestRoute) do |klass|
klass.singleton_class.instance_variable_set(:@test_run_identifier_block, block)
klass.singleton_class.instance_variable_set(:@tags, tags)
end

route(method, path, route_class)
Expand Down
Loading
Loading