gitlab-org--gitlab-foss/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
Reuben Pereira 434359446a Add ability to do variable substitution
- In prometheus proxy api, allow variables to be replaced. For example,
if 'up{env="%{ci_environment_slug}"}' is passed to the endpoint, it
becomes 'up{env="production"}' before being sent to prometheus.
2019-04-15 15:31:59 +00:00

185 lines
5.4 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
describe Projects::Environments::PrometheusApiController do
set(:project) { create(:project) }
set(:environment) { create(:environment, project: project) }
set(:user) { create(:user) }
before do
project.add_reporter(user)
sign_in(user)
end
describe 'GET #proxy' do
let(:prometheus_proxy_service) { instance_double(Prometheus::ProxyService) }
let(:expected_params) do
ActionController::Parameters.new(
environment_params(
proxy_path: 'query',
controller: 'projects/environments/prometheus_api',
action: 'proxy'
)
).permit!
end
context 'with valid requests' do
before do
allow(Prometheus::ProxyService).to receive(:new)
.with(environment, 'GET', 'query', expected_params)
.and_return(prometheus_proxy_service)
allow(prometheus_proxy_service).to receive(:execute)
.and_return(service_result)
end
context 'with success result' do
let(:service_result) { { status: :success, body: prometheus_body } }
let(:prometheus_body) { '{"status":"success"}' }
let(:prometheus_json_body) { JSON.parse(prometheus_body) }
it 'returns prometheus response' do
get :proxy, params: environment_params
expect(Prometheus::ProxyService).to have_received(:new)
.with(environment, 'GET', 'query', expected_params)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to eq(prometheus_json_body)
end
context 'with format string' do
before do
expected_params[:query] = %{up{environment="#{environment.slug}"}}
end
it 'replaces variables with values' do
get :proxy, params: environment_params.merge(query: 'up{environment="%{ci_environment_slug}"}')
expect(Prometheus::ProxyService).to have_received(:new)
.with(environment, 'GET', 'query', expected_params)
end
context 'with nil query' do
let(:params_without_query) do
params = environment_params
params.delete(:query)
params
end
before do
expected_params.delete(:query)
end
it 'does not raise error' do
get :proxy, params: params_without_query
expect(Prometheus::ProxyService).to have_received(:new)
.with(environment, 'GET', 'query', expected_params)
end
end
end
end
context 'with nil result' do
let(:service_result) { nil }
it 'returns 202 accepted' do
get :proxy, params: environment_params
expect(json_response['status']).to eq('processing')
expect(json_response['message']).to eq('Not ready yet. Try again later.')
expect(response).to have_gitlab_http_status(:accepted)
end
end
context 'with 404 result' do
let(:service_result) { { http_status: 404, status: :success, body: '{"body": "value"}' } }
it 'returns body' do
get :proxy, params: environment_params
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['body']).to eq('value')
end
end
context 'with error result' do
context 'with http_status' do
let(:service_result) do
{ http_status: :service_unavailable, status: :error, message: 'error message' }
end
it 'sets the http response status code' do
get :proxy, params: environment_params
expect(response).to have_gitlab_http_status(:service_unavailable)
expect(json_response['status']).to eq('error')
expect(json_response['message']).to eq('error message')
end
end
context 'without http_status' do
let(:service_result) { { status: :error, message: 'error message' } }
it 'returns bad_request' do
get :proxy, params: environment_params
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['status']).to eq('error')
expect(json_response['message']).to eq('error message')
end
end
end
end
context 'with inappropriate requests' do
context 'with anonymous user' do
before do
sign_out(user)
end
it 'redirects to signin page' do
get :proxy, params: environment_params
expect(response).to redirect_to(new_user_session_path)
end
end
context 'without correct permissions' do
before do
project.team.truncate
end
it 'returns 404' do
get :proxy, params: environment_params
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
context 'with invalid environment id' do
let(:other_environment) { create(:environment) }
it 'returns 404' do
get :proxy, params: environment_params(id: other_environment.id)
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
private
def environment_params(params = {})
{
id: environment.id.to_s,
namespace_id: project.namespace.name,
project_id: project.name,
proxy_path: 'query',
query: '1'
}.merge(params)
end
end