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:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-03-10 09:15:47 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-03-10 09:15:47 +0300
commita46f64e06d98c745c4e7ceee705022273924cb78 (patch)
treea0f4336e110f2f24cc276836e88d1e34dab082e1
parentd5954a6879517e10e80ffe9b2a200730a748e3ac (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/as-if-jh.gitlab-ci.yml5
-rw-r--r--app/assets/stylesheets/framework/tables.scss2
-rw-r--r--app/assets/stylesheets/framework/wells.scss4
-rw-r--r--app/assets/stylesheets/page_bundles/tree.scss1
-rw-r--r--app/controllers/concerns/renders_projects_list.rb1
-rw-r--r--app/helpers/sidebars_helper.rb17
-rw-r--r--app/models/members/member_role.rb60
-rw-r--r--app/models/namespace.rb1
-rw-r--r--app/models/project.rb6
-rw-r--r--app/services/projects/batch_open_merge_requests_count_service.rb18
-rw-r--r--app/services/projects/open_merge_requests_count_service.rb8
-rw-r--r--app/views/layouts/nav/sidebar/_your_work.html.haml2
-rw-r--r--doc/topics/your_work.md3
-rw-r--r--doc/user/application_security/security_dashboard/img/security_center_dashboard_v13_4.pngbin29797 -> 0 bytes
-rw-r--r--doc/user/application_security/security_dashboard/img/security_center_dashboard_v15_10.pngbin0 -> 73370 bytes
-rw-r--r--doc/user/application_security/security_dashboard/index.md2
-rw-r--r--lib/banzai/reference_parser/commit_parser.rb7
-rw-r--r--lib/banzai/reference_parser/commit_range_parser.rb7
-rw-r--r--locale/gitlab.pot6
-rw-r--r--spec/features/dashboard/projects_spec.rb1
-rw-r--r--spec/models/member_spec.rb91
-rw-r--r--spec/models/members/member_role_spec.rb131
-rw-r--r--spec/models/merge_request_spec.rb7
-rw-r--r--spec/models/namespace_spec.rb1
-rw-r--r--spec/services/merge_requests/close_service_spec.rb6
-rw-r--r--spec/services/merge_requests/create_service_spec.rb7
-rw-r--r--spec/services/merge_requests/post_merge_service_spec.rb6
-rw-r--r--spec/services/merge_requests/reopen_service_spec.rb6
-rw-r--r--spec/services/projects/batch_open_merge_requests_count_service_spec.rb32
-rw-r--r--spec/support/db_cleaner.rb3
30 files changed, 115 insertions, 326 deletions
diff --git a/.gitlab/ci/as-if-jh.gitlab-ci.yml b/.gitlab/ci/as-if-jh.gitlab-ci.yml
index 73247984589..6bd46bee770 100644
--- a/.gitlab/ci/as-if-jh.gitlab-ci.yml
+++ b/.gitlab/ci/as-if-jh.gitlab-ci.yml
@@ -35,11 +35,12 @@ prepare-as-if-jh-branch:
- .shared-as-if-jh
- .as-if-jh:rules:prepare-as-if-jh
stage: prepare
- variables:
- GIT_DEPTH: "0" # clone the full history so we can push
needs:
- add-jh-files
script:
+ # Fetch for the history of the branch so it does not cause the following error:
+ # ! [remote rejected] ref -> ref (shallow update not allowed)
+ - git fetch --unshallow --filter=tree:0 origin "${CI_COMMIT_SHA}"
- git checkout -b "${AS_IF_JH_BRANCH}"
- git add ${JH_FILES_TO_COMMIT}
- git commit -m 'Add JH files' # TODO: Mark which SHA we add
diff --git a/app/assets/stylesheets/framework/tables.scss b/app/assets/stylesheets/framework/tables.scss
index 8b2a494527b..a288701595e 100644
--- a/app/assets/stylesheets/framework/tables.scss
+++ b/app/assets/stylesheets/framework/tables.scss
@@ -41,7 +41,7 @@ table {
}
th {
- @include gl-bg-gray-50;
+ @include gl-bg-gray-10;
border-bottom: 0;
&.wide {
diff --git a/app/assets/stylesheets/framework/wells.scss b/app/assets/stylesheets/framework/wells.scss
index cb9c623c8fc..1434c16b68f 100644
--- a/app/assets/stylesheets/framework/wells.scss
+++ b/app/assets/stylesheets/framework/wells.scss
@@ -1,7 +1,7 @@
.info-well {
- background: $gray-light;
+ background: $gray-10;
color: $gl-text-color;
- border: 1px solid $border-color;
+ border: 1px solid $gray-100;
border-radius: $border-radius-default;
.card.card-body-segment {
diff --git a/app/assets/stylesheets/page_bundles/tree.scss b/app/assets/stylesheets/page_bundles/tree.scss
index 50d9684c7d2..4fa3f4f63f1 100644
--- a/app/assets/stylesheets/page_bundles/tree.scss
+++ b/app/assets/stylesheets/page_bundles/tree.scss
@@ -103,7 +103,6 @@
tr {
border-bottom: 1px solid var(--gray-50, $gray-50);
- border-top: 1px solid var(--gray-50, $gray-50);
&:last-of-type {
border-bottom-color: transparent;
diff --git a/app/controllers/concerns/renders_projects_list.rb b/app/controllers/concerns/renders_projects_list.rb
index 05bd9972ee7..739b2be3fe9 100644
--- a/app/controllers/concerns/renders_projects_list.rb
+++ b/app/controllers/concerns/renders_projects_list.rb
@@ -8,6 +8,7 @@ module RendersProjectsList
# once when the entities are rendered
projects.each(&:forks_count)
projects.each(&:open_issues_count)
+ projects.each(&:open_merge_requests_count)
projects
end
diff --git a/app/helpers/sidebars_helper.rb b/app/helpers/sidebars_helper.rb
index 84d552c15ec..b4657fce467 100644
--- a/app/helpers/sidebars_helper.rb
+++ b/app/helpers/sidebars_helper.rb
@@ -34,6 +34,12 @@ module SidebarsHelper
Sidebars::Groups::Context.new(**context_data, **args)
end
+ def your_work_sidebar_context(user, **args)
+ context_data = your_work_context_data(user)
+
+ Sidebars::Context.new(**context_data, **args)
+ end
+
def super_sidebar_context(user, group:, project:, panel:)
{
current_menu_items: panel.super_sidebar_menu_items,
@@ -94,7 +100,8 @@ module SidebarsHelper
context = group_sidebar_context(group, user, **context_adds)
Sidebars::Groups::SuperSidebarPanel.new(context)
else
- Sidebars::YourWork::Panel.new(Sidebars::Context.new(current_user: user, container: nil, **context_adds))
+ context = your_work_sidebar_context(user, **context_adds)
+ Sidebars::YourWork::Panel.new(context)
end
end
@@ -203,6 +210,14 @@ module SidebarsHelper
container: group
}
end
+
+ def your_work_context_data(user)
+ {
+ current_user: user,
+ container: user,
+ show_security_dashboard: false
+ }
+ end
end
SidebarsHelper.prepend_mod_with('SidebarsHelper')
diff --git a/app/models/members/member_role.rb b/app/models/members/member_role.rb
deleted file mode 100644
index 77e97a35b6d..00000000000
--- a/app/models/members/member_role.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-class MemberRole < ApplicationRecord # rubocop:disable Gitlab/NamespacedClass
- include IgnorableColumns
- ignore_column :download_code, remove_with: '15.9', remove_after: '2023-01-22'
-
- MAX_COUNT_PER_GROUP_HIERARCHY = 10
-
- has_many :members
- belongs_to :namespace
-
- validates :namespace, presence: true
- validates :base_access_level, presence: true
- validate :belongs_to_top_level_namespace
- validate :max_count_per_group_hierarchy, on: :create
- validate :validate_namespace_locked, on: :update
- validate :attributes_locked_after_member_associated, on: :update
-
- validates_associated :members
-
- before_destroy :prevent_delete_after_member_associated
-
- private
-
- def belongs_to_top_level_namespace
- return if !namespace || namespace.root?
-
- errors.add(:namespace, s_("MemberRole|must be top-level namespace"))
- end
-
- def max_count_per_group_hierarchy
- return unless namespace
- return if namespace.member_roles.count < MAX_COUNT_PER_GROUP_HIERARCHY
-
- errors.add(:namespace, s_("MemberRole|maximum number of Member Roles are already in use by the group hierarchy. "\
- "Please delete an existing Member Role."))
- end
-
- def validate_namespace_locked
- return unless namespace_id_changed?
-
- errors.add(:namespace, s_("MemberRole|can't be changed"))
- end
-
- def attributes_locked_after_member_associated
- return unless members.present?
-
- errors.add(:base, s_("MemberRole|cannot be changed because it is already assigned to a user. "\
- "Please create a new Member Role instead"))
- end
-
- def prevent_delete_after_member_associated
- return unless members.present?
-
- errors.add(:base, s_("MemberRole|cannot be deleted because it is already assigned to a user. "\
- "Please disassociate the member role from all users before deletion."))
-
- throw :abort # rubocop:disable Cop/BanCatchThrow
- end
-end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 13466f147bd..2d264e40f33 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -52,7 +52,6 @@ class Namespace < ApplicationRecord
has_one :namespace_statistics
has_one :namespace_route, foreign_key: :namespace_id, autosave: false, inverse_of: :namespace, class_name: 'Route'
has_many :namespace_members, foreign_key: :member_namespace_id, inverse_of: :member_namespace, class_name: 'Member'
- has_many :member_roles
has_one :namespace_ldap_settings, inverse_of: :namespace, class_name: 'Namespaces::LdapSetting', autosave: true
diff --git a/app/models/project.rb b/app/models/project.rb
index f96cff89221..dba14f92e4d 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -2082,7 +2082,11 @@ class Project < ApplicationRecord
# rubocop: disable CodeReuse/ServiceClass
def open_merge_requests_count(_current_user = nil)
- Projects::OpenMergeRequestsCountService.new(self).count
+ BatchLoader.for(self).batch do |projects, loader|
+ ::Projects::BatchOpenMergeRequestsCountService.new(projects)
+ .refresh_cache_and_retrieve_data
+ .each { |project, count| loader.call(project, count) }
+ end
end
# rubocop: enable CodeReuse/ServiceClass
diff --git a/app/services/projects/batch_open_merge_requests_count_service.rb b/app/services/projects/batch_open_merge_requests_count_service.rb
new file mode 100644
index 00000000000..62d1b018a55
--- /dev/null
+++ b/app/services/projects/batch_open_merge_requests_count_service.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+# Service class for getting and caching the number of merge requests of several projects
+# Warning: do not user this service with a really large set of projects
+# because the service use maps to retrieve the project ids
+module Projects
+ class BatchOpenMergeRequestsCountService < Projects::BatchCountService
+ # rubocop: disable CodeReuse/ActiveRecord
+ def global_count
+ @global_count ||= count_service.query(project_ids).group(:project_id).count
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def count_service
+ ::Projects::OpenMergeRequestsCountService
+ end
+ end
+end
diff --git a/app/services/projects/open_merge_requests_count_service.rb b/app/services/projects/open_merge_requests_count_service.rb
index 76ec13952ab..c67ebf2f26a 100644
--- a/app/services/projects/open_merge_requests_count_service.rb
+++ b/app/services/projects/open_merge_requests_count_service.rb
@@ -4,12 +4,12 @@ module Projects
# Service class for counting and caching the number of open merge requests of
# a project.
class OpenMergeRequestsCountService < Projects::CountService
- def relation_for_count
- @project.merge_requests.opened
- end
-
def cache_key_name
'open_merge_requests_count'
end
+
+ def self.query(project_ids)
+ MergeRequest.opened.of_projects(project_ids)
+ end
end
end
diff --git a/app/views/layouts/nav/sidebar/_your_work.html.haml b/app/views/layouts/nav/sidebar/_your_work.html.haml
index 0eba5045ab1..0da66c2e14e 100644
--- a/app/views/layouts/nav/sidebar/_your_work.html.haml
+++ b/app/views/layouts/nav/sidebar/_your_work.html.haml
@@ -1 +1 @@
-= render partial: 'shared/nav/sidebar', object: Sidebars::YourWork::Panel.new(Sidebars::Context.new(current_user: current_user, container: nil))
+= render partial: 'shared/nav/sidebar', object: Sidebars::YourWork::Panel.new(your_work_sidebar_context(current_user))
diff --git a/doc/topics/your_work.md b/doc/topics/your_work.md
index a73838ae8e3..268a6c4df5b 100644
--- a/doc/topics/your_work.md
+++ b/doc/topics/your_work.md
@@ -18,3 +18,6 @@ The **Your work** left sidebar provides access to your:
- [Milestones](../user/project/milestones/index.md)
- [Snippets](../user/snippets.md#snippets)
- [Activity](../user/profile/index.md#view-your-activity)
+- [Environments dashboard](../ci/environments/environments_dashboard.md)
+- [Operations dashboard](../user/operations_dashboard/index.md)
+- [Security center](../user/application_security/security_dashboard/index.md#security-center)
diff --git a/doc/user/application_security/security_dashboard/img/security_center_dashboard_v13_4.png b/doc/user/application_security/security_dashboard/img/security_center_dashboard_v13_4.png
deleted file mode 100644
index 5379b5c6e5d..00000000000
--- a/doc/user/application_security/security_dashboard/img/security_center_dashboard_v13_4.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/application_security/security_dashboard/img/security_center_dashboard_v15_10.png b/doc/user/application_security/security_dashboard/img/security_center_dashboard_v15_10.png
new file mode 100644
index 00000000000..106b0a13063
--- /dev/null
+++ b/doc/user/application_security/security_dashboard/img/security_center_dashboard_v15_10.png
Binary files differ
diff --git a/doc/user/application_security/security_dashboard/index.md b/doc/user/application_security/security_dashboard/index.md
index 4b9aeefcfe9..1a8b4dac10e 100644
--- a/doc/user/application_security/security_dashboard/index.md
+++ b/doc/user/application_security/security_dashboard/index.md
@@ -133,7 +133,7 @@ The Security Center includes:
- A [vulnerability report](../vulnerability_report/index.md).
- A settings area to configure which projects to display.
-![Security Center Dashboard with projects](img/security_center_dashboard_v13_4.png)
+![Security Center Dashboard with projects](img/security_center_dashboard_v15_10.png)
### View the Security Center
diff --git a/lib/banzai/reference_parser/commit_parser.rb b/lib/banzai/reference_parser/commit_parser.rb
index c51f4976c28..88896970bc6 100644
--- a/lib/banzai/reference_parser/commit_parser.rb
+++ b/lib/banzai/reference_parser/commit_parser.rb
@@ -32,13 +32,6 @@ module Banzai
commits
end
- def nodes_visible_to_user(user, nodes)
- projects = lazy { projects_for_nodes(nodes) }
- user.preloaded_member_roles_for_projects(projects.values) if user
-
- super
- end
-
private
def can_read_reference?(user, ref_project, node)
diff --git a/lib/banzai/reference_parser/commit_range_parser.rb b/lib/banzai/reference_parser/commit_range_parser.rb
index 3d09bc83151..fb4a392105f 100644
--- a/lib/banzai/reference_parser/commit_range_parser.rb
+++ b/lib/banzai/reference_parser/commit_range_parser.rb
@@ -38,13 +38,6 @@ module Banzai
range.valid_commits? ? range : nil
end
- def nodes_visible_to_user(user, nodes)
- projects = lazy { projects_for_nodes(nodes) }
- user.preloaded_member_roles_for_projects(projects.values) if user
-
- super
- end
-
private
def can_read_reference?(user, ref_project, node)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index bdd8d4f258f..757c8102e31 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -38558,9 +38558,6 @@ msgstr ""
msgid "Security dashboard"
msgstr ""
-msgid "Security navigation"
-msgstr ""
-
msgid "Security report is out of date. Please update your branch with the latest changes from the target branch (%{targetBranchName})"
msgstr ""
@@ -50647,6 +50644,9 @@ msgstr ""
msgid "can only have one escalation policy"
msgstr ""
+msgid "can't be blank"
+msgstr ""
+
msgid "can't be enabled when delayed group deletion is disabled"
msgstr ""
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index 8761d8291f8..099a7b14cd8 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -248,7 +248,6 @@ RSpec.describe 'Dashboard Projects', feature_category: :projects do
ActiveRecord::QueryRecorder.new { visit dashboard_projects_path }.count
# There are a few known N+1 queries: https://gitlab.com/gitlab-org/gitlab/-/issues/214037
- # - Project#open_merge_requests_count
# - User#max_member_access_for_project_ids
# - ProjectsHelper#load_pipeline_status / Ci::CommitWithPipeline#last_pipeline
# - Ci::Pipeline#detailed_status
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index 6a52f12553f..781da6d07df 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -16,7 +16,6 @@ RSpec.describe Member, feature_category: :subgroups do
describe 'Associations' do
it { is_expected.to belong_to(:user) }
it { is_expected.to belong_to(:member_namespace) }
- it { is_expected.to belong_to(:member_role) }
it { is_expected.to have_one(:member_task) }
end
@@ -173,96 +172,6 @@ RSpec.describe Member, feature_category: :subgroups do
end
end
end
-
- context 'member role access level' do
- let_it_be_with_reload(:member) { create(:group_member, access_level: Gitlab::Access::DEVELOPER) }
-
- 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!(:member_role) do
- create(
- :member_role,
- members: [member],
- base_access_level: Gitlab::Access::DEVELOPER,
- namespace: member.member_namespace
- )
- end
-
- context 'when member role matches access level' do
- it 'is valid' do
- expect(member).to be_valid
- end
- end
-
- context 'when member role does not match access level' do
- it 'is invalid' do
- member_role.base_access_level = Gitlab::Access::MAINTAINER
-
- expect(member).not_to be_valid
- end
- end
-
- 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[: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
- end
- end
end
describe 'Scopes & finders' do
diff --git a/spec/models/members/member_role_spec.rb b/spec/models/members/member_role_spec.rb
deleted file mode 100644
index 69d164e1942..00000000000
--- a/spec/models/members/member_role_spec.rb
+++ /dev/null
@@ -1,131 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe MemberRole, feature_category: :system_access do
- describe 'associations' do
- it { is_expected.to belong_to(:namespace) }
- it { is_expected.to have_many(:members) }
- end
-
- describe 'validation' do
- 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 attributes_locked_after_member_associated' do
- context 'when assigned to member' do
- it 'cannot be changed' do
- member_role.save!
- member_role.members << create(:project_member)
-
- expect(member_role).not_to be_valid
- expect(member_role.errors.messages[:base]).to include(
- s_("MemberRole|cannot be changed because it is already assigned to a user. "\
- "Please create a new Member Role instead")
- )
- end
- end
-
- context 'when not assigned to member' do
- it 'can be changed' do
- expect(member_role).to be_valid
- end
- end
- end
-
- context 'for max_count_per_group_hierarchy' do
- let_it_be(:group) { create(:group) }
-
- subject(:member_role) { build(:member_role, namespace: group) }
-
- context 'when number of member roles is below limit' do
- it 'is valid' do
- is_expected.to be_valid
- end
- end
-
- context 'when number of member roles is above limit' do
- before do
- stub_const('MemberRole::MAX_COUNT_PER_GROUP_HIERARCHY', 1)
- create(:member_role, namespace: group)
- group.reload
- end
-
- it 'is invalid' do
- is_expected.to be_invalid
- end
- end
- end
-
- 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)
- member_role.namespace = subgroup
-
- 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
- member_role.namespace = root_group
-
- expect(member_role).to be_valid
- end
- end
-
- context 'when namespace is not present' do
- it 'is invalid with a different error message' do
- 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(member_role).not_to be_valid
- expect(member_role.errors[:namespace]).to include(s_("MemberRole|can't be changed"))
- end
- end
- end
- end
-
- describe 'callbacks' do
- context 'for preventing deletion after member is associated' do
- let_it_be(:member_role) { create(:member_role) }
-
- subject(:destroy_member_role) { member_role.destroy } # rubocop: disable Rails/SaveBang
-
- it 'allows deletion without any member associated' do
- expect(destroy_member_role).to be_truthy
- end
-
- it 'prevent deletion when member is associated' do
- create(:group_member, { group: member_role.namespace,
- access_level: Gitlab::Access::DEVELOPER,
- member_role: member_role })
- member_role.members.reload
-
- expect(destroy_member_role).to be_falsey
- expect(member_role.errors.messages[:base])
- .to(
- include(s_("MemberRole|cannot be deleted because it is already assigned to a user. "\
- "Please disassociate the member role from all users before deletion."))
- )
- end
- end
- end
-end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 3932a925086..e7d815414a8 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -4291,8 +4291,11 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev
it 'refreshes the number of open merge requests of the target project' do
project = subject.target_project
- expect { subject.destroy! }
- .to change { project.open_merge_requests_count }.from(1).to(0)
+ expect do
+ subject.destroy!
+
+ BatchLoader::Executor.clear_current
+ end.to change { project.open_merge_requests_count }.from(1).to(0)
end
end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 0553a7d7152..60338d42bfa 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -31,7 +31,6 @@ RSpec.describe Namespace, feature_category: :subgroups do
it { is_expected.to have_many :pending_builds }
it { is_expected.to have_one :namespace_route }
it { is_expected.to have_many :namespace_members }
- it { is_expected.to have_many :member_roles }
it { is_expected.to have_one :cluster_enabled_grant }
it { is_expected.to have_many(:work_items) }
it { is_expected.to have_many :achievements }
diff --git a/spec/services/merge_requests/close_service_spec.rb b/spec/services/merge_requests/close_service_spec.rb
index 2c0817550c6..25c75ae7244 100644
--- a/spec/services/merge_requests/close_service_spec.rb
+++ b/spec/services/merge_requests/close_service_spec.rb
@@ -88,7 +88,11 @@ RSpec.describe MergeRequests::CloseService, feature_category: :code_review_workf
end
it 'refreshes the number of open merge requests for a valid MR', :use_clean_rails_memory_store_caching do
- expect { execute }
+ expect do
+ execute
+
+ BatchLoader::Executor.clear_current
+ end
.to change { project.open_merge_requests_count }.from(1).to(0)
end
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index 394fc269ac3..7e20af32985 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -43,8 +43,11 @@ RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state, f
end
it 'refreshes the number of open merge requests', :use_clean_rails_memory_store_caching do
- expect { service.execute }
- .to change { project.open_merge_requests_count }.from(0).to(1)
+ expect do
+ service.execute
+
+ BatchLoader::Executor.clear_current
+ end.to change { project.open_merge_requests_count }.from(0).to(1)
end
it 'creates exactly 1 create MR event', :sidekiq_might_not_need_inline do
diff --git a/spec/services/merge_requests/post_merge_service_spec.rb b/spec/services/merge_requests/post_merge_service_spec.rb
index d89bfba5129..f7526c169bd 100644
--- a/spec/services/merge_requests/post_merge_service_spec.rb
+++ b/spec/services/merge_requests/post_merge_service_spec.rb
@@ -23,7 +23,11 @@ RSpec.describe MergeRequests::PostMergeService, feature_category: :code_review_w
# Cache the counter before the MR changed state.
project.open_merge_requests_count
- expect { subject }.to change { project.open_merge_requests_count }.from(1).to(0)
+ expect do
+ subject
+
+ BatchLoader::Executor.clear_current
+ end.to change { project.open_merge_requests_count }.from(1).to(0)
end
it 'updates metrics' do
diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb
index 6d30dd39293..7399b29d06e 100644
--- a/spec/services/merge_requests/reopen_service_spec.rb
+++ b/spec/services/merge_requests/reopen_service_spec.rb
@@ -92,7 +92,11 @@ RSpec.describe MergeRequests::ReopenService, feature_category: :code_review_work
it 'refreshes the number of open merge requests for a valid MR' do
service = described_class.new(project: project, current_user: user)
- expect { service.execute(merge_request) }
+ expect do
+ service.execute(merge_request)
+
+ BatchLoader::Executor.clear_current
+ end
.to change { project.open_merge_requests_count }.from(0).to(1)
end
diff --git a/spec/services/projects/batch_open_merge_requests_count_service_spec.rb b/spec/services/projects/batch_open_merge_requests_count_service_spec.rb
new file mode 100644
index 00000000000..96fc6c5e9dd
--- /dev/null
+++ b/spec/services/projects/batch_open_merge_requests_count_service_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::BatchOpenMergeRequestsCountService, feature_category: :code_review_workflow do
+ subject { described_class.new([project_1, project_2]) }
+
+ let_it_be(:project_1) { create(:project) }
+ let_it_be(:project_2) { create(:project) }
+
+ describe '#refresh_cache_and_retrieve_data', :use_clean_rails_memory_store_caching do
+ before do
+ create(:merge_request, source_project: project_1, target_project: project_1)
+ create(:merge_request, source_project: project_2, target_project: project_2)
+ end
+
+ it 'refreshes cache keys correctly when cache is clean', :aggregate_failures do
+ subject.refresh_cache_and_retrieve_data
+
+ expect(Rails.cache.read(get_cache_key(subject, project_1))).to eq(1)
+ expect(Rails.cache.read(get_cache_key(subject, project_2))).to eq(1)
+
+ expect { subject.refresh_cache_and_retrieve_data }.not_to exceed_query_limit(0)
+ end
+ end
+
+ def get_cache_key(subject, project)
+ subject.count_service
+ .new(project)
+ .cache_key
+ end
+end
diff --git a/spec/support/db_cleaner.rb b/spec/support/db_cleaner.rb
index 223862c17a9..b9a99eff413 100644
--- a/spec/support/db_cleaner.rb
+++ b/spec/support/db_cleaner.rb
@@ -75,9 +75,6 @@ module DbCleaner
Gitlab::Database::Partitioning.sync_partitions_ignore_db_error
- # Restore write locks
- Gitlab::Database::TablesLocker.new.lock_writes
-
puts "Databases re-creation done in #{Gitlab::Metrics::System.monotonic_time - start}"
end