pact 1.67.4 → 2.0.0
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/CHANGELOG.md +15 -0
- data/lib/pact/configuration.rb +21 -0
- data/lib/pact/consumer/grpc_interaction_builder.rb +192 -0
- data/lib/pact/consumer/http_interaction_builder.rb +160 -0
- data/lib/pact/consumer/interaction_contents.rb +60 -0
- data/lib/pact/consumer/message_interaction_builder.rb +286 -0
- data/lib/pact/consumer/mock_server.rb +106 -0
- data/lib/pact/consumer/pact_config/base.rb +22 -0
- data/lib/pact/consumer/pact_config/grpc.rb +24 -0
- data/lib/pact/consumer/pact_config/http.rb +53 -0
- data/lib/pact/consumer/pact_config/message.rb +15 -0
- data/lib/pact/consumer/pact_config/plugin_async_message.rb +24 -0
- data/lib/pact/consumer/pact_config/plugin_http.rb +24 -0
- data/lib/pact/consumer/pact_config/plugin_sync_message.rb +24 -0
- data/lib/pact/consumer/pact_config.rb +28 -0
- data/lib/pact/consumer/plugin_async_message_interaction_builder.rb +169 -0
- data/lib/pact/consumer/plugin_http_interaction_builder.rb +199 -0
- data/lib/pact/consumer/plugin_sync_message_interaction_builder.rb +178 -0
- data/lib/pact/consumer.rb +6 -7
- data/lib/pact/generators/base.rb +285 -0
- data/lib/pact/generators.rb +47 -0
- data/lib/pact/matchers/base.rb +72 -0
- data/lib/pact/matchers/v1/equality.rb +17 -0
- data/lib/pact/matchers/v2/regex.rb +26 -0
- data/lib/pact/matchers/v2/type.rb +18 -0
- data/lib/pact/matchers/v3/boolean.rb +18 -0
- data/lib/pact/matchers/v3/content_type.rb +30 -0
- data/lib/pact/matchers/v3/date.rb +22 -0
- data/lib/pact/matchers/v3/date_time.rb +22 -0
- data/lib/pact/matchers/v3/decimal.rb +18 -0
- data/lib/pact/matchers/v3/each.rb +46 -0
- data/lib/pact/matchers/v3/include.rb +18 -0
- data/lib/pact/matchers/v3/integer.rb +18 -0
- data/lib/pact/matchers/v3/null.rb +13 -0
- data/lib/pact/matchers/v3/number.rb +18 -0
- data/lib/pact/matchers/v3/semver.rb +22 -0
- data/lib/pact/matchers/v3/time.rb +22 -0
- data/lib/pact/matchers/v3/values.rb +13 -0
- data/lib/pact/matchers/v4/each_key.rb +34 -0
- data/lib/pact/matchers/v4/each_key_value.rb +38 -0
- data/lib/pact/matchers/v4/each_value.rb +40 -0
- data/lib/pact/matchers/v4/not_empty.rb +22 -0
- data/lib/pact/matchers/v4/status_code.rb +15 -0
- data/lib/pact/matchers.rb +108 -0
- data/lib/pact/native/blocking_verifier.rb +15 -0
- data/lib/pact/native/logger.rb +24 -0
- data/lib/pact/provider/async_message_verifier.rb +29 -0
- data/lib/pact/provider/base_verifier.rb +259 -0
- data/lib/pact/provider/grpc_verifier.rb +40 -0
- data/lib/pact/provider/gruf_server.rb +73 -0
- data/lib/pact/provider/http_server.rb +77 -0
- data/lib/pact/provider/http_verifier.rb +45 -0
- data/lib/pact/provider/message_provider_servlet.rb +77 -0
- data/lib/pact/provider/mixed_verifier.rb +21 -0
- data/lib/pact/provider/pact_broker_proxy.rb +62 -0
- data/lib/pact/provider/pact_broker_proxy_runner.rb +78 -0
- data/lib/pact/provider/pact_config/async.rb +28 -0
- data/lib/pact/provider/pact_config/base.rb +101 -0
- data/lib/pact/provider/pact_config/grpc.rb +24 -0
- data/lib/pact/provider/pact_config/http.rb +25 -0
- data/lib/pact/provider/pact_config/mixed.rb +38 -0
- data/lib/pact/provider/pact_config.rb +24 -0
- data/lib/pact/provider/provider_server_runner.rb +90 -0
- data/lib/pact/provider/provider_state_configuration.rb +32 -0
- data/lib/pact/provider/provider_state_servlet.rb +84 -0
- data/lib/pact/provider.rb +6 -3
- data/lib/pact/railtie.rb +11 -0
- data/lib/pact/{v2/rspec → rspec}/support/pact_consumer_helpers.rb +8 -8
- data/lib/pact/{v2/rspec → rspec}/support/pact_provider_helpers.rb +25 -24
- data/lib/pact/{v2/rspec.rb → rspec.rb} +6 -5
- data/lib/pact/tasks/pact.rake +13 -0
- data/lib/pact/version.rb +1 -1
- data/lib/pact.rb +46 -11
- data/pact.gemspec +42 -65
- metadata +145 -404
- data/lib/pact/cli/generate_pact_docs.rb +0 -4
- data/lib/pact/cli/run_pact_verification.rb +0 -99
- data/lib/pact/cli/spec_criteria.rb +0 -26
- data/lib/pact/cli.rb +0 -45
- data/lib/pact/consumer/configuration/configuration_extensions.rb +0 -90
- data/lib/pact/consumer/configuration/dsl.rb +0 -11
- data/lib/pact/consumer/configuration/mock_service.rb +0 -112
- data/lib/pact/consumer/configuration/service_consumer.rb +0 -51
- data/lib/pact/consumer/configuration/service_provider.rb +0 -40
- data/lib/pact/consumer/configuration.rb +0 -10
- data/lib/pact/consumer/consumer_contract_builder.rb +0 -82
- data/lib/pact/consumer/consumer_contract_builders.rb +0 -10
- data/lib/pact/consumer/interaction_builder.rb +0 -45
- data/lib/pact/consumer/rspec.rb +0 -35
- data/lib/pact/consumer/spec_hooks.rb +0 -40
- data/lib/pact/consumer/world.rb +0 -37
- data/lib/pact/doc/README.md +0 -13
- data/lib/pact/doc/doc_file.rb +0 -40
- data/lib/pact/doc/generate.rb +0 -11
- data/lib/pact/doc/generator.rb +0 -82
- data/lib/pact/doc/interaction_view_model.rb +0 -124
- data/lib/pact/doc/markdown/consumer_contract_renderer.rb +0 -68
- data/lib/pact/doc/markdown/generator.rb +0 -26
- data/lib/pact/doc/markdown/index_renderer.rb +0 -43
- data/lib/pact/doc/markdown/interaction.erb +0 -14
- data/lib/pact/doc/markdown/interaction_renderer.rb +0 -43
- data/lib/pact/doc/sort_interactions.rb +0 -16
- data/lib/pact/hal/authorization_header_redactor.rb +0 -32
- data/lib/pact/hal/entity.rb +0 -110
- data/lib/pact/hal/http_client.rb +0 -128
- data/lib/pact/hal/link.rb +0 -112
- data/lib/pact/hal/non_json_entity.rb +0 -28
- data/lib/pact/hash_refinements.rb +0 -17
- data/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb +0 -112
- data/lib/pact/pact_broker/fetch_pacts.rb +0 -103
- data/lib/pact/pact_broker/notices.rb +0 -34
- data/lib/pact/pact_broker/pact_selection_description.rb +0 -66
- data/lib/pact/pact_broker.rb +0 -25
- data/lib/pact/project_root.rb +0 -7
- data/lib/pact/provider/configuration/configuration_extension.rb +0 -69
- data/lib/pact/provider/configuration/dsl.rb +0 -18
- data/lib/pact/provider/configuration/message_provider_dsl.rb +0 -63
- data/lib/pact/provider/configuration/pact_verification.rb +0 -48
- data/lib/pact/provider/configuration/pact_verification_from_broker.rb +0 -126
- data/lib/pact/provider/configuration/service_provider_config.rb +0 -32
- data/lib/pact/provider/configuration/service_provider_dsl.rb +0 -107
- data/lib/pact/provider/configuration.rb +0 -7
- data/lib/pact/provider/context.rb +0 -0
- data/lib/pact/provider/help/console_text.rb +0 -76
- data/lib/pact/provider/help/content.rb +0 -38
- data/lib/pact/provider/help/pact_diff.rb +0 -43
- data/lib/pact/provider/help/prompt_text.rb +0 -49
- data/lib/pact/provider/help/write.rb +0 -56
- data/lib/pact/provider/matchers/messages.rb +0 -66
- data/lib/pact/provider/pact_helper_locator.rb +0 -24
- data/lib/pact/provider/pact_source.rb +0 -40
- data/lib/pact/provider/pact_spec_runner.rb +0 -188
- data/lib/pact/provider/pact_uri.rb +0 -55
- data/lib/pact/provider/pact_verification.rb +0 -17
- data/lib/pact/provider/print_missing_provider_states.rb +0 -35
- data/lib/pact/provider/request.rb +0 -90
- data/lib/pact/provider/rspec/backtrace_formatter.rb +0 -43
- data/lib/pact/provider/rspec/calculate_exit_code.rb +0 -18
- data/lib/pact/provider/rspec/custom_options_file +0 -0
- data/lib/pact/provider/rspec/formatter_rspec_2.rb +0 -76
- data/lib/pact/provider/rspec/formatter_rspec_3.rb +0 -195
- data/lib/pact/provider/rspec/json_formatter.rb +0 -100
- data/lib/pact/provider/rspec/matchers.rb +0 -80
- data/lib/pact/provider/rspec/pact_broker_formatter.rb +0 -76
- data/lib/pact/provider/rspec.rb +0 -234
- data/lib/pact/provider/state/provider_state.rb +0 -180
- data/lib/pact/provider/state/provider_state_configured_modules.rb +0 -15
- data/lib/pact/provider/state/provider_state_manager.rb +0 -42
- data/lib/pact/provider/state/provider_state_proxy.rb +0 -39
- data/lib/pact/provider/state/set_up.rb +0 -13
- data/lib/pact/provider/state/tear_down.rb +0 -13
- data/lib/pact/provider/test_methods.rb +0 -77
- data/lib/pact/provider/verification_report.rb +0 -36
- data/lib/pact/provider/verification_results/create.rb +0 -88
- data/lib/pact/provider/verification_results/publish.rb +0 -143
- data/lib/pact/provider/verification_results/publish_all.rb +0 -50
- data/lib/pact/provider/verification_results/verification_result.rb +0 -40
- data/lib/pact/provider/world.rb +0 -50
- data/lib/pact/retry.rb +0 -37
- data/lib/pact/tasks/task_helper.rb +0 -62
- data/lib/pact/tasks/verification_task.rb +0 -95
- data/lib/pact/tasks.rb +0 -2
- data/lib/pact/templates/help.erb +0 -22
- data/lib/pact/templates/provider_state.erb +0 -14
- data/lib/pact/utils/metrics.rb +0 -100
- data/lib/pact/utils/string.rb +0 -35
- data/lib/pact/v2/configuration.rb +0 -23
- data/lib/pact/v2/consumer/grpc_interaction_builder.rb +0 -194
- data/lib/pact/v2/consumer/http_interaction_builder.rb +0 -162
- data/lib/pact/v2/consumer/interaction_contents.rb +0 -62
- data/lib/pact/v2/consumer/message_interaction_builder.rb +0 -288
- data/lib/pact/v2/consumer/mock_server.rb +0 -108
- data/lib/pact/v2/consumer/pact_config/base.rb +0 -24
- data/lib/pact/v2/consumer/pact_config/grpc.rb +0 -26
- data/lib/pact/v2/consumer/pact_config/http.rb +0 -55
- data/lib/pact/v2/consumer/pact_config/message.rb +0 -17
- data/lib/pact/v2/consumer/pact_config/plugin_async_message.rb +0 -26
- data/lib/pact/v2/consumer/pact_config/plugin_http.rb +0 -26
- data/lib/pact/v2/consumer/pact_config/plugin_sync_message.rb +0 -26
- data/lib/pact/v2/consumer/pact_config.rb +0 -30
- data/lib/pact/v2/consumer/plugin_async_message_interaction_builder.rb +0 -171
- data/lib/pact/v2/consumer/plugin_http_interaction_builder.rb +0 -201
- data/lib/pact/v2/consumer/plugin_sync_message_interaction_builder.rb +0 -180
- data/lib/pact/v2/consumer.rb +0 -8
- data/lib/pact/v2/generators/base.rb +0 -287
- data/lib/pact/v2/generators.rb +0 -49
- data/lib/pact/v2/matchers/base.rb +0 -74
- data/lib/pact/v2/matchers/v1/equality.rb +0 -19
- data/lib/pact/v2/matchers/v2/regex.rb +0 -19
- data/lib/pact/v2/matchers/v2/type.rb +0 -17
- data/lib/pact/v2/matchers/v3/boolean.rb +0 -17
- data/lib/pact/v2/matchers/v3/content_type.rb +0 -32
- data/lib/pact/v2/matchers/v3/date.rb +0 -18
- data/lib/pact/v2/matchers/v3/date_time.rb +0 -18
- data/lib/pact/v2/matchers/v3/decimal.rb +0 -17
- data/lib/pact/v2/matchers/v3/each.rb +0 -42
- data/lib/pact/v2/matchers/v3/include.rb +0 -17
- data/lib/pact/v2/matchers/v3/integer.rb +0 -17
- data/lib/pact/v2/matchers/v3/null.rb +0 -16
- data/lib/pact/v2/matchers/v3/number.rb +0 -17
- data/lib/pact/v2/matchers/v3/semver.rb +0 -23
- data/lib/pact/v2/matchers/v3/time.rb +0 -18
- data/lib/pact/v2/matchers/v3/values.rb +0 -16
- data/lib/pact/v2/matchers/v4/each_key.rb +0 -26
- data/lib/pact/v2/matchers/v4/each_key_value.rb +0 -32
- data/lib/pact/v2/matchers/v4/each_value.rb +0 -33
- data/lib/pact/v2/matchers/v4/not_empty.rb +0 -24
- data/lib/pact/v2/matchers/v4/status_code.rb +0 -17
- data/lib/pact/v2/matchers.rb +0 -110
- data/lib/pact/v2/native/blocking_verifier.rb +0 -17
- data/lib/pact/v2/native/logger.rb +0 -25
- data/lib/pact/v2/provider/async_message_verifier.rb +0 -28
- data/lib/pact/v2/provider/base_verifier.rb +0 -242
- data/lib/pact/v2/provider/grpc_verifier.rb +0 -38
- data/lib/pact/v2/provider/gruf_server.rb +0 -75
- data/lib/pact/v2/provider/http_server.rb +0 -79
- data/lib/pact/v2/provider/http_verifier.rb +0 -43
- data/lib/pact/v2/provider/message_provider_servlet.rb +0 -79
- data/lib/pact/v2/provider/mixed_verifier.rb +0 -22
- data/lib/pact/v2/provider/pact_broker_proxy.rb +0 -66
- data/lib/pact/v2/provider/pact_broker_proxy_runner.rb +0 -80
- data/lib/pact/v2/provider/pact_config/async.rb +0 -29
- data/lib/pact/v2/provider/pact_config/base.rb +0 -103
- data/lib/pact/v2/provider/pact_config/grpc.rb +0 -26
- data/lib/pact/v2/provider/pact_config/http.rb +0 -27
- data/lib/pact/v2/provider/pact_config/mixed.rb +0 -40
- data/lib/pact/v2/provider/pact_config.rb +0 -26
- data/lib/pact/v2/provider/provider_server_runner.rb +0 -92
- data/lib/pact/v2/provider/provider_state_configuration.rb +0 -32
- data/lib/pact/v2/provider/provider_state_servlet.rb +0 -86
- data/lib/pact/v2/provider.rb +0 -8
- data/lib/pact/v2/railtie.rb +0 -13
- data/lib/pact/v2/tasks/pact.rake +0 -13
- data/lib/pact/v2.rb +0 -71
- data/lib/tasks/pact.rake +0 -34
- /data/lib/pact/{v2/rspec → rspec}/support/pact_message_helpers.rb +0 -0
- /data/lib/pact/{v2/rspec → rspec}/support/waterdrop/pact_waterdrop_client.rb +0 -0
- /data/lib/pact/{v2/rspec → rspec}/support/webmock/webmock_helpers.rb +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module Matchers
|
|
5
|
+
module V3
|
|
6
|
+
class Number < Pact::Matchers::Base
|
|
7
|
+
def initialize(template)
|
|
8
|
+
unless template.is_a?(Numeric)
|
|
9
|
+
raise MatcherInitializationError,
|
|
10
|
+
"#{self.class}: #{template} should be an instance of Numeric"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
super(spec_version: Pact::Matchers::PACT_SPEC_V3, kind: 'number', template: template)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module Matchers
|
|
5
|
+
module V3
|
|
6
|
+
class Semver < Pact::Matchers::Base
|
|
7
|
+
def initialize(template = nil)
|
|
8
|
+
@template = template
|
|
9
|
+
super(spec_version: Pact::Matchers::PACT_SPEC_V3, kind: 'semver', template: template)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def as_plugin
|
|
13
|
+
if @template.nil? || @template.blank?
|
|
14
|
+
raise MatcherInitializationError, "#{self.class}: template must be provided when calling as_plugin"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
"matching(semver, '#{@template}')"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module Matchers
|
|
5
|
+
module V3
|
|
6
|
+
class Time < Pact::Matchers::Base
|
|
7
|
+
def initialize(format, template)
|
|
8
|
+
unless template.is_a?(String)
|
|
9
|
+
raise MatcherInitializationError,
|
|
10
|
+
"#{self.class}: #{format} should be an instance of String"
|
|
11
|
+
end
|
|
12
|
+
unless template.is_a?(String)
|
|
13
|
+
raise MatcherInitializationError,
|
|
14
|
+
"#{self.class}: #{template} should be an instance of String"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
super(spec_version: Pact::Matchers::PACT_SPEC_V3, kind: 'time', template: template, opts: { format: format })
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module Matchers
|
|
5
|
+
module V4
|
|
6
|
+
class EachKey < Pact::Matchers::Base
|
|
7
|
+
def initialize(key_matchers, template)
|
|
8
|
+
raise MatcherInitializationError, "#{self.class}: #{template} should be a Hash" unless template.is_a?(Hash)
|
|
9
|
+
|
|
10
|
+
unless key_matchers.is_a?(Array)
|
|
11
|
+
raise MatcherInitializationError,
|
|
12
|
+
"#{self.class}: #{key_matchers} should be an Array"
|
|
13
|
+
end
|
|
14
|
+
unless key_matchers.all?(Pact::Matchers::Base)
|
|
15
|
+
raise MatcherInitializationError,
|
|
16
|
+
"#{self.class}: #{key_matchers} should be instances of Pact::Matchers::Base"
|
|
17
|
+
end
|
|
18
|
+
unless key_matchers.size > 0
|
|
19
|
+
raise MatcherInitializationError,
|
|
20
|
+
"#{self.class}: #{key_matchers} size should be greater than 0"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
super(spec_version: Pact::Matchers::PACT_SPEC_V4, kind: 'each-key', template: template, opts: { rules: key_matchers }) # rubocop:disable Layout/LineLength
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def as_plugin
|
|
27
|
+
@opts[:rules].map do |matcher|
|
|
28
|
+
"eachKey(#{matcher.as_plugin})"
|
|
29
|
+
end.join(', ')
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module Matchers
|
|
5
|
+
module V4
|
|
6
|
+
class EachKeyValue < Pact::Matchers::Base
|
|
7
|
+
def initialize(key_matchers, template)
|
|
8
|
+
raise MatcherInitializationError, "#{self.class}: #{template} should be a Hash" unless template.is_a?(Hash)
|
|
9
|
+
|
|
10
|
+
unless key_matchers.is_a?(Array)
|
|
11
|
+
raise MatcherInitializationError,
|
|
12
|
+
"#{self.class}: #{key_matchers} should be an Array"
|
|
13
|
+
end
|
|
14
|
+
unless key_matchers.all?(Pact::Matchers::Base)
|
|
15
|
+
raise MatcherInitializationError,
|
|
16
|
+
"#{self.class}: #{key_matchers} should be instances of Pact::Matchers::Base"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
super(
|
|
20
|
+
spec_version: Pact::Matchers::PACT_SPEC_V4,
|
|
21
|
+
kind: [
|
|
22
|
+
EachKey.new(key_matchers, {}),
|
|
23
|
+
EachValue.new([Pact::Matchers::V2::Type.new('')], {})
|
|
24
|
+
],
|
|
25
|
+
template: template
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
@key_matchers = key_matchers
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def as_plugin
|
|
32
|
+
raise MatcherInitializationError,
|
|
33
|
+
"#{self.class}: each-key-value is not supported in plugin syntax. Use each / each_key / each_value matchers instead" # rubocop:disable Layout/LineLength
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module Matchers
|
|
5
|
+
module V4
|
|
6
|
+
class EachValue < Pact::Matchers::Base
|
|
7
|
+
def initialize(value_matchers, template)
|
|
8
|
+
# raise MatcherInitializationError, "#{self.class}: #{template} should be a Hash" unless template.is_a?(Hash)
|
|
9
|
+
unless value_matchers.is_a?(Array)
|
|
10
|
+
raise MatcherInitializationError,
|
|
11
|
+
"#{self.class}: #{value_matchers} should be an Array"
|
|
12
|
+
end
|
|
13
|
+
unless value_matchers.all?(Pact::Matchers::Base)
|
|
14
|
+
raise MatcherInitializationError,
|
|
15
|
+
"#{self.class}: #{value_matchers} should be instances of Pact::Matchers::Base"
|
|
16
|
+
end
|
|
17
|
+
unless value_matchers.size > 0
|
|
18
|
+
raise MatcherInitializationError,
|
|
19
|
+
"#{self.class}: #{value_matchers} size should be greater than 0"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
super(spec_version: Pact::Matchers::PACT_SPEC_V4, kind: 'each-value', template: template, opts: { rules: value_matchers }) # rubocop:disable Layout/LineLength
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def as_plugin
|
|
26
|
+
if @template.is_a?(Hash)
|
|
27
|
+
return {
|
|
28
|
+
'pact:match' => "eachValue(matching($'SAMPLE'))",
|
|
29
|
+
'SAMPLE' => serialize!(@template.deep_dup, :plugin)
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
@opts[:rules].map do |matcher|
|
|
34
|
+
"eachValue(#{matcher.as_plugin})"
|
|
35
|
+
end.join(', ')
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module Matchers
|
|
5
|
+
module V4
|
|
6
|
+
class NotEmpty < Pact::Matchers::Base
|
|
7
|
+
def initialize(template = nil)
|
|
8
|
+
@template = template
|
|
9
|
+
super(spec_version: Pact::Matchers::PACT_SPEC_V4, kind: 'notEmpty', template: @template)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def as_plugin
|
|
13
|
+
if @template.nil? || @template.blank?
|
|
14
|
+
raise MatcherInitializationError, "#{self.class}: template must be provided when calling as_plugin"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
"notEmpty('#{@template}')"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module Matchers
|
|
5
|
+
module V4
|
|
6
|
+
class StatusCode < Pact::Matchers::Base
|
|
7
|
+
def initialize(template = nil)
|
|
8
|
+
super(spec_version: Pact::Matchers::PACT_SPEC_V4, kind: 'statusCode', opts: {
|
|
9
|
+
'status' => template
|
|
10
|
+
})
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module Matchers
|
|
5
|
+
PACT_SPEC_V1 = 1
|
|
6
|
+
PACT_SPEC_V2 = 2
|
|
7
|
+
PACT_SPEC_V3 = 3
|
|
8
|
+
PACT_SPEC_V4 = 4
|
|
9
|
+
|
|
10
|
+
ANY_STRING_REGEX = /.*/
|
|
11
|
+
UUID_REGEX = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i
|
|
12
|
+
|
|
13
|
+
# simplified
|
|
14
|
+
ISO8601_REGEX = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)*(.\d{2}:\d{2})*/i
|
|
15
|
+
|
|
16
|
+
def match_exactly(arg)
|
|
17
|
+
V1::Equality.new(arg)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def match_type_of(arg)
|
|
21
|
+
V2::Type.new(arg)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def match_include(arg)
|
|
25
|
+
V3::Include.new(arg)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def match_any_string(sample = "any")
|
|
29
|
+
V2::Regex.new(ANY_STRING_REGEX, sample)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def match_any_integer(sample = 10)
|
|
33
|
+
V3::Integer.new(sample)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def match_any_decimal(sample = 10.0)
|
|
37
|
+
V3::Decimal.new(sample)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def match_any_number(sample = 10.0)
|
|
41
|
+
V3::Number.new(sample)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def match_any_boolean(sample = true)
|
|
45
|
+
V3::Boolean.new(sample)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def match_uuid(sample = "e1d01e04-3a2b-4eed-a4fb-54f5cd257338")
|
|
49
|
+
V2::Regex.new(UUID_REGEX, sample)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def match_regex(regex, sample)
|
|
53
|
+
V2::Regex.new(regex, sample)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def match_datetime(format, sample)
|
|
57
|
+
V3::DateTime.new(format, sample)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def match_iso8601(sample = "2024-08-12T12:25:00.243118+03:00")
|
|
61
|
+
V2::Regex.new(ISO8601_REGEX, sample)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def match_date(format, sample)
|
|
65
|
+
V3::Date.new(format, sample)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def match_time(format, sample)
|
|
69
|
+
V3::Time.new(format, sample)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def match_each(template, min = nil)
|
|
73
|
+
V3::Each.new(template, min)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def match_each_regex(regex, sample)
|
|
77
|
+
match_each_value(sample, match_regex(regex, sample))
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def match_each_key(template, key_matchers)
|
|
81
|
+
V4::EachKey.new(key_matchers.is_a?(Array) ? key_matchers : [key_matchers], template)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def match_each_value(template, value_matchers = V2::Type.new(""))
|
|
85
|
+
V4::EachValue.new(value_matchers.is_a?(Array) ? value_matchers : [value_matchers], template)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def match_each_kv(template, key_matchers)
|
|
89
|
+
V4::EachKeyValue.new(key_matchers.is_a?(Array) ? key_matchers : [key_matchers], template)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def match_semver(template = nil)
|
|
93
|
+
V3::Semver.new(template)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def match_content_type(content_type, template = nil)
|
|
97
|
+
V3::ContentType.new(content_type, template: template)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def match_not_empty(template = nil)
|
|
101
|
+
V4::NotEmpty.new(template)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def match_status_code(template)
|
|
105
|
+
V4::StatusCode.new(template)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'ffi'
|
|
4
|
+
require 'pact/ffi/verifier'
|
|
5
|
+
|
|
6
|
+
module Pact
|
|
7
|
+
module Native
|
|
8
|
+
module BlockingVerifier
|
|
9
|
+
extend FFI::Library
|
|
10
|
+
ffi_lib DetectOS.get_bin_path
|
|
11
|
+
|
|
12
|
+
attach_function :execute, :pactffi_verifier_execute, %i[pointer], :int32, blocking: true
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'pact/ffi/logger'
|
|
4
|
+
|
|
5
|
+
module Pact
|
|
6
|
+
module Native
|
|
7
|
+
module Logger
|
|
8
|
+
LOG_LEVELS = {
|
|
9
|
+
off: PactFfi::FfiLogLevelFilter['LOG_LEVEL_OFF'],
|
|
10
|
+
error: PactFfi::FfiLogLevelFilter['LOG_LEVEL_ERROR'],
|
|
11
|
+
warn: PactFfi::FfiLogLevelFilter['LOG_LEVEL_WARN'],
|
|
12
|
+
info: PactFfi::FfiLogLevelFilter['LOG_LEVEL_INFO'],
|
|
13
|
+
debug: PactFfi::FfiLogLevelFilter['LOG_LEVEL_DEBUG'],
|
|
14
|
+
trace: PactFfi::FfiLogLevelFilter['LOG_LEVEL_TRACE']
|
|
15
|
+
}.freeze
|
|
16
|
+
|
|
17
|
+
def self.log_to_stdout(log_level)
|
|
18
|
+
raise 'invalid log level for PactFfi::FfiLogLevelFilter' unless LOG_LEVELS.key?(log_level)
|
|
19
|
+
|
|
20
|
+
PactFfi::Logger.log_to_stdout(LOG_LEVELS[log_level]) unless log_level == :off
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'pact/ffi/verifier'
|
|
4
|
+
require 'pact/native/logger'
|
|
5
|
+
|
|
6
|
+
module Pact
|
|
7
|
+
module Provider
|
|
8
|
+
class AsyncMessageVerifier < BaseVerifier
|
|
9
|
+
PROVIDER_TRANSPORT_TYPE = 'message'
|
|
10
|
+
|
|
11
|
+
def initialize(pact_config, mixed_config = nil)
|
|
12
|
+
super
|
|
13
|
+
|
|
14
|
+
return if pact_config.is_a?(::Pact::Provider::PactConfig::Async)
|
|
15
|
+
|
|
16
|
+
raise ArgumentError,
|
|
17
|
+
'pact_config must be an instance of Pact::Provider::PactConfig::Message'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def add_provider_transport(pact_handle)
|
|
23
|
+
setup_uri = URI(@pact_config.message_setup_url)
|
|
24
|
+
PactFfi::Verifier.add_provider_transport(pact_handle, PROVIDER_TRANSPORT_TYPE, setup_uri.port, setup_uri.path,
|
|
25
|
+
'')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'pact/ffi/verifier'
|
|
4
|
+
require 'pact/native/logger'
|
|
5
|
+
require 'pact/native/blocking_verifier'
|
|
6
|
+
|
|
7
|
+
module Pact
|
|
8
|
+
module Provider
|
|
9
|
+
class BaseVerifier
|
|
10
|
+
PROVIDER_TRANSPORT_TYPE = nil
|
|
11
|
+
attr_reader :logger
|
|
12
|
+
|
|
13
|
+
class VerificationError < Pact::FfiError; end
|
|
14
|
+
|
|
15
|
+
class VerifierError < Pact::Error; end
|
|
16
|
+
|
|
17
|
+
DEFAULT_CONSUMER_SELECTORS = {}
|
|
18
|
+
|
|
19
|
+
# https://docs.rs/pact_ffi/0.4.17/pact_ffi/verifier/fn.pactffi_verify.html#errors
|
|
20
|
+
VERIFICATION_ERRORS = {
|
|
21
|
+
1 => { reason: :verification_failed, status: 1,
|
|
22
|
+
description: 'The verification process failed, see output for errors' },
|
|
23
|
+
2 => { reason: :null_pointer, status: 2, description: 'A null pointer was received' },
|
|
24
|
+
3 => { reason: :internal_error, status: 3, description: 'The method panicked' },
|
|
25
|
+
4 => { reason: :invalid_arguments, status: 4,
|
|
26
|
+
description: 'Invalid arguments were provided to the verification process' }
|
|
27
|
+
}.freeze
|
|
28
|
+
|
|
29
|
+
# env below are set up by pipeline-builder
|
|
30
|
+
# see paas/cicd/images/pact/pipeline-builder/-/blob/master/internal/commands/consumers-pipeline/ruby.go
|
|
31
|
+
def initialize(pact_config, mixed_config = nil)
|
|
32
|
+
unless pact_config.is_a?(::Pact::Provider::PactConfig::Base)
|
|
33
|
+
raise ArgumentError,
|
|
34
|
+
'pact_config must be a subclass of Pact::Provider::PactConfig::Base'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
@pact_config = pact_config
|
|
38
|
+
@mixed_config = mixed_config
|
|
39
|
+
@logger = @pact_config.logger || Logger.new($stdout)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def verify!
|
|
43
|
+
raise VerifierError.new('interaction is designed to be used one-time only') if defined?(@used)
|
|
44
|
+
|
|
45
|
+
# if consumer_selectors.blank?
|
|
46
|
+
# logger.info("[verifier] does not need to verify consumer #{@pact_config.consumer_name}")
|
|
47
|
+
# return
|
|
48
|
+
# end
|
|
49
|
+
|
|
50
|
+
exception = nil
|
|
51
|
+
pact_handle = init_pact
|
|
52
|
+
|
|
53
|
+
start_servers!
|
|
54
|
+
|
|
55
|
+
logger.info('[verifier] starting provider verification')
|
|
56
|
+
|
|
57
|
+
result = Pact::Native::BlockingVerifier.execute(pact_handle)
|
|
58
|
+
if VERIFICATION_ERRORS[result].present?
|
|
59
|
+
error = VERIFICATION_ERRORS[result]
|
|
60
|
+
exception = VerificationError.new(
|
|
61
|
+
"There was an error while trying to verify provider \"#{@pact_config.provider_name}\"", error[:reason], error[:status] # rubocop:disable Layout/LineLength
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
ensure
|
|
65
|
+
@used = true
|
|
66
|
+
PactFfi::Verifier.shutdown(pact_handle) if pact_handle
|
|
67
|
+
stop_servers
|
|
68
|
+
@grpc_server.stop if @grpc_server
|
|
69
|
+
raise exception if exception
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def create_c_pointer_array_from_string_array(string_array)
|
|
75
|
+
pointers = string_array.map { |str| FFI::MemoryPointer.from_string(str) }
|
|
76
|
+
array_pointer = FFI::MemoryPointer.new(:pointer, pointers.size)
|
|
77
|
+
pointers.each_with_index do |ptr, index|
|
|
78
|
+
array_pointer[index].put_pointer(0, ptr)
|
|
79
|
+
end
|
|
80
|
+
array_pointer
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def bool_to_int(value)
|
|
84
|
+
value ? 1 : 0
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def init_pact
|
|
88
|
+
handle = PactFfi::Verifier.new_for_application('pact-ruby', PactFfi.version)
|
|
89
|
+
set_provider_info(handle)
|
|
90
|
+
|
|
91
|
+
if defined?(@mixed_config.grpc_config) && @mixed_config.grpc_config
|
|
92
|
+
@grpc_server = GrufServer.new(host: "127.0.0.1:#{@mixed_config.grpc_config.grpc_port}",
|
|
93
|
+
services: @mixed_config.grpc_config.grpc_services)
|
|
94
|
+
@grpc_server.start
|
|
95
|
+
PactFfi::Verifier.add_provider_transport(handle, 'grpc', @mixed_config.grpc_config.grpc_port, '', '')
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
if defined?(@mixed_config.async_config) && @mixed_config.async_config
|
|
99
|
+
setup_uri = URI(@mixed_config.async_config.message_setup_url)
|
|
100
|
+
PactFfi::Verifier.add_provider_transport(handle, 'message', setup_uri.port, setup_uri.path, '')
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# TODO: add http transport?
|
|
104
|
+
|
|
105
|
+
PactFfi::Verifier.set_provider_state(handle, @pact_config.provider_setup_url, 1, 1)
|
|
106
|
+
PactFfi::Verifier.set_verification_options(handle, 0, 10_000)
|
|
107
|
+
# pactffi_verifier_set_publish_options(
|
|
108
|
+
# handle: *mut VerifierHandle,
|
|
109
|
+
# provider_version: *const c_char,
|
|
110
|
+
# build_url: *const c_char,
|
|
111
|
+
# provider_tags: *const *const c_char,
|
|
112
|
+
# provider_tags_len: c_ushort,
|
|
113
|
+
# provider_branch: *const c_char,
|
|
114
|
+
# )
|
|
115
|
+
c_provider_version_tags = create_c_pointer_array_from_string_array(@pact_config.provider_version_tags)
|
|
116
|
+
c_provider_version_tags_size = @pact_config.provider_version_tags.size
|
|
117
|
+
c_consumer_version_tags = create_c_pointer_array_from_string_array(@pact_config.consumer_version_tags)
|
|
118
|
+
c_consumer_version_tags_size = @pact_config.consumer_version_tags.size
|
|
119
|
+
|
|
120
|
+
if @pact_config.provider_build_uri.present?
|
|
121
|
+
begin
|
|
122
|
+
URI.parse(@pact_config.provider_build_uri)
|
|
123
|
+
rescue URI::InvalidURIError
|
|
124
|
+
raise VerifierError.new('provider_build_uri is not a valid URI')
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
if @pact_config.publish_verification_results == true
|
|
129
|
+
if @pact_config.provider_version
|
|
130
|
+
PactFfi::Verifier.set_publish_options(handle, @pact_config.provider_version,
|
|
131
|
+
@pact_config.provider_build_uri, c_provider_version_tags, c_provider_version_tags_size, @pact_config.provider_version_branch) # rubocop:disable Layout/LineLength
|
|
132
|
+
else
|
|
133
|
+
logger.warn('[verifier] - unable to publish verification results as provider version is not set')
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
configure_verification_source(handle, c_provider_version_tags, c_provider_version_tags_size,
|
|
138
|
+
c_consumer_version_tags, c_consumer_version_tags_size)
|
|
139
|
+
|
|
140
|
+
PactFfi::Verifier.set_no_pacts_is_error(handle, bool_to_int(@pact_config.fail_if_no_pacts_found))
|
|
141
|
+
|
|
142
|
+
add_provider_transport(handle)
|
|
143
|
+
|
|
144
|
+
# the core doesnt pick up these env vars, so we need to set them here
|
|
145
|
+
# https://github.com/pact-foundation/pact-reference/issues/451#issuecomment-2338130587
|
|
146
|
+
# PACT_DESCRIPTION
|
|
147
|
+
# Only validate interactions whose descriptions match this filter (regex format)
|
|
148
|
+
# PACT_PROVIDER_STATE
|
|
149
|
+
# Only validate interactions whose provider states match this filter (regex format)
|
|
150
|
+
# PACT_PROVIDER_NO_STATE
|
|
151
|
+
# Only validate interactions that have no defined provider state (true or false)
|
|
152
|
+
PactFfi::Verifier.set_filter_info(
|
|
153
|
+
handle,
|
|
154
|
+
ENV['PACT_DESCRIPTION'] || nil,
|
|
155
|
+
ENV['PACT_PROVIDER_STATE'] || nil,
|
|
156
|
+
bool_to_int(ENV['PACT_PROVIDER_NO_STATE'] || false)
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
Pact::Native::Logger.log_to_stdout(@pact_config.log_level)
|
|
160
|
+
|
|
161
|
+
logger.info("[verifier] verification initialized for provider #{@pact_config.provider_name}, version #{@pact_config.provider_version}, transport #{self.class::PROVIDER_TRANSPORT_TYPE}") # rubocop:disable Layout/LineLength
|
|
162
|
+
|
|
163
|
+
handle
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def set_provider_info(pact_handle)
|
|
167
|
+
# pub extern "C" fn pactffi_verifier_set_provider_info(
|
|
168
|
+
# handle: *mut VerifierHandle,
|
|
169
|
+
# name: *const c_char,
|
|
170
|
+
# scheme: *const c_char,
|
|
171
|
+
# host: *const c_char,
|
|
172
|
+
# port: c_ushort,
|
|
173
|
+
# path: *const c_char,
|
|
174
|
+
# ) {
|
|
175
|
+
PactFfi::Verifier.set_provider_info(pact_handle, @pact_config.provider_name, '', '', 0, '')
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def add_provider_transport(pact_handle)
|
|
179
|
+
raise PactImplementationRequired, 'Implement #add_provider_transport in a subclass'
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def start_servers!
|
|
183
|
+
logger.info('[verifier] starting services')
|
|
184
|
+
|
|
185
|
+
@servers_started = true
|
|
186
|
+
@pact_config.start_servers
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def stop_servers
|
|
190
|
+
return unless @servers_started
|
|
191
|
+
|
|
192
|
+
logger.info('[verifier] stopping services')
|
|
193
|
+
|
|
194
|
+
@pact_config.stop_servers
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def configure_verification_source(handle, c_provider_version_tags, c_provider_version_tags_size,
|
|
198
|
+
c_consumer_version_tags, c_consumer_version_tags_size)
|
|
199
|
+
logger.info('[verifier] configuring verification source')
|
|
200
|
+
if @pact_config.pact_broker_proxy_url.blank? && @pact_config.pact_uri.blank?
|
|
201
|
+
path = @pact_config.pact_dir || (defined?(Rails) ? Rails.root.join('pacts').to_s : 'pacts')
|
|
202
|
+
logger.info("[verifier] pact broker url or pact uri is not set, using directory #{path} as a verification source") # rubocop:disable Layout/LineLength
|
|
203
|
+
return PactFfi::Verifier.add_directory_source(handle, path)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
if @pact_config.pact_uri.present?
|
|
207
|
+
if @pact_config.pact_uri.start_with?('http')
|
|
208
|
+
logger.info("[verifier] using pact uri #{@pact_config.pact_uri} as a verification source")
|
|
209
|
+
PactFfi::Verifier.url_source(handle, @pact_config.pact_uri, @pact_config.broker_username,
|
|
210
|
+
@pact_config.broker_password, @pact_config.broker_token)
|
|
211
|
+
else
|
|
212
|
+
logger.info("[verifier] using pact file #{@pact_config.pact_uri} as a verification source")
|
|
213
|
+
PactFfi::Verifier.add_file_source(handle, @pact_config.pact_uri)
|
|
214
|
+
end
|
|
215
|
+
else
|
|
216
|
+
logger.info("[verifier] using pact broker url #{@pact_config.broker_url} with consumer selectors: #{JSON.dump(consumer_selectors)} as a verification source") # rubocop:disable Layout/LineLength
|
|
217
|
+
consumer_selectors = [] if consumer_selectors.nil?
|
|
218
|
+
filters = consumer_selectors.map do |selector|
|
|
219
|
+
FFI::MemoryPointer.from_string(JSON.dump(selector).to_s)
|
|
220
|
+
end
|
|
221
|
+
filters_ptr = FFI::MemoryPointer.new(:pointer, filters.size + 1)
|
|
222
|
+
filters_ptr.write_array_of_pointer(filters)
|
|
223
|
+
PactFfi::Verifier.broker_source_with_selectors(handle, @pact_config.pact_broker_proxy_url,
|
|
224
|
+
@pact_config.broker_username, @pact_config.broker_password, @pact_config.broker_token, bool_to_int(@pact_config.enable_pending), @pact_config.include_wip_pacts_since, c_provider_version_tags, c_provider_version_tags_size, @pact_config.provider_version_branch, filters_ptr, consumer_selectors.size, c_consumer_version_tags, c_consumer_version_tags_size) # rubocop:disable Layout/LineLength
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def consumer_selectors
|
|
229
|
+
return unless @pact_config.consumer_version_selectors
|
|
230
|
+
|
|
231
|
+
(!@pact_config.consumer_version_selectors.empty? && @pact_config.consumer_version_selectors) || @consumer_selectors # rubocop:disable Layout/LineLength
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def build_consumer_selectors(verify_only, consumer_name, consumer_branch)
|
|
235
|
+
# if verify_only and consumer_name are defined - select only needed consumer
|
|
236
|
+
if verify_only.present?
|
|
237
|
+
# select proper consumer branch if defined
|
|
238
|
+
if consumer_name.present?
|
|
239
|
+
return [] unless verify_only.include?(consumer_name)
|
|
240
|
+
return [{ 'branch' => consumer_branch, 'consumer' => consumer_name }] if consumer_branch.present?
|
|
241
|
+
|
|
242
|
+
return [DEFAULT_CONSUMER_SELECTORS.merge('consumer' => consumer_name)]
|
|
243
|
+
end
|
|
244
|
+
# or default selectors
|
|
245
|
+
return verify_only.map { |name| DEFAULT_CONSUMER_SELECTORS.merge('consumer' => name) }
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# select provided consumer_name
|
|
249
|
+
if consumer_name.present? && consumer_branch.present?
|
|
250
|
+
return [{ 'branch' => consumer_branch,
|
|
251
|
+
'consumer' => consumer_name }]
|
|
252
|
+
end
|
|
253
|
+
return [DEFAULT_CONSUMER_SELECTORS.merge('consumer' => consumer_name)] if consumer_name.present?
|
|
254
|
+
|
|
255
|
+
[DEFAULT_CONSUMER_SELECTORS]
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
end
|