Skip to content

Commit

Permalink
feat: allow mock service host to be configured
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Feb 21, 2019
1 parent b41d161 commit 7e2d810
Show file tree
Hide file tree
Showing 11 changed files with 40 additions and 47 deletions.
11 changes: 4 additions & 7 deletions lib/pact/consumer/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ def ports
end
end

attr_reader :app, :port, :options
attr_reader :app, :host, :port, :options

def initialize(app, port, options = {})
def initialize(app, host, port, options = {})
@app = app
@middleware = Middleware.new(@app)
@server_thread = nil
@host = host
@port = port
@options = options
end
Expand All @@ -52,10 +53,6 @@ def error
@middleware.error
end

def host
"localhost"
end

def responsive?
return false if @server_thread && @server_thread.join(0)
res = get_identity
Expand Down Expand Up @@ -96,7 +93,7 @@ def webrick_opts
end

def ssl_opts
{ SSLEnable: true, SSLCertName: [ %w[CN localhost] ] }
{ SSLEnable: true, SSLCertName: [ ["CN", host] ] }
end

def boot
Expand Down
30 changes: 15 additions & 15 deletions lib/pact/mock_service/app_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ def initialize
def register_mock_service_for(name, url, options = {})
uri = URI(url)
raise "Currently only http is supported" unless uri.scheme == 'http'
raise "Currently only services on localhost are supported" unless uri.host == 'localhost'
uri.port = nil if options[:find_available_port]

app = Pact::MockService.new(
Expand All @@ -32,21 +31,21 @@ def register_mock_service_for(name, url, options = {})
pact_dir: pact_dir,
pact_specification_version: options.fetch(:pact_specification_version)
)
register(app, uri.port)
register(app, uri.host, uri.port)
end

def register(app, port = nil)
def register(app, host, port = nil)
if port
existing = existing_app_on_port(port)
existing = existing_app_on_host_and_port(host, port)
raise "Port #{port} is already being used by #{existing}" if existing and not existing == app
end
app_registration = register_app(app, port)
app_registration = register_app(app, host, port)
app_registration.spawn
app_registration.port
end

def ports_of_mock_services
app_registrations.find_all(&:is_a_mock_service?).collect(&:port)
def urls_of_mock_services
app_registrations.find_all(&:is_a_mock_service?).collect{ |ar| "http://#{ar.host}:#{ar.port}" }
end

def kill_all
Expand All @@ -70,13 +69,13 @@ def app_registered_on?(port)

private

def existing_app_on_port(port)
app_registration = registration_on_port(port)
def existing_app_on_host_and_port(host, port)
app_registration = registration_on_host_and_port(host, port)
app_registration ? app_registration.app : nil
end

def registration_on_port(port)
@app_registrations.find { |app_registration| app_registration.port == port }
def registration_on_host_and_port(host, port)
@app_registrations.find { |app_registration| app_registration.port == port && app_registration.host == host }
end

def pact_dir
Expand Down Expand Up @@ -107,20 +106,21 @@ def app_registrations
@app_registrations
end

def register_app(app, port)
app_registration = AppRegistration.new(app: app, port: port)
def register_app(app, host, port)
app_registration = AppRegistration.new(app: app, host: host, port: port)
app_registrations << app_registration
app_registration
end
end

class AppRegistration
include Pact::Logging
attr_accessor :port, :app
attr_accessor :host, :port, :app

def initialize(opts)
@max_wait = 10
@port = opts[:port]
@host = opts[:host]
@app = opts[:app]
@spawned = false
end
Expand Down Expand Up @@ -148,7 +148,7 @@ def to_s

def spawn
logger.info "Starting app #{self}..."
@server = Pact::Server.new(app, port).boot
@server = Pact::Server.new(app, host, port).boot
@port = @server.port
@spawned = true
logger.info "Started on port #{port}"
Expand Down
6 changes: 4 additions & 2 deletions lib/pact/mock_service/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ def restart

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

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

def start_server pidfile
require 'pact/mock_service/server/spawn'
Pact::MockService::Server::Spawn.(pidfile, options[:port], options[:ssl]) do
Pact::MockService::Server::Spawn.(pidfile, options[:host], options[:port], options[:ssl]) do
yield
end
end

def restart_server pidfile
require 'pact/mock_service/server/respawn'
Pact::MockService::Server::Respawn.(pidfile, options[:port], options[:ssl]) do
Pact::MockService::Server::Respawn.(pidfile, options[:host], options[:port], options[:ssl]) do
yield
end
end
Expand Down
9 changes: 5 additions & 4 deletions lib/pact/mock_service/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ class Client

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

def initialize port
@http = Net::HTTP.new('localhost', port)
def initialize port, host = 'localhost'
@http = Net::HTTP.new(host, port)
end

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

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

def write_pact pacticipant_details
Expand Down
3 changes: 1 addition & 2 deletions lib/pact/mock_service/control_server/mock_service_creator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
module Pact
module MockService
module ControlServer

class MockServiceCreator

attr_reader :options
Expand All @@ -22,7 +21,7 @@ def call env
consumer_name = env['HTTP_X_PACT_CONSUMER']
provider_name = env['HTTP_X_PACT_PROVIDER']
port = FindAPort.available_port
mock_service = Pact::MockService::Spawn.(consumer_name, provider_name, port, options)
mock_service = Pact::MockService::Spawn.(consumer_name, provider_name, options[:host] || 'localhost', port, options)
delegator = Delegator.new(mock_service, consumer_name, provider_name)
@mock_services.add(delegator)
delegator.call(env)
Expand Down
1 change: 1 addition & 0 deletions lib/pact/mock_service/control_server/run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def control_server_options
unique_pact_file_names: options[:unique_pact_file_names],
cors_enabled: options[:cors] || false,
ssl: options[:ssl],
host: options[:host],
pact_specification_version: options[:pact_specification_version]
}
end
Expand Down
2 changes: 1 addition & 1 deletion lib/pact/mock_service/run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def webbrick_opts
def ssl_opts
{
:SSLEnable => true,
:SSLCertName => [ %w[CN localhost] ]
:SSLCertName => [ ["CN", host] ]
}
end

Expand Down
13 changes: 7 additions & 6 deletions lib/pact/mock_service/spawn.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ module Pact
module MockService
class Spawn

def self.call consumer, provider, port, options
new(consumer, provider, port, options).call
def self.call consumer, provider, host, port, options
new(consumer, provider, host, port, options).call
end

attr_reader :consumer, :provider, :port, :options
attr_reader :consumer, :provider, :host, :port, :options

def initialize consumer, provider, port, options
def initialize consumer, provider, host, port, options
@consumer = consumer
@provider = provider
@host = host
@port = port
@options = options
end
Expand Down Expand Up @@ -49,7 +50,7 @@ def mock_service
end

def start_mock_service app, port
Pact::Server.new(app, port, ssl: options[:ssl]).boot
Pact::Server.new(app, host, port, ssl: options[:ssl]).boot
end

def create_log_file
Expand All @@ -73,7 +74,7 @@ def log_file_path
end

def base_url
options[:ssl] ? "https://localhost:#{port}" : "http://localhost:#{port}"
options[:ssl] ? "https://#{host}:#{port}" : "http://#{host}:#{port}"
end

def name
Expand Down
2 changes: 1 addition & 1 deletion spec/lib/pact/consumer/server_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
describe 'booting' do
context 'with `nil` port' do
let(:app) { -> (env) { [200, {}, ['OK']] } }
let(:server) { described_class.new(app, nil) }
let(:server) { described_class.new(app, 'localhost', nil) }

it 'boots server with port 0 trick' do
expect(server.port).to be_nil
Expand Down
8 changes: 0 additions & 8 deletions spec/lib/pact/mock_service/app_manager_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ module Pact::MockService
end
end

context "for a host other than localhost" do
let(:url) { 'http://aserver:1234'}

it "should throw an unsupported error" do
expect { AppManager.instance.register_mock_service_for name, url, options }.to raise_error "Currently only services on localhost are supported"
end
end

describe "find_a_port option" do
let(:url) { 'http://localhost' }

Expand Down
2 changes: 1 addition & 1 deletion spec/lib/pact/mock_service/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module MockService
end

it "deletes the interactions" do
Pact::MockService::Client.clear_interactions 4444, "some example"
Pact::MockService::Client.clear_interactions "http://localhost:4444", "some example"
expect(delete_verifications).to have_been_made
end
end
Expand Down

0 comments on commit 7e2d810

Please sign in to comment.