2019-12-21 20:55:43 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'spec_helper'
|
|
|
|
|
2023-01-10 11:22:00 +05:30
|
|
|
RSpec.describe Projects::GrafanaApiController, feature_category: :metrics do
|
|
|
|
let_it_be(:project) { create(:project, :public) }
|
|
|
|
let_it_be(:reporter) { create(:user) }
|
|
|
|
let_it_be(:guest) { create(:user) }
|
|
|
|
let(:anonymous) { nil }
|
|
|
|
let(:user) { reporter }
|
|
|
|
|
|
|
|
before_all do
|
|
|
|
project.add_reporter(reporter)
|
|
|
|
project.add_guest(guest)
|
|
|
|
end
|
2019-12-21 20:55:43 +05:30
|
|
|
|
|
|
|
before do
|
2023-07-09 08:55:56 +05:30
|
|
|
stub_feature_flags(remove_monitor_metrics: false)
|
2023-01-10 11:22:00 +05:30
|
|
|
sign_in(user) if user
|
2019-12-21 20:55:43 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
describe 'GET #proxy' do
|
|
|
|
let(:proxy_service) { instance_double(Grafana::ProxyService) }
|
|
|
|
let(:params) do
|
|
|
|
{
|
|
|
|
namespace_id: project.namespace.full_path,
|
2023-07-09 08:55:56 +05:30
|
|
|
project_id: project.path,
|
2019-12-21 20:55:43 +05:30
|
|
|
proxy_path: 'api/v1/query_range',
|
|
|
|
datasource_id: '1',
|
|
|
|
query: 'rate(relevant_metric)',
|
2020-04-22 19:07:51 +05:30
|
|
|
start_time: '1570441248',
|
|
|
|
end_time: '1570444848',
|
2019-12-21 20:55:43 +05:30
|
|
|
step: '900'
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(Grafana::ProxyService).to receive(:new).and_return(proxy_service)
|
|
|
|
allow(proxy_service).to receive(:execute).and_return(service_result)
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples_for 'error response' do |http_status|
|
|
|
|
it "returns #{http_status}" do
|
|
|
|
get :proxy, params: params
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(http_status)
|
|
|
|
expect(json_response['status']).to eq('error')
|
|
|
|
expect(json_response['message']).to eq('error message')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-01-10 11:22:00 +05:30
|
|
|
shared_examples_for 'accessible' do
|
|
|
|
let(:service_result) { nil }
|
|
|
|
|
|
|
|
it 'returns non erroneous response' do
|
|
|
|
get :proxy, params: params
|
|
|
|
|
|
|
|
# We don't care about the specific code as long it's not an error.
|
|
|
|
expect(response).to have_gitlab_http_status(:no_content)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples_for 'not accessible' do
|
|
|
|
let(:service_result) { nil }
|
|
|
|
|
|
|
|
it 'returns 404 Not found' do
|
|
|
|
get :proxy, params: params
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
expect(Grafana::ProxyService).not_to have_received(:new)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples_for 'login required' do
|
|
|
|
let(:service_result) { nil }
|
|
|
|
|
|
|
|
it 'redirects to login page' do
|
|
|
|
get :proxy, params: params
|
|
|
|
|
|
|
|
expect(response).to redirect_to(new_user_session_path)
|
|
|
|
expect(Grafana::ProxyService).not_to have_received(:new)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-12-21 20:55:43 +05:30
|
|
|
context 'with a successful result' do
|
|
|
|
let(:service_result) { { status: :success, body: '{}' } }
|
|
|
|
|
|
|
|
it 'returns a grafana datasource response' do
|
|
|
|
get :proxy, params: params
|
|
|
|
|
2023-05-27 22:25:52 +05:30
|
|
|
expect(Grafana::ProxyService).to have_received(:new).with(
|
|
|
|
project, '1', 'api/v1/query_range',
|
|
|
|
{
|
|
|
|
'query' => params[:query],
|
|
|
|
'start' => params[:start_time],
|
|
|
|
'end' => params[:end_time],
|
|
|
|
'step' => params[:step]
|
|
|
|
}
|
|
|
|
)
|
2019-12-21 20:55:43 +05:30
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
|
|
|
expect(json_response).to eq({})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the request is still unavailable' do
|
|
|
|
let(:service_result) { nil }
|
|
|
|
|
|
|
|
it 'returns 204 no content' do
|
|
|
|
get :proxy, params: params
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:no_content)
|
|
|
|
expect(json_response['status']).to eq('processing')
|
|
|
|
expect(json_response['message']).to eq('Not ready yet. Try again later.')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when an error has occurred' do
|
|
|
|
context 'with an error accessing grafana' do
|
|
|
|
let(:service_result) do
|
|
|
|
{
|
|
|
|
http_status: :service_unavailable,
|
|
|
|
status: :error,
|
|
|
|
message: 'error message'
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'error response', :service_unavailable
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with a processing error' do
|
|
|
|
let(:service_result) do
|
|
|
|
{
|
|
|
|
status: :error,
|
|
|
|
message: 'error message'
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'error response', :bad_request
|
|
|
|
end
|
2023-01-10 11:22:00 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
context 'as guest' do
|
|
|
|
let(:user) { guest }
|
|
|
|
|
|
|
|
it_behaves_like 'not accessible'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'as anonymous' do
|
|
|
|
let(:user) { anonymous }
|
|
|
|
|
|
|
|
it_behaves_like 'not accessible'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'on a private project' do
|
|
|
|
let_it_be(:project) { create(:project, :private) }
|
|
|
|
|
|
|
|
before_all do
|
|
|
|
project.add_guest(guest)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'as anonymous' do
|
|
|
|
let(:user) { anonymous }
|
|
|
|
|
|
|
|
it_behaves_like 'login required'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'as guest' do
|
|
|
|
let(:user) { guest }
|
|
|
|
|
|
|
|
it_behaves_like 'accessible'
|
|
|
|
end
|
2019-12-21 20:55:43 +05:30
|
|
|
end
|
2023-07-09 08:55:56 +05:30
|
|
|
|
|
|
|
context 'when metrics dashboard feature is unavailable' do
|
|
|
|
before do
|
|
|
|
stub_feature_flags(remove_monitor_metrics: true)
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'not accessible'
|
|
|
|
end
|
2019-12-21 20:55:43 +05:30
|
|
|
end
|
2019-12-26 22:10:19 +05:30
|
|
|
|
|
|
|
describe 'GET #metrics_dashboard' do
|
|
|
|
let(:service_result) { { status: :success, dashboard: '{}' } }
|
|
|
|
let(:params) do
|
|
|
|
{
|
|
|
|
format: :json,
|
|
|
|
embedded: true,
|
|
|
|
grafana_url: 'https://grafana.example.com',
|
|
|
|
namespace_id: project.namespace.full_path,
|
2023-07-09 08:55:56 +05:30
|
|
|
project_id: project.path
|
2019-12-26 22:10:19 +05:30
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(Gitlab::Metrics::Dashboard::Finder)
|
|
|
|
.to receive(:find)
|
|
|
|
.and_return(service_result)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the result is still processing' do
|
|
|
|
let(:service_result) { nil }
|
|
|
|
|
|
|
|
it 'returns 204 no content' do
|
|
|
|
get :metrics_dashboard, params: params
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:no_content)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the result was successful' do
|
|
|
|
it 'returns the dashboard response' do
|
|
|
|
get :metrics_dashboard, params: params
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
2020-05-24 23:13:21 +05:30
|
|
|
expect(json_response).to include({
|
2019-12-26 22:10:19 +05:30
|
|
|
'dashboard' => '{}',
|
|
|
|
'status' => 'success'
|
|
|
|
})
|
2020-05-24 23:13:21 +05:30
|
|
|
expect(json_response).to include('metrics_data')
|
2019-12-26 22:10:19 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when an error has occurred' do
|
|
|
|
shared_examples_for 'error response' do |http_status|
|
|
|
|
it "returns #{http_status}" do
|
|
|
|
get :metrics_dashboard, params: params
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(http_status)
|
|
|
|
expect(json_response['status']).to eq('error')
|
|
|
|
expect(json_response['message']).to eq('error message')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with an error accessing grafana' do
|
|
|
|
let(:service_result) do
|
|
|
|
{
|
|
|
|
http_status: :service_unavailable,
|
|
|
|
status: :error,
|
|
|
|
message: 'error message'
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'error response', :service_unavailable
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with a processing error' do
|
|
|
|
let(:service_result) { { status: :error, message: 'error message' } }
|
|
|
|
|
|
|
|
it_behaves_like 'error response', :bad_request
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-12-21 20:55:43 +05:30
|
|
|
end
|