BigW Consortium Gitlab

additional_metrics_shared_examples.rb 6.26 KB
Newer Older
1 2 3
RSpec.shared_examples 'additional metrics query' do
  include Prometheus::MetricBuilders

4 5 6 7 8 9 10 11 12
  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

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

17 18 19 20 21
  before do
    allow(client).to receive(:label_values).and_return(metric_names)
    allow(metric_group_class).to receive(:all).and_return([simple_metric_group(metrics: [simple_metric])])
  end

22
  context 'metrics query context' do
23 24
    subject! { described_class.new(client) }

25
    shared_examples 'query context containing environment slug and filter' do
26
      it 'contains ci_environment_slug' do
27 28 29 30
        expect(subject).to receive(:query_metrics).with(hash_including(ci_environment_slug: environment.slug))

        subject.query(*query_params)
      end
31

32
      it 'contains environment filter' do
33 34 35 36 37
        expect(subject).to receive(:query_metrics).with(
          hash_including(
            environment_filter: "container_name!=\"POD\",environment=\"#{environment.slug}\""
          )
        )
38

39 40
        subject.query(*query_params)
      end
41 42
    end

43
    describe 'project has Kubernetes service' do
44
      shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
45
        let(:environment) { create(:environment, slug: 'environment-slug', project: project) }
46
        let(:kube_namespace) { project.deployment_platform.actual_namespace }
47

48
        it_behaves_like 'query context containing environment slug and filter'
49

50 51
        it 'query context contains kube_namespace' do
          expect(subject).to receive(:query_metrics).with(hash_including(kube_namespace: kube_namespace))
52

53 54 55 56 57 58 59
          subject.query(*query_params)
        end
      end

      context 'when user configured kubernetes from Integration > Kubernetes' do
        let(:project) { create(:kubernetes_project) }

60
        it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
61 62 63 64 65 66
      end

      context 'when user configured kubernetes from CI/CD > Clusters' do
        let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
        let(:project) { cluster.project }

67
        it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
68 69 70 71 72 73 74 75 76
      end
    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
        expect(subject).to receive(:query_metrics).with(hash_including(kube_namespace: ''))

77 78 79 80 81
        subject.query(*query_params)
      end
    end
  end

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
  context 'with one group where two metrics is found' do
    before do
      allow(metric_group_class).to receive(:all).and_return([simple_metric_group])
    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: [
              {
101
                title: 'title', weight: 1, y_label: 'Values', queries: [
102 103 104 105 106 107 108 109
                { query_range: 'query_range_a', result: query_range_result },
                { query_range: 'query_range_b', label: 'label', unit: 'unit', result: query_range_result }
              ]
              }
            ]
          }
        ]

110
        expect(query_result).to match_schema('prometheus/additional_metrics_query_result')
111 112 113 114 115 116 117
        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])] }
118

119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
    before do
      allow(metric_group_class).to receive(:all).and_return(
        [
          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
135 136
        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 }] }
137

138 139 140 141 142 143 144
        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)
145 146 147 148 149 150 151 152 153 154
      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
155
        queries_with_result = { queries: [{ query_range: 'query_range_a', result: query_range_result }] }
156

157 158 159 160 161 162
        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)
163 164 165
      end
    end
  end
166
end