Move MetricsDashboard to Metrics::Dashboard
This commit is contained in:
parent
dde709912f
commit
4a5c48c47c
|
@ -160,7 +160,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
|||
def metrics_dashboard
|
||||
return render_403 unless Feature.enabled?(:environment_metrics_use_prometheus_endpoint, @project)
|
||||
|
||||
result = Gitlab::MetricsDashboard::Service.new(@project, @current_user, environment: environment).get_dashboard
|
||||
result = Gitlab::Metrics::Dashboard::Service.new(@project, @current_user, environment: environment).get_dashboard
|
||||
|
||||
respond_to do |format|
|
||||
if result[:status] == :success
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Metrics
|
||||
module Dashboard
|
||||
# Responsible for processesing a dashboard hash, inserting
|
||||
# relevant DB records & sorting for proper rendering in
|
||||
# the UI. These includes shared metric info, custom metrics
|
||||
# info, and alerts (only in EE).
|
||||
class Processor
|
||||
SEQUENCE = [
|
||||
Stages::CommonMetricsInserter,
|
||||
Stages::ProjectMetricsInserter,
|
||||
Stages::Sorter
|
||||
].freeze
|
||||
|
||||
def initialize(project, environment)
|
||||
@project = project
|
||||
@environment = environment
|
||||
end
|
||||
|
||||
# Returns a new dashboard hash with the results of
|
||||
# running transforms on the dashboard.
|
||||
def process(dashboard)
|
||||
dashboard = dashboard.deep_symbolize_keys
|
||||
|
||||
stage_params = [@project, @environment]
|
||||
sequence.each { |stage| stage.new(*stage_params).transform!(dashboard) }
|
||||
|
||||
dashboard
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sequence
|
||||
SEQUENCE
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Fetches the metrics dashboard layout and supplemented the output with DB info.
|
||||
module Gitlab
|
||||
module Metrics
|
||||
module Dashboard
|
||||
class Service < ::BaseService
|
||||
SYSTEM_DASHBOARD_NAME = 'common_metrics'
|
||||
SYSTEM_DASHBOARD_PATH = Rails.root.join('config', 'prometheus', "#{SYSTEM_DASHBOARD_NAME}.yml")
|
||||
|
||||
# Returns a DB-supplemented json representation of a dashboard config file.
|
||||
def get_dashboard
|
||||
dashboard_string = Rails.cache.fetch(cache_key) { system_dashboard }
|
||||
|
||||
dashboard = process_dashboard(dashboard_string)
|
||||
|
||||
success(dashboard: dashboard)
|
||||
rescue Gitlab::Metrics::Dashboard::Stages::BaseStage::DashboardLayoutError => e
|
||||
error(e.message, :unprocessable_entity)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Returns the base metrics shipped with every GitLab service.
|
||||
def system_dashboard
|
||||
YAML.load_file(SYSTEM_DASHBOARD_PATH)
|
||||
end
|
||||
|
||||
def cache_key
|
||||
"metrics_dashboard_#{SYSTEM_DASHBOARD_NAME}"
|
||||
end
|
||||
|
||||
# Returns a new dashboard Hash, supplemented with DB info
|
||||
def process_dashboard(dashboard)
|
||||
Processor.new(project, params[:environment]).process(dashboard)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,60 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Metrics
|
||||
module Dashboard
|
||||
module Stages
|
||||
class BaseStage
|
||||
DashboardLayoutError = Class.new(StandardError)
|
||||
|
||||
DEFAULT_PANEL_TYPE = 'area-chart'
|
||||
|
||||
attr_reader :project, :environment
|
||||
|
||||
def initialize(project, environment)
|
||||
@project = project
|
||||
@environment = environment
|
||||
end
|
||||
|
||||
# Entry-point to the stage
|
||||
# @param dashboard [Hash]
|
||||
# @param project [Project]
|
||||
# @param environment [Environment]
|
||||
def transform!(_dashboard)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def missing_panel_groups!
|
||||
raise DashboardLayoutError.new('Top-level key :panel_groups must be an array')
|
||||
end
|
||||
|
||||
def missing_panels!
|
||||
raise DashboardLayoutError.new('Each "panel_group" must define an array :panels')
|
||||
end
|
||||
|
||||
def missing_metrics!
|
||||
raise DashboardLayoutError.new('Each "panel" must define an array :metrics')
|
||||
end
|
||||
|
||||
def for_metrics(dashboard)
|
||||
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|
|
||||
missing_metrics! unless panel[:metrics].is_a?(Array)
|
||||
|
||||
panel[:metrics].each do |metric|
|
||||
yield metric
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Metrics
|
||||
module Dashboard
|
||||
module Stages
|
||||
class CommonMetricsInserter < BaseStage
|
||||
# For each metric in the dashboard config, attempts to
|
||||
# find a corresponding database record. If found,
|
||||
# includes the record's id in the dashboard config.
|
||||
def transform!(dashboard)
|
||||
common_metrics = ::PrometheusMetric.common
|
||||
|
||||
for_metrics(dashboard) do |metric|
|
||||
metric_record = common_metrics.find { |m| m.identifier == metric[:id] }
|
||||
metric[:metric_id] = metric_record.id if metric_record
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,106 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Metrics
|
||||
module Dashboard
|
||||
module Stages
|
||||
class ProjectMetricsInserter < BaseStage
|
||||
# Inserts project-specific metrics into the dashboard
|
||||
# config. If there are no project-specific metrics,
|
||||
# this will have no effect.
|
||||
def transform!(dashboard)
|
||||
project.prometheus_metrics.each do |project_metric|
|
||||
group = find_or_create_panel_group(dashboard[:panel_groups], project_metric)
|
||||
panel = find_or_create_panel(group[:panels], project_metric)
|
||||
find_or_create_metric(panel[:metrics], project_metric)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Looks for a panel_group corresponding to the
|
||||
# provided metric object. If unavailable, inserts one.
|
||||
# @param panel_groups [Array<Hash>]
|
||||
# @param metric [PrometheusMetric]
|
||||
def find_or_create_panel_group(panel_groups, metric)
|
||||
panel_group = find_panel_group(panel_groups, metric)
|
||||
return panel_group if panel_group
|
||||
|
||||
panel_group = new_panel_group(metric)
|
||||
panel_groups << panel_group
|
||||
|
||||
panel_group
|
||||
end
|
||||
|
||||
# Looks for a panel corresponding to the provided
|
||||
# metric object. If unavailable, inserts one.
|
||||
# @param panels [Array<Hash>]
|
||||
# @param metric [PrometheusMetric]
|
||||
def find_or_create_panel(panels, metric)
|
||||
panel = find_panel(panels, metric)
|
||||
return panel if panel
|
||||
|
||||
panel = new_panel(metric)
|
||||
panels << panel
|
||||
|
||||
panel
|
||||
end
|
||||
|
||||
# Looks for a metric corresponding to the provided
|
||||
# metric object. If unavailable, inserts one.
|
||||
# @param metrics [Array<Hash>]
|
||||
# @param metric [PrometheusMetric]
|
||||
def find_or_create_metric(metrics, metric)
|
||||
target_metric = find_metric(metrics, metric)
|
||||
return target_metric if target_metric
|
||||
|
||||
target_metric = new_metric(metric)
|
||||
metrics << target_metric
|
||||
|
||||
target_metric
|
||||
end
|
||||
|
||||
def find_panel_group(panel_groups, metric)
|
||||
return unless panel_groups
|
||||
|
||||
panel_groups.find { |group| group[:group] == metric.group_title }
|
||||
end
|
||||
|
||||
def find_panel(panels, metric)
|
||||
return unless panels
|
||||
|
||||
panel_identifiers = [DEFAULT_PANEL_TYPE, metric.title, metric.y_label]
|
||||
panels.find { |panel| panel.values_at(:type, :title, :y_label) == panel_identifiers }
|
||||
end
|
||||
|
||||
def find_metric(metrics, metric)
|
||||
return unless metrics
|
||||
|
||||
metrics.find { |m| m[:id] == metric.identifier }
|
||||
end
|
||||
|
||||
def new_panel_group(metric)
|
||||
{
|
||||
group: metric.group_title,
|
||||
priority: metric.priority,
|
||||
panels: []
|
||||
}
|
||||
end
|
||||
|
||||
def new_panel(metric)
|
||||
{
|
||||
type: DEFAULT_PANEL_TYPE,
|
||||
title: metric.title,
|
||||
y_label: metric.y_label,
|
||||
metrics: []
|
||||
}
|
||||
end
|
||||
|
||||
def new_metric(metric)
|
||||
metric.queries.first.merge(metric_id: metric.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Metrics
|
||||
module Dashboard
|
||||
module Stages
|
||||
class Sorter < BaseStage
|
||||
def transform!(dashboard)
|
||||
missing_panel_groups! unless dashboard[:panel_groups].is_a? Array
|
||||
|
||||
sort_groups!(dashboard)
|
||||
sort_panels!(dashboard)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Sorts the groups in the dashboard by the :priority key
|
||||
def sort_groups!(dashboard)
|
||||
dashboard[:panel_groups] = dashboard[:panel_groups].sort_by { |group| -group[:priority].to_i }
|
||||
end
|
||||
|
||||
# Sorts the panels in the dashboard by the :weight key
|
||||
def sort_panels!(dashboard)
|
||||
dashboard[:panel_groups].each do |group|
|
||||
missing_panels! unless group[:panels].is_a? Array
|
||||
|
||||
group[:panels] = group[:panels].sort_by { |panel| -panel[:weight].to_i }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,39 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module MetricsDashboard
|
||||
# Responsible for processesing a dashboard hash, inserting
|
||||
# relevant DB records & sorting for proper rendering in
|
||||
# the UI. These includes shared metric info, custom metrics
|
||||
# info, and alerts (only in EE).
|
||||
class Processor
|
||||
SEQUENCE = [
|
||||
Stages::CommonMetricsInserter,
|
||||
Stages::ProjectMetricsInserter,
|
||||
Stages::Sorter
|
||||
].freeze
|
||||
|
||||
def initialize(project, environment)
|
||||
@project = project
|
||||
@environment = environment
|
||||
end
|
||||
|
||||
# Returns a new dashboard hash with the results of
|
||||
# running transforms on the dashboard.
|
||||
def process(dashboard)
|
||||
dashboard = dashboard.deep_transform_keys(&:to_sym)
|
||||
|
||||
stage_params = [@project, @environment]
|
||||
sequence.each { |stage| stage.new(*stage_params).transform!(dashboard) }
|
||||
|
||||
dashboard
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sequence
|
||||
SEQUENCE
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,38 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Fetches the metrics dashboard layout and supplemented the output with DB info.
|
||||
module Gitlab
|
||||
module MetricsDashboard
|
||||
class Service < ::BaseService
|
||||
SYSTEM_DASHBOARD_NAME = 'common_metrics'
|
||||
SYSTEM_DASHBOARD_PATH = Rails.root.join('config', 'prometheus', "#{SYSTEM_DASHBOARD_NAME}.yml")
|
||||
|
||||
# Returns a DB-supplemented json representation of a dashboard config file.
|
||||
def get_dashboard
|
||||
dashboard_string = Rails.cache.fetch(cache_key) { system_dashboard }
|
||||
|
||||
dashboard = process_dashboard(dashboard_string)
|
||||
|
||||
success(dashboard: dashboard)
|
||||
rescue Gitlab::MetricsDashboard::Stages::BaseStage::DashboardLayoutError => e
|
||||
error(e.message, :unprocessable_entity)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Returns the base metrics shipped with every GitLab service.
|
||||
def system_dashboard
|
||||
YAML.load_file(SYSTEM_DASHBOARD_PATH)
|
||||
end
|
||||
|
||||
def cache_key
|
||||
"metrics_dashboard_#{SYSTEM_DASHBOARD_NAME}"
|
||||
end
|
||||
|
||||
# Returns a new dashboard Hash, supplemented with DB info
|
||||
def process_dashboard(dashboard)
|
||||
Processor.new(project, params[:environment]).process(dashboard)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,58 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module MetricsDashboard
|
||||
module Stages
|
||||
class BaseStage
|
||||
DashboardLayoutError = Class.new(StandardError)
|
||||
|
||||
DEFAULT_PANEL_TYPE = 'area-chart'
|
||||
|
||||
attr_reader :project, :environment
|
||||
|
||||
def initialize(project, environment)
|
||||
@project = project
|
||||
@environment = environment
|
||||
end
|
||||
|
||||
# Entry-point to the stage
|
||||
# @param dashboard [Hash]
|
||||
# @param project [Project]
|
||||
# @param environment [Environment]
|
||||
def transform!(_dashboard)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def missing_panel_groups!
|
||||
raise DashboardLayoutError.new('Top-level key :panel_groups must be an array')
|
||||
end
|
||||
|
||||
def missing_panels!
|
||||
raise DashboardLayoutError.new('Each "panel_group" must define an array :panels')
|
||||
end
|
||||
|
||||
def missing_metrics!
|
||||
raise DashboardLayoutError.new('Each "panel" must define an array :metrics')
|
||||
end
|
||||
|
||||
def for_metrics(dashboard)
|
||||
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|
|
||||
missing_metrics! unless panel[:metrics].is_a?(Array)
|
||||
|
||||
panel[:metrics].each do |metric|
|
||||
yield metric
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module MetricsDashboard
|
||||
module Stages
|
||||
class CommonMetricsInserter < BaseStage
|
||||
# For each metric in the dashboard config, attempts to
|
||||
# find a corresponding database record. If found,
|
||||
# includes the record's id in the dashboard config.
|
||||
def transform!(dashboard)
|
||||
common_metrics = ::PrometheusMetric.common
|
||||
|
||||
for_metrics(dashboard) do |metric|
|
||||
metric_record = common_metrics.find { |m| m.identifier == metric[:id] }
|
||||
metric[:metric_id] = metric_record.id if metric_record
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,104 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module MetricsDashboard
|
||||
module Stages
|
||||
class ProjectMetricsInserter < BaseStage
|
||||
# Inserts project-specific metrics into the dashboard
|
||||
# config. If there are no project-specific metrics,
|
||||
# this will have no effect.
|
||||
def transform!(dashboard)
|
||||
project.prometheus_metrics.each do |project_metric|
|
||||
group = find_or_create_panel_group(dashboard[:panel_groups], project_metric)
|
||||
panel = find_or_create_panel(group[:panels], project_metric)
|
||||
find_or_create_metric(panel[:metrics], project_metric)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Looks for a panel_group corresponding to the
|
||||
# provided metric object. If unavailable, inserts one.
|
||||
# @param panel_groups [Array<Hash>]
|
||||
# @param metric [PrometheusMetric]
|
||||
def find_or_create_panel_group(panel_groups, metric)
|
||||
panel_group = find_panel_group(panel_groups, metric)
|
||||
return panel_group if panel_group
|
||||
|
||||
panel_group = new_panel_group(metric)
|
||||
panel_groups << panel_group
|
||||
|
||||
panel_group
|
||||
end
|
||||
|
||||
# Looks for a panel corresponding to the provided
|
||||
# metric object. If unavailable, inserts one.
|
||||
# @param panels [Array<Hash>]
|
||||
# @param metric [PrometheusMetric]
|
||||
def find_or_create_panel(panels, metric)
|
||||
panel = find_panel(panels, metric)
|
||||
return panel if panel
|
||||
|
||||
panel = new_panel(metric)
|
||||
panels << panel
|
||||
|
||||
panel
|
||||
end
|
||||
|
||||
# Looks for a metric corresponding to the provided
|
||||
# metric object. If unavailable, inserts one.
|
||||
# @param metrics [Array<Hash>]
|
||||
# @param metric [PrometheusMetric]
|
||||
def find_or_create_metric(metrics, metric)
|
||||
target_metric = find_metric(metrics, metric)
|
||||
return target_metric if target_metric
|
||||
|
||||
target_metric = new_metric(metric)
|
||||
metrics << target_metric
|
||||
|
||||
target_metric
|
||||
end
|
||||
|
||||
def find_panel_group(panel_groups, metric)
|
||||
return unless panel_groups
|
||||
|
||||
panel_groups.find { |group| group[:group] == metric.group_title }
|
||||
end
|
||||
|
||||
def find_panel(panels, metric)
|
||||
return unless panels
|
||||
|
||||
panel_identifiers = [DEFAULT_PANEL_TYPE, metric.title, metric.y_label]
|
||||
panels.find { |panel| panel.values_at(:type, :title, :y_label) == panel_identifiers }
|
||||
end
|
||||
|
||||
def find_metric(metrics, metric)
|
||||
return unless metrics
|
||||
|
||||
metrics.find { |m| m[:id] == metric.identifier }
|
||||
end
|
||||
|
||||
def new_panel_group(metric)
|
||||
{
|
||||
group: metric.group_title,
|
||||
priority: metric.priority,
|
||||
panels: []
|
||||
}
|
||||
end
|
||||
|
||||
def new_panel(metric)
|
||||
{
|
||||
type: DEFAULT_PANEL_TYPE,
|
||||
title: metric.title,
|
||||
y_label: metric.y_label,
|
||||
metrics: []
|
||||
}
|
||||
end
|
||||
|
||||
def new_metric(metric)
|
||||
metric.queries.first.merge(metric_id: metric.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,32 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module MetricsDashboard
|
||||
module Stages
|
||||
class Sorter < BaseStage
|
||||
def transform!(dashboard)
|
||||
missing_panel_groups! unless dashboard[:panel_groups].is_a? Array
|
||||
|
||||
sort_groups!(dashboard)
|
||||
sort_panels!(dashboard)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Sorts the groups in the dashboard by the :priority key
|
||||
def sort_groups!(dashboard)
|
||||
dashboard[:panel_groups] = dashboard[:panel_groups].sort_by { |group| -group[:priority].to_i }
|
||||
end
|
||||
|
||||
# Sorts the panels in the dashboard by the :weight key
|
||||
def sort_panels!(dashboard)
|
||||
dashboard[:panel_groups].each do |group|
|
||||
missing_panels! unless group[:panels].is_a? Array
|
||||
|
||||
group[:panels] = group[:panels].sort_by { |panel| -panel[:weight].to_i }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,16 +1,12 @@
|
|||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"dashboard",
|
||||
"priority",
|
||||
"panel_groups"
|
||||
],
|
||||
"required": ["dashboard", "priority", "panel_groups"],
|
||||
"properties": {
|
||||
"dashboard": { "type": "string" },
|
||||
"priority": { "type": "number" },
|
||||
"panel_groups": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "spec/fixtures/lib/gitlab/metrics_dashboard/schemas/panel_groups.json" }
|
||||
"items": { "$ref": "spec/fixtures/lib/gitlab/metrics/dashboard/schemas/panel_groups.json" }
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::MetricsDashboard::Processor do
|
||||
describe Gitlab::Metrics::Dashboard::Processor do
|
||||
let(:project) { build(:project) }
|
||||
let(:environment) { build(:environment) }
|
||||
let(:dashboard_yml) { YAML.load_file('spec/fixtures/lib/gitlab/metrics_dashboard/sample_dashboard.yml') }
|
||||
let(:dashboard_yml) { YAML.load_file('spec/fixtures/lib/gitlab/metrics/dashboard/sample_dashboard.yml') }
|
||||
|
||||
describe 'process' do
|
||||
let(:process_params) { [project, environment] }
|
||||
|
@ -50,7 +50,7 @@ describe Gitlab::MetricsDashboard::Processor do
|
|||
|
||||
shared_examples_for 'errors with message' do |expected_message|
|
||||
it 'raises a DashboardLayoutError' do
|
||||
error_class = Gitlab::MetricsDashboard::Stages::BaseStage::DashboardLayoutError
|
||||
error_class = Gitlab::Metrics::Dashboard::Stages::BaseStage::DashboardLayoutError
|
||||
|
||||
expect { dashboard }.to raise_error(error_class, expected_message)
|
||||
end
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::MetricsDashboard::Service, :use_clean_rails_memory_store_caching do
|
||||
describe Gitlab::Metrics::Dashboard::Service, :use_clean_rails_memory_store_caching do
|
||||
let(:project) { build(:project) }
|
||||
let(:environment) { build(:environment) }
|
||||
|
||||
describe 'get_dashboard' do
|
||||
let(:dashboard_schema) { JSON.parse(fixture_file('lib/gitlab/metrics_dashboard/schemas/dashboard.json')) }
|
||||
let(:dashboard_schema) { JSON.parse(fixture_file('lib/gitlab/metrics/dashboard/schemas/dashboard.json')) }
|
||||
|
||||
it 'returns a json representation of the environment dashboard' do
|
||||
result = described_class.new(project, environment).get_dashboard
|
Loading…
Reference in New Issue