additional_metrics_shared_examples.rb 6.05 KB
Newer Older
1 2
# frozen_string_literal: true

3 4 5
RSpec.shared_examples 'additional metrics query' do
  include Prometheus::MetricBuilders

6 7 8 9 10 11 12 13 14
  let(:metric_group_class) { Gitlab::Prometheus::MetricGroup }
  let(:metric_class) { Gitlab::Prometheus::Metric }

  let(:metric_names) { %w{metric_a metric_b} }

  let(:query_range_result) do
    [{ 'metric': {}, 'values': [[1488758662.506, '0.00002996364761904785'], [1488758722.506, '0.00003090239047619091']] }]
  end

15
  let(:client) { double('prometheus_client') }
16
  let(:query_result) { described_class.new(client).query(*query_params) }
17 18
  let(:project) { create(:project) }
  let(:environment) { create(:environment, slug: 'environment-slug', project: project) }
19

20 21
  before do
    allow(client).to receive(:label_values).and_return(metric_names)
22
    allow(metric_group_class).to receive(:common_metrics).and_return([simple_metric_group(metrics: [simple_metric])])
23 24
  end

25
  context 'metrics query context' do
26 27
    subject! { described_class.new(client) }

28
    shared_examples 'query context containing environment slug and filter' do
29
      it 'contains ci_environment_slug' do
30
        expect(subject).to receive(:query_metrics).with(project, environment, hash_including(ci_environment_slug: environment.slug))
31 32 33

        subject.query(*query_params)
      end
34

35
      it 'contains environment filter' do
36
        expect(subject).to receive(:query_metrics).with(
37
          project,
38
          environment,
39 40 41 42
          hash_including(
            environment_filter: "container_name!=\"POD\",environment=\"#{environment.slug}\""
          )
        )
43

44 45
        subject.query(*query_params)
      end
46 47
    end

48
    describe 'project has Kubernetes service' do
49 50 51
      context 'when user configured kubernetes from CI/CD > Clusters' do
        let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
        let(:project) { cluster.project }
52
        let(:environment) { create(:environment, slug: 'environment-slug', project: project) }
53
        let(:kube_namespace) { environment.deployment_namespace }
54

55
        it_behaves_like 'query context containing environment slug and filter'
56

57
        it 'query context contains kube_namespace' do
58
          expect(subject).to receive(:query_metrics).with(project, environment, hash_including(kube_namespace: kube_namespace))
59

60 61 62
          subject.query(*query_params)
        end
      end
63 64 65 66 67 68
    end

    describe 'project without Kubernetes service' do
      it_behaves_like 'query context containing environment slug and filter'

      it 'query context contains empty kube_namespace' do
69
        expect(subject).to receive(:query_metrics).with(project, environment, hash_including(kube_namespace: ''))
70

71 72 73 74 75
        subject.query(*query_params)
      end
    end
  end

76 77
  context 'with one group where two metrics is found' do
    before do
78
      allow(metric_group_class).to receive(:common_metrics).and_return([simple_metric_group])
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
    end

    context 'some queries return results' do
      before do
        allow(client).to receive(:query_range).with('query_range_a', any_args).and_return(query_range_result)
        allow(client).to receive(:query_range).with('query_range_b', any_args).and_return(query_range_result)
        allow(client).to receive(:query_range).with('query_range_empty', any_args).and_return([])
      end

      it 'return group data only for queries with results' do
        expected = [
          {
            group: 'name',
            priority: 1,
            metrics: [
              {
95
                title: 'title', weight: 1, y_label: 'Values', queries: [
96 97 98 99 100 101 102 103
                { query_range: 'query_range_a', result: query_range_result },
                { query_range: 'query_range_b', label: 'label', unit: 'unit', result: query_range_result }
              ]
              }
            ]
          }
        ]

104
        expect(query_result).to match_schema('prometheus/additional_metrics_query_result')
105 106 107 108 109 110 111
        expect(query_result).to eq(expected)
      end
    end
  end

  context 'with two groups with one metric each' do
    let(:metrics) { [simple_metric(queries: [simple_query])] }
112

113
    before do
114
      allow(metric_group_class).to receive(:common_metrics).and_return(
115 116 117 118 119 120 121 122 123 124 125 126 127 128
        [
          simple_metric_group(name: 'group_a', metrics: [simple_metric(queries: [simple_query])]),
          simple_metric_group(name: 'group_b', metrics: [simple_metric(title: 'title_b', queries: [simple_query('b')])])
        ])
      allow(client).to receive(:label_values).and_return(metric_names)
    end

    context 'both queries return results' do
      before do
        allow(client).to receive(:query_range).with('query_range_a', any_args).and_return(query_range_result)
        allow(client).to receive(:query_range).with('query_range_b', any_args).and_return(query_range_result)
      end

      it 'return group data both queries' do
129 130
        queries_with_result_a = { queries: [{ query_range: 'query_range_a', result: query_range_result }] }
        queries_with_result_b = { queries: [{ query_range: 'query_range_b', result: query_range_result }] }
131

132 133 134 135 136 137 138
        expect(query_result).to match_schema('prometheus/additional_metrics_query_result')

        expect(query_result.count).to eq(2)
        expect(query_result).to all(satisfy { |r| r[:metrics].count == 1 })

        expect(query_result[0][:metrics].first).to include(queries_with_result_a)
        expect(query_result[1][:metrics].first).to include(queries_with_result_b)
139 140 141 142 143 144 145 146 147 148
      end
    end

    context 'one query returns result' do
      before do
        allow(client).to receive(:query_range).with('query_range_a', any_args).and_return(query_range_result)
        allow(client).to receive(:query_range).with('query_range_b', any_args).and_return([])
      end

      it 'return group data only for query with results' do
149
        queries_with_result = { queries: [{ query_range: 'query_range_a', result: query_range_result }] }
150

151 152 153 154 155 156
        expect(query_result).to match_schema('prometheus/additional_metrics_query_result')

        expect(query_result.count).to eq(1)
        expect(query_result).to all(satisfy { |r| r[:metrics].count == 1 })

        expect(query_result.first[:metrics].first).to include(queries_with_result)
157 158 159
      end
    end
  end
160
end