prometheus_api_controller_spec.rb 5.37 KB
Newer Older
1
2
3
4
5
# frozen_string_literal: true

require 'spec_helper'

describe Projects::Environments::PrometheusApiController do
6
7
8
  let_it_be(:project) { create(:project) }
  let_it_be(:environment) { create(:environment, project: project) }
  let_it_be(:user) { create(:user) }
9
10
11
12
13
14
15
16

  before do
    project.add_reporter(user)
    sign_in(user)
  end

  describe 'GET #proxy' do
    let(:prometheus_proxy_service) { instance_double(Prometheus::ProxyService) }
17

Reuben Pereira's avatar
Reuben Pereira committed
18
19
    let(:expected_params) do
      ActionController::Parameters.new(
20
21
22
23
24
        environment_params(
          proxy_path: 'query',
          controller: 'projects/environments/prometheus_api',
          action: 'proxy'
        )
Reuben Pereira's avatar
Reuben Pereira committed
25
26
      ).permit!
    end
27

Peter Leitzen's avatar
Peter Leitzen committed
28
29
30
    context 'with valid requests' do
      before do
        allow(Prometheus::ProxyService).to receive(:new)
Reuben Pereira's avatar
Reuben Pereira committed
31
          .with(environment, 'GET', 'query', expected_params)
Peter Leitzen's avatar
Peter Leitzen committed
32
          .and_return(prometheus_proxy_service)
33

Peter Leitzen's avatar
Peter Leitzen committed
34
35
36
        allow(prometheus_proxy_service).to receive(:execute)
          .and_return(service_result)
      end
37

Peter Leitzen's avatar
Peter Leitzen committed
38
39
40
41
      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) }
42

Peter Leitzen's avatar
Peter Leitzen committed
43
44
        it 'returns prometheus response' do
          get :proxy, params: environment_params
45

Reuben Pereira's avatar
Reuben Pereira committed
46
47
          expect(Prometheus::ProxyService).to have_received(:new)
            .with(environment, 'GET', 'query', expected_params)
Peter Leitzen's avatar
Peter Leitzen committed
48
49
50
          expect(response).to have_gitlab_http_status(:ok)
          expect(json_response).to eq(prometheus_json_body)
        end
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

        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
66
              environment_params.except(:query)
67
68
69
70
71
72
73
74
75
76
77
78
79
80
            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
81
82
      end

Peter Leitzen's avatar
Peter Leitzen committed
83
84
      context 'with nil result' do
        let(:service_result) { nil }
85

86
        it 'returns 204 no_content' do
Peter Leitzen's avatar
Peter Leitzen committed
87
          get :proxy, params: environment_params
88

Peter Leitzen's avatar
Peter Leitzen committed
89
90
          expect(json_response['status']).to eq('processing')
          expect(json_response['message']).to eq('Not ready yet. Try again later.')
91
          expect(response).to have_gitlab_http_status(:no_content)
Peter Leitzen's avatar
Peter Leitzen committed
92
        end
93
94
      end

Peter Leitzen's avatar
Peter Leitzen committed
95
96
      context 'with 404 result' do
        let(:service_result) { { http_status: 404, status: :success, body: '{"body": "value"}' } }
97

Peter Leitzen's avatar
Peter Leitzen committed
98
99
        it 'returns body' do
          get :proxy, params: environment_params
100

Peter Leitzen's avatar
Peter Leitzen committed
101
102
103
          expect(response).to have_gitlab_http_status(:not_found)
          expect(json_response['body']).to eq('value')
        end
104
105
      end

Peter Leitzen's avatar
Peter Leitzen committed
106
107
108
109
110
      context 'with error result' do
        context 'with http_status' do
          let(:service_result) do
            { http_status: :service_unavailable, status: :error, message: 'error message' }
          end
111

Peter Leitzen's avatar
Peter Leitzen committed
112
113
          it 'sets the http response status code' do
            get :proxy, params: environment_params
114

Peter Leitzen's avatar
Peter Leitzen committed
115
116
117
118
            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
119
120
        end

Peter Leitzen's avatar
Peter Leitzen committed
121
122
        context 'without http_status' do
          let(:service_result) { { status: :error, message: 'error message' } }
123

Peter Leitzen's avatar
Peter Leitzen committed
124
125
          it 'returns bad_request' do
            get :proxy, params: environment_params
126

Peter Leitzen's avatar
Peter Leitzen committed
127
128
129
130
            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
131
132
133
134
        end
      end
    end

Peter Leitzen's avatar
Peter Leitzen committed
135
136
137
138
139
    context 'with inappropriate requests' do
      context 'with anonymous user' do
        before do
          sign_out(user)
        end
140

Peter Leitzen's avatar
Peter Leitzen committed
141
142
        it 'redirects to signin page' do
          get :proxy, params: environment_params
143

Peter Leitzen's avatar
Peter Leitzen committed
144
145
          expect(response).to redirect_to(new_user_session_path)
        end
146
147
      end

Peter Leitzen's avatar
Peter Leitzen committed
148
149
150
151
      context 'without correct permissions' do
        before do
          project.team.truncate
        end
152

Peter Leitzen's avatar
Peter Leitzen committed
153
154
        it 'returns 404' do
          get :proxy, params: environment_params
155

Peter Leitzen's avatar
Peter Leitzen committed
156
157
          expect(response).to have_gitlab_http_status(:not_found)
        end
158
159
      end
    end
160
161
162
163
164
165
166
167
168
169

    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
170
171
172
173
174
175
  end

  private

  def environment_params(params = {})
    {
176
      id: environment.id.to_s,
177
      namespace_id: project.namespace.full_path,
178
      project_id: project.name,
179
180
      proxy_path: 'query',
      query: '1'
181
    }.merge(params)
182
183
  end
end