Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/review-apps/qa.gitlab-ci.yml1
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml2
-rw-r--r--.secretsignore66
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.checksum2
-rw-r--r--Gemfile.lock6
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss8
-rw-r--r--app/models/concerns/taskable.rb15
-rw-r--r--app/models/member.rb10
-rw-r--r--app/models/members/member_role.rb11
-rw-r--r--app/services/ci/append_build_trace_service.rb15
-rw-r--r--app/services/ci/create_pipeline_service.rb17
-rw-r--r--app/views/projects/merge_requests/show.html.haml2
-rw-r--r--config/feature_flags/development/ci_skip_auto_cancelation_on_child_pipelines.yml8
-rw-r--r--db/migrate/20221114212908_add_debug_trace_to_ci_builds_metadata.rb9
-rw-r--r--db/schema_migrations/202211142129081
-rw-r--r--db/structure.sql6
-rw-r--r--doc/administration/audit_events.md1
-rw-r--r--doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md98
-rw-r--r--doc/development/pipelines/index.md8
-rw-r--r--doc/development/pipelines/internals.md2
-rw-r--r--lefthook.yml7
-rw-r--r--lib/api/ci/runner.rb4
-rw-r--r--lib/gitlab/auth/current_user_mode.rb12
-rw-r--r--lib/gitlab/ci/lint.rb10
-rw-r--r--lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb16
-rw-r--r--lib/gitlab/ci/pipeline/chain/command.rb6
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/process.rb2
-rw-r--r--lib/gitlab/ci/pipeline/chain/create.rb2
-rw-r--r--lib/gitlab/ci/pipeline/chain/seed.rb18
-rw-r--r--lib/gitlab/ci/pipeline/logger.rb42
-rw-r--r--lib/gitlab/gfm/uploads_rewriter.rb3
-rw-r--r--lib/gitlab/git.rb1
-rw-r--r--lib/gitlab/git/repository.rb4
-rw-r--r--lib/gitlab/gitaly_client/ref_service.rb6
-rw-r--r--lib/gitlab/memory/reporter.rb66
-rw-r--r--lib/gitlab/memory/reports/jemalloc_stats.rb16
-rw-r--r--lib/gitlab/memory/reports_daemon.rb69
-rw-r--r--locale/gitlab.pot26
-rw-r--r--spec/features/admin/admin_abuse_reports_spec.rb2
-rw-r--r--spec/features/admin/admin_appearance_spec.rb2
-rw-r--r--spec/features/admin/admin_broadcast_messages_spec.rb2
-rw-r--r--spec/features/admin/admin_browse_spam_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_deploy_keys_spec.rb2
-rw-r--r--spec/features/admin/admin_dev_ops_reports_spec.rb2
-rw-r--r--spec/features/admin/admin_disables_git_access_protocol_spec.rb2
-rw-r--r--spec/features/admin/admin_disables_two_factor_spec.rb2
-rw-r--r--spec/features/admin/admin_groups_spec.rb2
-rw-r--r--spec/features/admin/admin_health_check_spec.rb2
-rw-r--r--spec/features/admin/admin_hook_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_hooks_spec.rb2
-rw-r--r--spec/features/admin/admin_jobs_spec.rb2
-rw-r--r--spec/features/admin/admin_labels_spec.rb2
-rw-r--r--spec/features/admin/admin_manage_applications_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/login_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/logout_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/workers_spec.rb2
-rw-r--r--spec/features/admin/admin_mode_spec.rb2
-rw-r--r--spec/features/admin/admin_projects_spec.rb2
-rw-r--r--spec/features/admin/admin_runners_spec.rb2
-rw-r--r--spec/features/admin/admin_search_settings_spec.rb2
-rw-r--r--spec/features/admin/admin_sees_background_migrations_spec.rb2
-rw-r--r--spec/features/admin/admin_sees_project_statistics_spec.rb2
-rw-r--r--spec/features/admin/admin_sees_projects_statistics_spec.rb2
-rw-r--r--spec/features/admin/admin_settings_spec.rb2
-rw-r--r--spec/features/admin/admin_system_info_spec.rb2
-rw-r--r--spec/features/admin/admin_users_impersonation_tokens_spec.rb2
-rw-r--r--spec/features/admin/admin_users_spec.rb2
-rw-r--r--spec/features/admin/admin_uses_repository_checks_spec.rb2
-rw-r--r--spec/features/admin/dashboard_spec.rb6
-rw-r--r--spec/features/admin/integrations/instance_integrations_spec.rb2
-rw-r--r--spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb3
-rw-r--r--spec/features/admin/users/user_spec.rb2
-rw-r--r--spec/features/admin/users/users_spec.rb2
-rw-r--r--spec/features/alert_management/alert_details_spec.rb2
-rw-r--r--spec/features/alert_management/alert_management_list_spec.rb2
-rw-r--r--spec/features/alert_management/user_filters_alerts_by_status_spec.rb2
-rw-r--r--spec/features/alert_management/user_searches_alerts_spec.rb2
-rw-r--r--spec/features/alert_management/user_updates_alert_status_spec.rb2
-rw-r--r--spec/features/alert_management_spec.rb2
-rw-r--r--spec/features/alerts_settings/user_views_alerts_settings_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/current_user_mode_spec.rb31
-rw-r--r--spec/lib/gitlab/ci/lint_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb15
-rw-r--r--spec/lib/gitlab/ci/pipeline/logger_spec.rb122
-rw-r--r--spec/lib/gitlab/gfm/uploads_rewriter_spec.rb22
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb18
-rw-r--r--spec/lib/gitlab/gitaly_client/ref_service_spec.rb10
-rw-r--r--spec/lib/gitlab/memory/reporter_spec.rb77
-rw-r--r--spec/lib/gitlab/memory/reports/jemalloc_stats_spec.rb15
-rw-r--r--spec/lib/gitlab/memory/reports_daemon_spec.rb76
-rw-r--r--spec/models/member_spec.rb83
-rw-r--r--spec/models/members/member_role_spec.rb33
-rw-r--r--spec/requests/api/branches_spec.rb12
-rw-r--r--spec/services/ci/append_build_trace_service_spec.rb16
-rw-r--r--spec/services/ci/create_pipeline_service/logger_spec.rb34
96 files changed, 793 insertions, 470 deletions
diff --git a/.gitlab/ci/review-apps/qa.gitlab-ci.yml b/.gitlab/ci/review-apps/qa.gitlab-ci.yml
index 69ce028987a..d28819208b7 100644
--- a/.gitlab/ci/review-apps/qa.gitlab-ci.yml
+++ b/.gitlab/ci/review-apps/qa.gitlab-ci.yml
@@ -99,6 +99,7 @@ review-qa-non-blocking:
variables:
QA_SCENARIO: Test::Instance::ReviewNonBlocking
QA_RUN_TYPE: review-qa-non-blocking
+ when: manual
allow_failure: true
review-qa-non-blocking-parallel:
extends:
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index 1d7617e9df5..79da496d782 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -902,6 +902,7 @@
when: never
- <<: *if-merge-request-labels-as-if-foss
- <<: *if-merge-request-labels-run-all-rspec
+ - <<: *if-merge-request-labels-frontend-and-feature-flag
- <<: *if-default-refs
changes: *code-backstage-qa-patterns
- <<: *if-default-refs
@@ -932,6 +933,7 @@
- !reference [".strict-ee-only-rules", rules]
- !reference [".frontend:rules:default-frontend-jobs-as-if-foss", rules]
- <<: *if-merge-request-labels-run-all-jest
+ - <<: *if-merge-request-labels-frontend-and-feature-flag
- <<: *if-merge-request
changes: *frontend-patterns-for-as-if-foss
diff --git a/.secretsignore b/.secretsignore
deleted file mode 100644
index 071423bd3c1..00000000000
--- a/.secretsignore
+++ /dev/null
@@ -1,66 +0,0 @@
-# This file is for defining paths and secrets that will be ignored by ripsecret
-
-doc/*
-spec/*
-ee/spec/*
-qa/*
-*_spec.rb
-config/gitlab.yml.example
-workhorse/testdata/localhost.key
-db/fixtures/**/*.rb
-
-[secrets]
-AUTO_DEVOPS_DOMAIN
-BACKWARD_DIRECTION
-CI_BUILD_BEFORE_SHA
-CI_BUILD_REF_NAME
-CI_BUILD_REF_SLUG
-CI_COMMIT_BRANCH
-CI_COMMIT_REF_SLUG
-CI_DEFAULT_BRANCH
-CI_DEPLOY_FREEZE
-CI_DEPLOY_PASSWORD
-CI_ENVIRONMENT_SLUG
-CI_ENVIRONMENT_URL
-CI_GITLAB_FIPS_MODE
-CI_JOB_NAME_SLUG
-CI_JOB_STARTED_AT
-CI_PAGES_DOMAIN
-CI_PROJECT_NAME
-CI_PROJECT_PATH
-CI_PROJECT_PATH_SLUG
-CI_PROJECT_VISIBILITY
-CI_REGISTRY_IMAGE
-CI_REGISTRY_PASSWORD
-CI_REPOSITORY_URL
-CROWDIN_API_KEY
-DAST_API_PROFILE
-DAST_PASSWORD_BASE64
-DAST_SUBMIT_FIELD
-DAST_USERNAME_FIELD
-DORA_METRICS_KEYS
-ESCALATION_STATUS
-FIFTY_PACKAGE_FILES
-FORTY_PACKAGE_FILES
-FORWARD_DIRECTION
-GITLAB_FEATURES
-GITLAB_USER_EMAIL
-GITLAB_USER_LOGIN
-GITLAB_USER_NAME
-HARBOR_PASSWORD
-HARBOR_USERNAME
-KUBE_CA_PEM_FILE
-KUBE_SERVICE_ACCOUNT
-NAVSOURCE_VALUE
-ONE_HUNDRED_TAGS
-ONE_PACKAGE_FILE
-STAGING_ENABLED
-TEN_PACKAGE_FILES
-THIRTY_PACKAGE_FILES
-TRIGGER_PAYLOAD
-TWENTY_FIVE_TAGS
-TWENTY_PACKAGE_FILES
-YOUR-ACCESSKEYID
-YOUR-CLIENT-SECRET
-YOUR_AUTH0_CLIENT_SECRET
-sbdMsxcgW2Xs75Q2uHc9FhUCZSEV3fSg
diff --git a/Gemfile b/Gemfile
index 01874392fb7..380e00f82d5 100644
--- a/Gemfile
+++ b/Gemfile
@@ -362,7 +362,7 @@ gem 'prometheus-client-mmap', '~> 0.16', require: 'prometheus/client'
gem 'warning', '~> 1.3.0'
group :development do
- gem 'lefthook', '~> 1.2.1', require: false
+ gem 'lefthook', '~> 1.2.2', require: false
gem 'rubocop'
gem 'solargraph', '~> 0.47.2', require: false
diff --git a/Gemfile.checksum b/Gemfile.checksum
index ee9dcac0206..5f15974fe93 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -313,7 +313,7 @@
{"name":"kramdown-parser-gfm","version":"1.1.0","platform":"ruby","checksum":"fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729"},
{"name":"kubeclient","version":"4.9.3","platform":"ruby","checksum":"d5d38e719fbac44f396851aa57cd1b9f4f7dab4410ab680ccd21c9b741230046"},
{"name":"launchy","version":"2.5.0","platform":"ruby","checksum":"954243c4255920982ce682f89a42e76372dba94770bf09c23a523e204bdebef5"},
-{"name":"lefthook","version":"1.2.1","platform":"ruby","checksum":"857c7f99fe03252e6b1fd67267e08bd700cf94e3d178c7b7bf18d79f84686abf"},
+{"name":"lefthook","version":"1.2.2","platform":"ruby","checksum":"51359198401f1d6ccd4d21ce974eadad871d725f6de08fddb2f441512e34049f"},
{"name":"letter_opener","version":"1.7.0","platform":"ruby","checksum":"095bc0d58e006e5b43ea7d219e64ecf2de8d1f7d9dafc432040a845cf59b4725"},
{"name":"letter_opener_web","version":"2.0.0","platform":"ruby","checksum":"33860ad41e1785d75456500e8ca8bba8ed71ee6eaf08a98d06bbab67c5577b6f"},
{"name":"libyajl2","version":"1.2.0","platform":"ruby","checksum":"1117cd1e48db013b626e36269bbf1cef210538ca6d2e62d3fa3db9ded005b258"},
diff --git a/Gemfile.lock b/Gemfile.lock
index 7eaaee07595..97b8c995cb1 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -835,7 +835,7 @@ GEM
rest-client (~> 2.0)
launchy (2.5.0)
addressable (~> 2.7)
- lefthook (1.2.1)
+ lefthook (1.2.2)
letter_opener (1.7.0)
launchy (~> 2.2)
letter_opener_web (2.0.0)
@@ -1718,7 +1718,7 @@ DEPENDENCIES
knapsack (~> 1.21.1)
kramdown (~> 2.3.1)
kubeclient (~> 4.9.3)
- lefthook (~> 1.2.1)
+ lefthook (~> 1.2.2)
letter_opener_web (~> 2.0.0)
license_finder (~> 7.0)
licensee (~> 9.15)
@@ -1872,4 +1872,4 @@ DEPENDENCIES
yajl-ruby (~> 1.4.3)
BUNDLED WITH
- 2.3.25
+ 2.3.26
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index 7878e08e549..9b4323979b7 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -198,17 +198,17 @@
}
}
+ $line-height: map-get($spacers, 4) + px-to-rem(2px);
+
&-icon {
/**
* 2px extra is to give a little more height than needed
* to hide timeline line before/after the element starts/ends
*/
- height: map-get($spacers, 4) + px-to-rem(2px);
+ height: $line-height;
z-index: 1;
position: relative;
- top: -3px;
padding: $gl-padding-4 0;
- background-color: $body-bg;
&.opened {
color: $green-500;
@@ -220,7 +220,7 @@
}
&-content {
- line-height: initial;
+ line-height: $line-height;
margin-left: $gl-padding-8;
}
}
diff --git a/app/models/concerns/taskable.rb b/app/models/concerns/taskable.rb
index ee5774d4868..05addcf83d2 100644
--- a/app/models/concerns/taskable.rb
+++ b/app/models/concerns/taskable.rb
@@ -63,14 +63,15 @@ module Taskable
def task_status(short: false)
return '' if description.blank?
- prep, completed = if short
- ['/', '']
- else
- [' of ', ' completed']
- end
-
sum = tasks.summary
- "#{sum.complete_count}#{prep}#{sum.item_count} #{'checklist item'.pluralize(sum.item_count)}#{completed}"
+ checklist_item_noun = n_('checklist item', 'checklist items', sum.item_count)
+ if short
+ format(s_('Tasks|%{complete_count}/%{total_count} %{checklist_item_noun}'),
+checklist_item_noun: checklist_item_noun, complete_count: sum.complete_count, total_count: sum.item_count)
+ else
+ format(s_('Tasks|%{complete_count} of %{total_count} %{checklist_item_noun} completed'),
+checklist_item_noun: checklist_item_noun, complete_count: sum.complete_count, total_count: sum.item_count)
+ end
end
# Return a short string that describes the current state of this Taskable's
diff --git a/app/models/member.rb b/app/models/member.rb
index 80c5fd7e468..8deeebbeda9 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -61,6 +61,7 @@ class Member < ApplicationRecord
validate :access_level_inclusion
validate :validate_member_role_access_level
validate :validate_access_level_locked_for_member_role, on: :update
+ validate :validate_member_role_belongs_to_same_root_namespace
scope :with_invited_user_state, -> do
joins('LEFT JOIN users as invited_user ON invited_user.email = members.invite_email')
@@ -515,6 +516,15 @@ class Member < ApplicationRecord
end
end
+ def validate_member_role_belongs_to_same_root_namespace
+ return unless member_role_id
+
+ return if member_namespace.id == member_role.namespace_id
+ return if member_namespace.root_ancestor.id == member_role.namespace_id
+
+ errors.add(:member_namespace, _("must be in same hierarchy as custom role's namespace"))
+ end
+
def send_invite
# override in subclass
end
diff --git a/app/models/members/member_role.rb b/app/models/members/member_role.rb
index b4e3d6874ef..0661082dced 100644
--- a/app/models/members/member_role.rb
+++ b/app/models/members/member_role.rb
@@ -7,12 +7,21 @@ class MemberRole < ApplicationRecord # rubocop:disable Gitlab/NamespacedClass
validates :namespace, presence: true
validates :base_access_level, presence: true
validate :belongs_to_top_level_namespace
+ validate :validate_namespace_locked, on: :update
+
+ validates_associated :members
private
def belongs_to_top_level_namespace
return if !namespace || namespace.root?
- errors.add(:namespace, s_("must be top-level namespace"))
+ errors.add(:namespace, s_("MemberRole|must be top-level namespace"))
+ end
+
+ def validate_namespace_locked
+ return unless namespace_id_changed?
+
+ errors.add(:namespace, s_("MemberRole|can't be changed"))
end
end
diff --git a/app/services/ci/append_build_trace_service.rb b/app/services/ci/append_build_trace_service.rb
index 0eef0ff0e61..a5ef5b27100 100644
--- a/app/services/ci/append_build_trace_service.rb
+++ b/app/services/ci/append_build_trace_service.rb
@@ -20,6 +20,9 @@ module Ci
# as we cannot use `content_length[1]`
# Issue: https://gitlab.com/gitlab-org/gitlab-runner/issues/3275
+ # Update the build metadata prior to appending trace content
+ update_build_metadata if debug_trace
+
content_range = stream_range.split('-')
body_start = content_range[0].to_i
body_end = body_start + body_data.bytesize
@@ -49,6 +52,18 @@ module Ci
params.fetch(:content_range)
end
+ def debug_trace
+ params.fetch(:debug_trace, false)
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def update_build_metadata
+ metadata = Ci::BuildMetadata.find_by(build_id: build)
+
+ metadata.update!(debug_trace_enabled: debug_trace)
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
def log_range_error(stream_size, body_end)
extra = {
build_id: build.id,
diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb
index 4106dfe0ecc..43a2f4e9a71 100644
--- a/app/services/ci/create_pipeline_service.rb
+++ b/app/services/ci/create_pipeline_service.rb
@@ -140,25 +140,24 @@ module Ci
def build_logger
Gitlab::Ci::Pipeline::Logger.new(project: project) do |l|
l.log_when do |observations|
- observations.any? do |name, values|
- values.any? &&
+ observations.any? do |name, observation|
name.to_s.end_with?('duration_s') &&
- values.max >= LOG_MAX_DURATION_THRESHOLD
+ Array(observation).max >= LOG_MAX_DURATION_THRESHOLD
end
end
l.log_when do |observations|
- values = observations['pipeline_size_count']
- next false if values.empty?
+ count = observations['pipeline_size_count']
+ next false unless count
- values.max >= LOG_MAX_PIPELINE_SIZE
+ count >= LOG_MAX_PIPELINE_SIZE
end
l.log_when do |observations|
- values = observations['pipeline_creation_duration_s']
- next false if values.empty?
+ duration = observations['pipeline_creation_duration_s']
+ next false unless duration
- values.max >= LOG_MAX_CREATION_THRESHOLD
+ duration >= LOG_MAX_CREATION_THRESHOLD
end
end
end
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index 203724fc1f1..41c2187f0b1 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -51,7 +51,7 @@
- if moved_mr_sidebar_enabled?
- if !!@issuable_sidebar.dig(:current_user, :id)
.js-sidebar-todo-widget-root{ data: { project_path: @issuable_sidebar[:project_full_path], iid: @issuable_sidebar[:iid], id: @issuable_sidebar[:id] } }
- .gl-ml-auto.gl-align-items-center.gl-display-none.gl-md-display-flex.gl-ml-3.js-expand-sidebar{ class: "gl-lg-display-none!" }
+ .gl-ml-auto.gl-align-items-center.gl-display-none.gl-md-display-flex.gl-ml-3.js-expand-sidebar.gl-absolute.gl-right-5{ class: "gl-lg-display-none!" }
= render Pajamas::ButtonComponent.new(icon: 'chevron-double-lg-left',
button_options: { class: 'js-sidebar-toggle' }) do
= _('Expand')
diff --git a/config/feature_flags/development/ci_skip_auto_cancelation_on_child_pipelines.yml b/config/feature_flags/development/ci_skip_auto_cancelation_on_child_pipelines.yml
deleted file mode 100644
index 71d5836bee1..00000000000
--- a/config/feature_flags/development/ci_skip_auto_cancelation_on_child_pipelines.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_skip_auto_cancelation_on_child_pipelines
-introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/100854"
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/377712
-milestone: '15.5'
-type: development
-group: group::pipeline execution
-default_enabled: false
diff --git a/db/migrate/20221114212908_add_debug_trace_to_ci_builds_metadata.rb b/db/migrate/20221114212908_add_debug_trace_to_ci_builds_metadata.rb
new file mode 100644
index 00000000000..aee479dfcee
--- /dev/null
+++ b/db/migrate/20221114212908_add_debug_trace_to_ci_builds_metadata.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddDebugTraceToCiBuildsMetadata < Gitlab::Database::Migration[2.0]
+ enable_lock_retries!
+
+ def change
+ add_column :p_ci_builds_metadata, :debug_trace_enabled, :boolean, null: false, default: false
+ end
+end
diff --git a/db/schema_migrations/20221114212908 b/db/schema_migrations/20221114212908
new file mode 100644
index 00000000000..cbd453b2cc9
--- /dev/null
+++ b/db/schema_migrations/20221114212908
@@ -0,0 +1 @@
+0a939e4568d4edcdee322a9a4f69dac51e7604a30e79d2eced9e131a7e06937a \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 586a9aaacff..0e8904c919e 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -12727,7 +12727,8 @@ CREATE TABLE p_ci_builds_metadata (
id bigint NOT NULL,
runtime_runner_features jsonb DEFAULT '{}'::jsonb NOT NULL,
id_tokens jsonb DEFAULT '{}'::jsonb NOT NULL,
- partition_id bigint DEFAULT 100 NOT NULL
+ partition_id bigint DEFAULT 100 NOT NULL,
+ debug_trace_enabled boolean DEFAULT false NOT NULL
)
PARTITION BY LIST (partition_id);
@@ -12755,7 +12756,8 @@ CREATE TABLE ci_builds_metadata (
id bigint DEFAULT nextval('ci_builds_metadata_id_seq'::regclass) NOT NULL,
runtime_runner_features jsonb DEFAULT '{}'::jsonb NOT NULL,
id_tokens jsonb DEFAULT '{}'::jsonb NOT NULL,
- partition_id bigint DEFAULT 100 NOT NULL
+ partition_id bigint DEFAULT 100 NOT NULL,
+ debug_trace_enabled boolean DEFAULT false NOT NULL
);
ALTER TABLE ONLY p_ci_builds_metadata ATTACH PARTITION ci_builds_metadata FOR VALUES IN ('100');
diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md
index 9f00a46dbb6..e8d19363242 100644
--- a/doc/administration/audit_events.md
+++ b/doc/administration/audit_events.md
@@ -227,6 +227,7 @@ The following user actions on a GitLab instance generate instance audit events:
- Removed SSH key ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/220127) in GitLab 14.1)
- Added or removed GPG key ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/220127) in GitLab 14.1)
- A user's two-factor authentication was disabled ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238177) in GitLab 15.1)
+- Enabled Admin Mode ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/362101) in GitLab 15.7)
Instance events can also be accessed via the [Instance Audit Events API](../api/audit_events.md#instance-audit-events).
diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
index 6993d48b450..7c5feb24e15 100644
--- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
+++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
@@ -1,11 +1,95 @@
---
-redirect_to: 'index.md'
-remove_date: '2023-02-01'
+stage: Systems
+group: Distribution
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
-This document was moved to [another location](index.md).
+# GitLab Rails Console Cheat Sheet **(FREE SELF)**
-<!-- This redirect file can be deleted after 2023-02-01. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
+This was the GitLab Support Team's collection of information regarding the GitLab Rails
+console, for use while troubleshooting. It is listed here for posterity,
+as most content has been moved to feature-specific troubleshooting pages and sections,
+see epic [&8147](https://gitlab.com/groups/gitlab-org/-/epics/8147#tree).
+Please update your bookmarks accordingly.
+
+If you are currently having an issue with GitLab,
+it is highly recommended that you first check
+our guide on [the Rails console](../operations/rails_console.md),
+and your [support options](https://about.gitlab.com/support/),
+before attempting the information pointed to from here.
+
+WARNING:
+Some of these scripts could be damaging if not run correctly,
+or under the right conditions. We highly recommend running them under the
+guidance of a Support Engineer, or running them in a test environment with a
+backup of the instance ready to be restored, just in case.
+
+WARNING:
+As GitLab changes, changes to the code are inevitable,
+and so some scripts may not work as they once used to. These are not kept
+up-to-date as these scripts/commands were added as they were found/needed. As
+mentioned above, we recommend running these scripts under the supervision of a
+Support Engineer, who can also verify that they continue to work as they
+should and, if needed, update the script for the latest version of GitLab.
+
+## Mirrors
+
+### Find mirrors with "bad decrypt" errors
+
+This content has been converted to a Rake task, see [verify database values can be decrypted using the current secrets](../raketasks/check.md#verify-database-values-can-be-decrypted-using-the-current-secrets).
+
+### Transfer mirror users and tokens to a single service account
+
+This content has been moved to [Troubleshooting Repository mirroring](../../user/project/repository/mirror/index.md#transfer-mirror-users-and-tokens-to-a-single-service-account-in-rails-console).
+
+## Merge requests
+
+## CI
+
+This content has been moved to [Troubleshooting CI/CD](../../ci/troubleshooting.md).
+
+## License
+
+This content has been moved to [Activate GitLab EE with a license file or key](../../user/admin_area/license_file.md).
+
+## Registry
+
+### Registry Disk Space Usage by Project
+
+Find this content in the [Container Registry troubleshooting documentation](../packages/container_registry.md#registry-disk-space-usage-by-project).
+
+### Run the Cleanup policy now
+
+Find this content in the [Container Registry troubleshooting documentation](../packages/container_registry.md#run-the-cleanup-policy-now).
+
+## Sidekiq
+
+This content has been moved to [Troubleshooting Sidekiq](../sidekiq/sidekiq_troubleshooting.md).
+
+## Geo
+
+### Reverify all uploads (or any SSF data type which is verified)
+
+Moved to [Geo replication troubleshooting](../geo/replication/troubleshooting.md#reverify-all-uploads-or-any-ssf-data-type-which-is-verified).
+
+### Artifacts
+
+Moved to [Geo replication troubleshooting](../geo/replication/troubleshooting.md#find-failed-artifacts).
+
+### Repository verification failures
+
+Moved to [Geo replication troubleshooting](../geo/replication/troubleshooting.md#find-repository-verification-failures).
+
+### Resync repositories
+
+Moved to [Geo replication troubleshooting - Resync repository types except for project or project wiki repositories](../geo/replication/troubleshooting.md#repository-types-except-for-project-or-project-wiki-repositories).
+
+Moved to [Geo replication troubleshooting - Resync project and project wiki repositories](../geo/replication/troubleshooting.md#resync-project-and-project-wiki-repositories).
+
+### Blob types
+
+Moved to [Geo replication troubleshooting](../geo/replication/troubleshooting.md#blob-types).
+
+## Generate Service Ping
+
+This content has been moved to [Service Ping Troubleshooting](../../development/service_ping/troubleshooting.md).
diff --git a/doc/development/pipelines/index.md b/doc/development/pipelines/index.md
index 01bb813e794..78d07bb804f 100644
--- a/doc/development/pipelines/index.md
+++ b/doc/development/pipelines/index.md
@@ -88,10 +88,12 @@ In addition, there are a few circumstances where we would always run the full Je
- when the `pipeline:run-all-jest` label is set on the merge request
- when the merge request is created by an automation (for example, Gitaly update or MR targeting a stable branch)
- when the merge request is created in a security mirror
-- when any CI configuration file is changed (for example, `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
-- when any frontend "core" file is changed (for example, `package.json`, `yarn.lock`, `babel.config.js`, `jest.config.*.js`, `config/helpers/**/*.js`)
+- when relevant CI configuration file is changed (`.gitlab/ci/rules.gitlab-ci.yml`, `.gitlab/ci/frontend.gitlab-ci.yml`)
+- when any frontend dependency file is changed (for example, `package.json`, `yarn.lock`, `config/webpack.config.js`, `config/helpers/**/*.js`)
- when any vendored JavaScript file is changed (for example, `vendor/assets/javascripts/**/*`)
-- when any backend file is changed ([see the patterns list for details](https://gitlab.com/gitlab-org/gitlab/-/blob/3616946936c1adbd9e754c1bd06f86ba670796d8/.gitlab/ci/rules.gitlab-ci.yml#L205-216))
+
+The `rules` definitions for full Jest tests are defined at `.frontend:rules:jest` in
+[`rules.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/42321b18b946c64d2f6f788c38844499a5ae9141/.gitlab/ci/rules.gitlab-ci.yml#L938-955).
### Fork pipelines
diff --git a/doc/development/pipelines/internals.md b/doc/development/pipelines/internals.md
index 2861e2f266b..133d11986d5 100644
--- a/doc/development/pipelines/internals.md
+++ b/doc/development/pipelines/internals.md
@@ -203,7 +203,7 @@ and included in `rules` definitions via [YAML anchors](../../ci/yaml/yaml_optimi
| `ci-qa-patterns` | Only create job for CI configuration-related changes related to the `qa` stage. |
| `yaml-lint-patterns` | Only create job for YAML-related changes. |
| `docs-patterns` | Only create job for docs-related changes. |
-| `frontend-dependency-patterns` | Only create job when frontend dependencies are updated (that is, `package.json`, and `yarn.lock`). changes. |
+| `frontend-dependency-patterns` | Only create job when frontend dependencies are updated (for example, `package.json`, and `yarn.lock`) changes. |
| `frontend-patterns-for-as-if-foss` | Only create job for frontend-related changes that have impact on FOSS. |
| `backend-patterns` | Only create job for backend-related changes. |
| `db-patterns` | Only create job for DB-related changes. |
diff --git a/lefthook.yml b/lefthook.yml
index cfe68b5c390..c44ea8cdeab 100644
--- a/lefthook.yml
+++ b/lefthook.yml
@@ -79,7 +79,10 @@ pre-push:
files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD
glob: 'data/removals/*.yml'
run: echo "Changes to removals files detected. Checking removals..\n"; bundle exec rake gitlab:docs:check_removals
+pre-commit:
+ parallel: true
+ commands:
secrets-detection:
tags: secrets
- files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD
- run: 'if command -v ripsecrets > /dev/null 2>&1; then ripsecrets --strict-ignore {files}; else echo "WARNING: ripsecrets is not installed. Please install it."; fi'
+ files: git diff --name-only --diff-filter=d --staged
+ run: 'if command -v gitleaks > /dev/null 2>&1; then gitleaks protect --no-banner --staged --redact --verbose; else echo "WARNING: gitleaks is not installed. Please install it. See https://github.com/zricethezav/gitleaks#installing."; fi'
diff --git a/lib/api/ci/runner.rb b/lib/api/ci/runner.rb
index e64db375421..b073eb49bf1 100644
--- a/lib/api/ci/runner.rb
+++ b/lib/api/ci/runner.rb
@@ -229,15 +229,17 @@ module API
params do
requires :id, type: Integer, desc: %q(Job's ID)
optional :token, type: String, desc: %q(Job's authentication token)
+ optional :debug_trace, type: Boolean, desc: %q(Enable or Disable the debug trace)
end
patch '/:id/trace', urgency: :low, feature_category: :continuous_integration do
job = authenticate_job!(heartbeat_runner: true)
error!('400 Missing header Content-Range', 400) unless request.headers.key?('Content-Range')
content_range = request.headers['Content-Range']
+ debug_trace = Gitlab::Utils.to_boolean(params[:debug_trace])
result = ::Ci::AppendBuildTraceService
- .new(job, content_range: content_range)
+ .new(job, content_range: content_range, debug_trace: debug_trace)
.execute(request.body.read)
if result.status == 403
diff --git a/lib/gitlab/auth/current_user_mode.rb b/lib/gitlab/auth/current_user_mode.rb
index fc391543f4d..9bd4711c4bb 100644
--- a/lib/gitlab/auth/current_user_mode.rb
+++ b/lib/gitlab/auth/current_user_mode.rb
@@ -106,8 +106,8 @@ module Gitlab
end
def enable_admin_mode!(password: nil, skip_password_validation: false)
- return unless user&.admin?
- return unless skip_password_validation || user&.valid_password?(password)
+ return false unless user&.admin?
+ return false unless skip_password_validation || user&.valid_password?(password)
raise NotRequestedError unless admin_mode_requested?
@@ -115,6 +115,10 @@ module Gitlab
current_session_data[ADMIN_MODE_REQUESTED_TIME_KEY] = nil
current_session_data[ADMIN_MODE_START_TIME_KEY] = Time.now
+
+ audit_user_enable_admin_mode
+
+ true
end
def disable_admin_mode!
@@ -175,6 +179,10 @@ module Gitlab
def privileged_runtime?
Gitlab::Runtime.rake? || Gitlab::Runtime.rails_runner? || Gitlab::Runtime.console?
end
+
+ def audit_user_enable_admin_mode; end
end
end
end
+
+Gitlab::Auth::CurrentUserMode.prepend_mod_with('Gitlab::Auth::CurrentUserMode')
diff --git a/lib/gitlab/ci/lint.rb b/lib/gitlab/ci/lint.rb
index 51743a1f273..e0112a1b1c2 100644
--- a/lib/gitlab/ci/lint.rb
+++ b/lib/gitlab/ci/lint.rb
@@ -73,7 +73,7 @@ module Gitlab
end
def yaml_processor_result(content, logger)
- logger.instrument(:yaml_process) do
+ logger.instrument(:yaml_process, once: true) do
Gitlab::Ci::YamlProcessor.new(content, project: @project,
user: @current_user,
sha: @sha,
@@ -119,7 +119,7 @@ module Gitlab
environment: job[:environment],
when: job[:when],
allow_failure: job[:allow_failure],
- needs: job.dig(:needs_attributes)
+ needs: job[:needs_attributes]
}
end
end
@@ -130,10 +130,10 @@ module Gitlab
def build_logger
Gitlab::Ci::Pipeline::Logger.new(project: @project) do |l|
l.log_when do |observations|
- values = observations['yaml_process_duration_s']
- next false if values.empty?
+ duration = observations['yaml_process_duration_s']
+ next false unless duration
- values.max >= LOG_MAX_DURATION_THRESHOLD
+ duration >= LOG_MAX_DURATION_THRESHOLD
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb b/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb
index 07a3aff1862..53c8a7ac122 100644
--- a/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb
+++ b/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb
@@ -11,11 +11,10 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
def perform!
- ff_enabled = Feature.enabled?(:ci_skip_auto_cancelation_on_child_pipelines, project)
- return if ff_enabled && pipeline.parent_pipeline? # skip if child pipeline
+ return if pipeline.parent_pipeline? # skip if child pipeline
return unless project.auto_cancel_pending_pipelines?
- Gitlab::OptimisticLocking.retry_lock(auto_cancelable_pipelines(ff_enabled), name: 'cancel_pending_pipelines') do |cancelables|
+ Gitlab::OptimisticLocking.retry_lock(auto_cancelable_pipelines, name: 'cancel_pending_pipelines') do |cancelables|
cancelables.select(:id).each_batch(of: BATCH_SIZE) do |cancelables_batch|
auto_cancel_interruptible_pipelines(cancelables_batch.ids)
end
@@ -29,19 +28,14 @@ module Gitlab
private
- def auto_cancelable_pipelines(ff_enabled)
- relation = project.all_pipelines
+ def auto_cancelable_pipelines
+ project.all_pipelines
.created_after(1.week.ago)
.ci_and_parent_sources
.for_ref(pipeline.ref)
.where_not_sha(project.commit(pipeline.ref).try(:id))
.alive_or_scheduled
-
- if ff_enabled
- relation.id_not_in(pipeline.id)
- else
- relation.id_not_in(pipeline.same_family_pipeline_ids)
- end
+ .id_not_in(pipeline.id)
end
def auto_cancel_interruptible_pipelines(pipeline_ids)
diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb
index 5ec04b4889e..837c09e8045 100644
--- a/lib/gitlab/ci/pipeline/chain/command.rb
+++ b/lib/gitlab/ci/pipeline/chain/command.rb
@@ -98,7 +98,7 @@ module Gitlab
def observe_step_duration(step_class, duration)
step = step_class.name.underscore.parameterize(separator: '_')
- logger.observe("pipeline_step_#{step}_duration_s", duration)
+ logger.observe("pipeline_step_#{step}_duration_s", duration, once: true)
if Feature.enabled?(:ci_pipeline_creation_step_duration_tracking, type: :ops)
metrics.pipeline_creation_step_duration_histogram
@@ -107,14 +107,14 @@ module Gitlab
end
def observe_creation_duration(duration)
- logger.observe(:pipeline_creation_duration_s, duration)
+ logger.observe(:pipeline_creation_duration_s, duration, once: true)
metrics.pipeline_creation_duration_histogram
.observe({}, duration.seconds)
end
def observe_pipeline_size(pipeline)
- logger.observe(:pipeline_size_count, pipeline.total_size)
+ logger.observe(:pipeline_size_count, pipeline.total_size, once: true)
metrics.pipeline_size_histogram
.observe({ source: pipeline.source.to_s, plan: project.actual_plan_name }, pipeline.total_size)
diff --git a/lib/gitlab/ci/pipeline/chain/config/process.rb b/lib/gitlab/ci/pipeline/chain/config/process.rb
index 5548fca320f..ad6b2fd3411 100644
--- a/lib/gitlab/ci/pipeline/chain/config/process.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/process.rb
@@ -11,7 +11,7 @@ module Gitlab
def perform!
raise ArgumentError, 'missing config content' unless @command.config_content
- result = logger.instrument(:pipeline_config_process) do
+ result = logger.instrument(:pipeline_config_process, once: true) do
processor = ::Gitlab::Ci::YamlProcessor.new(
@command.config_content, {
project: project,
diff --git a/lib/gitlab/ci/pipeline/chain/create.rb b/lib/gitlab/ci/pipeline/chain/create.rb
index 207b4b5ff8b..d4c4f94c7d3 100644
--- a/lib/gitlab/ci/pipeline/chain/create.rb
+++ b/lib/gitlab/ci/pipeline/chain/create.rb
@@ -9,7 +9,7 @@ module Gitlab
include Gitlab::Utils::StrongMemoize
def perform!
- logger.instrument_with_sql(:pipeline_save) do
+ logger.instrument_once_with_sql(:pipeline_save) do
BulkInsertableAssociations.with_bulk_insert do
::Ci::BulkInsertableTags.with_bulk_insert_tags do
pipeline.transaction do
diff --git a/lib/gitlab/ci/pipeline/chain/seed.rb b/lib/gitlab/ci/pipeline/chain/seed.rb
index feae123f216..3f5df5ce71c 100644
--- a/lib/gitlab/ci/pipeline/chain/seed.rb
+++ b/lib/gitlab/ci/pipeline/chain/seed.rb
@@ -13,7 +13,7 @@ module Gitlab
raise ArgumentError, 'missing workflow rules result' unless @command.workflow_rules_result
# Allocate next IID. This operation must be outside of transactions of pipeline creations.
- logger.instrument(:pipeline_allocate_seed_attributes) do
+ logger.instrument(:pipeline_allocate_seed_attributes, once: true) do
pipeline.ensure_project_iid!
pipeline.ensure_ci_ref!
end
@@ -25,7 +25,7 @@ module Gitlab
##
# Gather all runtime build/stage errors
#
- seed_errors = logger.instrument(:pipeline_seed_evaluation) do
+ seed_errors = logger.instrument(:pipeline_seed_evaluation, once: true) do
pipeline_seed.errors
end
@@ -44,7 +44,7 @@ module Gitlab
def pipeline_seed
strong_memoize(:pipeline_seed) do
- logger.instrument(:pipeline_seed_initialization) do
+ logger.instrument(:pipeline_seed_initialization, once: true) do
stages_attributes = @command.yaml_processor_result.stages_attributes
Gitlab::Ci::Pipeline::Seed::Pipeline.new(context, stages_attributes)
@@ -61,11 +61,13 @@ module Gitlab
end
def root_variables
- logger.instrument(:pipeline_seed_merge_variables) do
- ::Gitlab::Ci::Variables::Helpers.merge_variables(
- @command.yaml_processor_result.root_variables,
- @command.workflow_rules_result.variables
- )
+ strong_memoize(:root_variables) do
+ logger.instrument(:pipeline_seed_merge_variables, once: true) do
+ ::Gitlab::Ci::Variables::Helpers.merge_variables(
+ @command.yaml_processor_result.root_variables,
+ @command.workflow_rules_result.variables
+ )
+ end
end
end
end
diff --git a/lib/gitlab/ci/pipeline/logger.rb b/lib/gitlab/ci/pipeline/logger.rb
index 5a1743dcfca..9659cec4889 100644
--- a/lib/gitlab/ci/pipeline/logger.rb
+++ b/lib/gitlab/ci/pipeline/logger.rb
@@ -23,7 +23,7 @@ module Gitlab
log_conditions.push(block)
end
- def instrument(operation)
+ def instrument(operation, once: false)
return yield unless enabled?
raise ArgumentError, 'block not given' unless block_given?
@@ -32,25 +32,29 @@ module Gitlab
result = yield
- observe("#{operation}_duration_s", current_monotonic_time - op_started_at)
+ observe("#{operation}_duration_s", current_monotonic_time - op_started_at, once: once)
result
end
- def instrument_with_sql(operation, &block)
+ def instrument_once_with_sql(operation, &block)
op_start_db_counters = current_db_counter_payload
- result = instrument(operation, &block)
+ result = instrument(operation, once: true, &block)
- observe_sql_counters(operation, op_start_db_counters, current_db_counter_payload)
+ observe_sql_counters(operation, op_start_db_counters, current_db_counter_payload, once: true)
result
end
- def observe(operation, value)
+ def observe(operation, value, once: false)
return unless enabled?
- observations[operation.to_s].push(value)
+ if once
+ observations[operation.to_s] = value
+ else
+ observations[operation.to_s].push(value)
+ end
end
def commit(pipeline:, caller:)
@@ -79,14 +83,18 @@ module Gitlab
end
def observations_hash
- observations.transform_values do |values|
- next if values.empty?
-
- {
- 'count' => values.size,
- 'max' => values.max,
- 'sum' => values.sum
- }
+ observations.transform_values do |observation|
+ next if observation.blank?
+
+ if observation.is_a?(Array)
+ {
+ 'count' => observation.size,
+ 'max' => observation.max,
+ 'sum' => observation.sum
+ }
+ else
+ observation
+ end
end.compact
end
@@ -117,12 +125,12 @@ module Gitlab
@observations ||= Hash.new { |hash, key| hash[key] = [] }
end
- def observe_sql_counters(operation, start_db_counters, end_db_counters)
+ def observe_sql_counters(operation, start_db_counters, end_db_counters, once: false)
end_db_counters.each do |key, value|
result = value - start_db_counters.fetch(key, 0)
next if result == 0
- observe("#{operation}_#{key}", result)
+ observe("#{operation}_#{key}", result, once: once)
end
end
diff --git a/lib/gitlab/gfm/uploads_rewriter.rb b/lib/gitlab/gfm/uploads_rewriter.rb
index 58b46a85aae..6b5f10ed78e 100644
--- a/lib/gitlab/gfm/uploads_rewriter.rb
+++ b/lib/gitlab/gfm/uploads_rewriter.rb
@@ -54,8 +54,7 @@ module Gitlab
file = find_file(match[:secret], match[:file])
# No file will be returned for a path traversal
- return '' if file.nil?
-
+ return markdown if file.nil?
return markdown unless file.try(:exists?)
klass = @target_parent.is_a?(Namespace) ? NamespaceFileUploader : FileUploader
diff --git a/lib/gitlab/git.rb b/lib/gitlab/git.rb
index 4b877bf44da..8e1b51fcec5 100644
--- a/lib/gitlab/git.rb
+++ b/lib/gitlab/git.rb
@@ -16,6 +16,7 @@ module Gitlab
CommitError = Class.new(BaseError)
OSError = Class.new(BaseError)
UnknownRef = Class.new(BaseError)
+ AmbiguousRef = Class.new(BaseError)
CommandTimedOut = Class.new(CommandError)
InvalidPageToken = Class.new(BaseError)
InvalidRefFormatError = Class.new(BaseError)
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 2d13d3378c2..1bbbc16fe67 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -134,6 +134,10 @@ module Gitlab
wrapped_gitaly_errors do
gitaly_ref_client.find_branch(name)
end
+ rescue Gitlab::Git::AmbiguousRef
+ # Gitaly returns "reference is ambiguous" error in case when users request
+ # branch "my-branch", when another branch "my-branch/branch" exists.
+ # We handle this error here and return nil for this case.
end
def find_tag(name)
diff --git a/lib/gitlab/gitaly_client/ref_service.rb b/lib/gitlab/gitaly_client/ref_service.rb
index de76ade76cb..3ab596da529 100644
--- a/lib/gitlab/gitaly_client/ref_service.rb
+++ b/lib/gitlab/gitaly_client/ref_service.rb
@@ -17,6 +17,8 @@ module Gitlab
'desc' => Gitaly::SortDirection::DESCENDING
}.freeze
+ AMBIGUOUS_REFERENCE = 'reference is ambiguous'
+
# 'repository' is a Gitlab::Git::Repository
def initialize(repository)
@repository = repository
@@ -109,6 +111,10 @@ module Gitlab
target_commit = Gitlab::Git::Commit.decorate(@repository, branch.target_commit)
Gitlab::Git::Branch.new(@repository, branch.name.dup, branch.target_commit.id, target_commit)
+ rescue GRPC::BadStatus => e
+ raise e unless e.message.include?(AMBIGUOUS_REFERENCE)
+
+ raise Gitlab::Git::AmbiguousRef, "branch is ambiguous: #{branch_name}"
end
def find_tag(tag_name)
diff --git a/lib/gitlab/memory/reporter.rb b/lib/gitlab/memory/reporter.rb
new file mode 100644
index 00000000000..b4f3f950b95
--- /dev/null
+++ b/lib/gitlab/memory/reporter.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Memory
+ class Reporter
+ def initialize
+ @worker_uuid = SecureRandom.uuid
+
+ init_prometheus_metrics
+ end
+
+ def run_report(report)
+ start_monotonic_time = Gitlab::Metrics::System.monotonic_time
+ start_thread_cpu_time = Gitlab::Metrics::System.thread_cpu_time
+
+ file_path = report.run(report_id)
+
+ cpu_s = Gitlab::Metrics::System.thread_cpu_duration(start_thread_cpu_time)
+ duration_s = Gitlab::Metrics::System.monotonic_time - start_monotonic_time
+
+ log_report(name: report.name, cpu_s: cpu_s, duration_s: duration_s, size: file_size(file_path))
+
+ @report_duration_counter.increment({ report: report.name }, duration_s)
+ end
+
+ private
+
+ def log_report(name:, duration_s:, cpu_s:, size:)
+ Gitlab::AppLogger.info(
+ message: 'finished',
+ pid: $$,
+ worker_id: worker_id,
+ perf_report: name,
+ duration_s: duration_s.round(2),
+ cpu_s: cpu_s.round(2),
+ perf_report_size_bytes: size,
+ perf_report_worker_uuid: @worker_uuid
+ )
+ end
+
+ def report_id
+ [worker_id, @worker_uuid].join(".")
+ end
+
+ def worker_id
+ ::Prometheus::PidProvider.worker_id
+ end
+
+ def file_size(file_path)
+ File.size(file_path.to_s)
+ rescue Errno::ENOENT
+ 0
+ end
+
+ def init_prometheus_metrics
+ default_labels = { pid: worker_id }
+
+ @report_duration_counter = Gitlab::Metrics.counter(
+ :gitlab_diag_report_duration_seconds_total,
+ 'Total time elapsed for running diagnostic report',
+ default_labels
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/memory/reports/jemalloc_stats.rb b/lib/gitlab/memory/reports/jemalloc_stats.rb
index 720f22ddbe4..2e5a053031e 100644
--- a/lib/gitlab/memory/reports/jemalloc_stats.rb
+++ b/lib/gitlab/memory/reports/jemalloc_stats.rb
@@ -16,9 +16,8 @@ module Gitlab
# The cleanup logic will be redundant after we'll implement the uploads, which would perform the cleanup.
DEFAULT_MAX_REPORTS_STORED = 250
- def initialize(reports_path:, filename_label:)
+ def initialize(reports_path:)
@reports_path = reports_path
- @filename_label = filename_label
# Store report in tmp subdir while it is still streaming.
# This will clearly separate finished reports from the files we are still writing to.
@@ -26,11 +25,16 @@ module Gitlab
FileUtils.mkdir_p(@tmp_dir)
end
- def run
+ def name
+ 'jemalloc_stats'
+ end
+
+ def run(report_id)
return unless active?
- Gitlab::Memory::Jemalloc.dump_stats(path: reports_path, tmp_dir: @tmp_dir,
- filename_label: filename_label).tap do
+ Gitlab::Memory::Jemalloc.dump_stats(path: reports_path,
+ tmp_dir: @tmp_dir,
+ filename_label: report_id).tap do
cleanup
end
end
@@ -41,7 +45,7 @@ module Gitlab
private
- attr_reader :reports_path, :filename_label
+ attr_reader :reports_path
def cleanup
reports_files_modified_order[0...-max_reports_stored].each do |f|
diff --git a/lib/gitlab/memory/reports_daemon.rb b/lib/gitlab/memory/reports_daemon.rb
index 7070c65c705..9a044dbd06c 100644
--- a/lib/gitlab/memory/reports_daemon.rb
+++ b/lib/gitlab/memory/reports_daemon.rb
@@ -9,7 +9,7 @@ module Gitlab
DEFAULT_REPORTS_PATH = Dir.tmpdir
- def initialize(**options)
+ def initialize(reporter: Reporter.new, reports: nil, **options)
super
@alive = true
@@ -24,17 +24,10 @@ module Gitlab
@reports_path =
ENV["GITLAB_DIAGNOSTIC_REPORTS_PATH"] || DEFAULT_REPORTS_PATH
- # Set unique uuid for every ReportsDaemon instance.
- # Because we spawn a single instance of it per process, it will also uniquely identify the worker.
- # Unlike `::Prometheus::PidProvider.worker_id`, this uuid will remain unique across all Puma clusters.
- # This way, we can identify reports that were produced from the same worker process during its lifetime.
- @worker_uuid = SecureRandom.uuid
-
- @reports = [
- Gitlab::Memory::Reports::JemallocStats.new(reports_path: reports_path, filename_label: filename_label)
+ @reporter = reporter
+ @reports = reports || [
+ Gitlab::Memory::Reports::JemallocStats.new(reports_path: reports_path)
]
-
- init_prometheus_metrics
end
attr_reader :sleep_s, :sleep_max_delta_s, :sleep_between_reports_s, :reports_path
@@ -44,16 +37,7 @@ module Gitlab
sleep interval_with_jitter
reports.select(&:active?).each do |report|
- start_monotonic_time = Gitlab::Metrics::System.monotonic_time
- start_thread_cpu_time = Gitlab::Metrics::System.thread_cpu_time
-
- file_path = report.run
-
- cpu_s = Gitlab::Metrics::System.thread_cpu_duration(start_thread_cpu_time)
- duration_s = Gitlab::Metrics::System.monotonic_time - start_monotonic_time
-
- log_report(label: report_label(report), cpu_s: cpu_s, duration_s: duration_s, size: file_size(file_path))
- @report_duration_counter.increment({ report: report_label(report) }, duration_s)
+ @reporter.run_report(report)
sleep sleep_between_reports_s
end
@@ -62,11 +46,7 @@ module Gitlab
private
- attr_reader :alive, :reports, :worker_uuid
-
- def filename_label
- [worker_id, worker_uuid].join(".")
- end
+ attr_reader :alive, :reports
# Returns the sleep interval with a random adjustment.
# The random adjustment is put in place to ensure continued availability.
@@ -74,46 +54,9 @@ module Gitlab
sleep_s + rand(sleep_max_delta_s)
end
- def log_report(label:, duration_s:, cpu_s:, size:)
- Gitlab::AppLogger.info(
- message: 'finished',
- pid: $$,
- worker_id: worker_id,
- perf_report: label,
- duration_s: duration_s.round(2),
- cpu_s: cpu_s.round(2),
- perf_report_size_bytes: size,
- perf_report_worker_uuid: worker_uuid
- )
- end
-
- def worker_id
- ::Prometheus::PidProvider.worker_id
- end
-
- def report_label(report)
- report.class.to_s.demodulize.underscore
- end
-
def stop_working
@alive = false
end
-
- def init_prometheus_metrics
- default_labels = { pid: worker_id }
-
- @report_duration_counter = Gitlab::Metrics.counter(
- :gitlab_diag_report_duration_seconds_total,
- 'Total time elapsed for running diagnostic report',
- default_labels
- )
- end
-
- def file_size(file_path)
- File.size(file_path.to_s)
- rescue Errno::ENOENT
- 0
- end
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ceb57944c8e..82fd192bb7e 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -25410,6 +25410,12 @@ msgstr ""
msgid "MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}"
msgstr ""
+msgid "MemberRole|can't be changed"
+msgstr ""
+
+msgid "MemberRole|must be top-level namespace"
+msgstr ""
+
msgid "Members"
msgstr ""
@@ -40271,6 +40277,12 @@ msgstr ""
msgid "TasksToBeDone|Set up CI/CD pipelines to build, test, deploy, and monitor code"
msgstr ""
+msgid "Tasks|%{complete_count} of %{total_count} %{checklist_item_noun} completed"
+msgstr ""
+
+msgid "Tasks|%{complete_count}/%{total_count} %{checklist_item_noun}"
+msgstr ""
+
msgid "Team"
msgstr ""
@@ -47021,6 +47033,9 @@ msgstr ""
msgid "You don't have permission to review this deployment. Contact the project or group owner for help."
msgstr ""
+msgid "You don't have permission to view this epic"
+msgstr ""
+
msgid "You don't have permissions to create this project"
msgstr ""
@@ -47960,6 +47975,11 @@ msgid_plural "checks"
msgstr[0] ""
msgstr[1] ""
+msgid "checklist item"
+msgid_plural "checklist items"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ciReport|%{criticalStart}critical%{criticalEnd}, %{highStart}high%{highEnd} and %{otherStart}others%{otherEnd}"
msgstr ""
@@ -49239,6 +49259,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "must be in same hierarchy as custom role's namespace"
+msgstr ""
+
msgid "must be inside the fork network"
msgstr ""
@@ -49248,9 +49271,6 @@ msgstr ""
msgid "must be set for a project namespace"
msgstr ""
-msgid "must be top-level namespace"
-msgstr ""
-
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
diff --git a/spec/features/admin/admin_abuse_reports_spec.rb b/spec/features/admin/admin_abuse_reports_spec.rb
index 3a02ce89aa9..10f12d7116f 100644
--- a/spec/features/admin/admin_abuse_reports_spec.rb
+++ b/spec/features/admin/admin_abuse_reports_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "Admin::AbuseReports", :js do
+RSpec.describe "Admin::AbuseReports", :js, feature_category: :not_owned do
let(:user) { create(:user) }
context 'as an admin' do
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
index b297d92b2fa..5fbe7039c1d 100644
--- a/spec/features/admin/admin_appearance_spec.rb
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin Appearance' do
+RSpec.describe 'Admin Appearance', feature_category: :not_owned do
let!(:appearance) { create(:appearance) }
let(:admin) { create(:admin) }
diff --git a/spec/features/admin/admin_broadcast_messages_spec.rb b/spec/features/admin/admin_broadcast_messages_spec.rb
index b5416f539f1..a6bbdd70fc3 100644
--- a/spec/features/admin/admin_broadcast_messages_spec.rb
+++ b/spec/features/admin/admin_broadcast_messages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin Broadcast Messages' do
+RSpec.describe 'Admin Broadcast Messages', feature_category: :onboarding do
before do
admin = create(:admin)
sign_in(admin)
diff --git a/spec/features/admin/admin_browse_spam_logs_spec.rb b/spec/features/admin/admin_browse_spam_logs_spec.rb
index 471a7e8f0ab..348b6db94fe 100644
--- a/spec/features/admin/admin_browse_spam_logs_spec.rb
+++ b/spec/features/admin/admin_browse_spam_logs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin browse spam logs' do
+RSpec.describe 'Admin browse spam logs', feature_category: :not_owned do
let!(:spam_log) { create(:spam_log, description: 'abcde ' * 20) }
before do
diff --git a/spec/features/admin/admin_deploy_keys_spec.rb b/spec/features/admin/admin_deploy_keys_spec.rb
index 56b8c7fce14..e55e1cce6b9 100644
--- a/spec/features/admin/admin_deploy_keys_spec.rb
+++ b/spec/features/admin/admin_deploy_keys_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'admin deploy keys', :js do
+RSpec.describe 'admin deploy keys', :js, feature_category: :authentication_and_authorization do
include Spec::Support::Helpers::ModalHelpers
let_it_be(:admin) { create(:admin) }
diff --git a/spec/features/admin/admin_dev_ops_reports_spec.rb b/spec/features/admin/admin_dev_ops_reports_spec.rb
index f65862c568f..f290464b043 100644
--- a/spec/features/admin/admin_dev_ops_reports_spec.rb
+++ b/spec/features/admin/admin_dev_ops_reports_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'DevOps Report page', :js do
+RSpec.describe 'DevOps Report page', :js, feature_category: :devops_reports do
before do
admin = create(:admin)
sign_in(admin)
diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
index b370b779afe..76620b93557 100644
--- a/spec/features/admin/admin_disables_git_access_protocol_spec.rb
+++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin disables Git access protocol', :js do
+RSpec.describe 'Admin disables Git access protocol', :js, feature_category: :source_code_management do
include StubENV
include MobileHelpers
diff --git a/spec/features/admin/admin_disables_two_factor_spec.rb b/spec/features/admin/admin_disables_two_factor_spec.rb
index 4463dbb1eb0..eed20d449cd 100644
--- a/spec/features/admin/admin_disables_two_factor_spec.rb
+++ b/spec/features/admin/admin_disables_two_factor_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin disables 2FA for a user' do
+RSpec.describe 'Admin disables 2FA for a user', feature_category: :system_access do
include Spec::Support::Helpers::ModalHelpers
it 'successfully', :js do
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index 657dd52228e..c36a742af6b 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin Groups' do
+RSpec.describe 'Admin Groups', feature_category: :subgroups do
include Select2Helper
include Spec::Support::Helpers::Features::MembersHelpers
include Spec::Support::Helpers::Features::InviteMembersModalHelper
diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb
index 0f6cba6c105..de71a48d2dc 100644
--- a/spec/features/admin/admin_health_check_spec.rb
+++ b/spec/features/admin/admin_health_check_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "Admin Health Check", :feature do
+RSpec.describe "Admin Health Check", feature_category: :continuous_verification do
include StubENV
let_it_be(:admin) { create(:admin) }
diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb
index a2ee6343886..d6507e68692 100644
--- a/spec/features/admin/admin_hook_logs_spec.rb
+++ b/spec/features/admin/admin_hook_logs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin::HookLogs' do
+RSpec.describe 'Admin::HookLogs', feature_category: :continuous_verification do
let_it_be(:system_hook) { create(:system_hook) }
let_it_be(:hook_log) { create(:web_hook_log, web_hook: system_hook, internal_error_message: 'some error') }
let_it_be(:admin) { create(:admin) }
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index dc5b0ae009e..c4cd88817bc 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin::Hooks' do
+RSpec.describe 'Admin::Hooks', feature_category: :integrations do
include Spec::Support::Helpers::ModalHelpers
let_it_be(:user) { create(:admin) }
diff --git a/spec/features/admin/admin_jobs_spec.rb b/spec/features/admin/admin_jobs_spec.rb
index 36822f89c12..f0eaa83f05e 100644
--- a/spec/features/admin/admin_jobs_spec.rb
+++ b/spec/features/admin/admin_jobs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin Jobs' do
+RSpec.describe 'Admin Jobs', feature_category: :continuous_integration do
before do
admin = create(:admin)
sign_in(admin)
diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb
index fa5c94aa66e..8d2813d26f7 100644
--- a/spec/features/admin/admin_labels_spec.rb
+++ b/spec/features/admin/admin_labels_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'admin issues labels' do
+RSpec.describe 'admin issues labels', feature_category: :team_planning do
include Spec::Support::Helpers::ModalHelpers
let!(:bug_label) { Label.create!(title: 'bug', template: true) }
diff --git a/spec/features/admin/admin_manage_applications_spec.rb b/spec/features/admin/admin_manage_applications_spec.rb
index 4cf290293bd..b4c77e802a8 100644
--- a/spec/features/admin/admin_manage_applications_spec.rb
+++ b/spec/features/admin/admin_manage_applications_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'admin manage applications' do
+RSpec.describe 'admin manage applications', feature_category: :system_access do
let_it_be(:new_application_path) { new_admin_application_path }
let_it_be(:applications_path) { admin_applications_path }
let_it_be(:index_path) { admin_applications_path }
diff --git a/spec/features/admin/admin_mode/login_spec.rb b/spec/features/admin/admin_mode/login_spec.rb
index 6b4c9adb096..393721fe451 100644
--- a/spec/features/admin/admin_mode/login_spec.rb
+++ b/spec/features/admin/admin_mode/login_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin Mode Login' do
+RSpec.describe 'Admin Mode Login', feature_category: :authentication_and_authorization do
include TermsHelper
include UserLoginHelper
include LdapHelpers
diff --git a/spec/features/admin/admin_mode/logout_spec.rb b/spec/features/admin/admin_mode/logout_spec.rb
index 3ca66ef0d6a..f4e8941d25a 100644
--- a/spec/features/admin/admin_mode/logout_spec.rb
+++ b/spec/features/admin/admin_mode/logout_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin Mode Logout', :js do
+RSpec.describe 'Admin Mode Logout', :js, feature_category: :authentication_and_authorization do
include TermsHelper
include UserLoginHelper
include Spec::Support::Helpers::Features::TopNavSpecHelpers
diff --git a/spec/features/admin/admin_mode/workers_spec.rb b/spec/features/admin/admin_mode/workers_spec.rb
index 8405e9132b6..f3639fd0800 100644
--- a/spec/features/admin/admin_mode/workers_spec.rb
+++ b/spec/features/admin/admin_mode/workers_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
# Test an operation that triggers background jobs requiring administrative rights
-RSpec.describe 'Admin mode for workers', :request_store do
+RSpec.describe 'Admin mode for workers', :request_store, feature_category: :authentication_and_authorization do
include Spec::Support::Helpers::Features::AdminUsersHelpers
let(:user) { create(:user) }
diff --git a/spec/features/admin/admin_mode_spec.rb b/spec/features/admin/admin_mode_spec.rb
index 33cf0e8c4f8..769ff75b5a2 100644
--- a/spec/features/admin/admin_mode_spec.rb
+++ b/spec/features/admin/admin_mode_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin mode', :js do
+RSpec.describe 'Admin mode', :js, feature_category: :not_owned do
include MobileHelpers
include Spec::Support::Helpers::Features::TopNavSpecHelpers
include StubENV
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index 6b147b01991..0cb813c40f4 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "Admin::Projects" do
+RSpec.describe "Admin::Projects", feature_category: :projects do
include Spec::Support::Helpers::Features::MembersHelpers
include Spec::Support::Helpers::Features::InviteMembersModalHelper
include Spec::Support::Helpers::ModalHelpers
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 92a3b388994..342c4d55dd6 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "Admin Runners" do
+RSpec.describe "Admin Runners", feature_category: :runner do
include Spec::Support::Helpers::Features::RunnersHelpers
include Spec::Support::Helpers::ModalHelpers
diff --git a/spec/features/admin/admin_search_settings_spec.rb b/spec/features/admin/admin_search_settings_spec.rb
index 989cb7cc787..3254bf75738 100644
--- a/spec/features/admin/admin_search_settings_spec.rb
+++ b/spec/features/admin/admin_search_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin searches application settings', :js do
+RSpec.describe 'Admin searches application settings', :js, feature_category: :global_search do
let_it_be(:admin) { create(:admin) }
let_it_be(:application_settings) { create(:application_setting) }
diff --git a/spec/features/admin/admin_sees_background_migrations_spec.rb b/spec/features/admin/admin_sees_background_migrations_spec.rb
index d72259d91b3..e1746dad196 100644
--- a/spec/features/admin/admin_sees_background_migrations_spec.rb
+++ b/spec/features/admin/admin_sees_background_migrations_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "Admin > Admin sees background migrations" do
+RSpec.describe "Admin > Admin sees background migrations", feature_category: :database do
let_it_be(:admin) { create(:admin) }
let(:job_class) { Gitlab::BackgroundMigration::CopyColumnUsingBackgroundMigrationJob }
diff --git a/spec/features/admin/admin_sees_project_statistics_spec.rb b/spec/features/admin/admin_sees_project_statistics_spec.rb
index 9d9217c4574..d3d0625ac43 100644
--- a/spec/features/admin/admin_sees_project_statistics_spec.rb
+++ b/spec/features/admin/admin_sees_project_statistics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "Admin > Admin sees project statistics" do
+RSpec.describe "Admin > Admin sees project statistics", feature_category: :projects do
let(:current_user) { create(:admin) }
before do
diff --git a/spec/features/admin/admin_sees_projects_statistics_spec.rb b/spec/features/admin/admin_sees_projects_statistics_spec.rb
index d340eb47f34..82361a985ae 100644
--- a/spec/features/admin/admin_sees_projects_statistics_spec.rb
+++ b/spec/features/admin/admin_sees_projects_statistics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "Admin > Admin sees projects statistics" do
+RSpec.describe "Admin > Admin sees projects statistics", feature_category: :projects do
let(:current_user) { create(:admin) }
before do
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 72c9053ba49..3fdcf4151ed 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin updates settings' do
+RSpec.describe 'Admin updates settings', feature_category: :not_owned do
include StubENV
include TermsHelper
include UsageDataHelpers
diff --git a/spec/features/admin/admin_system_info_spec.rb b/spec/features/admin/admin_system_info_spec.rb
index 8ff31dfded7..6c4a316ae77 100644
--- a/spec/features/admin/admin_system_info_spec.rb
+++ b/spec/features/admin/admin_system_info_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin System Info' do
+RSpec.describe 'Admin System Info', feature_category: :not_owned do
before do
admin = create(:admin)
sign_in(admin)
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index d93dac4834e..5e6cc206883 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
+RSpec.describe 'Admin > Users > Impersonation Tokens', :js, feature_category: :authentication_and_authorization do
include Spec::Support::Helpers::ModalHelpers
include Spec::Support::Helpers::AccessTokenHelpers
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index f4b7fa45e4f..1f40f1f1bce 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "Admin::Users" do
+RSpec.describe "Admin::Users", feature_category: :user_management do
let(:current_user) { create(:admin) }
before do
diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb
index 2dffef93600..318572a7664 100644
--- a/spec/features/admin/admin_uses_repository_checks_spec.rb
+++ b/spec/features/admin/admin_uses_repository_checks_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin uses repository checks', :request_store do
+RSpec.describe 'Admin uses repository checks', :request_store, feature_category: :user_management do
include StubENV
include Spec::Support::Helpers::ModalHelpers
diff --git a/spec/features/admin/dashboard_spec.rb b/spec/features/admin/dashboard_spec.rb
index e7ff8c23a8c..baca60134b9 100644
--- a/spec/features/admin/dashboard_spec.rb
+++ b/spec/features/admin/dashboard_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe 'admin visits dashboard' do
gitlab_enable_admin_mode_sign_in(admin)
end
- context 'counting forks', :js do
+ context 'counting forks', :js, feature_category: :source_code_management do
it 'correctly counts 2 forks of a project' do
project = create(:project)
project_fork = fork_project(project)
@@ -28,7 +28,7 @@ RSpec.describe 'admin visits dashboard' do
end
end
- describe 'Users statistic' do
+ describe 'Users statistic', feature_category: :user_management do
let_it_be(:users_statistics) { create(:users_statistics) }
it 'shows correct amounts of users', :aggregate_failures do
@@ -54,7 +54,7 @@ RSpec.describe 'admin visits dashboard' do
end
end
- describe 'Version check', :js do
+ describe 'Version check', :js, feature_category: :deployment_management do
it 'shows badge on CE' do
visit admin_root_path
diff --git a/spec/features/admin/integrations/instance_integrations_spec.rb b/spec/features/admin/integrations/instance_integrations_spec.rb
index 7b326ec161c..3b2ed1d9810 100644
--- a/spec/features/admin/integrations/instance_integrations_spec.rb
+++ b/spec/features/admin/integrations/instance_integrations_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Instance integrations', :js do
+RSpec.describe 'Instance integrations', :js, feature_category: :integrations do
include_context 'instance integration activation'
it_behaves_like 'integration settings form' do
diff --git a/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb b/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb
index 22a27b33671..d0ca5d76cc7 100644
--- a/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb
+++ b/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb
@@ -2,7 +2,8 @@
require 'spec_helper'
-RSpec.describe 'User activates the instance-level Mattermost Slash Command integration', :js do
+RSpec.describe 'User activates the instance-level Mattermost Slash Command integration', :js,
+feature_category: :integrations do
include_context 'instance integration activation'
before do
diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb
index 35b5c755b66..1552d4e6187 100644
--- a/spec/features/admin/users/user_spec.rb
+++ b/spec/features/admin/users/user_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin::Users::User' do
+RSpec.describe 'Admin::Users::User', feature_category: :user_management do
include Spec::Support::Helpers::Features::AdminUsersHelpers
include Spec::Support::Helpers::ModalHelpers
diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb
index 9c59f0226e0..53d3aec9cff 100644
--- a/spec/features/admin/users/users_spec.rb
+++ b/spec/features/admin/users/users_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin::Users' do
+RSpec.describe 'Admin::Users', feature_category: :user_management do
include Spec::Support::Helpers::Features::AdminUsersHelpers
include Spec::Support::Helpers::ModalHelpers
diff --git a/spec/features/alert_management/alert_details_spec.rb b/spec/features/alert_management/alert_details_spec.rb
index 579b8221041..26233fbda64 100644
--- a/spec/features/alert_management/alert_details_spec.rb
+++ b/spec/features/alert_management/alert_details_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Alert details', :js do
+RSpec.describe 'Alert details', :js, feature_category: :incident_management do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
let_it_be(:alert) { create(:alert_management_alert, project: project, status: 'triggered', title: 'Alert') }
diff --git a/spec/features/alert_management/alert_management_list_spec.rb b/spec/features/alert_management/alert_management_list_spec.rb
index 2fbce27033e..6ed3bdec5f5 100644
--- a/spec/features/alert_management/alert_management_list_spec.rb
+++ b/spec/features/alert_management/alert_management_list_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Alert Management index', :js do
+RSpec.describe 'Alert Management index', :js, feature_category: :incident_management do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
diff --git a/spec/features/alert_management/user_filters_alerts_by_status_spec.rb b/spec/features/alert_management/user_filters_alerts_by_status_spec.rb
index bebbbcbf5f7..c3dab05550e 100644
--- a/spec/features/alert_management/user_filters_alerts_by_status_spec.rb
+++ b/spec/features/alert_management/user_filters_alerts_by_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'User filters Alert Management table by status', :js do
+RSpec.describe 'User filters Alert Management table by status', :js, feature_category: :incident_management do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
let_it_be(:alert1, reload: true) { create(:alert_management_alert, :triggered, project: project) }
diff --git a/spec/features/alert_management/user_searches_alerts_spec.rb b/spec/features/alert_management/user_searches_alerts_spec.rb
index 3bb1b260f36..d1e400f4145 100644
--- a/spec/features/alert_management/user_searches_alerts_spec.rb
+++ b/spec/features/alert_management/user_searches_alerts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'User searches Alert Management alerts', :js do
+RSpec.describe 'User searches Alert Management alerts', :js, feature_category: :incident_management do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
let_it_be(:alert) { create(:alert_management_alert, project: project, status: 'triggered') }
diff --git a/spec/features/alert_management/user_updates_alert_status_spec.rb b/spec/features/alert_management/user_updates_alert_status_spec.rb
index 2d7be3a0022..98fd7449c4f 100644
--- a/spec/features/alert_management/user_updates_alert_status_spec.rb
+++ b/spec/features/alert_management/user_updates_alert_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'User updates Alert Management status', :js do
+RSpec.describe 'User updates Alert Management status', :js, feature_category: :incident_management do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
let_it_be(:alert) { create(:alert_management_alert, project: project, status: 'triggered') }
diff --git a/spec/features/alert_management_spec.rb b/spec/features/alert_management_spec.rb
index 3322c9c574f..de6b385b4cd 100644
--- a/spec/features/alert_management_spec.rb
+++ b/spec/features/alert_management_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Alert management', :js do
+RSpec.describe 'Alert management', :js, feature_category: :incident_management do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
diff --git a/spec/features/alerts_settings/user_views_alerts_settings_spec.rb b/spec/features/alerts_settings/user_views_alerts_settings_spec.rb
index 60f2f776595..70223b2c0d4 100644
--- a/spec/features/alerts_settings/user_views_alerts_settings_spec.rb
+++ b/spec/features/alerts_settings/user_views_alerts_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Alert integrations settings form', :js do
+RSpec.describe 'Alert integrations settings form', :js, feature_category: :incident_management do
let_it_be(:project) { create(:project) }
let_it_be(:maintainer) { create(:user) }
let_it_be(:developer) { create(:user) }
diff --git a/spec/lib/gitlab/auth/current_user_mode_spec.rb b/spec/lib/gitlab/auth/current_user_mode_spec.rb
index a21f0931b78..0a68a4a0ae2 100644
--- a/spec/lib/gitlab/auth/current_user_mode_spec.rb
+++ b/spec/lib/gitlab/auth/current_user_mode_spec.rb
@@ -194,10 +194,41 @@ RSpec.describe Gitlab::Auth::CurrentUserMode, :request_store do
it 'creates a timestamp in the session' do
subject.request_admin_mode!
+
subject.enable_admin_mode!(password: user.password)
expect(session).to include(expected_session_entry(be_within(1.second).of(Time.now)))
end
+
+ it 'returns true after successful enable' do
+ subject.request_admin_mode!
+
+ expect(subject.enable_admin_mode!(password: user.password)).to eq(true)
+ end
+
+ it 'returns false after unsuccessful enable' do
+ subject.request_admin_mode!
+
+ expect(subject.enable_admin_mode!(password: 'wrong password')).to eq(false)
+ end
+
+ context 'when user is not an admin' do
+ let(:user) { build_stubbed(:user) }
+
+ it 'returns false' do
+ subject.request_admin_mode!
+
+ expect(subject.enable_admin_mode!(password: user.password)).to eq(false)
+ end
+ end
+
+ context 'when admin mode is not requested' do
+ it 'raises error' do
+ expect do
+ subject.enable_admin_mode!(password: user.password)
+ end.to raise_error(Gitlab::Auth::CurrentUserMode::NotRequestedError)
+ end
+ end
end
describe '#disable_admin_mode!' do
diff --git a/spec/lib/gitlab/ci/lint_spec.rb b/spec/lib/gitlab/ci/lint_spec.rb
index cd3d4ee07bb..32afb893545 100644
--- a/spec/lib/gitlab/ci/lint_spec.rb
+++ b/spec/lib/gitlab/ci/lint_spec.rb
@@ -337,7 +337,7 @@ RSpec.describe Gitlab::Ci::Lint do
end
end
- context 'pipeline logger' do
+ describe 'pipeline logger' do
let(:counters) do
{
'count' => a_kind_of(Numeric),
@@ -346,7 +346,7 @@ RSpec.describe Gitlab::Ci::Lint do
}
end
- let(:loggable_data) do
+ let(:expected_data) do
{
'class' => 'Gitlab::Ci::Pipeline::Logger',
'config_build_context_duration_s' => counters,
@@ -363,7 +363,7 @@ RSpec.describe Gitlab::Ci::Lint do
'pipeline_persisted' => false,
'pipeline_source' => 'unknown',
'project_id' => project&.id,
- 'yaml_process_duration_s' => counters
+ 'yaml_process_duration_s' => a_kind_of(Numeric)
}
end
@@ -401,7 +401,7 @@ RSpec.describe Gitlab::Ci::Lint do
end
it 'creates a log entry' do
- expect(Gitlab::AppJsonLogger).to receive(:info).with(loggable_data)
+ expect(Gitlab::AppJsonLogger).to receive(:info).with(expected_data)
validate
end
@@ -422,7 +422,7 @@ RSpec.describe Gitlab::Ci::Lint do
let(:project) { nil }
let(:project_nil_loggable_data) do
- loggable_data.except('project_id')
+ expected_data.except('project_id')
end
it 'creates a log entry without project_id' do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
index fc3de2a14cd..16deeb6916f 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
@@ -173,21 +173,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::CancelPendingPipelines do
expect(build_statuses(prev_pipeline)).to contain_exactly('running', 'success', 'created')
expect(build_statuses(parent_pipeline)).to contain_exactly('running', 'running')
end
-
- context 'when feature flag ci_skip_auto_cancelation_on_child_pipelines is disabled' do
- before do
- stub_feature_flags(ci_skip_auto_cancelation_on_child_pipelines: false)
- end
-
- it 'does not cancel the parent pipeline' do
- expect(build_statuses(parent_pipeline)).to contain_exactly('running', 'running')
-
- perform
-
- expect(build_statuses(prev_pipeline)).to contain_exactly('success', 'canceled', 'canceled')
- expect(build_statuses(parent_pipeline)).to contain_exactly('running', 'running')
- end
- end
end
context 'when the previous pipeline source is webide' do
diff --git a/spec/lib/gitlab/ci/pipeline/logger_spec.rb b/spec/lib/gitlab/ci/pipeline/logger_spec.rb
index 049a9a416a0..4492ca716ae 100644
--- a/spec/lib/gitlab/ci/pipeline/logger_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/logger_spec.rb
@@ -22,55 +22,54 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Logger do
end
it 'records durations of instrumented operations' do
- loggable_data = {
+ logger.instrument(:expensive_operation) { 123 }
+
+ expected_data = {
'expensive_operation_duration_s' => {
'count' => 1,
'max' => a_kind_of(Numeric),
'sum' => a_kind_of(Numeric)
}
}
-
- logger.instrument(:expensive_operation) { 123 }
- expect(logger.observations_hash).to match(a_hash_including(loggable_data))
+ expect(logger.observations_hash).to match(a_hash_including(expected_data))
end
it 'raises an error when block is not provided' do
expect { logger.instrument(:expensive_operation) }
.to raise_error(ArgumentError, 'block not given')
end
+
+ context 'when once: true' do
+ it 'logs only one observation' do
+ logger.instrument(:expensive_operation, once: true) { 123 }
+ logger.instrument(:expensive_operation, once: true) { 123 }
+
+ expected_data = {
+ 'expensive_operation_duration_s' => a_kind_of(Numeric)
+ }
+ expect(logger.observations_hash).to match(a_hash_including(expected_data))
+ end
+ end
end
- describe '#instrument_with_sql', :request_store do
- subject(:instrument_with_sql) do
- logger.instrument_with_sql(:expensive_operation, &operation)
+ describe '#instrument_once_with_sql', :request_store do
+ subject(:instrument_once_with_sql) do
+ logger.instrument_once_with_sql(:expensive_operation, &operation)
end
- def loggable_data(count:, db_count: nil)
+ def expected_data(count:, db_count: nil)
database_name = Ci::ApplicationRecord.connection.pool.db_config.name
- keys = %W[
- expensive_operation_duration_s
- expensive_operation_db_count
- expensive_operation_db_primary_count
- expensive_operation_db_primary_duration_s
- expensive_operation_db_#{database_name}_count
- expensive_operation_db_#{database_name}_duration_s
- ]
-
- data = keys.each.with_object({}) do |key, accumulator|
- accumulator[key] = {
- 'count' => count,
- 'max' => a_kind_of(Numeric),
- 'sum' => a_kind_of(Numeric)
- }
- end
+ total_db_count = count * db_count if db_count
- if db_count
- data['expensive_operation_db_count']['max'] = db_count
- data['expensive_operation_db_count']['sum'] = count * db_count
- end
-
- data
+ {
+ "expensive_operation_duration_s" => a_kind_of(Numeric),
+ "expensive_operation_db_count" => total_db_count || a_kind_of(Numeric),
+ "expensive_operation_db_primary_count" => a_kind_of(Numeric),
+ "expensive_operation_db_primary_duration_s" => a_kind_of(Numeric),
+ "expensive_operation_db_#{database_name}_count" => a_kind_of(Numeric),
+ "expensive_operation_db_#{database_name}_duration_s" => a_kind_of(Numeric)
+ }
end
context 'with a single query' do
@@ -79,10 +78,10 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Logger do
it { is_expected.to eq(operation.call) }
it 'includes SQL metrics' do
- instrument_with_sql
+ instrument_once_with_sql
expect(logger.observations_hash)
- .to match(a_hash_including(loggable_data(count: 1, db_count: 1)))
+ .to match(a_hash_including(expected_data(count: 1, db_count: 1)))
end
end
@@ -92,21 +91,10 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Logger do
it { is_expected.to eq(operation.call) }
it 'includes SQL metrics' do
- instrument_with_sql
-
- expect(logger.observations_hash)
- .to match(a_hash_including(loggable_data(count: 1, db_count: 2)))
- end
- end
-
- context 'with multiple observations' do
- let(:operation) { -> { Ci::Build.count + Ci::Bridge.count } }
-
- it 'includes SQL metrics' do
- 2.times { logger.instrument_with_sql(:expensive_operation, &operation) }
+ instrument_once_with_sql
expect(logger.observations_hash)
- .to match(a_hash_including(loggable_data(count: 2, db_count: 2)))
+ .to match(a_hash_including(expected_data(count: 1, db_count: 2)))
end
end
@@ -116,7 +104,7 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Logger do
it { is_expected.to eq(operation.call) }
it 'does not include SQL metrics' do
- instrument_with_sql
+ instrument_once_with_sql
expect(logger.observations_hash.keys)
.to match_array(['expensive_operation_duration_s'])
@@ -126,14 +114,40 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Logger do
describe '#observe' do
it 'records durations of observed operations' do
- loggable_data = {
+ expect(logger.observe(:pipeline_creation_duration_s, 30)).to be_truthy
+
+ expected_data = {
'pipeline_creation_duration_s' => {
'sum' => 30, 'count' => 1, 'max' => 30
}
}
+ expect(logger.observations_hash).to match(a_hash_including(expected_data))
+ end
- expect(logger.observe(:pipeline_creation_duration_s, 30)).to be_truthy
- expect(logger.observations_hash).to match(a_hash_including(loggable_data))
+ context 'when once: true' do
+ it 'records the latest observation' do
+ expect(logger.observe(:pipeline_creation_duration_s, 20, once: true)).to be_truthy
+ expect(logger.observe(:pipeline_creation_duration_s, 30, once: true)).to be_truthy
+
+ expected_data = {
+ 'pipeline_creation_duration_s' => 30
+ }
+ expect(logger.observations_hash).to match(a_hash_including(expected_data))
+ end
+
+ it 'logs data as expected' do
+ expect(logger.observe(:pipeline_creation_duration_s, 30, once: true)).to be_truthy
+ expect(logger.observe(:pipeline_operation_x_duration_s, 20)).to be_truthy
+ expect(logger.observe(:pipeline_operation_x_duration_s, 20)).to be_truthy
+
+ expected_data = {
+ 'pipeline_creation_duration_s' => 30,
+ 'pipeline_operation_x_duration_s' => {
+ 'sum' => 40, 'count' => 2, 'max' => 20
+ }
+ }
+ expect(logger.observations_hash).to match(a_hash_including(expected_data))
+ end
end
end
@@ -152,7 +166,7 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Logger do
context 'when the feature flag is enabled' do
let(:flag) { true }
- let(:loggable_data) do
+ let(:expected_data) do
{
'class' => described_class.name.to_s,
'pipeline_id' => pipeline.id,
@@ -173,7 +187,7 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Logger do
it 'logs to application.json' do
expect(Gitlab::AppJsonLogger)
.to receive(:info)
- .with(a_hash_including(loggable_data))
+ .with(a_hash_including(expected_data))
.and_call_original
expect(commit).to be_truthy
@@ -194,7 +208,7 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Logger do
expect(Gitlab::AppJsonLogger)
.to receive(:info)
- .with(a_hash_including(loggable_data))
+ .with(a_hash_including(expected_data))
.and_call_original
expect(commit).to be_truthy
@@ -205,7 +219,7 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Logger do
let(:project) {}
let(:pipeline) { build(:ci_pipeline) }
- let(:loggable_data) do
+ let(:expected_data) do
{
'class' => described_class.name.to_s,
'pipeline_persisted' => false,
@@ -223,7 +237,7 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Logger do
it 'logs to application.json' do
expect(Gitlab::AppJsonLogger)
.to receive(:info)
- .with(a_hash_including(loggable_data))
+ .with(a_hash_including(expected_data))
.and_call_original
expect(commit).to be_truthy
diff --git a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
index b1bff242f33..e1c0da69317 100644
--- a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
+++ b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe Gitlab::Gfm::UploadsRewriter do
referenced_files.compact.select(&:exists?)
end
- shared_examples "files are accessible" do
+ shared_examples 'files are accessible' do
describe '#rewrite' do
subject(:rewrite) { new_text }
@@ -82,6 +82,18 @@ RSpec.describe Gitlab::Gfm::UploadsRewriter do
rewrite
expect(new_files).to be_empty
+ expect(new_text).to eq(text)
+ end
+
+ it 'skips non-existant files' do
+ allow_next_instance_of(FileUploader) do |file|
+ allow(file).to receive(:exists?).and_return(false)
+ end
+
+ rewrite
+
+ expect(new_files).to be_empty
+ expect(new_text).to eq(text)
end
end
end
@@ -107,11 +119,11 @@ RSpec.describe Gitlab::Gfm::UploadsRewriter do
end
end
- context "file are stored locally" do
- include_examples "files are accessible"
+ context 'file are stored locally' do
+ include_examples 'files are accessible'
end
- context "files are stored remotely" do
+ context 'files are stored remotely' do
before do
stub_uploads_object_storage(FileUploader)
@@ -120,7 +132,7 @@ RSpec.describe Gitlab::Gfm::UploadsRewriter do
end
end
- include_examples "files are accessible"
+ include_examples 'files are accessible'
end
describe '#needs_rewrite?' do
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 1984c1157fe..a00df3a7dda 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -1377,6 +1377,24 @@ RSpec.describe Gitlab::Git::Repository do
expect(branch).to eq(nil)
end
+
+ context 'when branch is ambiguous' do
+ let(:ambiguous_branch) { 'prefix' }
+ let(:branch_with_prefix) { 'prefix/branch' }
+
+ before do
+ repository.create_branch(branch_with_prefix)
+ end
+
+ after do
+ repository.delete_branch(branch_with_prefix)
+ end
+
+ it 'returns nil for ambiguous branch' do
+ expect(repository.find_branch(branch_with_prefix)).to be_a_kind_of(Gitlab::Git::Branch)
+ expect(repository.find_branch(ambiguous_branch)).to eq(nil)
+ end
+ end
end
describe '#branches' do
diff --git a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
index bd96e9baf1d..b413c47e033 100644
--- a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
@@ -102,6 +102,16 @@ RSpec.describe Gitlab::GitalyClient::RefService do
client.find_branch('name')
end
+
+ context 'when Gitaly returns a ambiguios reference error' do
+ it 'raises an UnknownRef error' do
+ expect_any_instance_of(Gitaly::RefService::Stub)
+ .to receive(:find_branch)
+ .and_raise(GRPC::BadStatus.new(2, 'reference is ambiguous'))
+
+ expect { client.find_branch('name') }.to raise_error(Gitlab::Git::AmbiguousRef, 'branch is ambiguous: name')
+ end
+ end
end
describe '#find_tag' do
diff --git a/spec/lib/gitlab/memory/reporter_spec.rb b/spec/lib/gitlab/memory/reporter_spec.rb
new file mode 100644
index 00000000000..7924b37cb4b
--- /dev/null
+++ b/spec/lib/gitlab/memory/reporter_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Memory::Reporter, :aggregate_failures do
+ subject(:reporter) { described_class.new }
+
+ let(:fake_report) do
+ Class.new do
+ attr_reader :did_run
+
+ def name
+ 'fake_report'
+ end
+
+ def run(report_id)
+ @did_run = true
+ '/path/to/report'
+ end
+ end
+ end
+
+ let(:report) { fake_report.new }
+
+ describe '#run_report' do
+ let(:report_duration_counter) { instance_double(::Prometheus::Client::Counter) }
+ let(:file_size) { 1_000_000 }
+
+ before do
+ allow(Gitlab::Metrics).to receive(:counter).and_return(report_duration_counter)
+ allow(report_duration_counter).to receive(:increment)
+
+ allow(::Prometheus::PidProvider).to receive(:worker_id).and_return('worker_1')
+ allow(File).to receive(:size).with('/path/to/report').and_return(file_size)
+
+ allow(SecureRandom).to receive(:uuid).and_return('abc123')
+ end
+
+ it 'runs the given report' do
+ expect { reporter.run_report(report) }.to change { report.did_run }.from(nil).to(true)
+ end
+
+ it 'logs duration and other metrics' do
+ expect(Gitlab::AppLogger).to receive(:info).with(
+ hash_including(
+ :duration_s,
+ :cpu_s,
+ perf_report_size_bytes: file_size,
+ message: 'finished',
+ pid: Process.pid,
+ worker_id: 'worker_1',
+ perf_report_worker_uuid: 'abc123',
+ perf_report: 'fake_report'
+ ))
+
+ reporter.run_report(report)
+ end
+
+ it 'increments Prometheus duration counter' do
+ expect(report_duration_counter).to receive(:increment).with({ report: 'fake_report' }, an_instance_of(Float))
+
+ reporter.run_report(report)
+ end
+
+ context 'when the report returns invalid file path' do
+ before do
+ allow(File).to receive(:size).with('/path/to/report').and_raise(Errno::ENOENT)
+ end
+
+ it 'logs `0` as `perf_report_size_bytes`' do
+ expect(Gitlab::AppLogger).to receive(:info).with(hash_including(perf_report_size_bytes: 0))
+
+ reporter.run_report(report)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/memory/reports/jemalloc_stats_spec.rb b/spec/lib/gitlab/memory/reports/jemalloc_stats_spec.rb
index de27c8352f9..ee4c6004c52 100644
--- a/spec/lib/gitlab/memory/reports/jemalloc_stats_spec.rb
+++ b/spec/lib/gitlab/memory/reports/jemalloc_stats_spec.rb
@@ -5,8 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Memory::Reports::JemallocStats do
let_it_be(:outdir) { Dir.mktmpdir }
- let(:filename_label) { SecureRandom.uuid }
- let(:jemalloc_stats) { described_class.new(reports_path: outdir, filename_label: filename_label) }
+ let(:jemalloc_stats) { described_class.new(reports_path: outdir) }
after do
FileUtils.rm_f(outdir)
@@ -27,14 +26,14 @@ RSpec.describe Gitlab::Memory::Reports::JemallocStats do
.to receive(:dump_stats)
.with(path: outdir,
tmp_dir: File.join(outdir, '/tmp'),
- filename_label: filename_label)
+ filename_label: 'test_report')
.and_return(report_path)
- expect(jemalloc_stats.run).to eq(report_path)
+ expect(jemalloc_stats.run('test_report')).to eq(report_path)
end
describe 'reports cleanup' do
- let(:jemalloc_stats) { described_class.new(reports_path: outdir, filename_label: filename_label) }
+ let(:jemalloc_stats) { described_class.new(reports_path: outdir) }
before do
stub_env('GITLAB_DIAGNOSTIC_REPORTS_JEMALLOC_MAX_REPORTS_STORED', 3)
@@ -62,7 +61,7 @@ RSpec.describe Gitlab::Memory::Reports::JemallocStats do
end
it 'keeps only `max_reports_stored` total newest files' do
- expect { jemalloc_stats.run }
+ expect { jemalloc_stats.run('test_report') }
.to change { Dir.entries(outdir).count { |e| e.match(/jemalloc_stats.*/) } }
.from(5).to(3)
@@ -90,7 +89,7 @@ RSpec.describe Gitlab::Memory::Reports::JemallocStats do
end
it 'does not remove any reports' do
- expect { jemalloc_stats.run }
+ expect { jemalloc_stats.run('test_report') }
.not_to change { Dir.entries(outdir).count { |e| e.match(/jemalloc_stats.*/) } }
end
end
@@ -105,7 +104,7 @@ RSpec.describe Gitlab::Memory::Reports::JemallocStats do
it 'does not run the report and returns nil' do
expect(Gitlab::Memory::Jemalloc).not_to receive(:dump_stats)
- expect(jemalloc_stats.run).to be_nil
+ expect(jemalloc_stats.run('test_report')).to be_nil
end
end
end
diff --git a/spec/lib/gitlab/memory/reports_daemon_spec.rb b/spec/lib/gitlab/memory/reports_daemon_spec.rb
index ab616e92b00..b6be4eac919 100644
--- a/spec/lib/gitlab/memory/reports_daemon_spec.rb
+++ b/spec/lib/gitlab/memory/reports_daemon_spec.rb
@@ -3,85 +3,56 @@
require 'spec_helper'
RSpec.describe Gitlab::Memory::ReportsDaemon, :aggregate_failures do
- let(:daemon) { described_class.new }
+ let(:reporter) { instance_double(Gitlab::Memory::Reporter) }
+ let(:reports) { nil }
let_it_be(:tmp_dir) { Dir.mktmpdir }
+ subject(:daemon) { described_class.new(reporter: reporter, reports: reports) }
+
after(:all) do
FileUtils.remove_entry(tmp_dir)
end
describe '#run_thread' do
- let(:report_duration_counter) { instance_double(::Prometheus::Client::Counter) }
- let(:file_size) { 1_000_000 }
-
before do
- allow(Gitlab::Metrics).to receive(:counter).and_return(report_duration_counter)
- allow(report_duration_counter).to receive(:increment)
-
# make sleep no-op
allow(daemon).to receive(:sleep) {}
# let alive return 3 times: true, true, false
allow(daemon).to receive(:alive).and_return(true, true, false)
-
- allow(File).to receive(:size).with(/#{daemon.reports_path}.*\.json/).and_return(file_size)
- end
-
- it 'runs reports, logs and sets gauge' do
- expect(daemon.send(:reports))
- .to all(receive(:run).twice { Tempfile.new("report.json", tmp_dir).path })
-
- expect(::Prometheus::PidProvider).to receive(:worker_id).at_least(:once).and_return('worker_1')
-
- expect(Gitlab::AppLogger).to receive(:info).with(
- hash_including(
- :duration_s,
- :cpu_s,
- :perf_report_worker_uuid,
- perf_report_size_bytes: file_size,
- message: 'finished',
- pid: Process.pid,
- worker_id: 'worker_1',
- perf_report: 'jemalloc_stats'
- )).twice
-
- expect(report_duration_counter).to receive(:increment).with({ report: 'jemalloc_stats' }, an_instance_of(Float))
-
- daemon.send(:run_thread)
end
- context 'when the report object returns invalid file path' do
- before do
- allow(File).to receive(:size).with(/#{daemon.reports_path}.*\.json/).and_raise(Errno::ENOENT)
- end
-
- it 'logs `0` as `perf_report_size_bytes`' do
- expect(daemon.send(:reports))
- .to all(receive(:run).twice { Tempfile.new("report.json", tmp_dir).path })
-
- expect(Gitlab::AppLogger).to receive(:info).with(hash_including(perf_report_size_bytes: 0)).twice
+ context 'with default reports' do
+ it 'runs them using the given reporter' do
+ expect(reporter).to receive(:run_report).twice.with(an_instance_of(Gitlab::Memory::Reports::JemallocStats))
daemon.send(:run_thread)
end
end
- it 'allows configure and run multiple reports' do
+ context 'with inactive reports' do
# rubocop: disable RSpec/VerifiedDoubles
# We test how ReportsDaemon could be extended in the future
# We configure it with new reports classes which are not yet defined so we cannot make this an instance_double.
- active_report_1 = double("Active Report 1", active?: true)
- active_report_2 = double("Active Report 2", active?: true)
- inactive_report = double("Inactive Report", active?: false)
+ let(:active_report_1) { double("Active Report 1", active?: true) }
+ let(:active_report_2) { double("Active Report 2", active?: true) }
+ let(:inactive_report) { double("Inactive Report", active?: false) }
# rubocop: enable RSpec/VerifiedDoubles
- allow(daemon).to receive(:reports).and_return([active_report_1, inactive_report, active_report_2])
+ let(:reports) do
+ [active_report_1, active_report_2, inactive_report]
+ end
- expect(active_report_1).to receive(:run).and_return(File.join(tmp_dir, 'report_1.json')).twice
- expect(active_report_2).to receive(:run).and_return(File.join(tmp_dir, 'report_2.json')).twice
- expect(inactive_report).not_to receive(:run)
+ it 'runs only active reports' do
+ expect(reporter).to receive(:run_report).ordered.with(active_report_1)
+ expect(reporter).to receive(:run_report).ordered.with(active_report_2)
+ expect(reporter).to receive(:run_report).ordered.with(active_report_1)
+ expect(reporter).to receive(:run_report).ordered.with(active_report_2)
+ expect(reporter).not_to receive(:run_report).with(inactive_report)
- daemon.send(:run_thread)
+ daemon.send(:run_thread)
+ end
end
context 'sleep timers logic' do
@@ -90,9 +61,6 @@ RSpec.describe Gitlab::Memory::ReportsDaemon, :aggregate_failures do
daemon = described_class.new
allow(daemon).to receive(:alive).and_return(true, true, false)
- expect(daemon.send(:reports))
- .to all(receive(:run).twice { Tempfile.new("report.json", tmp_dir).path })
-
expect(daemon).to receive(:sleep).with(described_class::DEFAULT_SLEEP_S).ordered
expect(daemon).to receive(:sleep).with(described_class::DEFAULT_SLEEP_BETWEEN_REPORTS_S).ordered
expect(daemon).to receive(:sleep).with(described_class::DEFAULT_SLEEP_S).ordered
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index 2ecd10cccc6..9b7a63bffdf 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -175,26 +175,31 @@ RSpec.describe Member do
end
context 'member role access level' do
- let_it_be(:member) { create(:group_member, access_level: Gitlab::Access::DEVELOPER) }
+ let_it_be_with_reload(:member) { create(:group_member, access_level: Gitlab::Access::DEVELOPER) }
- context 'no member role is associated' do
+ context 'when no member role is associated' do
it 'is valid' do
expect(member).to be_valid
end
end
- context 'member role is associated' do
+ context 'when member role is associated' do
let!(:member_role) do
- create(:member_role, members: [member], base_access_level: Gitlab::Access::DEVELOPER)
+ create(
+ :member_role,
+ members: [member],
+ base_access_level: Gitlab::Access::DEVELOPER,
+ namespace: member.member_namespace
+ )
end
- context 'member role matches access level' do
+ context 'when member role matches access level' do
it 'is valid' do
expect(member).to be_valid
end
end
- context 'member role does not match access level' do
+ context 'when member role does not match access level' do
it 'is invalid' do
member_role.base_access_level = Gitlab::Access::MAINTAINER
@@ -202,13 +207,57 @@ RSpec.describe Member do
end
end
- context 'access_level cannot be changed' do
+ context 'when access_level is changed' do
it 'is invalid' do
member.access_level = Gitlab::Access::MAINTAINER
expect(member).not_to be_valid
- expect(member.errors.full_messages).to include(
- "Access level cannot be changed since member is associated with a custom role"
+ expect(member.errors[:access_level]).to include(
+ _("cannot be changed since member is associated with a custom role")
+ )
+ end
+ end
+ end
+ end
+
+ context 'member role namespace' do
+ let_it_be_with_reload(:member) { create(:group_member) }
+
+ context 'when no member role is associated' do
+ it 'is valid' do
+ expect(member).to be_valid
+ end
+ end
+
+ context 'when member role is associated' do
+ let_it_be(:member_role) do
+ create(:member_role, members: [member], namespace: member.group, base_access_level: member.access_level)
+ end
+
+ context 'when member#member_namespace is a group within hierarchy of member_role#namespace' do
+ it 'is valid' do
+ member.member_namespace = create(:group, parent: member_role.namespace)
+
+ expect(member).to be_valid
+ end
+ end
+
+ context 'when member#member_namespace is a project within hierarchy of member_role#namespace' do
+ it 'is valid' do
+ project = create(:project, group: member_role.namespace)
+ member.member_namespace = Namespace.find(project.parent_id)
+
+ expect(member).to be_valid
+ end
+ end
+
+ context 'when member#member_namespace is outside hierarchy of member_role#namespace' do
+ it 'is invalid' do
+ member.member_namespace = create(:group)
+
+ expect(member).not_to be_valid
+ expect(member.errors[:member_namespace]).to include(
+ _("must be in same hierarchy as custom role's namespace")
)
end
end
@@ -248,7 +297,7 @@ RSpec.describe Member do
accepted_invite_user = build(:user, state: :active)
@accepted_invite_member = create(:project_member, :invited, :developer, project: project)
- .tap { |u| u.accept_invite!(accepted_invite_user) }
+ .tap { |u| u.accept_invite!(accepted_invite_user) }
requested_user = create(:user).tap { |u| project.request_access(u) }
@requested_member = project.requesters.find_by(user_id: requested_user.id)
@@ -612,14 +661,14 @@ RSpec.describe Member do
subject { described_class.authorizable.to_a }
it 'includes the member who has an associated user record,'\
- 'but also having an invite_token' do
- member = create(:project_member,
- :developer,
- :invited,
- user: create(:user))
+ 'but also having an invite_token' do
+ member = create(:project_member,
+ :developer,
+ :invited,
+ user: create(:user))
- expect(subject).to include(member)
- end
+ expect(subject).to include(member)
+ end
it { is_expected.to include @owner }
it { is_expected.to include @maintainer }
diff --git a/spec/models/members/member_role_spec.rb b/spec/models/members/member_role_spec.rb
index e2691e2e78c..f9d6757bb90 100644
--- a/spec/models/members/member_role_spec.rb
+++ b/spec/models/members/member_role_spec.rb
@@ -9,39 +9,50 @@ RSpec.describe MemberRole do
end
describe 'validation' do
- subject { described_class.new }
+ subject(:member_role) { build(:member_role) }
it { is_expected.to validate_presence_of(:namespace) }
it { is_expected.to validate_presence_of(:base_access_level) }
- context 'for namespace' do
- subject { build(:member_role) }
-
+ context 'when for namespace' do
let_it_be(:root_group) { create(:group) }
context 'when namespace is a subgroup' do
it 'is invalid' do
subgroup = create(:group, parent: root_group)
- subject.namespace = subgroup
+ member_role.namespace = subgroup
- expect(subject).to be_invalid
+ expect(member_role).to be_invalid
+ expect(member_role.errors[:namespace]).to include(
+ s_("MemberRole|must be top-level namespace")
+ )
end
end
context 'when namespace is a root group' do
it 'is valid' do
- subject.namespace = root_group
+ member_role.namespace = root_group
- expect(subject).to be_valid
+ expect(member_role).to be_valid
end
end
context 'when namespace is not present' do
it 'is invalid with a different error message' do
- subject.namespace = nil
+ member_role.namespace = nil
+
+ expect(member_role).to be_invalid
+ expect(member_role.errors[:namespace]).to include(_("can't be blank"))
+ end
+ end
+
+ context 'when namespace is outside hierarchy of member' do
+ it 'creates a validation error' do
+ member_role.save!
+ member_role.namespace = create(:group)
- expect(subject).to be_invalid
- expect(subject.errors.full_messages).to eq(["Namespace can't be blank"])
+ expect(member_role).not_to be_valid
+ expect(member_role.errors[:namespace]).to include(s_("MemberRole|can't be changed"))
end
end
end
diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb
index 750b9a39e15..186afaa1b79 100644
--- a/spec/requests/api/branches_spec.rb
+++ b/spec/requests/api/branches_spec.rb
@@ -344,6 +344,18 @@ RSpec.describe API::Branches do
end
end
+ context 'when branch is ambiguous' do
+ let(:branch_name) { 'prefix' }
+
+ before do
+ project.repository.create_branch('prefix/branch')
+ end
+
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, current_user) }
+ end
+ end
+
context 'when repository does not exist' do
it_behaves_like '404 response' do
let(:project) { create(:project, creator: user) }
diff --git a/spec/services/ci/append_build_trace_service_spec.rb b/spec/services/ci/append_build_trace_service_spec.rb
index 487dbacbe90..36061bc3596 100644
--- a/spec/services/ci/append_build_trace_service_spec.rb
+++ b/spec/services/ci/append_build_trace_service_spec.rb
@@ -76,4 +76,20 @@ RSpec.describe Ci::AppendBuildTraceService do
expect(build.failure_reason).to eq 'trace_size_exceeded'
end
end
+
+ context 'when debug_trace param is provided' do
+ let(:metadata) { Ci::BuildMetadata.find_by(build_id: build) }
+
+ it 'changes the build metadata debug_trace value' do
+ stream_size = 192.kilobytes
+ body_data = 'x' * stream_size
+ content_range = "0-#{stream_size}"
+
+ described_class
+ .new(build, content_range: content_range, debug_trace: true)
+ .execute(body_data)
+
+ expect(metadata.debug_trace_enabled).to be(true)
+ end
+ end
end
diff --git a/spec/services/ci/create_pipeline_service/logger_spec.rb b/spec/services/ci/create_pipeline_service/logger_spec.rb
index 9cd5d48a439..76155690ced 100644
--- a/spec/services/ci/create_pipeline_service/logger_spec.rb
+++ b/spec/services/ci/create_pipeline_service/logger_spec.rb
@@ -2,8 +2,8 @@
require 'spec_helper'
-RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectness do
- context 'pipeline logger' do
+RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectness do # rubocop: disable RSpec/FilePath
+ describe 'pipeline logger' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { project.first_owner }
@@ -12,10 +12,6 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
let(:pipeline) { service.execute(:push).payload }
let(:file_location) { 'spec/fixtures/gitlab/ci/external_files/.gitlab-ci-template-1.yml' }
- before do
- stub_ci_pipeline_yaml_file(gitlab_ci_yaml)
- end
-
let(:counters) do
{
'count' => a_kind_of(Numeric),
@@ -32,15 +28,19 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
'pipeline_persisted' => true,
'project_id' => project.id,
'pipeline_creation_service_duration_s' => a_kind_of(Numeric),
- 'pipeline_creation_duration_s' => counters,
- 'pipeline_size_count' => counters,
- 'pipeline_step_gitlab_ci_pipeline_chain_seed_duration_s' => counters,
+ 'pipeline_creation_duration_s' => a_kind_of(Numeric),
+ 'pipeline_size_count' => a_kind_of(Numeric),
+ 'pipeline_step_gitlab_ci_pipeline_chain_seed_duration_s' => a_kind_of(Numeric),
'pipeline_seed_build_inclusion_duration_s' => counters,
'pipeline_builds_tags_count' => a_kind_of(Numeric),
'pipeline_builds_distinct_tags_count' => a_kind_of(Numeric)
}
end
+ before do
+ stub_ci_pipeline_yaml_file(gitlab_ci_yaml)
+ end
+
context 'when the duration is under the threshold' do
it 'does not create a log entry but it collects the data' do
expect(Gitlab::AppJsonLogger).not_to receive(:info)
@@ -49,9 +49,9 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
expect(service.logger.observations_hash)
.to match(
a_hash_including(
- 'pipeline_creation_duration_s' => counters,
- 'pipeline_size_count' => counters,
- 'pipeline_step_gitlab_ci_pipeline_chain_seed_duration_s' => counters
+ 'pipeline_creation_duration_s' => a_kind_of(Numeric),
+ 'pipeline_size_count' => a_kind_of(Numeric),
+ 'pipeline_step_gitlab_ci_pipeline_chain_seed_duration_s' => a_kind_of(Numeric)
)
)
end
@@ -60,7 +60,7 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
context 'when the durations exceeds the threshold' do
let(:timer) do
proc do
- @timer = @timer.to_i + 30
+ @timer = @timer.to_i + 30 # rubocop: disable RSpec/InstanceVariable
end
end
@@ -86,17 +86,15 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
'pipeline_persisted' => false,
'project_id' => project.id,
'pipeline_creation_service_duration_s' => a_kind_of(Numeric),
- 'pipeline_step_gitlab_ci_pipeline_chain_seed_duration_s' => counters
+ 'pipeline_step_gitlab_ci_pipeline_chain_seed_duration_s' => a_kind_of(Numeric)
}
end
- before do
+ it 'creates a log entry' do
allow_next_instance_of(Ci::Pipeline) do |pipeline|
expect(pipeline).to receive(:save!).and_raise { RuntimeError }
end
- end
- it 'creates a log entry' do
expect(Gitlab::AppJsonLogger)
.to receive(:info)
.with(a_hash_including(loggable_data))
@@ -123,7 +121,7 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
context 'when the size exceeds the threshold' do
before do
allow_next_instance_of(Ci::Pipeline) do |pipeline|
- allow(pipeline).to receive(:total_size) { 5000 }
+ allow(pipeline).to receive(:total_size).and_return(5000)
end
end