Skip to content

Commit 7e2d810

Browse files
committedFeb 21, 2019
feat: allow mock service host to be configured
pact-foundation/pact-ruby#186
1 parent b41d161 commit 7e2d810

File tree

11 files changed

+40
-47
lines changed

11 files changed

+40
-47
lines changed
 

‎lib/pact/consumer/server.rb

+4-7
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,13 @@ def ports
3434
end
3535
end
3636

37-
attr_reader :app, :port, :options
37+
attr_reader :app, :host, :port, :options
3838

39-
def initialize(app, port, options = {})
39+
def initialize(app, host, port, options = {})
4040
@app = app
4141
@middleware = Middleware.new(@app)
4242
@server_thread = nil
43+
@host = host
4344
@port = port
4445
@options = options
4546
end
@@ -52,10 +53,6 @@ def error
5253
@middleware.error
5354
end
5455

55-
def host
56-
"localhost"
57-
end
58-
5956
def responsive?
6057
return false if @server_thread && @server_thread.join(0)
6158
res = get_identity
@@ -96,7 +93,7 @@ def webrick_opts
9693
end
9794

9895
def ssl_opts
99-
{ SSLEnable: true, SSLCertName: [ %w[CN localhost] ] }
96+
{ SSLEnable: true, SSLCertName: [ ["CN", host] ] }
10097
end
10198

10299
def boot

‎lib/pact/mock_service/app_manager.rb

+15-15
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ def initialize
2323
def register_mock_service_for(name, url, options = {})
2424
uri = URI(url)
2525
raise "Currently only http is supported" unless uri.scheme == 'http'
26-
raise "Currently only services on localhost are supported" unless uri.host == 'localhost'
2726
uri.port = nil if options[:find_available_port]
2827

2928
app = Pact::MockService.new(
@@ -32,21 +31,21 @@ def register_mock_service_for(name, url, options = {})
3231
pact_dir: pact_dir,
3332
pact_specification_version: options.fetch(:pact_specification_version)
3433
)
35-
register(app, uri.port)
34+
register(app, uri.host, uri.port)
3635
end
3736

38-
def register(app, port = nil)
37+
def register(app, host, port = nil)
3938
if port
40-
existing = existing_app_on_port(port)
39+
existing = existing_app_on_host_and_port(host, port)
4140
raise "Port #{port} is already being used by #{existing}" if existing and not existing == app
4241
end
43-
app_registration = register_app(app, port)
42+
app_registration = register_app(app, host, port)
4443
app_registration.spawn
4544
app_registration.port
4645
end
4746

48-
def ports_of_mock_services
49-
app_registrations.find_all(&:is_a_mock_service?).collect(&:port)
47+
def urls_of_mock_services
48+
app_registrations.find_all(&:is_a_mock_service?).collect{ |ar| "http://#{ar.host}:#{ar.port}" }
5049
end
5150

5251
def kill_all
@@ -70,13 +69,13 @@ def app_registered_on?(port)
7069

7170
private
7271

73-
def existing_app_on_port(port)
74-
app_registration = registration_on_port(port)
72+
def existing_app_on_host_and_port(host, port)
73+
app_registration = registration_on_host_and_port(host, port)
7574
app_registration ? app_registration.app : nil
7675
end
7776

78-
def registration_on_port(port)
79-
@app_registrations.find { |app_registration| app_registration.port == port }
77+
def registration_on_host_and_port(host, port)
78+
@app_registrations.find { |app_registration| app_registration.port == port && app_registration.host == host }
8079
end
8180

8281
def pact_dir
@@ -107,20 +106,21 @@ def app_registrations
107106
@app_registrations
108107
end
109108

110-
def register_app(app, port)
111-
app_registration = AppRegistration.new(app: app, port: port)
109+
def register_app(app, host, port)
110+
app_registration = AppRegistration.new(app: app, host: host, port: port)
112111
app_registrations << app_registration
113112
app_registration
114113
end
115114
end
116115

117116
class AppRegistration
118117
include Pact::Logging
119-
attr_accessor :port, :app
118+
attr_accessor :host, :port, :app
120119

121120
def initialize(opts)
122121
@max_wait = 10
123122
@port = opts[:port]
123+
@host = opts[:host]
124124
@app = opts[:app]
125125
@spawned = false
126126
end
@@ -148,7 +148,7 @@ def to_s
148148

149149
def spawn
150150
logger.info "Starting app #{self}..."
151-
@server = Pact::Server.new(app, port).boot
151+
@server = Pact::Server.new(app, host, port).boot
152152
@port = @server.port
153153
@spawned = true
154154
logger.info "Started on port #{port}"

‎lib/pact/mock_service/cli.rb

+4-2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ def restart
107107

108108
desc 'control-start', "Start a Pact mock service control server."
109109
method_option :port, aliases: "-p", desc: "Port on which to run the service", default: '1234'
110+
method_option :host, aliases: "-h", desc: "Host on which to bind the service", default: 'localhost'
110111
method_option :log_dir, aliases: "-l", desc: "File to which to log output", default: "log"
111112
method_option :log_level, desc: "Log level. Options are DEBUG INFO WARN ERROR", default: "DEBUG"
112113
method_option :pact_file_write_mode, aliases: "-m", desc: PACT_FILE_WRITE_MODE_DESC, type: :string, default: 'overwrite'
@@ -134,6 +135,7 @@ def control_stop
134135

135136
desc 'control-restart', "Start a Pact mock service control server."
136137
method_option :port, aliases: "-p", desc: "Port on which to run the service", default: '1234'
138+
method_option :host, aliases: "-h", desc: "Host on which to bind the service", default: 'localhost'
137139
method_option :log_dir, aliases: "-l", desc: "File to which to log output", default: "log"
138140
method_option :log_level, desc: "Log level. Options are DEBUG INFO WARN ERROR", default: "DEBUG"
139141
method_option :pact_dir, aliases: "-d", desc: "Directory to which the pacts will be written", default: "."
@@ -180,14 +182,14 @@ def control_pidfile_name
180182

181183
def start_server pidfile
182184
require 'pact/mock_service/server/spawn'
183-
Pact::MockService::Server::Spawn.(pidfile, options[:port], options[:ssl]) do
185+
Pact::MockService::Server::Spawn.(pidfile, options[:host], options[:port], options[:ssl]) do
184186
yield
185187
end
186188
end
187189

188190
def restart_server pidfile
189191
require 'pact/mock_service/server/respawn'
190-
Pact::MockService::Server::Respawn.(pidfile, options[:port], options[:ssl]) do
192+
Pact::MockService::Server::Respawn.(pidfile, options[:host], options[:port], options[:ssl]) do
191193
yield
192194
end
193195
end

‎lib/pact/mock_service/client.rb

+5-4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ class Client
1313

1414
MOCK_SERVICE_ADMINISTRATON_HEADERS = {'X-Pact-Mock-Service' => 'true'}
1515

16-
def initialize port
17-
@http = Net::HTTP.new('localhost', port)
16+
def initialize port, host = 'localhost'
17+
@http = Net::HTTP.new(host, port)
1818
end
1919

2020
def verify example_description
@@ -46,8 +46,9 @@ def add_expected_interaction interaction
4646
raise AddInteractionError.new("\e[31m#{response.body}\e[m") unless response.is_a? Net::HTTPSuccess
4747
end
4848

49-
def self.clear_interactions port, example_description
50-
Net::HTTP.new("localhost", port).delete("/interactions?example_description=#{CGI.escape(example_description)}", MOCK_SERVICE_ADMINISTRATON_HEADERS)
49+
def self.clear_interactions mock_service_base_url, example_description
50+
uri = URI(mock_service_base_url)
51+
Net::HTTP.new(uri.host, uri.port).delete("/interactions?example_description=#{CGI.escape(example_description)}", MOCK_SERVICE_ADMINISTRATON_HEADERS)
5152
end
5253

5354
def write_pact pacticipant_details

‎lib/pact/mock_service/control_server/mock_service_creator.rb

+1-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
module Pact
99
module MockService
1010
module ControlServer
11-
1211
class MockServiceCreator
1312

1413
attr_reader :options
@@ -22,7 +21,7 @@ def call env
2221
consumer_name = env['HTTP_X_PACT_CONSUMER']
2322
provider_name = env['HTTP_X_PACT_PROVIDER']
2423
port = FindAPort.available_port
25-
mock_service = Pact::MockService::Spawn.(consumer_name, provider_name, port, options)
24+
mock_service = Pact::MockService::Spawn.(consumer_name, provider_name, options[:host] || 'localhost', port, options)
2625
delegator = Delegator.new(mock_service, consumer_name, provider_name)
2726
@mock_services.add(delegator)
2827
delegator.call(env)

‎lib/pact/mock_service/control_server/run.rb

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def control_server_options
5555
unique_pact_file_names: options[:unique_pact_file_names],
5656
cors_enabled: options[:cors] || false,
5757
ssl: options[:ssl],
58+
host: options[:host],
5859
pact_specification_version: options[:pact_specification_version]
5960
}
6061
end

‎lib/pact/mock_service/run.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def webbrick_opts
9898
def ssl_opts
9999
{
100100
:SSLEnable => true,
101-
:SSLCertName => [ %w[CN localhost] ]
101+
:SSLCertName => [ ["CN", host] ]
102102
}
103103
end
104104

‎lib/pact/mock_service/spawn.rb

+7-6
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@ module Pact
88
module MockService
99
class Spawn
1010

11-
def self.call consumer, provider, port, options
12-
new(consumer, provider, port, options).call
11+
def self.call consumer, provider, host, port, options
12+
new(consumer, provider, host, port, options).call
1313
end
1414

15-
attr_reader :consumer, :provider, :port, :options
15+
attr_reader :consumer, :provider, :host, :port, :options
1616

17-
def initialize consumer, provider, port, options
17+
def initialize consumer, provider, host, port, options
1818
@consumer = consumer
1919
@provider = provider
20+
@host = host
2021
@port = port
2122
@options = options
2223
end
@@ -49,7 +50,7 @@ def mock_service
4950
end
5051

5152
def start_mock_service app, port
52-
Pact::Server.new(app, port, ssl: options[:ssl]).boot
53+
Pact::Server.new(app, host, port, ssl: options[:ssl]).boot
5354
end
5455

5556
def create_log_file
@@ -73,7 +74,7 @@ def log_file_path
7374
end
7475

7576
def base_url
76-
options[:ssl] ? "https://localhost:#{port}" : "http://localhost:#{port}"
77+
options[:ssl] ? "https://#{host}:#{port}" : "http://#{host}:#{port}"
7778
end
7879

7980
def name

‎spec/lib/pact/consumer/server_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
describe 'booting' do
55
context 'with `nil` port' do
66
let(:app) { -> (env) { [200, {}, ['OK']] } }
7-
let(:server) { described_class.new(app, nil) }
7+
let(:server) { described_class.new(app, 'localhost', nil) }
88

99
it 'boots server with port 0 trick' do
1010
expect(server.port).to be_nil

‎spec/lib/pact/mock_service/app_manager_spec.rb

-8
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,6 @@ module Pact::MockService
5050
end
5151
end
5252

53-
context "for a host other than localhost" do
54-
let(:url) { 'http://aserver:1234'}
55-
56-
it "should throw an unsupported error" do
57-
expect { AppManager.instance.register_mock_service_for name, url, options }.to raise_error "Currently only services on localhost are supported"
58-
end
59-
end
60-
6153
describe "find_a_port option" do
6254
let(:url) { 'http://localhost' }
6355

‎spec/lib/pact/mock_service/client_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ module MockService
5353
end
5454

5555
it "deletes the interactions" do
56-
Pact::MockService::Client.clear_interactions 4444, "some example"
56+
Pact::MockService::Client.clear_interactions "http://localhost:4444", "some example"
5757
expect(delete_verifications).to have_been_made
5858
end
5959
end

0 commit comments

Comments
 (0)
Please sign in to comment.