Commit 4a2c5f31 authored by Mikolaj Wawrzyniak's avatar Mikolaj Wawrzyniak

Add PanelIdsInserter stage for dashboards

When processing metrics dashboard structure from yml files
we need to insert id property to each panel.
parent aa8067bd
......@@ -37,10 +37,8 @@ module Gitlab
def for_metrics
missing_panel_groups! unless dashboard[:panel_groups].is_a?(Array)
dashboard[:panel_groups].each do |panel_group|
missing_panels! unless panel_group[:panels].is_a?(Array)
panel_group[:panels].each do |panel|
for_panel_groups do |panel_group|
for_panels_in(panel_group) do |panel|
missing_metrics! unless panel[:metrics].is_a?(Array)
panel[:metrics].each do |metric|
......@@ -49,6 +47,20 @@ module Gitlab
end
end
end
def for_panel_groups
dashboard[:panel_groups].each do |panel_group|
yield panel_group
end
end
def for_panels_in(panel_group)
missing_panels! unless panel_group[:panels].is_a?(Array)
panel_group[:panels].each do |panel|
yield panel
end
end
end
end
end
......
# frozen_string_literal: true
module Gitlab
module Metrics
module Dashboard
module Stages
class PanelIdsInserter < BaseStage
# For each panel within given dashboard inserts panel_id unique in scope of the dashboard
def transform!
missing_panel_groups! unless dashboard[:panel_groups]
for_panels_group_with_panels do |panel_group, panel|
id = generate_panel_id(panel_group, panel)
remove_panel_ids! && break if duplicated_panel_id?(id)
insert_panel_id(id, panel)
end
end
private
def generate_panel_id(group, panel)
::PerformanceMonitoring::PrometheusPanel.new(panel.with_indifferent_access).id(group[:group])
end
def insert_panel_id(id, panel)
track_inserted_panel_ids(id, panel)
panel[:id] = id
end
def track_inserted_panel_ids(id, panel)
panel_ids[id] = panel
end
def duplicated_panel_id?(id)
panel_ids.key?(id)
end
def remove_panel_ids!
panel_ids.each_value { |panel| panel.delete(:id) }
end
def panel_ids
@_panel_ids ||= {}
end
def for_panels_group_with_panels
for_panel_groups do |panel_group|
for_panels_in(panel_group) do |panel|
yield panel_group, panel
end
end
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Metrics::Dashboard::Stages::PanelIdsInserter do
let(:project) { build_stubbed(:project) }
def fetch_panel_ids(dashboard_hash)
dashboard_hash[:panel_groups].flat_map { |group| group[:panels].flat_map { |panel| panel[:id] } }
end
describe '#transform!' do
subject(:transform!) { described_class.new(project, dashboard, nil).transform! }
let(:dashboard) { YAML.safe_load(fixture_file('lib/gitlab/metrics/dashboard/sample_dashboard.yml')).deep_symbolize_keys }
context 'when dashboard panels are present' do
it 'assigns unique ids to each panel using PerformanceMonitoring::PrometheusPanel', :aggregate_failures do
dashboard.fetch(:panel_groups).each do |group|
group.fetch(:panels).each do |panel|
panel_double = instance_double(::PerformanceMonitoring::PrometheusPanel)
expect(::PerformanceMonitoring::PrometheusPanel).to receive(:new).with(panel).and_return(panel_double)
expect(panel_double).to receive(:id).with(group[:group]).and_return(FFaker::Lorem.unique.characters(125))
end
end
transform!
expect(fetch_panel_ids(dashboard)).not_to include nil
end
end
context 'when dashboard panels has duplicated ids' do
it 'no panel has assigned id' do
panel_double = instance_double(::PerformanceMonitoring::PrometheusPanel)
allow(::PerformanceMonitoring::PrometheusPanel).to receive(:new).and_return(panel_double)
allow(panel_double).to receive(:id).and_return('duplicated id')
transform!
expect(fetch_panel_ids(dashboard)).to all be_nil
expect(fetch_panel_ids(dashboard)).not_to include 'duplicated id'
end
end
context 'when there are no panels in the dashboard' do
it 'raises a processing error' do
dashboard[:panel_groups][0].delete(:panels)
expect { transform! }.to(
raise_error(::Gitlab::Metrics::Dashboard::Errors::DashboardProcessingError)
)
end
end
context 'when there are no panel_groups in the dashboard' do
it 'raises a processing error' do
dashboard.delete(:panel_groups)
expect { transform! }.to(
raise_error(::Gitlab::Metrics::Dashboard::Errors::DashboardProcessingError)
)
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment