diff options
Diffstat (limited to 'spec/services/grafana/proxy_service_spec.rb')
-rw-r--r-- | spec/services/grafana/proxy_service_spec.rb | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/spec/services/grafana/proxy_service_spec.rb b/spec/services/grafana/proxy_service_spec.rb new file mode 100644 index 00000000000..694d531c9fc --- /dev/null +++ b/spec/services/grafana/proxy_service_spec.rb @@ -0,0 +1,139 @@ +# 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 + expect(ReactiveCachingWorker) + .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 |