a9bcddee4c
Gitlab::HTTP now resolves the hostname only once, verifies the IP is not blocked, and then uses the same IP to perform the actual request, while passing the original hostname in the `Host` header and SSL SNI field.
272 lines
8.1 KiB
Ruby
272 lines
8.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
describe BambooService, :use_clean_rails_memory_store_caching do
|
|
include ReactiveCachingHelpers
|
|
include StubRequests
|
|
|
|
let(:bamboo_url) { 'http://gitlab.com/bamboo' }
|
|
|
|
subject(:service) do
|
|
described_class.create(
|
|
project: create(:project),
|
|
properties: {
|
|
bamboo_url: bamboo_url,
|
|
username: 'mic',
|
|
password: 'password',
|
|
build_key: 'foo'
|
|
}
|
|
)
|
|
end
|
|
|
|
describe 'Associations' do
|
|
it { is_expected.to belong_to :project }
|
|
it { is_expected.to have_one :service_hook }
|
|
end
|
|
|
|
describe 'Validations' do
|
|
context 'when service is active' do
|
|
before do
|
|
subject.active = true
|
|
end
|
|
|
|
it { is_expected.to validate_presence_of(:build_key) }
|
|
it { is_expected.to validate_presence_of(:bamboo_url) }
|
|
it_behaves_like 'issue tracker service URL attribute', :bamboo_url
|
|
|
|
describe '#username' do
|
|
it 'does not validate the presence of username if password is nil' do
|
|
subject.password = nil
|
|
|
|
expect(subject).not_to validate_presence_of(:username)
|
|
end
|
|
|
|
it 'validates the presence of username if password is present' do
|
|
subject.password = 'secret'
|
|
|
|
expect(subject).to validate_presence_of(:username)
|
|
end
|
|
end
|
|
|
|
describe '#password' do
|
|
it 'does not validate the presence of password if username is nil' do
|
|
subject.username = nil
|
|
|
|
expect(subject).not_to validate_presence_of(:password)
|
|
end
|
|
|
|
it 'validates the presence of password if username is present' do
|
|
subject.username = 'john'
|
|
|
|
expect(subject).to validate_presence_of(:password)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when service is inactive' do
|
|
before do
|
|
subject.active = false
|
|
end
|
|
|
|
it { is_expected.not_to validate_presence_of(:build_key) }
|
|
it { is_expected.not_to validate_presence_of(:bamboo_url) }
|
|
it { is_expected.not_to validate_presence_of(:username) }
|
|
it { is_expected.not_to validate_presence_of(:password) }
|
|
end
|
|
end
|
|
|
|
describe 'Callbacks' do
|
|
describe 'before_update :reset_password' do
|
|
context 'when a password was previously set' do
|
|
it 'resets password if url changed' do
|
|
bamboo_service = service
|
|
|
|
bamboo_service.bamboo_url = 'http://gitlab1.com'
|
|
bamboo_service.save
|
|
|
|
expect(bamboo_service.password).to be_nil
|
|
end
|
|
|
|
it 'does not reset password if username changed' do
|
|
bamboo_service = service
|
|
|
|
bamboo_service.username = 'some_name'
|
|
bamboo_service.save
|
|
|
|
expect(bamboo_service.password).to eq('password')
|
|
end
|
|
|
|
it "does not reset password if new url is set together with password, even if it's the same password" do
|
|
bamboo_service = service
|
|
|
|
bamboo_service.bamboo_url = 'http://gitlab_edited.com'
|
|
bamboo_service.password = 'password'
|
|
bamboo_service.save
|
|
|
|
expect(bamboo_service.password).to eq('password')
|
|
expect(bamboo_service.bamboo_url).to eq('http://gitlab_edited.com')
|
|
end
|
|
end
|
|
|
|
it 'saves password if new url is set together with password when no password was previously set' do
|
|
bamboo_service = service
|
|
bamboo_service.password = nil
|
|
|
|
bamboo_service.bamboo_url = 'http://gitlab_edited.com'
|
|
bamboo_service.password = 'password'
|
|
bamboo_service.save
|
|
|
|
expect(bamboo_service.password).to eq('password')
|
|
expect(bamboo_service.bamboo_url).to eq('http://gitlab_edited.com')
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#execute' do
|
|
it 'runs update and build action' do
|
|
stub_update_and_build_request
|
|
|
|
subject.execute(Gitlab::DataBuilder::Push::SAMPLE_DATA)
|
|
end
|
|
end
|
|
|
|
describe '#build_page' do
|
|
it 'returns the contents of the reactive cache' do
|
|
stub_reactive_cache(service, { build_page: 'foo' }, 'sha', 'ref')
|
|
|
|
expect(service.build_page('sha', 'ref')).to eq('foo')
|
|
end
|
|
end
|
|
|
|
describe '#commit_status' do
|
|
it 'returns the contents of the reactive cache' do
|
|
stub_reactive_cache(service, { commit_status: 'foo' }, 'sha', 'ref')
|
|
|
|
expect(service.commit_status('sha', 'ref')).to eq('foo')
|
|
end
|
|
end
|
|
|
|
shared_examples 'reactive cache calculation' do
|
|
context '#build_page' do
|
|
subject { service.calculate_reactive_cache('123', 'unused')[:build_page] }
|
|
|
|
it 'returns a specific URL when status is 500' do
|
|
stub_request(status: 500)
|
|
|
|
is_expected.to eq('http://gitlab.com/bamboo/browse/foo')
|
|
end
|
|
|
|
it 'returns a specific URL when response has no results' do
|
|
stub_request(body: %q({"results":{"results":{"size":"0"}}}))
|
|
|
|
is_expected.to eq('http://gitlab.com/bamboo/browse/foo')
|
|
end
|
|
|
|
it 'returns a build URL when bamboo_url has no trailing slash' do
|
|
stub_request(body: bamboo_response)
|
|
|
|
is_expected.to eq('http://gitlab.com/bamboo/browse/42')
|
|
end
|
|
|
|
context 'bamboo_url has trailing slash' do
|
|
let(:bamboo_url) { 'http://gitlab.com/bamboo/' }
|
|
|
|
it 'returns a build URL' do
|
|
stub_request(body: bamboo_response)
|
|
|
|
is_expected.to eq('http://gitlab.com/bamboo/browse/42')
|
|
end
|
|
end
|
|
end
|
|
|
|
context '#commit_status' do
|
|
subject { service.calculate_reactive_cache('123', 'unused')[:commit_status] }
|
|
|
|
it 'sets commit status to :error when status is 500' do
|
|
stub_request(status: 500)
|
|
|
|
is_expected.to eq(:error)
|
|
end
|
|
|
|
it 'sets commit status to "pending" when status is 404' do
|
|
stub_request(status: 404)
|
|
|
|
is_expected.to eq('pending')
|
|
end
|
|
|
|
it 'sets commit status to "pending" when response has no results' do
|
|
stub_request(body: %q({"results":{"results":{"size":"0"}}}))
|
|
|
|
is_expected.to eq('pending')
|
|
end
|
|
|
|
it 'sets commit status to "success" when build state contains Success' do
|
|
stub_request(body: bamboo_response(build_state: 'YAY Success!'))
|
|
|
|
is_expected.to eq('success')
|
|
end
|
|
|
|
it 'sets commit status to "failed" when build state contains Failed' do
|
|
stub_request(body: bamboo_response(build_state: 'NO Failed!'))
|
|
|
|
is_expected.to eq('failed')
|
|
end
|
|
|
|
it 'sets commit status to "pending" when build state contains Pending' do
|
|
stub_request(body: bamboo_response(build_state: 'NO Pending!'))
|
|
|
|
is_expected.to eq('pending')
|
|
end
|
|
|
|
it 'sets commit status to :error when build state is unknown' do
|
|
stub_request(body: bamboo_response(build_state: 'FOO BAR!'))
|
|
|
|
is_expected.to eq(:error)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#calculate_reactive_cache' do
|
|
context 'when Bamboo API returns single result' do
|
|
let(:bamboo_response_template) do
|
|
%q({"results":{"results":{"size":"1","result":{"buildState":"%{build_state}","planResultKey":{"key":"42"}}}}})
|
|
end
|
|
|
|
it_behaves_like 'reactive cache calculation'
|
|
end
|
|
|
|
context 'when Bamboo API returns an array of results and we only consider the last one' do
|
|
let(:bamboo_response_template) do
|
|
%q({"results":{"results":{"size":"2","result":[{"buildState":"%{build_state}","planResultKey":{"key":"41"}},{"buildState":"%{build_state}","planResultKey":{"key":"42"}}]}}})
|
|
end
|
|
|
|
it_behaves_like 'reactive cache calculation'
|
|
end
|
|
end
|
|
|
|
def stub_update_and_build_request(status: 200, body: nil)
|
|
bamboo_full_url = 'http://gitlab.com/bamboo/updateAndBuild.action?buildKey=foo&os_authType=basic'
|
|
|
|
stub_bamboo_request(bamboo_full_url, status, body)
|
|
end
|
|
|
|
def stub_request(status: 200, body: nil)
|
|
bamboo_full_url = 'http://gitlab.com/bamboo/rest/api/latest/result/byChangeset/123?os_authType=basic'
|
|
|
|
stub_bamboo_request(bamboo_full_url, status, body)
|
|
end
|
|
|
|
def stub_bamboo_request(url, status, body)
|
|
stub_full_request(url).to_return(
|
|
status: status,
|
|
headers: { 'Content-Type' => 'application/json' },
|
|
body: body
|
|
).with(basic_auth: %w(mic password))
|
|
end
|
|
|
|
def bamboo_response(build_state: 'success')
|
|
# reference: https://docs.atlassian.com/atlassian-bamboo/REST/6.2.5/#d2e786
|
|
bamboo_response_template % { build_state: build_state }
|
|
end
|
|
end
|