Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
7f84fce54e
commit
a060caf3db
|
@ -91,21 +91,7 @@ export default {
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
activated() {
|
|
||||||
this.updateIcon();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
updateIcon() {
|
|
||||||
return document.querySelectorAll('.js-service-active-status').forEach((icon) => {
|
|
||||||
if (icon.dataset.value === this.activated.toString()) {
|
|
||||||
icon.classList.remove('d-none');
|
|
||||||
} else {
|
|
||||||
icon.classList.add('d-none');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetKey() {
|
resetKey() {
|
||||||
return axios
|
return axios
|
||||||
.put(this.formPath, { service: { token: '' } })
|
.put(this.formPath, { service: { token: '' } })
|
||||||
|
|
|
@ -806,3 +806,20 @@ export const dateAtFirstDayOfMonth = (date) => new Date(newDate(date).setDate(1)
|
||||||
* @return {Boolean} true if the dates match
|
* @return {Boolean} true if the dates match
|
||||||
*/
|
*/
|
||||||
export const datesMatch = (date1, date2) => differenceInMilliseconds(date1, date2) === 0;
|
export const datesMatch = (date1, date2) => differenceInMilliseconds(date1, date2) === 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility function which computes a formatted 24 hour
|
||||||
|
* time string from a positive int in the range 0 - 24.
|
||||||
|
*
|
||||||
|
* @param {Int} time a positive Int between 0 and 24
|
||||||
|
*
|
||||||
|
* @returns {String} formatted 24 hour time String
|
||||||
|
*/
|
||||||
|
export const format24HourTimeStringFromInt = (time) => {
|
||||||
|
if (!Number.isInteger(time) || time < 0 || time > 24) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatted24HourString = time > 9 ? `${time}:00` : `0${time}:00`;
|
||||||
|
return formatted24HourString;
|
||||||
|
};
|
||||||
|
|
|
@ -5,10 +5,8 @@
|
||||||
.col-lg-4
|
.col-lg-4
|
||||||
%h3.page-title.gl-mt-0
|
%h3.page-title.gl-mt-0
|
||||||
= @service.title
|
= @service.title
|
||||||
- [true, false].each do |value|
|
- if @service.operating?
|
||||||
- hide_class = 'd-none' if @service.operating? != value
|
= sprite_icon('check', css_class: 'gl-text-green-500')
|
||||||
%span.js-service-active-status{ class: hide_class, data: { value: value.to_s } }
|
|
||||||
= boolean_to_icon value
|
|
||||||
|
|
||||||
- if @service.respond_to?(:detailed_description)
|
- if @service.respond_to?(:detailed_description)
|
||||||
%p= @service.detailed_description
|
%p= @service.detailed_description
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
- activated_label = (integration.activated? ? s_("ProjectService|%{service_title}: status on") : s_("ProjectService|%{service_title}: status off")) % { service_title: integration.title }
|
- activated_label = (integration.activated? ? s_("ProjectService|%{service_title}: status on") : s_("ProjectService|%{service_title}: status off")) % { service_title: integration.title }
|
||||||
%tr{ role: 'row' }
|
%tr{ role: 'row' }
|
||||||
%td{ role: 'cell', 'aria-colindex': 1, 'aria-label': activated_label, title: activated_label }
|
%td{ role: 'cell', 'aria-colindex': 1, 'aria-label': activated_label, title: activated_label }
|
||||||
= boolean_to_icon integration.operating?
|
- if integration.operating?
|
||||||
|
= sprite_icon('check', css_class: 'gl-text-green-500')
|
||||||
%td{ role: 'cell', 'aria-colindex': 2 }
|
%td{ role: 'cell', 'aria-colindex': 2 }
|
||||||
= link_to integration.title, scoped_edit_integration_path(integration), class: 'gl-font-weight-bold', data: { qa_selector: "#{integration.to_param}_link" }
|
= link_to integration.title, scoped_edit_integration_path(integration), class: 'gl-font-weight-bold', data: { qa_selector: "#{integration.to_param}_link" }
|
||||||
%td.d-none.d-sm-table-cell{ role: 'cell', 'aria-colindex': 3 }
|
%td.d-none.d-sm-table-cell{ role: 'cell', 'aria-colindex': 3 }
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Remove inactive integrations indicator in index and show pages
|
||||||
|
merge_request: 50753
|
||||||
|
author:
|
||||||
|
type: changed
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Deprecate prometheus.listen_address and prometheus.enable
|
||||||
|
merge_request: 50500
|
||||||
|
author:
|
||||||
|
type: deprecated
|
|
@ -1207,10 +1207,7 @@ production: &base
|
||||||
# yourself, and then update the values here.
|
# yourself, and then update the values here.
|
||||||
# https://docs.gitlab.com/ee/administration/monitoring/prometheus/
|
# https://docs.gitlab.com/ee/administration/monitoring/prometheus/
|
||||||
prometheus:
|
prometheus:
|
||||||
# Do not use `enable` and `listen_address` in any new code, as they are deprecated. Use `server_address` instead.
|
# enabled: true
|
||||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/227111
|
|
||||||
# enable: true
|
|
||||||
# listen_address: 'localhost:9090'
|
|
||||||
# server_address: 'localhost:9090'
|
# server_address: 'localhost:9090'
|
||||||
|
|
||||||
## Consul settings
|
## Consul settings
|
||||||
|
@ -1499,8 +1496,8 @@ test:
|
||||||
group_base: 'ou=groups,dc=example,dc=com'
|
group_base: 'ou=groups,dc=example,dc=com'
|
||||||
admin_group: ''
|
admin_group: ''
|
||||||
prometheus:
|
prometheus:
|
||||||
enable: true
|
enabled: true
|
||||||
listen_address: 'localhost:9090'
|
server_address: 'localhost:9090'
|
||||||
|
|
||||||
staging:
|
staging:
|
||||||
<<: *base
|
<<: *base
|
||||||
|
|
|
@ -851,6 +851,18 @@ Settings.monitoring.web_exporter['enabled'] ||= false
|
||||||
Settings.monitoring.web_exporter['address'] ||= 'localhost'
|
Settings.monitoring.web_exporter['address'] ||= 'localhost'
|
||||||
Settings.monitoring.web_exporter['port'] ||= 8083
|
Settings.monitoring.web_exporter['port'] ||= 8083
|
||||||
|
|
||||||
|
#
|
||||||
|
# Prometheus settings
|
||||||
|
#
|
||||||
|
Settings['prometheus'] ||= Settingslogic.new({})
|
||||||
|
# TODO: Remove listen_address and enable in GitLab 14.0 and set default value
|
||||||
|
# of server_address to be nil and enabled to be false -
|
||||||
|
# https://gitlab.com/gitlab-org/gitlab/-/issues/296022
|
||||||
|
Settings.prometheus['enable'] ||= false
|
||||||
|
Settings.prometheus['listen_address'] ||= nil
|
||||||
|
Settings.prometheus['enabled'] = Settings.prometheus['enable'] if Settings.prometheus['enabled'].nil?
|
||||||
|
Settings.prometheus['server_address'] ||= Settings.prometheus['listen_address']
|
||||||
|
|
||||||
#
|
#
|
||||||
# Shutdown settings
|
# Shutdown settings
|
||||||
#
|
#
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
name: deployments
|
||||||
|
description: Total deployments count for recent 28 days
|
||||||
|
value_type: integer
|
||||||
|
stage: release
|
||||||
|
status: data_available
|
||||||
|
default_generation: generation_1
|
||||||
|
full_path:
|
||||||
|
generation_1: counts_monthy.deployments
|
||||||
|
milestone: 13.2
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35493
|
||||||
|
group: 'group::ops release'
|
||||||
|
time_frame: 28d
|
||||||
|
data_source: database
|
||||||
|
distribution: [ee, ce]
|
||||||
|
tier: ['free', 'starter', 'premium', 'ultimate', 'bronze', 'silver', 'gold']
|
|
@ -0,0 +1,16 @@
|
||||||
|
name: g_project_management_issue_title_changed_weekly
|
||||||
|
description: Distinct users count that changed issue title in a group for last recent week
|
||||||
|
value_type: integer
|
||||||
|
product_category: issue_tracking
|
||||||
|
stage: plan
|
||||||
|
status: data_available
|
||||||
|
default_generation: generation_1
|
||||||
|
full_path:
|
||||||
|
generation_1: redis_hll_counters.issues_edit.g_project_management_issue_title_changed_weekly
|
||||||
|
milestone: 13.6
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/229918
|
||||||
|
group: 'group::project management'
|
||||||
|
time_frame: 7d
|
||||||
|
data_source: redis_hll
|
||||||
|
distribution: [ee, ce]
|
||||||
|
tier: ['free', 'starter', 'premium', 'ultimate', 'bronze', 'silver', 'gold']
|
|
@ -0,0 +1,15 @@
|
||||||
|
name: deployments
|
||||||
|
description: Total deployments count
|
||||||
|
value_type: integer
|
||||||
|
stage: release
|
||||||
|
status: data_available
|
||||||
|
default_generation: generation_1
|
||||||
|
full_path:
|
||||||
|
generation_1: counts.deployments
|
||||||
|
milestone: 8.12
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/735
|
||||||
|
group: 'group::ops release'
|
||||||
|
time_frame: all
|
||||||
|
data_source: database
|
||||||
|
distribution: [ee, ce]
|
||||||
|
tier: ['free', 'starter', 'premium', 'ultimate', 'bronze', 'silver', 'gold']
|
|
@ -0,0 +1,16 @@
|
||||||
|
name: recorded_at
|
||||||
|
description: When the Usage Ping computation was started
|
||||||
|
value_type: string
|
||||||
|
product_category: collection
|
||||||
|
stage: growth
|
||||||
|
status: data_available
|
||||||
|
default_generation: generation_1
|
||||||
|
full_path:
|
||||||
|
generation_1: recorded_at
|
||||||
|
milestone: 8.10
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/557
|
||||||
|
group: group::product analytics
|
||||||
|
time_frame: none
|
||||||
|
data_source: ruby
|
||||||
|
distribution: [ee, ce]
|
||||||
|
tier: ['free', 'starter', 'premium', 'ultimate', 'bronze', 'silver', 'gold']
|
|
@ -0,0 +1,17 @@
|
||||||
|
name: uuid
|
||||||
|
description: GitLab instance unique identifier
|
||||||
|
value_type: string
|
||||||
|
product_category: collection
|
||||||
|
stage: growth
|
||||||
|
status: data_available
|
||||||
|
default_generation: generation_1
|
||||||
|
full_path:
|
||||||
|
generation_1: uuid
|
||||||
|
generation_2: license.uuid
|
||||||
|
milestone: 9.1
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1521
|
||||||
|
group: group::product analytics
|
||||||
|
time_frame: none
|
||||||
|
data_source: database
|
||||||
|
distribution: [ee, ce]
|
||||||
|
tier: ['free', 'starter', 'premium', 'ultimate', 'bronze', 'silver', 'gold']
|
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name", "description", "value_type", "status", "default_generation", "full_path", "group", "time_frame", "data_source", "distribution", "tier"],
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value_type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["integer", "string", "number", "boolean"]
|
||||||
|
},
|
||||||
|
"product_category": {
|
||||||
|
"type": ["string", "null"]
|
||||||
|
},
|
||||||
|
"stage": {
|
||||||
|
"type": ["string", "null"]
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": ["string"],
|
||||||
|
"enum": ["data_available", "planned", "in_progress", "implmented"]
|
||||||
|
},
|
||||||
|
"default_generation": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"full_path": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"milestone": {
|
||||||
|
"type": ["number", "null"]
|
||||||
|
},
|
||||||
|
"milestone_removed": {
|
||||||
|
"type": ["number", "null"]
|
||||||
|
},
|
||||||
|
"introduced_by_url": {
|
||||||
|
"type": ["string", "null"]
|
||||||
|
},
|
||||||
|
"group": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"time_frame": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["7d", "28d", "all", "none"]
|
||||||
|
},
|
||||||
|
"data_source": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["database", "redis", "redis_hll", "prometheus", "ruby"]
|
||||||
|
},
|
||||||
|
"distribution": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["ee", "ce"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tier": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["free", "starter", "premium", "ultimate", "bronze", "silver", "gold"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
name: adapter
|
||||||
|
description: This metric only returns a value of PostgreSQL in supported versions of GitLab. It could be removed from the usage ping. Historically MySQL was also supported.
|
||||||
|
value_type: string
|
||||||
|
product_category: collection
|
||||||
|
stage: growth
|
||||||
|
status: data_available
|
||||||
|
default_generation: generation_1
|
||||||
|
full_path:
|
||||||
|
generation_1: database.adapter
|
||||||
|
group: group::enablement distribution
|
||||||
|
time_frame: none
|
||||||
|
data_source: database
|
||||||
|
distribution: [ee, ce]
|
||||||
|
tier: ['free', 'starter', 'premium', 'ultimate', 'bronze', 'silver', 'gold']
|
|
@ -1,9 +1,15 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_relative 'base_linter'
|
|
||||||
|
|
||||||
emoji_checker_path = File.expand_path('emoji_checker', __dir__)
|
emoji_checker_path = File.expand_path('emoji_checker', __dir__)
|
||||||
defined?(Rails) ? require_dependency(emoji_checker_path) : require_relative(emoji_checker_path)
|
base_linter_path = File.expand_path('base_linter', __dir__)
|
||||||
|
|
||||||
|
if defined?(Rails)
|
||||||
|
require_dependency(base_linter_path)
|
||||||
|
require_dependency(emoji_checker_path)
|
||||||
|
else
|
||||||
|
require_relative(base_linter_path)
|
||||||
|
require_relative(emoji_checker_path)
|
||||||
|
end
|
||||||
|
|
||||||
module Gitlab
|
module Gitlab
|
||||||
module Danger
|
module Danger
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_relative 'base_linter'
|
base_linter_path = File.expand_path('base_linter', __dir__)
|
||||||
|
|
||||||
|
if defined?(Rails)
|
||||||
|
require_dependency(base_linter_path)
|
||||||
|
else
|
||||||
|
require_relative(base_linter_path)
|
||||||
|
end
|
||||||
|
|
||||||
module Gitlab
|
module Gitlab
|
||||||
module Danger
|
module Danger
|
||||||
|
|
|
@ -75,7 +75,7 @@ module Gitlab
|
||||||
|
|
||||||
if response
|
if response
|
||||||
# In the add_prometheus_manual_configuration method, the Prometheus
|
# In the add_prometheus_manual_configuration method, the Prometheus
|
||||||
# listen_address config is saved as an api_url in the PrometheusService
|
# server_address config is saved as an api_url in the PrometheusService
|
||||||
# model. There are validates hooks in the PrometheusService model that
|
# model. There are validates hooks in the PrometheusService model that
|
||||||
# check if the project associated with the PrometheusService is the
|
# check if the project associated with the PrometheusService is the
|
||||||
# self_monitoring project. It checks
|
# self_monitoring project. It checks
|
||||||
|
@ -105,7 +105,7 @@ module Gitlab
|
||||||
|
|
||||||
def add_prometheus_manual_configuration(result)
|
def add_prometheus_manual_configuration(result)
|
||||||
return success(result) unless prometheus_enabled?
|
return success(result) unless prometheus_enabled?
|
||||||
return success(result) unless prometheus_listen_address.present?
|
return success(result) unless prometheus_server_address.present?
|
||||||
|
|
||||||
service = result[:project].find_or_initialize_service('prometheus')
|
service = result[:project].find_or_initialize_service('prometheus')
|
||||||
|
|
||||||
|
@ -132,8 +132,8 @@ module Gitlab
|
||||||
::Gitlab::Prometheus::Internal.prometheus_enabled?
|
::Gitlab::Prometheus::Internal.prometheus_enabled?
|
||||||
end
|
end
|
||||||
|
|
||||||
def prometheus_listen_address
|
def prometheus_server_address
|
||||||
::Gitlab::Prometheus::Internal.listen_address
|
::Gitlab::Prometheus::Internal.server_address
|
||||||
end
|
end
|
||||||
|
|
||||||
def docs_path
|
def docs_path
|
||||||
|
@ -152,13 +152,13 @@ module Gitlab
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def internal_prometheus_listen_address_uri
|
def internal_prometheus_server_address_uri
|
||||||
::Gitlab::Prometheus::Internal.uri
|
::Gitlab::Prometheus::Internal.uri
|
||||||
end
|
end
|
||||||
|
|
||||||
def prometheus_service_attributes
|
def prometheus_service_attributes
|
||||||
{
|
{
|
||||||
api_url: internal_prometheus_listen_address_uri,
|
api_url: internal_prometheus_server_address_uri,
|
||||||
manual_configuration: true,
|
manual_configuration: true,
|
||||||
active: true
|
active: true
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,43 +4,39 @@ module Gitlab
|
||||||
module Prometheus
|
module Prometheus
|
||||||
class Internal
|
class Internal
|
||||||
def self.uri
|
def self.uri
|
||||||
return if listen_address.blank?
|
return if server_address.blank?
|
||||||
|
|
||||||
if listen_address.starts_with?('0.0.0.0:')
|
if server_address.starts_with?('0.0.0.0:')
|
||||||
# 0.0.0.0:9090
|
# 0.0.0.0:9090
|
||||||
port = ':' + listen_address.split(':').second
|
port = ':' + server_address.split(':').second
|
||||||
'http://localhost' + port
|
'http://localhost' + port
|
||||||
|
|
||||||
elsif listen_address.starts_with?(':')
|
elsif server_address.starts_with?(':')
|
||||||
# :9090
|
# :9090
|
||||||
'http://localhost' + listen_address
|
'http://localhost' + server_address
|
||||||
|
|
||||||
elsif listen_address.starts_with?('http')
|
elsif server_address.starts_with?('http')
|
||||||
# https://localhost:9090
|
# https://localhost:9090
|
||||||
listen_address
|
server_address
|
||||||
|
|
||||||
else
|
else
|
||||||
# localhost:9090
|
# localhost:9090
|
||||||
'http://' + listen_address
|
'http://' + server_address
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.server_address
|
def self.server_address
|
||||||
uri&.strip&.sub(/^http[s]?:\/\//, '')
|
Gitlab.config.prometheus.server_address.to_s if Gitlab.config.prometheus
|
||||||
end
|
|
||||||
|
|
||||||
def self.listen_address
|
|
||||||
Gitlab.config.prometheus.listen_address.to_s if Gitlab.config.prometheus
|
|
||||||
rescue Settingslogic::MissingSetting
|
rescue Settingslogic::MissingSetting
|
||||||
Gitlab::AppLogger.error('Prometheus listen_address is not present in config/gitlab.yml')
|
Gitlab::AppLogger.error('Prometheus server_address is not present in config/gitlab.yml')
|
||||||
|
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.prometheus_enabled?
|
def self.prometheus_enabled?
|
||||||
Gitlab.config.prometheus.enable if Gitlab.config.prometheus
|
Gitlab.config.prometheus.enabled if Gitlab.config.prometheus
|
||||||
rescue Settingslogic::MissingSetting
|
rescue Settingslogic::MissingSetting
|
||||||
Gitlab::AppLogger.error('prometheus.enable is not present in config/gitlab.yml')
|
Gitlab::AppLogger.error('prometheus.enabled is not present in config/gitlab.yml')
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Gitlab
|
||||||
|
module Usage
|
||||||
|
class Metric
|
||||||
|
include ActiveModel::Model
|
||||||
|
|
||||||
|
InvalidMetricError = Class.new(RuntimeError)
|
||||||
|
|
||||||
|
attr_accessor :default_generation_path, :value
|
||||||
|
|
||||||
|
validates :default_generation_path, presence: true
|
||||||
|
|
||||||
|
def definition
|
||||||
|
self.class.definitions[default_generation_path]
|
||||||
|
end
|
||||||
|
|
||||||
|
def unflatten_default_path
|
||||||
|
unflatten(default_generation_path.split('.'), value)
|
||||||
|
end
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def definitions
|
||||||
|
@definitions ||= Gitlab::Usage::MetricDefinition.definitions
|
||||||
|
end
|
||||||
|
|
||||||
|
def dictionary
|
||||||
|
definitions.map { |key, definition| definition.to_dictionary }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def unflatten(keys, value)
|
||||||
|
loop do
|
||||||
|
value = { keys.pop.to_sym => value }
|
||||||
|
break if keys.blank?
|
||||||
|
end
|
||||||
|
value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,84 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Gitlab
|
||||||
|
module Usage
|
||||||
|
class MetricDefinition
|
||||||
|
METRIC_SCHEMA_PATH = Rails.root.join('config', 'metrics', 'schema.json')
|
||||||
|
|
||||||
|
attr_reader :path
|
||||||
|
attr_reader :attributes
|
||||||
|
|
||||||
|
def initialize(path, opts = {})
|
||||||
|
@path = path
|
||||||
|
@attributes = opts
|
||||||
|
end
|
||||||
|
|
||||||
|
# The key is defined by default_generation and full_path
|
||||||
|
def key
|
||||||
|
full_path[default_generation.to_sym]
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_h
|
||||||
|
attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate!
|
||||||
|
self.class.schemer.validate(attributes.stringify_keys).map do |error|
|
||||||
|
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(Metric::InvalidMetricError.new("#{error["details"] || error['data_pointer']} for `#{path}`"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :to_dictionary, :to_h
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def paths
|
||||||
|
@paths ||= [Rails.root.join('config', 'metrics', '**', '*.yml')]
|
||||||
|
end
|
||||||
|
|
||||||
|
def definitions
|
||||||
|
@definitions ||= load_all!
|
||||||
|
end
|
||||||
|
|
||||||
|
def schemer
|
||||||
|
@schemer ||= ::JSONSchemer.schema(Pathname.new(METRIC_SCHEMA_PATH))
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_all!
|
||||||
|
paths.each_with_object({}) do |glob_path, definitions|
|
||||||
|
load_all_from_path!(definitions, glob_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_from_file(path)
|
||||||
|
definition = File.read(path)
|
||||||
|
definition = YAML.safe_load(definition)
|
||||||
|
definition.deep_symbolize_keys!
|
||||||
|
|
||||||
|
self.new(path, definition).tap(&:validate!)
|
||||||
|
rescue => e
|
||||||
|
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(Metric::InvalidMetricError.new(e.message))
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_all_from_path!(definitions, glob_path)
|
||||||
|
Dir.glob(glob_path).each do |path|
|
||||||
|
definition = load_from_file(path)
|
||||||
|
|
||||||
|
if previous = definitions[definition.key]
|
||||||
|
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(Metric::InvalidMetricError.new("Metric '#{definition.key}' is already defined in '#{previous.path}'"))
|
||||||
|
end
|
||||||
|
|
||||||
|
definitions[definition.key] = definition
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def method_missing(method, *args)
|
||||||
|
attributes[method] || super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -145,7 +145,8 @@ module Gitlab
|
||||||
|
|
||||||
def prometheus_server_address
|
def prometheus_server_address
|
||||||
if Gitlab::Prometheus::Internal.prometheus_enabled?
|
if Gitlab::Prometheus::Internal.prometheus_enabled?
|
||||||
Gitlab::Prometheus::Internal.server_address
|
# Stripping protocol from URI
|
||||||
|
Gitlab::Prometheus::Internal.uri&.strip&.sub(%r{^https?://}, '')
|
||||||
elsif Gitlab::Consul::Internal.api_url
|
elsif Gitlab::Consul::Internal.api_url
|
||||||
Gitlab::Consul::Internal.discover_prometheus_server_address
|
Gitlab::Consul::Internal.discover_prometheus_server_address
|
||||||
end
|
end
|
||||||
|
|
|
@ -19535,6 +19535,15 @@ msgstr ""
|
||||||
msgid "OnCallSchedules|Sets the default timezone for the schedule, for all participants"
|
msgid "OnCallSchedules|Sets the default timezone for the schedule, for all participants"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "OnCallSchedules|Successfully created a new rotation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "OnCallSchedules|Successfully edited your rotation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "OnCallSchedules|The rotation could not be updated. Please try again."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "OnCallSchedules|The schedule could not be deleted. Please try again."
|
msgid "OnCallSchedules|The schedule could not be deleted. Please try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ RSpec.describe 'User activates Alerts', :js do
|
||||||
click_link(service_title)
|
click_link(service_title)
|
||||||
|
|
||||||
expect(page).to have_callout_message
|
expect(page).to have_callout_message
|
||||||
expect(page).not_to have_active_service
|
|
||||||
expect(page).to have_toggle_active_disabled
|
expect(page).to have_toggle_active_disabled
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -38,7 +37,6 @@ RSpec.describe 'User activates Alerts', :js do
|
||||||
|
|
||||||
it 'user cannot change settings' do
|
it 'user cannot change settings' do
|
||||||
expect(page).to have_callout_message
|
expect(page).to have_callout_message
|
||||||
expect(page).to have_active_service
|
|
||||||
expect(page).to have_toggle_active_disabled
|
expect(page).to have_toggle_active_disabled
|
||||||
expect(page).to have_button_reset_key_disabled
|
expect(page).to have_button_reset_key_disabled
|
||||||
end
|
end
|
||||||
|
@ -60,10 +58,6 @@ RSpec.describe 'User activates Alerts', :js do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def have_active_service
|
|
||||||
have_selector('.js-service-active-status[data-value="true"]')
|
|
||||||
end
|
|
||||||
|
|
||||||
def have_toggle_active_disabled
|
def have_toggle_active_disabled
|
||||||
have_selector('#activated .project-feature-toggle.is-disabled')
|
have_selector('#activated .project-feature-toggle.is-disabled')
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,16 +35,9 @@ describe('AlertsServiceForm', () => {
|
||||||
const findUrl = () => wrapper.find('#url');
|
const findUrl = () => wrapper.find('#url');
|
||||||
const findAuthorizationKey = () => wrapper.find('#authorization-key');
|
const findAuthorizationKey = () => wrapper.find('#authorization-key');
|
||||||
const findDescription = () => wrapper.find('[data-testid="description"');
|
const findDescription = () => wrapper.find('[data-testid="description"');
|
||||||
const findActiveStatusIcon = (val) =>
|
|
||||||
document.querySelector(`.js-service-active-status[data-value=${val.toString()}]`);
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockAxios = new MockAdapter(axios);
|
mockAxios = new MockAdapter(axios);
|
||||||
setFixtures(`
|
|
||||||
<div>
|
|
||||||
<span class="js-service-active-status" data-value="true"><svg class="s16 cgreen" data-testid="check-icon"><use xlink:href="icons.svg#check" /></svg></span>
|
|
||||||
<span class="js-service-active-status" data-value="false"><svg class="s16 clgray" data-testid="power-icon"><use xlink:href="icons.svg#power" /></svg></span>
|
|
||||||
</div>`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -124,11 +117,6 @@ describe('AlertsServiceForm', () => {
|
||||||
it(`updates toggle button value to ${value}`, () => {
|
it(`updates toggle button value to ${value}`, () => {
|
||||||
expect(wrapper.find(ToggleButton).props('value')).toBe(value);
|
expect(wrapper.find(ToggleButton).props('value')).toBe(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updates visible status icons', () => {
|
|
||||||
expect(findActiveStatusIcon(!value)).toHaveClass('d-none');
|
|
||||||
expect(findActiveStatusIcon(value)).not.toHaveClass('d-none');
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -731,3 +731,28 @@ describe('datesMatch', () => {
|
||||||
expect(datetimeUtility.datesMatch(date1, date2)).toBe(expected);
|
expect(datetimeUtility.datesMatch(date1, date2)).toBe(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('format24HourTimeStringFromInt', () => {
|
||||||
|
const expectedFormattedTimes = [
|
||||||
|
[0, '00:00'],
|
||||||
|
[2, '02:00'],
|
||||||
|
[6, '06:00'],
|
||||||
|
[9, '09:00'],
|
||||||
|
[10, '10:00'],
|
||||||
|
[16, '16:00'],
|
||||||
|
[22, '22:00'],
|
||||||
|
[32, ''],
|
||||||
|
[NaN, ''],
|
||||||
|
['Invalid Int', ''],
|
||||||
|
[null, ''],
|
||||||
|
[undefined, ''],
|
||||||
|
];
|
||||||
|
|
||||||
|
expectedFormattedTimes.forEach(([timeInt, expectedTimeStringIn24HourNotation]) => {
|
||||||
|
it(`formats ${timeInt} as ${expectedTimeStringIn24HourNotation}`, () => {
|
||||||
|
expect(datetimeUtility.format24HourTimeStringFromInt(timeInt)).toBe(
|
||||||
|
expectedTimeStringIn24HourNotation,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -8,8 +8,8 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService
|
||||||
|
|
||||||
let(:prometheus_settings) do
|
let(:prometheus_settings) do
|
||||||
{
|
{
|
||||||
enable: true,
|
enabled: true,
|
||||||
listen_address: 'localhost:9090'
|
server_address: 'localhost:9090'
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -63,13 +63,13 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService
|
||||||
application_setting.update(allow_local_requests_from_web_hooks_and_services: true)
|
application_setting.update(allow_local_requests_from_web_hooks_and_services: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'has prometheus service' do |listen_address|
|
shared_examples 'has prometheus service' do |server_address|
|
||||||
it do
|
it do
|
||||||
expect(result[:status]).to eq(:success)
|
expect(result[:status]).to eq(:success)
|
||||||
|
|
||||||
prometheus = project.prometheus_service
|
prometheus = project.prometheus_service
|
||||||
expect(prometheus).not_to eq(nil)
|
expect(prometheus).not_to eq(nil)
|
||||||
expect(prometheus.api_url).to eq(listen_address)
|
expect(prometheus.api_url).to eq(server_address)
|
||||||
expect(prometheus.active).to eq(true)
|
expect(prometheus.active).to eq(true)
|
||||||
expect(prometheus.manual_configuration).to eq(true)
|
expect(prometheus.manual_configuration).to eq(true)
|
||||||
end
|
end
|
||||||
|
@ -202,25 +202,25 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with non default prometheus address' do
|
context 'with non default prometheus address' do
|
||||||
let(:listen_address) { 'https://localhost:9090' }
|
let(:server_address) { 'https://localhost:9090' }
|
||||||
|
|
||||||
let(:prometheus_settings) do
|
let(:prometheus_settings) do
|
||||||
{
|
{
|
||||||
enable: true,
|
enabled: true,
|
||||||
listen_address: listen_address
|
server_address: server_address
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'has prometheus service', 'https://localhost:9090'
|
it_behaves_like 'has prometheus service', 'https://localhost:9090'
|
||||||
|
|
||||||
context 'with :9090 symbol' do
|
context 'with :9090 symbol' do
|
||||||
let(:listen_address) { :':9090' }
|
let(:server_address) { :':9090' }
|
||||||
|
|
||||||
it_behaves_like 'has prometheus service', 'http://localhost:9090'
|
it_behaves_like 'has prometheus service', 'http://localhost:9090'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with 0.0.0.0:9090' do
|
context 'with 0.0.0.0:9090' do
|
||||||
let(:listen_address) { '0.0.0.0:9090' }
|
let(:server_address) { '0.0.0.0:9090' }
|
||||||
|
|
||||||
it_behaves_like 'has prometheus service', 'http://localhost:9090'
|
it_behaves_like 'has prometheus service', 'http://localhost:9090'
|
||||||
end
|
end
|
||||||
|
@ -251,8 +251,8 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService
|
||||||
context 'when prometheus setting is disabled in gitlab.yml' do
|
context 'when prometheus setting is disabled in gitlab.yml' do
|
||||||
let(:prometheus_settings) do
|
let(:prometheus_settings) do
|
||||||
{
|
{
|
||||||
enable: false,
|
enabled: false,
|
||||||
listen_address: 'http://localhost:9090'
|
server_address: 'http://localhost:9090'
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -262,8 +262,8 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when prometheus listen address is blank in gitlab.yml' do
|
context 'when prometheus server address is blank in gitlab.yml' do
|
||||||
let(:prometheus_settings) { { enable: true, listen_address: '' } }
|
let(:prometheus_settings) { { enabled: true, server_address: '' } }
|
||||||
|
|
||||||
it 'does not configure prometheus' do
|
it 'does not configure prometheus' do
|
||||||
expect(result).to include(status: :success)
|
expect(result).to include(status: :success)
|
||||||
|
@ -296,8 +296,8 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService
|
||||||
context 'when prometheus manual configuration cannot be saved' do
|
context 'when prometheus manual configuration cannot be saved' do
|
||||||
let(:prometheus_settings) do
|
let(:prometheus_settings) do
|
||||||
{
|
{
|
||||||
enable: true,
|
enabled: true,
|
||||||
listen_address: 'httpinvalid://localhost:9090'
|
server_address: 'httpinvalid://localhost:9090'
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe Gitlab::Prometheus::Internal do
|
RSpec.describe Gitlab::Prometheus::Internal do
|
||||||
let(:listen_address) { 'localhost:9090' }
|
let(:server_address) { 'localhost:9090' }
|
||||||
|
|
||||||
let(:prometheus_settings) do
|
let(:prometheus_settings) do
|
||||||
{
|
{
|
||||||
enable: true,
|
enabled: true,
|
||||||
listen_address: listen_address
|
server_address: server_address
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -27,25 +27,25 @@ RSpec.describe Gitlab::Prometheus::Internal do
|
||||||
it_behaves_like 'returns valid uri', 'http://localhost:9090'
|
it_behaves_like 'returns valid uri', 'http://localhost:9090'
|
||||||
|
|
||||||
context 'with non default prometheus address' do
|
context 'with non default prometheus address' do
|
||||||
let(:listen_address) { 'https://localhost:9090' }
|
let(:server_address) { 'https://localhost:9090' }
|
||||||
|
|
||||||
it_behaves_like 'returns valid uri', 'https://localhost:9090'
|
it_behaves_like 'returns valid uri', 'https://localhost:9090'
|
||||||
|
|
||||||
context 'with :9090 symbol' do
|
context 'with :9090 symbol' do
|
||||||
let(:listen_address) { :':9090' }
|
let(:server_address) { :':9090' }
|
||||||
|
|
||||||
it_behaves_like 'returns valid uri', 'http://localhost:9090'
|
it_behaves_like 'returns valid uri', 'http://localhost:9090'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with 0.0.0.0:9090' do
|
context 'with 0.0.0.0:9090' do
|
||||||
let(:listen_address) { '0.0.0.0:9090' }
|
let(:server_address) { '0.0.0.0:9090' }
|
||||||
|
|
||||||
it_behaves_like 'returns valid uri', 'http://localhost:9090'
|
it_behaves_like 'returns valid uri', 'http://localhost:9090'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when listen_address is nil' do
|
context 'when server_address is nil' do
|
||||||
let(:listen_address) { nil }
|
let(:server_address) { nil }
|
||||||
|
|
||||||
it 'does not fail' do
|
it 'does not fail' do
|
||||||
expect(described_class.uri).to be_nil
|
expect(described_class.uri).to be_nil
|
||||||
|
@ -53,7 +53,7 @@ RSpec.describe Gitlab::Prometheus::Internal do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when prometheus listen address is blank in gitlab.yml' do
|
context 'when prometheus listen address is blank in gitlab.yml' do
|
||||||
let(:listen_address) { '' }
|
let(:server_address) { '' }
|
||||||
|
|
||||||
it 'does not configure prometheus' do
|
it 'does not configure prometheus' do
|
||||||
expect(described_class.uri).to be_nil
|
expect(described_class.uri).to be_nil
|
||||||
|
@ -61,26 +61,6 @@ RSpec.describe Gitlab::Prometheus::Internal do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.server_address' do
|
|
||||||
context 'self.uri returns valid uri' do
|
|
||||||
['http://localhost:9090', 'https://localhost:9090 '].each do |valid_uri|
|
|
||||||
it 'returns correct server address' do
|
|
||||||
expect(described_class).to receive(:uri).and_return(valid_uri)
|
|
||||||
|
|
||||||
expect(described_class.server_address).to eq('localhost:9090')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'self.uri returns nil' do
|
|
||||||
it 'returns nil' do
|
|
||||||
expect(described_class).to receive(:uri).and_return(nil)
|
|
||||||
|
|
||||||
expect(described_class.server_address).to be_nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.prometheus_enabled?' do
|
describe '.prometheus_enabled?' do
|
||||||
it 'returns correct value' do
|
it 'returns correct value' do
|
||||||
expect(described_class.prometheus_enabled?).to eq(true)
|
expect(described_class.prometheus_enabled?).to eq(true)
|
||||||
|
@ -89,8 +69,8 @@ RSpec.describe Gitlab::Prometheus::Internal do
|
||||||
context 'when prometheus setting is disabled in gitlab.yml' do
|
context 'when prometheus setting is disabled in gitlab.yml' do
|
||||||
let(:prometheus_settings) do
|
let(:prometheus_settings) do
|
||||||
{
|
{
|
||||||
enable: false,
|
enabled: false,
|
||||||
listen_address: listen_address
|
server_address: server_address
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -110,9 +90,9 @@ RSpec.describe Gitlab::Prometheus::Internal do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.listen_address' do
|
describe '.server_address' do
|
||||||
it 'returns correct value' do
|
it 'returns correct value' do
|
||||||
expect(described_class.listen_address).to eq(listen_address)
|
expect(described_class.server_address).to eq(server_address)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when prometheus setting is not present in gitlab.yml' do
|
context 'when prometheus setting is not present in gitlab.yml' do
|
||||||
|
@ -121,7 +101,7 @@ RSpec.describe Gitlab::Prometheus::Internal do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not fail' do
|
it 'does not fail' do
|
||||||
expect(described_class.listen_address).to be_nil
|
expect(described_class.server_address).to be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.describe Gitlab::Usage::MetricDefinition do
|
||||||
|
let(:attributes) do
|
||||||
|
{
|
||||||
|
name: 'uuid',
|
||||||
|
description: 'GitLab instance unique identifier',
|
||||||
|
value_type: 'string',
|
||||||
|
product_category: 'collection',
|
||||||
|
stage: 'growth',
|
||||||
|
status: 'data_available',
|
||||||
|
default_generation: 'generation_1',
|
||||||
|
full_path: {
|
||||||
|
generation_1: 'uuid',
|
||||||
|
generation_2: 'license.uuid'
|
||||||
|
},
|
||||||
|
group: 'group::product analytics',
|
||||||
|
time_frame: 'none',
|
||||||
|
data_source: 'database',
|
||||||
|
distribution: %w(ee ce),
|
||||||
|
tier: %w(free starter premium ultimate bronze silver gold)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:path) { File.join('metrics', 'uuid.yml') }
|
||||||
|
let(:definition) { described_class.new(path, attributes) }
|
||||||
|
let(:yaml_content) { attributes.deep_stringify_keys.to_yaml }
|
||||||
|
|
||||||
|
it 'has all definitons valid' do
|
||||||
|
expect { described_class.definitions }.not_to raise_error(Gitlab::Usage::Metric::InvalidMetricError)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#key' do
|
||||||
|
subject { definition.key }
|
||||||
|
|
||||||
|
it 'returns a symbol from name' do
|
||||||
|
is_expected.to eq('uuid')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#validate' do
|
||||||
|
using RSpec::Parameterized::TableSyntax
|
||||||
|
|
||||||
|
where(:attribute, :value) do
|
||||||
|
:name | nil
|
||||||
|
:description | nil
|
||||||
|
:value_type | nil
|
||||||
|
:value_type | 'test'
|
||||||
|
:status | nil
|
||||||
|
:default_generation | nil
|
||||||
|
:group | nil
|
||||||
|
:time_frame | nil
|
||||||
|
:time_frame | '29d'
|
||||||
|
:data_source | 'other'
|
||||||
|
:data_source | nil
|
||||||
|
:distribution | nil
|
||||||
|
:distribution | 'test'
|
||||||
|
:tier | %w(test ee)
|
||||||
|
end
|
||||||
|
|
||||||
|
with_them do
|
||||||
|
before do
|
||||||
|
attributes[attribute] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'raise exception' do
|
||||||
|
expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).at_least(:once).with(instance_of(Gitlab::Usage::Metric::InvalidMetricError))
|
||||||
|
|
||||||
|
described_class.new(path, attributes).validate!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.load_all!' do
|
||||||
|
let(:metric1) { Dir.mktmpdir('metric1') }
|
||||||
|
let(:metric2) { Dir.mktmpdir('metric2') }
|
||||||
|
let(:definitions) { {} }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(described_class).to receive(:paths).and_return(
|
||||||
|
[
|
||||||
|
File.join(metric1, '**', '*.yml'),
|
||||||
|
File.join(metric2, '**', '*.yml')
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
subject { described_class.send(:load_all!) }
|
||||||
|
|
||||||
|
it 'has empty list when there are no definition files' do
|
||||||
|
is_expected.to be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has one metric when there is one file' do
|
||||||
|
write_metric(metric1, path, yaml_content)
|
||||||
|
|
||||||
|
is_expected.to be_one
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'when the same meric is defined multiple times raises exception' do
|
||||||
|
write_metric(metric1, path, yaml_content)
|
||||||
|
write_metric(metric2, path, yaml_content)
|
||||||
|
|
||||||
|
expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).with(instance_of(Gitlab::Usage::Metric::InvalidMetricError))
|
||||||
|
|
||||||
|
subject
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
FileUtils.rm_rf(metric1)
|
||||||
|
FileUtils.rm_rf(metric2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def write_metric(metric, path, content)
|
||||||
|
path = File.join(metric, path)
|
||||||
|
dir = File.dirname(path)
|
||||||
|
FileUtils.mkdir_p(dir)
|
||||||
|
File.write(path, content)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,29 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.describe Gitlab::Usage::Metric do
|
||||||
|
describe '#definition' do
|
||||||
|
it 'returns generation_1 metric definiton' do
|
||||||
|
expect(described_class.new(default_generation_path: 'uuid').definition).to be_an(Gitlab::Usage::MetricDefinition)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#unflatten_default_path' do
|
||||||
|
using RSpec::Parameterized::TableSyntax
|
||||||
|
|
||||||
|
where(:default_generation_path, :value, :expected_hash) do
|
||||||
|
'uuid' | nil | { uuid: nil }
|
||||||
|
'uuid' | '1111' | { uuid: '1111' }
|
||||||
|
'counts.issues' | nil | { counts: { issues: nil } }
|
||||||
|
'counts.issues' | 100 | { counts: { issues: 100 } }
|
||||||
|
'usage_activity_by_stage.verify.ci_builds' | 100 | { usage_activity_by_stage: { verify: { ci_builds: 100 } } }
|
||||||
|
end
|
||||||
|
|
||||||
|
with_them do
|
||||||
|
subject { described_class.new(default_generation_path: default_generation_path, value: value).unflatten_default_path }
|
||||||
|
|
||||||
|
it { is_expected.to eq(expected_hash) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -284,7 +284,7 @@ RSpec.describe Gitlab::Utils::UsageData do
|
||||||
context 'when Prometheus server address is available from settings' do
|
context 'when Prometheus server address is available from settings' do
|
||||||
before do
|
before do
|
||||||
expect(Gitlab::Prometheus::Internal).to receive(:prometheus_enabled?).and_return(true)
|
expect(Gitlab::Prometheus::Internal).to receive(:prometheus_enabled?).and_return(true)
|
||||||
expect(Gitlab::Prometheus::Internal).to receive(:server_address).and_return('prom:9090')
|
expect(Gitlab::Prometheus::Internal).to receive(:uri).and_return('http://prom:9090')
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'try to query Prometheus with given address'
|
it_behaves_like 'try to query Prometheus with given address'
|
||||||
|
|
|
@ -95,7 +95,7 @@ RSpec.describe PrometheusService, :use_clean_rails_memory_store_caching, :snowpl
|
||||||
service.api_url = 'http://localhost:9090'
|
service.api_url = 'http://localhost:9090'
|
||||||
|
|
||||||
stub_application_setting(self_monitoring_project_id: project.id)
|
stub_application_setting(self_monitoring_project_id: project.id)
|
||||||
stub_config(prometheus: { enable: true, listen_address: 'localhost:9090' })
|
stub_config(prometheus: { enable: true, server_address: 'localhost:9090' })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'allows self-monitoring project to connect to internal Prometheus' do
|
it 'allows self-monitoring project to connect to internal Prometheus' do
|
||||||
|
@ -242,7 +242,7 @@ RSpec.describe PrometheusService, :use_clean_rails_memory_store_caching, :snowpl
|
||||||
|
|
||||||
stub_config(prometheus: {
|
stub_config(prometheus: {
|
||||||
enable: true,
|
enable: true,
|
||||||
listen_address: api_url
|
server_address: api_url
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue