-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
204 additions
and
393 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,223 +1,19 @@ | ||
require 'openssl' | ||
|
||
require 'rspec/core/rake_task' | ||
require './tasks/support' | ||
|
||
RSpec::Core::RakeTask.new(:spec) | ||
|
||
LOCAL_PACKAGE_LOCATION = "tmp/pact.zip".freeze | ||
# Simulate a Windows environment on Mac by giving it an empty cert_store | ||
SSL_OPTIONS = {ca_file: 'cacert.pem', cert_store: OpenSSL::X509::Store.new}.freeze | ||
|
||
def windows? | ||
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil | ||
end | ||
|
||
def github_access_token | ||
ENV.fetch('GITHUB_ACCESS_TOKEN') | ||
end | ||
|
||
def get_latest_release_asset_url release_asset_name_regexp | ||
require 'octokit' | ||
stack = Faraday::RackBuilder.new do |builder| | ||
builder.response :logger do | logger | | ||
logger.filter(/(Authorization: )(.*)/,'\1[REMOVED]') | ||
def logger.debug *args; end | ||
end | ||
builder.use Octokit::Response::RaiseError | ||
builder.adapter Faraday.default_adapter | ||
end | ||
Octokit.middleware = stack | ||
|
||
repository_slug = 'pact-foundation/pact-ruby-standalone' | ||
|
||
client = Octokit::Client.new(access_token: github_access_token) | ||
client.connection_options[:ssl] = SSL_OPTIONS | ||
release = client.latest_release repository_slug | ||
release_assets = client.release_assets release.url | ||
zip = release_assets.find { | release_asset | release_asset.name =~ release_asset_name_regexp } | ||
zip.url | ||
end | ||
|
||
def download_release_asset url, file_path | ||
require 'faraday' | ||
|
||
faraday = Faraday.new(:url => url, :ssl => SSL_OPTIONS) do |faraday| | ||
faraday.adapter Faraday.default_adapter | ||
faraday.response :logger do | logger | | ||
logger.filter(/(Authorization: )(.*)/,'\1[REMOVED]') | ||
def logger.debug *args; end | ||
end | ||
end | ||
|
||
response = faraday.get do | request | | ||
request.headers['Accept'] = 'application/octet-stream' | ||
request.headers['Authorization'] = "token #{github_access_token}" | ||
end | ||
raise "Expected response status 302 but got #{response.status}" unless response.status == 302 | ||
|
||
faraday = Faraday.new(:url => response.headers['Location'], :ssl => SSL_OPTIONS) | ||
response = faraday.get | ||
raise "Error downloading release" unless response.status == 200 | ||
|
||
puts "Writing file #{file_path}" | ||
File.open(file_path, "wb") { |file| file << response.body } | ||
puts "Finished writing file #{file_path}" | ||
end | ||
|
||
def unzip_package path | ||
require 'zip' | ||
require 'pathname' | ||
|
||
puts "Unzipping #{path}" | ||
Zip::File.open(path) do |zip_file| | ||
zip_file.each do |entry| | ||
entry.extract(File.join("tmp", entry.name)) | ||
end | ||
end | ||
puts "Finished unzipping #{path}" | ||
end | ||
|
||
def build_process cmd_parts, cwd = nil | ||
require 'childprocess' | ||
logger = Logger.new($stdout) | ||
logger.level = Logger::INFO | ||
ChildProcess.logger = logger | ||
process = ChildProcess.build(*cmd_parts) | ||
process.cwd = cwd if cwd | ||
process.leader = true if windows? # not sure if we need this | ||
process.io.inherit! | ||
process | ||
end | ||
|
||
def mock_service_process | ||
if windows? | ||
build_process ["cmd.exe", "/c","pact-mock-service.bat", "service", "-p", "1235"], "tmp/pact/bin" | ||
else | ||
# Manually downloaded and extracted, for local testing | ||
build_process ["./pact-mock-service", "service", "-p", "1235"], "osx/pact/bin" | ||
end | ||
end | ||
|
||
def test_provider_process | ||
if windows? | ||
build_process ["cmd.exe", "/c","bundle", "exec", "rackup", "-p", "1236", "test/config.ru"] | ||
else | ||
build_process ["ruby", "-S", "bundle", "exec", "rackup", "-p", "1236", "test/config.ru"] | ||
end | ||
end | ||
|
||
def pact_verifier_command | ||
suffix = "verify #{File.absolute_path("test/pact.json")} --provider-base-url http://localhost:1236" | ||
if windows? | ||
"cd tmp/pact/bin && cmd.exe /c pact-provider-verifier.bat #{suffix}" | ||
else | ||
# Manually downloaded and extracted, for local testing | ||
"cd osx/pact/bin && ./pact-provider-verifier #{suffix}" | ||
end | ||
end | ||
|
||
def with_process process, clean_env = true | ||
if clean_env | ||
Bundler.with_clean_env do | ||
process.start | ||
end | ||
else | ||
process.start | ||
end | ||
yield | ||
ensure | ||
process.stop if process && process.alive? | ||
end | ||
|
||
def expect_successful_request faraday, http_method, path, body = nil, headers = {} | ||
response = faraday.send(http_method, path, body, headers) | ||
raise "#{response.status} #{response.body}" unless response.status == 200 | ||
response | ||
end | ||
|
||
def test_mock_service | ||
require 'faraday' | ||
require 'json' | ||
|
||
with_process(mock_service_process) do | ||
sleep 5 | ||
admin_header = {'X-Pact-Mock-Service' => 'true'} | ||
pact_details = {consumer: {name: 'Foo'}, provider: {name: 'bar'}, pact_dir: '.\pacts'} | ||
interaction = {description: "test", providerState: nil, request: {method: 'GET', path: '/test'}, response: {status: 200} } | ||
|
||
faraday = Faraday.new(:url => "http://localhost:1235") do |faraday| | ||
faraday.adapter Faraday.default_adapter | ||
faraday.response :logger do | logger | | ||
def logger.debug *args; end | ||
end | ||
end | ||
|
||
expect_successful_request(faraday, :get, "/", nil, admin_header) | ||
expect_successful_request(faraday, :post, "/interactions", interaction.to_json, {'X-Pact-Mock-Service' => 'true', 'Content-Type' => 'application/json'}) | ||
expect_successful_request(faraday, :get, "/test") | ||
expect_successful_request(faraday, :get, "/interactions/verification", nil, admin_header) | ||
expect_successful_request(faraday, :post, "/pact", pact_details.to_json, admin_header) | ||
end | ||
end | ||
|
||
def test_verifier | ||
require 'faraday' | ||
with_process(test_provider_process, false) do | ||
sleep 2 | ||
|
||
Bundler.with_clean_env do | ||
output = `#{pact_verifier_command}` | ||
puts output | ||
raise "pact-provider-verifier did not run as expected" unless output.include?("1 interaction, 0 failures") | ||
end | ||
end | ||
end | ||
|
||
desc 'Download latest pact-X.X.X-win32.zip' | ||
task :download_latest_release do |t, args | | ||
begin | ||
require 'fileutils' | ||
FileUtils.rm_rf "tmp" | ||
FileUtils.mkdir_p "tmp" | ||
|
||
url = get_latest_release_asset_url /win.*zip/ | ||
download_release_asset url, LOCAL_PACKAGE_LOCATION | ||
|
||
rescue StandardError => e | ||
# Appveyor doesn't display stderr in a helpful way, need to manually print error | ||
puts "#{e.class} #{e.message} #{e.backtrace.join("\n")}" | ||
raise e | ||
end | ||
include Pact::StandaloneWindowsTest::Setup | ||
download_latest_release | ||
end | ||
|
||
desc 'Unzip package' | ||
task :unzip_package do | ||
unzip_package LOCAL_PACKAGE_LOCATION | ||
end | ||
|
||
desc 'Test windows batch file' | ||
task :test_mock_service do | ||
begin | ||
puts "Testing pact-mock-service" | ||
test_mock_service | ||
rescue StandardError => e | ||
# Appveyor doesn't display stderr in a helpful way, need to manually print error | ||
puts "#{e.class} #{e.message} #{e.backtrace.join("\n")}" | ||
raise e | ||
end | ||
end | ||
|
||
desc 'Test windows pact verifier batch file' | ||
task :test_verifier do | ||
begin | ||
puts "Testing pact-provider-verifier" | ||
test_verifier | ||
rescue StandardError => e | ||
# Appveyor doesn't display stderr in a helpful way, need to manually print error | ||
puts "#{e.class} #{e.message} #{e.backtrace.join("\n")}" | ||
raise e | ||
end | ||
include Pact::StandaloneWindowsTest::Setup | ||
unzip_package | ||
end | ||
|
||
task :test => [:test_mock_service, :test_verifier] # :test_verifier disabled for now, don't have time to debug why it isn't working | ||
task :default => [:download_latest_release, :unzip_package, :test] | ||
task :default => [:download_latest_release, :unzip_package, :spec] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
require 'faraday' | ||
|
||
RSpec.describe "The pact provider verifier" do | ||
it "verifies the given pact against a running service" do | ||
with_process(test_provider_process, false) do | ||
sleep 2 | ||
|
||
Bundler.with_clean_env do | ||
output = `#{pact_verifier_command}` | ||
puts output | ||
expect(output).to include "1 interaction, 0 failures" | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.