2019-10-10 08:06:19 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
describe Grafana::ProxyService do
|
|
|
|
include ReactiveCachingHelpers
|
|
|
|
|
|
|
|
let_it_be(:project) { create(:project) }
|
|
|
|
let_it_be(:grafana_integration) { create(:grafana_integration, project: project) }
|
|
|
|
|
|
|
|
let(:proxy_path) { 'api/v1/query_range' }
|
|
|
|
let(:datasource_id) { '1' }
|
|
|
|
let(:query_params) do
|
|
|
|
{
|
|
|
|
'query' => 'rate(relevant_metric)',
|
|
|
|
'start' => '1570441248',
|
|
|
|
'end' => '1570444848',
|
|
|
|
'step' => '900'
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:cache_params) { [project.id, datasource_id, proxy_path, query_params] }
|
|
|
|
|
|
|
|
let(:service) do
|
|
|
|
described_class.new(project, datasource_id, proxy_path, query_params)
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples_for 'initializes an instance' do
|
|
|
|
it 'initializes an instance of ProxyService class' do
|
|
|
|
expect(subject).to be_an_instance_of(described_class)
|
|
|
|
expect(subject.project).to eq(project)
|
|
|
|
expect(subject.datasource_id).to eq('1')
|
|
|
|
expect(subject.proxy_path).to eq('api/v1/query_range')
|
|
|
|
expect(subject.query_params).to eq(query_params)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '.from_cache' do
|
|
|
|
subject { described_class.from_cache(*cache_params) }
|
|
|
|
|
|
|
|
it_behaves_like 'initializes an instance'
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#initialize' do
|
|
|
|
subject { service }
|
|
|
|
|
|
|
|
it_behaves_like 'initializes an instance'
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#execute' do
|
|
|
|
subject(:result) { service.execute }
|
|
|
|
|
|
|
|
context 'when grafana integration is not configured' do
|
|
|
|
before do
|
|
|
|
allow(project).to receive(:grafana_integration).and_return(nil)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns error' do
|
|
|
|
expect(result).to eq(
|
|
|
|
status: :error,
|
|
|
|
message: 'Proxy support for this API is not available currently'
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with caching', :use_clean_rails_memory_store_caching do
|
|
|
|
context 'when value not present in cache' do
|
|
|
|
it 'returns nil' do
|
2020-04-24 17:09:48 -04:00
|
|
|
expect(ExternalServiceReactiveCachingWorker)
|
2019-10-10 08:06:19 -04:00
|
|
|
.to receive(:perform_async)
|
|
|
|
.with(service.class, service.id, *cache_params)
|
|
|
|
|
|
|
|
expect(result).to eq(nil)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when value present in cache' do
|
|
|
|
let(:return_value) { { 'http_status' => 200, 'body' => 'body' } }
|
|
|
|
|
|
|
|
before do
|
|
|
|
stub_reactive_cache(service, return_value, cache_params)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns cached value' do
|
|
|
|
expect(ReactiveCachingWorker)
|
|
|
|
.not_to receive(:perform_async)
|
|
|
|
.with(service.class, service.id, *cache_params)
|
|
|
|
|
|
|
|
expect(result[:http_status]).to eq(return_value[:http_status])
|
|
|
|
expect(result[:body]).to eq(return_value[:body])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'call prometheus api' do
|
|
|
|
let(:client) { service.send(:client) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
synchronous_reactive_cache(service)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'connection to grafana datasource succeeds' do
|
|
|
|
let(:response) { instance_double(Gitlab::HTTP::Response) }
|
|
|
|
let(:status_code) { 400 }
|
|
|
|
let(:body) { 'body' }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(client).to receive(:proxy_datasource).and_return(response)
|
|
|
|
|
|
|
|
allow(response).to receive(:code).and_return(status_code)
|
|
|
|
allow(response).to receive(:body).and_return(body)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns the http status code and body from prometheus' do
|
|
|
|
expect(result).to eq(
|
|
|
|
http_status: status_code,
|
|
|
|
body: body,
|
|
|
|
status: :success
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'connection to grafana datasource fails' do
|
|
|
|
before do
|
|
|
|
allow(client).to receive(:proxy_datasource)
|
|
|
|
.and_raise(Grafana::Client::Error, 'Network connection error')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns error' do
|
|
|
|
expect(result).to eq(
|
|
|
|
status: :error,
|
|
|
|
message: 'Network connection error',
|
|
|
|
http_status: :service_unavailable
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|