pact-mock_service 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 199d51223a496a48e6ab4ca142d1a1c9fdac4a0b
4
- data.tar.gz: 19d3aa4d3228559d5ceb27e7678d3f27842b0eeb
3
+ metadata.gz: 19d534d5cb2a38d99b0cb36e8f4c373e7452d708
4
+ data.tar.gz: 4bcd7d9c3438fdd76aaed92ac9823946285d5789
5
5
  SHA512:
6
- metadata.gz: 3ade3ab0ddb3feb73edcca000b9fa99ba0e82d373859f8accf0b1e4b532ad1b7ecfc48b0ee27a208624da6d1a528099a14ebc277c0afe53a0362a1f2f812f528
7
- data.tar.gz: a2916297569c675ab1ad635ce883b162fc54f5c030de1e326879b521bd89882576b47a253d836fd5d24e89ba5b3ac230ed730d65e6dda14ee99334c281b7bd3a
6
+ metadata.gz: 182e56ac2b5e437f4d5014e6c4e816a4a7f90d338243d90471fcbe6c9222cf60c76511bcada3766850c58989587fe860698722c00054e5a2f57a6d191c4e975a
7
+ data.tar.gz: 918ebb1400b5b9180f2a28b49ae9cd032b6209c22ad1b35b5746c8fd70c8a0066c3f777a9daba9dc0dbfdf6043622228eaee9d53a066d7d3ec5e389c968ad221
data/CHANGELOG.md CHANGED
@@ -2,6 +2,9 @@ Do this to generate your change history
2
2
 
3
3
  git log --pretty=format:' * %h - %s (%an, %ad)' vX.Y.Z..HEAD
4
4
 
5
+ ### 2.5.0 (2017-10-28)
6
+ * bc15e21 - feat(pact-stub-service): handle case where multiple responses match (Beth Skurrie, Sat Oct 28 09:15:55 2017 +1100)
7
+
5
8
  ### 2.4.0 (2017-10-13)
6
9
  * 56bd683 - feat(stub): add pact-stub-service CLI (Beth Skurrie, Fri Oct 13 08:20:49 2017 +1100)
7
10
 
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
 
2
- # Pact Mock Service
2
+ # Pact Mock and Stub Service
3
3
 
4
4
  [![Build Status](https://travis-ci.org/pact-foundation/pact-mock_service.svg?branch=master)](https://travis-ci.org/pact-foundation/pact-mock_service)
5
5
 
6
- This codebase provides the HTTP mock service used by implementations of [Pact][pact]. It is packaged as a gem, and as a standalone executable for Mac OSX and Linux and Windows.
6
+ This codebase provides the HTTP mock and stub service used by implementations of [Pact][pact]. It is packaged as a gem, and as a standalone executable for Mac OSX and Linux and Windows.
7
7
 
8
8
  The mock service provides the following endpoints:
9
9
 
@@ -40,15 +40,15 @@ Or add `gem "pact-mock_service"` to your Gemfile then run:
40
40
 
41
41
  Run `pact-mock-service help` for command line options.
42
42
 
43
- ## Usage
43
+ ## Mock Service Usage
44
44
 
45
- The lifecycle of the a mock service instance during at test suite is as follows:
45
+ Each mock service process is designed to mock only ONE provider. To mock multiple providers, you will need to start a process for each provider. The lifecycle of the a mock service instance during at test suite is as follows:
46
46
 
47
- _Before suite:_ start mock service
48
- _Before each test:_ clear interactions from previous test
49
- _During test:_ set up interactions, execute interactions
50
- _After each test:_ verify interactions
51
- _After suite:_ write pact file, stop mock service
47
+ * _Before suite:_ start mock service
48
+ * _Before each test:_ clear interactions from previous test
49
+ * _During test:_ set up interactions, execute interactions
50
+ * _After each test:_ verify interactions
51
+ * _After suite:_ write pact file, stop mock service
52
52
 
53
53
  Each mock service instance can only handle one test process/thread at a time. If you wish to run multiple test threads in parallel, you will need to start each mock service instance on a different port, and set the `--pact-file-write-mode` to `merge` (see usage notes below).
54
54
 
@@ -73,7 +73,7 @@ Options:
73
73
  [--sslcert=SSLCERT] # Specify the path to the SSL cert to use when running the service over HTTPS
74
74
  [--sslkey=SSLKEY] # Specify the path to the SSL key to use when running the service over HTTPS
75
75
 
76
- Start a mock service. If the consumer, provider and pact-dir options are provided, the pact will be written automatically on shutdown.
76
+ Start a mock service. If the consumer, provider and pact-dir options are provided, the pact will be written automatically on shutdown (INT).
77
77
  ```
78
78
 
79
79
  See [script/example.sh](script/example.sh) for an executable example.
@@ -94,6 +94,34 @@ If you need to provide your own certificate and key, use the following syntax.
94
94
 
95
95
  Read the wiki page on [CORS][cors].
96
96
 
97
+ ## Stub Service Usage
98
+
99
+ The pact-stub-service allows you to reuse interactions that have been generated in previous tests. The typical situation would be to generate your pact file using unit tests, and then use the pact stub service for your higher level integration/ui tests. To help reduce the number of interactions that need verifying, you will want to use flexible matching on both requests and responses.
100
+
101
+ Unlike the mock service, which has a Ruby DSL for managing its lifecycle, the mock service can currently only be started from the command line, so you will need to start/background/kill the process yourself. If this is causing problems, please raise it in the pact-dev google group and we can discuss potential enhancements.
102
+
103
+ ```
104
+ Usage:
105
+ pact-stub-service PACT ...
106
+
107
+ Options:
108
+ -p, [--port=PORT] # Port on which to run the service
109
+ -h, [--host=HOST] # Host on which to bind the service
110
+ # Default: localhost
111
+ -l, [--log=LOG] # File to which to log output
112
+ -o, [--cors=CORS] # Support browser security in tests by responding to OPTIONS requests and adding CORS headers to mocked responses
113
+ [--ssl], [--no-ssl] # Use a self-signed SSL cert to run the service over HTTPS
114
+ [--sslcert=SSLCERT] # Specify the path to the SSL cert to use when running the service over HTTPS
115
+ [--sslkey=SSLKEY] # Specify the path to the SSL key to use when running the service over HTTPS
116
+
117
+ Description:
118
+ Start a stub service with the given pact file(s). Where multiple matching interactions are found, the
119
+ interactions will be sorted by response status, and the first one will be returned. This may lead to some
120
+ non-deterministic behaviour. If you are having problems with this, please raise it on the pact-dev google
121
+ group, and we can discuss some potential enhancements. Note that only versions 1 and 2 of the pact
122
+ specification are currently supported.
123
+ ```
124
+
97
125
  ## Contributing
98
126
 
99
127
  See [CONTRIBUTING.md](/CONTRIBUTING.md)
@@ -13,7 +13,7 @@ module Pact
13
13
 
14
14
  class ConsumerContractWriter
15
15
 
16
- DEFAULT_PACT_SPECIFICATION_VERSION = '1.0.0'
16
+ DEFAULT_PACT_SPECIFICATION_VERSION = '2.0.0'
17
17
 
18
18
  include Pact::FileName
19
19
  include Pact::PactFile
@@ -20,7 +20,7 @@ module Pact
20
20
  logger = Logger.from_options(options)
21
21
  @name = options.fetch(:name, "MockService")
22
22
  @session = Session.new(options.merge(logger: logger))
23
- setup_stub(options[:stub_pactfile_paths]) if options[:stub_pactfile_paths] && options[:stub_pactfile_paths].any?
23
+ setup_stub(options[:stub_pactfile_paths]) if options[:stub_pactfile_paths]
24
24
  request_handlers = RequestHandlers.new(@name, logger, @session, options)
25
25
  @app = Rack::Builder.app do
26
26
  use Pact::Consumer::MockService::ErrorHandler, logger
@@ -39,7 +39,7 @@ module Pact
39
39
 
40
40
  def setup_stub stub_pactfile_paths
41
41
  stub_pactfile_paths.each do | pactfile_path |
42
- $stdout.puts "Loading interactions from #{pactfile_path}"
42
+ $stdout.puts "INFO: Loading interactions from #{pactfile_path}"
43
43
  hash_interactions = JSON.parse(File.read(pactfile_path))['interactions']
44
44
  interactions = hash_interactions.collect { | hash | Interaction.from_hash(hash) }
45
45
  @session.set_expected_interactions interactions
@@ -49,7 +49,7 @@ module Pact
49
49
  def write_pact_if_configured
50
50
  consumer_contract_writer = ConsumerContractWriter.new(@session.consumer_contract_details, StdoutLogger.new)
51
51
  if consumer_contract_writer.can_write? && !@session.pact_written?
52
- $stdout.puts "Writing pact before shutting down"
52
+ $stdout.puts "INFO: Writing pact before shutting down"
53
53
  consumer_contract_writer.write
54
54
  end
55
55
  end
@@ -13,14 +13,14 @@ module Pact
13
13
  PACT_FILE_WRITE_MODE_DESC = "`overwrite` or `merge`. Use `merge` when running multiple mock service instances in parallel for the same consumer/provider pair." +
14
14
  " Ensure the pact file is deleted before running tests when using this option so that interactions deleted from the code are not maintained in the file."
15
15
 
16
- desc 'service', "Start a mock service. If the consumer, provider and pact-dir options are provided, the pact will be written automatically on shutdown."
16
+ desc 'service', "Start a mock service. If the consumer, provider and pact-dir options are provided, the pact will be written automatically on shutdown (INT)."
17
17
  method_option :consumer, desc: "Consumer name"
18
18
  method_option :provider, desc: "Provider name"
19
19
  method_option :port, aliases: "-p", desc: "Port on which to run the service"
20
20
  method_option :host, aliases: "-h", desc: "Host on which to bind the service", default: 'localhost'
21
21
  method_option :pact_dir, aliases: "-d", desc: "Directory to which the pacts will be written"
22
22
  method_option :pact_file_write_mode, aliases: "-m", desc: PACT_FILE_WRITE_MODE_DESC, type: :string, default: 'overwrite'
23
- method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact", default: '1'
23
+ method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact. Note that only versions 1 and 2 are currently supported.", default: '2'
24
24
  method_option :log, aliases: "-l", desc: "File to which to log output"
25
25
  method_option :cors, aliases: "-o", desc: "Support browser security in tests by responding to OPTIONS requests and adding CORS headers to mocked responses"
26
26
  method_option :ssl, desc: "Use a self-signed SSL cert to run the service over HTTPS", type: :boolean, default: false
@@ -38,7 +38,7 @@ module Pact
38
38
  method_option :pact_dir, aliases: "-d", desc: "Directory to which the pacts will be written"
39
39
  method_option :log_dir, aliases: "-l", desc: "File to which to log output"
40
40
  method_option :pact_file_write_mode, aliases: "-m", desc: PACT_FILE_WRITE_MODE_DESC, type: :string, default: 'overwrite'
41
- method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact", default: '1'
41
+ method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact. Note that only versions 1 and 2 are currently supported.", default: '2'
42
42
  method_option :cors, aliases: "-o", desc: "Support browser security in tests by responding to OPTIONS requests and adding CORS headers to mocked responses"
43
43
  method_option :ssl, desc: "Use a self-signed SSL cert to run the service over HTTPS", type: :boolean, default: false
44
44
  method_option :sslcert, desc: "Specify the path to the SSL cert to use when running the service over HTTPS"
@@ -49,7 +49,7 @@ module Pact
49
49
  ControlServer::Run.(options)
50
50
  end
51
51
 
52
- desc 'start', "Start a mock service. If the consumer, provider and pact-dir options are provided, the pact will be written automatically on shutdown."
52
+ desc 'start', "Start a mock service. If the consumer, provider and pact-dir options are provided, the pact will be written automatically on shutdown (INT)."
53
53
  method_option :consumer, desc: "Consumer name"
54
54
  method_option :provider, desc: "Provider name"
55
55
  method_option :port, aliases: "-p", default: '1234', desc: "Port on which to run the service"
@@ -58,7 +58,7 @@ module Pact
58
58
  method_option :pact_file_write_mode, aliases: "-m", desc: PACT_FILE_WRITE_MODE_DESC, type: :string, default: 'overwrite'
59
59
  method_option :pid_dir, desc: "PID dir", default: 'tmp/pids'
60
60
  method_option :log, aliases: "-l", desc: "File to which to log output"
61
- method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact", default: '1'
61
+ method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact. Note that only versions 1 and 2 are currently supported.", default: '2'
62
62
  method_option :cors, aliases: "-o", desc: "Support browser security in tests by responding to OPTIONS requests and adding CORS headers to mocked responses"
63
63
  method_option :ssl, desc: "Use a self-signed SSL cert to run the service over HTTPS", type: :boolean, default: false
64
64
  method_option :sslcert, desc: "Specify the path to the SSL cert to use when running the service over HTTPS"
@@ -78,7 +78,7 @@ module Pact
78
78
  mock_service_pidfile.kill_process
79
79
  end
80
80
 
81
- desc 'restart', "Start or restart a mock service. If the consumer, provider and pact-dir options are provided, the pact will be written automatically on shutdown."
81
+ desc 'restart', "Start or restart a mock service. If the consumer, provider and pact-dir options are provided, the pact will be written automatically on shutdown (INT)."
82
82
  method_option :consumer, desc: "Consumer name"
83
83
  method_option :provider, desc: "Provider name"
84
84
  method_option :port, aliases: "-p", default: '1234', desc: "Port on which to run the service"
@@ -87,7 +87,7 @@ module Pact
87
87
  method_option :pact_file_write_mode, aliases: "-m", desc: PACT_FILE_WRITE_MODE_DESC, type: :string, default: 'overwrite'
88
88
  method_option :pid_dir, desc: "PID dir", default: 'tmp/pids'
89
89
  method_option :log, aliases: "-l", desc: "File to which to log output"
90
- method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact", default: '1'
90
+ method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact. Note that only versions 1 and 2 are currently supported.", default: '2'
91
91
  method_option :cors, aliases: "-o", desc: "Support browser security in tests by responding to OPTIONS requests and adding CORS headers to mocked responses"
92
92
  method_option :ssl, desc: "Use a self-signed SSL cert to run the service over HTTPS", type: :boolean, default: false
93
93
  method_option :sslcert, desc: "Specify the path to the SSL cert to use when running the service over HTTPS"
@@ -103,7 +103,7 @@ module Pact
103
103
  method_option :port, aliases: "-p", desc: "Port on which to run the service", default: '1234'
104
104
  method_option :log_dir, aliases: "-l", desc: "File to which to log output", default: "log"
105
105
  method_option :pact_file_write_mode, aliases: "-m", desc: PACT_FILE_WRITE_MODE_DESC, type: :string, default: 'overwrite'
106
- method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact", default: '1'
106
+ method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact", default: '2'
107
107
  method_option :pid_dir, desc: "PID dir", default: "tmp/pids"
108
108
  method_option :cors, aliases: "-o", desc: "Support browser security in tests by responding to OPTIONS requests and adding CORS headers to mocked responses"
109
109
  method_option :ssl, desc: "Use a self-signed SSL cert to run the service over HTTPS", type: :boolean, default: false
@@ -130,7 +130,7 @@ module Pact
130
130
  method_option :log_dir, aliases: "-l", desc: "File to which to log output", default: "log"
131
131
  method_option :pact_dir, aliases: "-d", desc: "Directory to which the pacts will be written", default: "."
132
132
  method_option :pact_file_write_mode, aliases: "-m", desc: PACT_FILE_WRITE_MODE_DESC, type: :string, default: 'overwrite'
133
- method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact", default: '1'
133
+ method_option :pact_specification_version, aliases: "-i", desc: "The pact specification version to use when writing the pact. Note that only versions 1 and 2 are currently supported.", default: '2'
134
134
  method_option :pid_dir, desc: "PID dir", default: "tmp/pids"
135
135
  method_option :cors, aliases: "-o", desc: "Support browser security in tests by responding to OPTIONS requests and adding CORS headers to mocked responses"
136
136
  method_option :ssl, desc: "Use a self-signed SSL cert to run the service over HTTPS", type: :boolean, default: false
@@ -21,15 +21,16 @@ module Pact
21
21
  include Pact::Matchers
22
22
  include PrettyGenerate
23
23
 
24
- attr_accessor :name, :logger, :expected_interactions, :actual_interactions, :verified_interactions
24
+ attr_accessor :name, :logger, :expected_interactions, :actual_interactions, :verified_interactions, :multiple_interactions_handler
25
25
 
26
- def initialize name, logger, session, cors_enabled=false
26
+ def initialize name, logger, session, cors_enabled = false, stub = false
27
27
  @name = name
28
28
  @logger = logger
29
29
  @expected_interactions = session.expected_interactions
30
30
  @actual_interactions = session.actual_interactions
31
31
  @verified_interactions = session.verified_interactions
32
32
  @cors_enabled = cors_enabled
33
+ @multiple_interactions_handler = stub ? HandleMultipleInteractionsFoundForStub : HandleMultipleInteractionsFound
33
34
  end
34
35
 
35
36
  def match? env
@@ -62,7 +63,7 @@ module Pact
62
63
  end
63
64
 
64
65
  def handle_more_than_one_matching_interaction actual_request, matching_interactions
65
- HandleMultipleInteractionsFound.call(actual_request, matching_interactions, logger)
66
+ multiple_interactions_handler.call(actual_request, matching_interactions, verified_interactions, actual_interactions, logger)
66
67
  end
67
68
 
68
69
  def handle_unrecognised_request actual_request, candidate_interactions
@@ -79,7 +80,7 @@ module Pact
79
80
 
80
81
  extend PrettyGenerate
81
82
 
82
- def self.call actual_request, matching_interactions, logger
83
+ def self.call actual_request, matching_interactions, verified_interactions, actual_interactions, logger
83
84
  logger.error "Multiple interactions found for #{actual_request.method_and_path}:"
84
85
  matching_interactions.each do | interaction |
85
86
  logger.debug pretty_generate(Pact::MockService::InteractionDecorator.new(interaction))
@@ -103,6 +104,29 @@ module Pact
103
104
  end
104
105
  end
105
106
 
107
+ class HandleMultipleInteractionsFoundForStub
108
+
109
+ extend PrettyGenerate
110
+
111
+ def self.call actual_request, matching_interactions, verified_interactions, actual_interactions, logger
112
+ logger.warn "Multiple interactions found for #{actual_request.method_and_path}:"
113
+ matching_interactions.each do | interaction |
114
+ logger.debug pretty_generate(Pact::MockService::InteractionDecorator.new(interaction))
115
+ end
116
+ response actual_request, matching_interactions, verified_interactions, actual_interactions, logger
117
+ end
118
+
119
+ def self.response actual_request, matching_interactions, verified_interactions, actual_interactions, logger
120
+ logger.warn "Sorting responses by response status and returning first."
121
+ interaction = first_most_successful_interaction(matching_interactions)
122
+ HandleMatchedInteraction.call(interaction, verified_interactions, actual_interactions, logger)
123
+ end
124
+
125
+ def self.first_most_successful_interaction matching_interactions
126
+ matching_interactions.sort{ |i1, i2| Pact::Reification.from_term(i1.response.status) <=> Pact::Reification.from_term(i2.response.status) }.first
127
+ end
128
+ end
129
+
106
130
  class HandleUnrecognisedInteraction
107
131
 
108
132
  def self.call actual_request, candidate_interactions, actual_interactions, logger
@@ -33,7 +33,7 @@ module Pact
33
33
  LogGet.new(name, logger),
34
34
  PactPost.new(name, logger, session),
35
35
  IndexGet.new(name, logger),
36
- InteractionReplay.new(name, logger, session, options[:cors_enabled])
36
+ InteractionReplay.new(name, logger, session, options[:cors_enabled], options[:stub_pactfile_paths])
37
37
  ]
38
38
  end
39
39
  end
@@ -1,5 +1,5 @@
1
1
  module Pact
2
2
  module MockService
3
- VERSION = "2.4.0"
3
+ VERSION = "2.5.0"
4
4
  end
5
5
  end
@@ -10,7 +10,16 @@ module Pact
10
10
  module StubService
11
11
  class CLI < Pact::MockService::CLI::CustomThor
12
12
 
13
- desc 'PACT ...', "Start a stub service with the given pact file(s). Note that this is in beta release, and no logic has been added to handle the situation where more than one matching interaction is found for a request. At the moment, an error response will be returned."
13
+ desc 'PACT ...', "Start a stub service with the given pact file(s)."
14
+ long_desc <<-DOC
15
+ Start a stub service with the given pact file(s).
16
+ Where multiple matching interactions are found, the interactions will be sorted by
17
+ response status, and the first one will be returned. This may lead to some non-deterministic
18
+ behaviour. If you are having problems with this, please raise it on the pact-dev google group,
19
+ and we can discuss some potential enhancements.
20
+ Note that only versions 1 and 2 of the pact specification are currently supported.
21
+ DOC
22
+
14
23
 
15
24
  method_option :port, aliases: "-p", desc: "Port on which to run the service"
16
25
  method_option :host, aliases: "-h", desc: "Host on which to bind the service", default: 'localhost'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact-mock_service
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Fraser
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2017-10-12 00:00:00.000000000 Z
15
+ date: 2017-10-27 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rack