Skip to content

Commit

Permalink
feat: timeout long running pact content diff requests (#555)
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque authored Apr 28, 2022
1 parent 91452db commit 88abb2c
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 8 deletions.
9 changes: 9 additions & 0 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,15 @@ with a unique version number.
**Allowed values:** `true`, `false`<br/>
**More information:** https://docs.pact.io/versioning<br/>

### pact_content_diff_timeout

The maximum amount of time in seconds to attempt to generate the diff between two pacts before aborting the request. This is required due to performance issues in the underlying diff generation code.

**Supported versions:** From 2.99.0<br/>
**Environment variable name:** `PACT_BROKER_PACT_CONTENT_DIFF_TIMEOUT`<br/>
**YAML configuration key name:** `pact_content_diff_timeout`<br/>
**Default:** `15`<br/>

<br/>

## Miscellaneous
Expand Down
5 changes: 5 additions & 0 deletions docs/configuration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,11 @@ groups:
- true
- false
more_info: https://docs.pact.io/versioning
pact_content_diff_timeout:
description: |-
The maximum amount of time in seconds to attempt to generate the diff between two pacts before aborting the request. This is required due to performance issues in the underlying diff generation code.
default_value: 15
supported_versions: From 2.99.0
- title: Miscellaneous
vars:
features:
Expand Down
9 changes: 7 additions & 2 deletions lib/pact_broker/api/resources/pact_content_diff.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require "pact_broker/api/resources/base_resource"
require "pact_broker/pacts/pact_params"
require "pact_broker/pacts/diff"
require "timeout"

module PactBroker
module Api
Expand All @@ -19,8 +20,12 @@ def resource_exists?
end

def to_text
output = PactBroker::Pacts::Diff.new.process pact_params.merge(base_url: base_url), comparison_pact_params, raw: false
response.body = output
Timeout::timeout(PactBroker.configuration.pact_content_diff_timeout) do
output = PactBroker::Pacts::Diff.new.process pact_params.merge(base_url: base_url), comparison_pact_params, raw: false
response.body = output
end
rescue Timeout::Error
408
end

def pact
Expand Down
3 changes: 2 additions & 1 deletion lib/pact_broker/config/runtime_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ class RuntimeConfiguration < Anyway::Config
badge_provider_mode: :redirect,
enable_public_badge_access: false,
shields_io_base_url: "https://img.shields.io",
use_case_sensitive_resource_names: true
use_case_sensitive_resource_names: true,
pact_content_diff_timeout: 15
)

# domain attributes
Expand Down
1 change: 1 addition & 0 deletions lib/pact_broker/pacts/create_formatted_diff.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def self.call pact_json_content, previous_pact_json_content, raw: false
end

difference = diff(previous_pact_hash, pact_hash)

Pact::Matchers::UnixDiffFormatter.call(difference, colour: false, include_explanation: false)
end
end
Expand Down
6 changes: 1 addition & 5 deletions spec/features/get_diff_spec.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
require "spec/support/test_data_builder"

describe "Get diff between versions" do

let(:path) { "/pacts/provider/Provider/consumer/Consumer/version/3/diff/previous-distinct" }

let(:last_response_body) { subject.body }

subject { get path; last_response }
subject { get(path) }

let(:pact_content_version_1) do
hash = load_json_fixture("consumer-provider.json")
Expand Down Expand Up @@ -42,12 +40,10 @@
end

context "when either version does not exist" do

let(:path) { "/pacts/provider/Provider/consumer/Consumer/versions/1/diff/previous-distinct" }

it "returns a 404 response" do
expect(subject).to be_a_404_response
end

end
end
36 changes: 36 additions & 0 deletions spec/lib/pact_broker/api/resources/pact_content_diff_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require "pact_broker/api/resources/pact_content_diff"

module PactBroker
module Api
module Resources
describe PactContentDiff do
include_context "stubbed services"

before do
allow(pact_service).to receive(:find_pact).and_return(pact)
allow(PactBroker::Pacts::Diff).to receive(:new).and_return(diff)
end

let(:pact) { double("pact") }
let(:diff) { instance_double("PactBroker::Pacts::Diff", process: diff_content) }
let(:diff_content) { "diff_content" }
let(:path) { "/pacts/provider/Provider/consumer/Consumer/version/3/diff/previous-distinct" }
let(:last_response_body) { subject.body }

subject { get(path) }

its(:status) { is_expected.to eq 200 }
its(:body) { is_expected.to eq "diff_content" }

context "when the diff takes too long to generate" do
before do
allow(diff).to receive(:process).and_raise(Timeout::Error)
end

its(:status) { is_expected.to eq 408 }
its(:body) { is_expected.to eq "" }
end
end
end
end
end

0 comments on commit 88abb2c

Please sign in to comment.