From 7b29a4f84e25ab3eb610c1595bad38478784f5ff Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 9 Nov 2022 06:11:32 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- app/components/pajamas/avatar_component.rb | 4 +- app/components/pajamas/badge_component.rb | 4 +- app/components/pajamas/banner_component.rb | 4 +- app/components/pajamas/spinner_component.rb | 6 +- app/models/concerns/subquery.rb | 24 ++++++++ ..._max_access_level_in_projects_preloader.rb | 4 +- app/models/project.rb | 1 + .../timeline_events/create_service.rb | 2 - app/views/layouts/component_preview.html.haml | 17 ++++-- app/workers/projects/post_creation_worker.rb | 1 - config/environments/development.rb | 4 ++ ...everity.yml => projects_preloader_fix.yml} | 8 +-- ...background_migration_on_query_canceled.yml | 8 --- ...hange_vulnerability_feedback_unique_idx.rb | 25 ++++++++ ...ding_uuid_and_feedback_type_on_feedback.rb | 15 +++++ ...5019_truncate_timeline_event_tags_table.rb | 13 ++++ db/schema_migrations/20221025145452 | 1 + db/schema_migrations/20221025150202 | 1 + db/schema_migrations/20221108045019 | 1 + db/structure.sql | 6 +- .../incident_timeline_events.md | 8 +-- .../iac_scanning/index.md | 8 ++- lib/api/entities/basic_project_details.rb | 2 + lib/api/entities/project_with_access.rb | 36 ++++++++--- lib/api/projects_relation_builder.rb | 2 + .../background_migration/batched_job.rb | 17 ++---- scripts/review_apps/base-config.yaml | 8 +-- .../pajamas/alert_component_preview.rb | 2 +- .../pajamas/avatar_component_preview.rb | 6 +- .../pajamas/badge_component_preview.rb | 4 +- .../pajamas/banner_component_preview.rb | 2 +- .../pajamas/button_component_preview.rb | 8 +-- .../pajamas/progress_component_preview.rb | 4 +- .../pajamas/spinner_component_preview.rb | 4 +- .../background_migration/batched_job_spec.rb | 18 +++--- spec/models/concerns/subquery_spec.rb | 61 +++++++++++++++++++ ...access_level_in_projects_preloader_spec.rb | 14 ++++- spec/models/project_spec.rb | 2 +- spec/requests/api/projects_spec.rb | 28 ++++++--- .../timeline_events/create_service_spec.rb | 10 --- .../projects/post_creation_worker_spec.rb | 34 ----------- 41 files changed, 287 insertions(+), 140 deletions(-) create mode 100644 app/models/concerns/subquery.rb rename config/feature_flags/development/{incident_timeline_events_for_severity.yml => projects_preloader_fix.yml} (67%) delete mode 100644 config/feature_flags/development/split_background_migration_on_query_canceled.yml create mode 100644 db/migrate/20221025145452_change_vulnerability_feedback_unique_idx.rb create mode 100644 db/migrate/20221025150202_add_index_for_finding_uuid_and_feedback_type_on_feedback.rb create mode 100644 db/post_migrate/20221108045019_truncate_timeline_event_tags_table.rb create mode 100644 db/schema_migrations/20221025145452 create mode 100644 db/schema_migrations/20221025150202 create mode 100644 db/schema_migrations/20221108045019 create mode 100644 spec/models/concerns/subquery_spec.rb diff --git a/app/components/pajamas/avatar_component.rb b/app/components/pajamas/avatar_component.rb index 073968e0491..423934b6887 100644 --- a/app/components/pajamas/avatar_component.rb +++ b/app/components/pajamas/avatar_component.rb @@ -17,10 +17,10 @@ module Pajamas @avatar_options = avatar_options end - private - SIZE_OPTIONS = [16, 24, 32, 48, 64, 96].freeze + private + def avatar_classes classes = ["gl-avatar", "gl-avatar-s#{@size}", @class] classes.push("gl-avatar-circle") if @record.is_a?(User) diff --git a/app/components/pajamas/badge_component.rb b/app/components/pajamas/badge_component.rb index 244064b0e1e..4955bcd29ed 100644 --- a/app/components/pajamas/badge_component.rb +++ b/app/components/pajamas/badge_component.rb @@ -22,11 +22,11 @@ module Pajamas @html_options = html_options end - private - SIZE_OPTIONS = [:sm, :md, :lg].freeze VARIANT_OPTIONS = [:muted, :neutral, :info, :success, :warning, :danger].freeze + private + delegate :sprite_icon, to: :helpers def badge_classes diff --git a/app/components/pajamas/banner_component.rb b/app/components/pajamas/banner_component.rb index 9b6343b47c9..6082762f22c 100644 --- a/app/components/pajamas/banner_component.rb +++ b/app/components/pajamas/banner_component.rb @@ -23,13 +23,15 @@ module Pajamas @button_text = button_text @button_link = button_link @embedded = embedded - @variant = variant.to_sym + @variant = filter_attribute(variant.to_sym, VARIANT_OPTIONS, default: :promotion) @svg_path = svg_path.to_s @banner_options = banner_options @button_options = button_options @close_options = close_options end + VARIANT_OPTIONS = [:introduction, :promotion].freeze + private def banner_class diff --git a/app/components/pajamas/spinner_component.rb b/app/components/pajamas/spinner_component.rb index b8e095bb73e..f2f7236ee3f 100644 --- a/app/components/pajamas/spinner_component.rb +++ b/app/components/pajamas/spinner_component.rb @@ -14,15 +14,15 @@ module Pajamas @html_options = html_options end + COLOR_OPTIONS = [:light, :dark].freeze + SIZE_OPTIONS = [:sm, :md, :lg, :xl].freeze + private def spinner_class ["gl-spinner", "gl-spinner-#{@size}", "gl-spinner-#{@color} gl-vertical-align-text-bottom!"] end - COLOR_OPTIONS = [:light, :dark].freeze - SIZE_OPTIONS = [:sm, :md, :lg, :xl].freeze - def html_options options = format_options(options: @html_options, css_classes: "gl-spinner-container") options[:role] = "status" diff --git a/app/models/concerns/subquery.rb b/app/models/concerns/subquery.rb new file mode 100644 index 00000000000..ae92d2137c1 --- /dev/null +++ b/app/models/concerns/subquery.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# Distinguish between a top level query and a subselect. +# +# Retrieve column values when the relation has already been loaded, otherwise reselect the relation. +# Useful for preload query patterns where the typical Rails #preload does not fit. Such as: +# +# projects = Project.where(...) +# projects.load +# ... +# options[members] = ProjectMember.where(...).where(source_id: projects.select(:id)) +module Subquery + extend ActiveSupport::Concern + + class_methods do + def subquery(*column_names, max_limit: 5_000) + if current_scope.loaded? && current_scope.size <= max_limit + current_scope.pluck(*column_names) + else + current_scope.reselect(*column_names) + end + end + end +end diff --git a/app/models/preloaders/user_max_access_level_in_projects_preloader.rb b/app/models/preloaders/user_max_access_level_in_projects_preloader.rb index 2e2272a2ef5..4897d90ad06 100644 --- a/app/models/preloaders/user_max_access_level_in_projects_preloader.rb +++ b/app/models/preloaders/user_max_access_level_in_projects_preloader.rb @@ -7,9 +7,11 @@ module Preloaders def initialize(projects, user) @projects = if projects.is_a?(Array) Project.where(id: projects) - else + elsif Feature.enabled?(:projects_preloader_fix) # Push projects base query in to a sub-select to avoid # table name clashes. Performs better than aliasing. + Project.where(id: projects.subquery(:id)) + else Project.where(id: projects.reselect(:id)) end diff --git a/app/models/project.rb b/app/models/project.rb index 0e60c466726..3f977d352a5 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -39,6 +39,7 @@ class Project < ApplicationRecord include BulkUsersByEmailLoad include RunnerTokenExpirationInterval include BlocksUnsafeSerialization + include Subquery extend Gitlab::Cache::RequestCache extend Gitlab::Utils::Override diff --git a/app/services/incident_management/timeline_events/create_service.rb b/app/services/incident_management/timeline_events/create_service.rb index ef6f48bd741..e8ec8aa6525 100644 --- a/app/services/incident_management/timeline_events/create_service.rb +++ b/app/services/incident_management/timeline_events/create_service.rb @@ -50,8 +50,6 @@ module IncidentManagement end def change_severity(incident, user) - return if Feature.disabled?(:incident_timeline_events_for_severity, incident.project) - severity_label = IssuableSeverity::SEVERITY_LABELS[incident.severity.to_sym] note = "@#{user.username} changed the incident severity to **#{severity_label}**" occurred_at = incident.updated_at diff --git a/app/views/layouts/component_preview.html.haml b/app/views/layouts/component_preview.html.haml index ec12395a5d4..a1b1304f994 100644 --- a/app/views/layouts/component_preview.html.haml +++ b/app/views/layouts/component_preview.html.haml @@ -1,5 +1,14 @@ %head - = stylesheet_link_tag "application" - = stylesheet_link_tag "application_utilities" -%body{ style: "background-color: #{params.dig(:lookbook, :display, :bg_color) || 'white'}" } - .container.gl-mt-6= yield + - if params[:lookbook][:display][:theme] == 'light' + = stylesheet_link_tag "application" + = stylesheet_link_tag "application_utilities" + - else + = stylesheet_link_tag "application_dark" + = stylesheet_link_tag "application_utilities_dark" +%body + .container.gl-mt-6 + - if params[:lookbook][:display][:bg_dark] + .bg-dark.rounded.shadow.p-4 + = yield + - else + = yield diff --git a/app/workers/projects/post_creation_worker.rb b/app/workers/projects/post_creation_worker.rb index 886919ecace..7448f1b202f 100644 --- a/app/workers/projects/post_creation_worker.rb +++ b/app/workers/projects/post_creation_worker.rb @@ -17,7 +17,6 @@ module Projects return unless project create_prometheus_integration(project) - create_incident_management_timeline_event_tags(project) end private diff --git a/config/environments/development.rb b/config/environments/development.rb index 5e67ed71954..8f266f2660c 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -51,6 +51,10 @@ Rails.application.configure do config.autoload_paths.push("#{config.root}/spec/components/previews") config.lookbook.page_paths = ["#{config.root}/spec/components/docs"] + config.lookbook.preview_params_options_eval = true + config.lookbook.preview_display_options = { + theme: ["light", "dark (alpha)"] + } # Adds additional error checking when serving assets at runtime. # Checks for improperly declared sprockets dependencies. diff --git a/config/feature_flags/development/incident_timeline_events_for_severity.yml b/config/feature_flags/development/projects_preloader_fix.yml similarity index 67% rename from config/feature_flags/development/incident_timeline_events_for_severity.yml rename to config/feature_flags/development/projects_preloader_fix.yml index e014cc8d268..1ad578f11a4 100644 --- a/config/feature_flags/development/incident_timeline_events_for_severity.yml +++ b/config/feature_flags/development/projects_preloader_fix.yml @@ -1,8 +1,8 @@ --- -name: incident_timeline_events_for_severity -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/100954 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/378408 +name: projects_preloader_fix +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96108 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/378858 milestone: '15.6' type: development -group: group::respond +group: group::workspace default_enabled: false diff --git a/config/feature_flags/development/split_background_migration_on_query_canceled.yml b/config/feature_flags/development/split_background_migration_on_query_canceled.yml deleted file mode 100644 index 48409041f1a..00000000000 --- a/config/feature_flags/development/split_background_migration_on_query_canceled.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: split_background_migration_on_query_canceled -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/101825 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/378846 -milestone: '15.6' -type: development -group: group::database -default_enabled: false diff --git a/db/migrate/20221025145452_change_vulnerability_feedback_unique_idx.rb b/db/migrate/20221025145452_change_vulnerability_feedback_unique_idx.rb new file mode 100644 index 00000000000..677245e1f50 --- /dev/null +++ b/db/migrate/20221025145452_change_vulnerability_feedback_unique_idx.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class ChangeVulnerabilityFeedbackUniqueIdx < Gitlab::Database::Migration[2.0] + NEW_INDEX_NAME = :index_vulnerability_feedback_on_common_attributes + OLD_INDEX_NAME = :vulnerability_feedback_unique_idx + + disable_ddl_transaction! + + def up + add_concurrent_index :vulnerability_feedback, + %i[project_id category feedback_type project_fingerprint], + name: NEW_INDEX_NAME + + remove_concurrent_index_by_name :vulnerability_feedback, OLD_INDEX_NAME + end + + def down + add_concurrent_index :vulnerability_feedback, + %i[project_id category feedback_type project_fingerprint], + name: OLD_INDEX_NAME, + unique: true + + remove_concurrent_index_by_name :vulnerability_feedback, NEW_INDEX_NAME + end +end diff --git a/db/migrate/20221025150202_add_index_for_finding_uuid_and_feedback_type_on_feedback.rb b/db/migrate/20221025150202_add_index_for_finding_uuid_and_feedback_type_on_feedback.rb new file mode 100644 index 00000000000..f909573937b --- /dev/null +++ b/db/migrate/20221025150202_add_index_for_finding_uuid_and_feedback_type_on_feedback.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddIndexForFindingUuidAndFeedbackTypeOnFeedback < Gitlab::Database::Migration[2.0] + INDEX_NAME = :index_vulnerability_feedback_on_feedback_type_and_finding_uuid + + disable_ddl_transaction! + + def up + add_concurrent_index :vulnerability_feedback, %i[feedback_type finding_uuid], name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :vulnerability_feedback, INDEX_NAME + end +end diff --git a/db/post_migrate/20221108045019_truncate_timeline_event_tags_table.rb b/db/post_migrate/20221108045019_truncate_timeline_event_tags_table.rb new file mode 100644 index 00000000000..37e6a21abed --- /dev/null +++ b/db/post_migrate/20221108045019_truncate_timeline_event_tags_table.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class TruncateTimelineEventTagsTable < Gitlab::Database::Migration[2.0] + disable_ddl_transaction! + + def up + execute('TRUNCATE TABLE incident_management_timeline_event_tags, incident_management_timeline_event_tag_links') + end + + def down + # no-op + end +end diff --git a/db/schema_migrations/20221025145452 b/db/schema_migrations/20221025145452 new file mode 100644 index 00000000000..df551b8bae6 --- /dev/null +++ b/db/schema_migrations/20221025145452 @@ -0,0 +1 @@ +951ad9faf483d58778cd831a0ac949473d6eeb753322754eff3f02756d757583 \ No newline at end of file diff --git a/db/schema_migrations/20221025150202 b/db/schema_migrations/20221025150202 new file mode 100644 index 00000000000..aa6db23de6c --- /dev/null +++ b/db/schema_migrations/20221025150202 @@ -0,0 +1 @@ +2185444f733eec25a2741764619516eecb1d2c6e3e4ec3b3ed5b72bfd9c4db46 \ No newline at end of file diff --git a/db/schema_migrations/20221108045019 b/db/schema_migrations/20221108045019 new file mode 100644 index 00000000000..518b5118173 --- /dev/null +++ b/db/schema_migrations/20221108045019 @@ -0,0 +1 @@ +b8438bebe77ae835b754431d8d67c306714205bef11826a15d4c84d7b67a3581 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 8c5d395e3f7..b36d645da31 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -30970,6 +30970,10 @@ CREATE INDEX index_vulnerability_feedback_on_author_id ON vulnerability_feedback CREATE INDEX index_vulnerability_feedback_on_comment_author_id ON vulnerability_feedback USING btree (comment_author_id); +CREATE INDEX index_vulnerability_feedback_on_common_attributes ON vulnerability_feedback USING btree (project_id, category, feedback_type, project_fingerprint); + +CREATE INDEX index_vulnerability_feedback_on_feedback_type_and_finding_uuid ON vulnerability_feedback USING btree (feedback_type, finding_uuid); + CREATE INDEX index_vulnerability_feedback_on_issue_id ON vulnerability_feedback USING btree (issue_id); CREATE INDEX index_vulnerability_feedback_on_issue_id_not_null ON vulnerability_feedback USING btree (id) WHERE (issue_id IS NOT NULL); @@ -31258,8 +31262,6 @@ CREATE INDEX user_follow_users_followee_id_idx ON user_follow_users USING btree CREATE INDEX users_forbidden_state_idx ON users USING btree (id) WHERE ((confirmed_at IS NOT NULL) AND ((state)::text <> ALL (ARRAY['blocked'::text, 'banned'::text, 'ldap_blocked'::text]))); -CREATE UNIQUE INDEX vulnerability_feedback_unique_idx ON vulnerability_feedback USING btree (project_id, category, feedback_type, project_fingerprint); - CREATE UNIQUE INDEX vulnerability_occurrence_pipelines_on_unique_keys ON vulnerability_occurrence_pipelines USING btree (occurrence_id, pipeline_id); CREATE UNIQUE INDEX work_item_types_namespace_id_and_name_unique ON work_item_types USING btree (namespace_id, btrim(lower(name))); diff --git a/doc/operations/incident_management/incident_timeline_events.md b/doc/operations/incident_management/incident_timeline_events.md index c35f53e1f2c..079f46cd60e 100644 --- a/doc/operations/incident_management/incident_timeline_events.md +++ b/doc/operations/incident_management/incident_timeline_events.md @@ -76,13 +76,7 @@ The comment is shown on the incident timeline as a timeline event. ### When incident severity changes -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375280) in GitLab 15.6 [with a flag](../../administration/feature_flags.md) named `incident_timeline_events_for_severity`. Disabled by default. Enabled on GitLab.com. - -FLAG: -On self-managed GitLab, by default this feature is unavailable. To show the feature per user, -ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `incident_timeline_events_for_severity`. -On GitLab.com, this feature is available. -This feature is not ready for production use. +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375280) in GitLab 15.6. A new timeline event is created when someone [changes the severity](incidents.md#change-severity) of an incident. diff --git a/doc/user/application_security/iac_scanning/index.md b/doc/user/application_security/iac_scanning/index.md index c97cb409c5f..026567383be 100644 --- a/doc/user/application_security/iac_scanning/index.md +++ b/doc/user/application_security/iac_scanning/index.md @@ -146,7 +146,7 @@ To disable analyzer rules: 1. Create a custom ruleset file named `sast-ruleset.toml` in the `.gitlab` directory, if one doesn't already exist. 1. Set the `disabled` flag to `true` in the context of a `ruleset` section. -1. In one or more `ruleset.identifier` subsections, list the rules to disable. Every +1. In one or more `ruleset` subsections, list the rules to disable. Every `ruleset.identifier` section has: - A `type` field for the rule. For IaC Scanning, the identifier type is `kics_id`. - A `value` field for the rule identifier. KICS rule identifiers are alphanumeric strings. To find the rule identifier, you can: @@ -163,6 +163,12 @@ the `kics` analyzer by matching the `type` and `value` of identifiers: [kics.ruleset.identifier] type = "kics_id" value = "8212e2d7-e683-49bc-bf78-d6799075c5a7" + + [[kics.ruleset]] + disable = true + [kics.ruleset.identifier] + type = "kics_id" + value = "b03a748a-542d-44f4-bb86-9199ab4fd2d5" ``` ### Override predefined analyzer rules diff --git a/lib/api/entities/basic_project_details.rb b/lib/api/entities/basic_project_details.rb index b3ae5885aef..f8f5b59cdc1 100644 --- a/lib/api/entities/basic_project_details.rb +++ b/lib/api/entities/basic_project_details.rb @@ -60,6 +60,8 @@ module API super end + def self.postload_relation(projects_relation, options = {}) end + private alias_method :project, :object diff --git a/lib/api/entities/project_with_access.rb b/lib/api/entities/project_with_access.rb index b541ccbadcf..9722b8806d4 100644 --- a/lib/api/entities/project_with_access.rb +++ b/lib/api/entities/project_with_access.rb @@ -25,23 +25,41 @@ module API # rubocop: disable CodeReuse/ActiveRecord def self.preload_relation(projects_relation, options = {}) - relation = super(projects_relation, options) - # use reselect to override the existing select and - # prevent an error `subquery has too many columns` - project_ids = relation.reselect('projects.id') - namespace_ids = relation.reselect(:namespace_id) + if ::Feature.enabled?(:projects_preloader_fix) + super(projects_relation, options) + else + relation = super(projects_relation, options) + # use reselect to override the existing select and + # prevent an error `subquery has too many columns` + project_ids = relation.reselect('projects.id') + namespace_ids = relation.reselect(:namespace_id) + + options[:project_members] = options[:current_user] + .project_members + .where(source_id: project_ids) + .preload(:source, user: [notification_settings: :source]) + + options[:group_members] = options[:current_user] + .group_members + .where(source_id: namespace_ids) + .preload(:source, user: [notification_settings: :source]) + + relation + end + end + + def self.postload_relation(projects_relation, options = {}) + return unless ::Feature.enabled?(:projects_preloader_fix) options[:project_members] = options[:current_user] .project_members - .where(source_id: project_ids) + .where(source_id: projects_relation.subquery(:id)) .preload(:source, user: [notification_settings: :source]) options[:group_members] = options[:current_user] .group_members - .where(source_id: namespace_ids) + .where(source_id: projects_relation.subquery(:namespace_id)) .preload(:source, user: [notification_settings: :source]) - - relation end # rubocop: enable CodeReuse/ActiveRecord end diff --git a/lib/api/projects_relation_builder.rb b/lib/api/projects_relation_builder.rb index fb782b49f02..df501c06137 100644 --- a/lib/api/projects_relation_builder.rb +++ b/lib/api/projects_relation_builder.rb @@ -10,6 +10,8 @@ module API execute_batch_counting(projects_relation) + postload_relation(projects_relation, options) + preload_repository_cache(projects_relation) Preloaders::UserMaxAccessLevelInProjectsPreloader.new(projects_relation, options[:current_user]).execute if options[:current_user] diff --git a/lib/gitlab/database/background_migration/batched_job.rb b/lib/gitlab/database/background_migration/batched_job.rb index 9ac6d1442a2..6b7ff308c7e 100644 --- a/lib/gitlab/database/background_migration/batched_job.rb +++ b/lib/gitlab/database/background_migration/batched_job.rb @@ -14,7 +14,8 @@ module Gitlab MAX_ATTEMPTS = 3 STUCK_JOBS_TIMEOUT = 1.hour.freeze TIMEOUT_EXCEPTIONS = [ActiveRecord::StatementTimeout, ActiveRecord::ConnectionTimeoutError, - ActiveRecord::AdapterTimeout, ActiveRecord::LockWaitTimeout].freeze + ActiveRecord::AdapterTimeout, ActiveRecord::LockWaitTimeout, + ActiveRecord::QueryCanceled].freeze belongs_to :batched_migration, foreign_key: :batched_background_migration_id has_many :batched_job_transition_logs, foreign_key: :batched_background_migration_job_id @@ -112,7 +113,10 @@ module Gitlab end def can_split?(exception) - attempts >= MAX_ATTEMPTS && timeout_exception?(exception&.class) && batch_size > sub_batch_size && batch_size > 1 + attempts >= MAX_ATTEMPTS && + exception&.class&.in?(TIMEOUT_EXCEPTIONS) && + batch_size > sub_batch_size && + batch_size > 1 end def split_and_retry! @@ -161,15 +165,6 @@ module Gitlab end end end - - private - - def timeout_exception?(exception_class) - return false unless exception_class - - TIMEOUT_EXCEPTIONS.include?(exception_class) || - (Feature.enabled?(:split_background_migration_on_query_canceled) && exception_class == ActiveRecord::QueryCanceled) - end end end end diff --git a/scripts/review_apps/base-config.yaml b/scripts/review_apps/base-config.yaml index 3ee4ec66786..132158d6e8c 100644 --- a/scripts/review_apps/base-config.yaml +++ b/scripts/review_apps/base-config.yaml @@ -41,11 +41,11 @@ gitlab: migrations: resources: requests: - cpu: 200m - memory: 500Mi - limits: cpu: 400m - memory: 1000Mi + memory: 920Mi + limits: + cpu: 600m + memory: 1100Mi gitlab-shell: resources: requests: diff --git a/spec/components/previews/pajamas/alert_component_preview.rb b/spec/components/previews/pajamas/alert_component_preview.rb index e1889032c8b..4768ef47975 100644 --- a/spec/components/previews/pajamas/alert_component_preview.rb +++ b/spec/components/previews/pajamas/alert_component_preview.rb @@ -4,7 +4,7 @@ module Pajamas # @param title text # @param body text # @param dismissible toggle - # @param variant select [info, warning, success, danger, tip] + # @param variant select {{ Pajamas::AlertComponent::VARIANT_ICONS.keys }} def default(title: "Alert title (optional)", body: "Alert message goes here.", dismissible: true, variant: :info) render(Pajamas::AlertComponent.new( title: title, diff --git a/spec/components/previews/pajamas/avatar_component_preview.rb b/spec/components/previews/pajamas/avatar_component_preview.rb index e5cdde1ccef..147d89169b0 100644 --- a/spec/components/previews/pajamas/avatar_component_preview.rb +++ b/spec/components/previews/pajamas/avatar_component_preview.rb @@ -9,17 +9,17 @@ module Pajamas end # We show user avatars in a circle. - # @param size select [16, 24, 32, 48, 64, 96] + # @param size select {{ Pajamas::AvatarComponent::SIZE_OPTIONS }} def user(size: 64) render(Pajamas::AvatarComponent.new(User.first, size: size)) end - # @param size select [16, 24, 32, 48, 64, 96] + # @param size select {{ Pajamas::AvatarComponent::SIZE_OPTIONS }} def project(size: 64) render(Pajamas::AvatarComponent.new(Project.first, size: size)) end - # @param size select [16, 24, 32, 48, 64, 96] + # @param size select {{ Pajamas::AvatarComponent::SIZE_OPTIONS }} def group(size: 64) render(Pajamas::AvatarComponent.new(Group.first, size: size)) end diff --git a/spec/components/previews/pajamas/badge_component_preview.rb b/spec/components/previews/pajamas/badge_component_preview.rb index e740a4a38aa..e833c4e458d 100644 --- a/spec/components/previews/pajamas/badge_component_preview.rb +++ b/spec/components/previews/pajamas/badge_component_preview.rb @@ -10,9 +10,9 @@ module Pajamas # @param icon select [~, star-o, issue-closed, tanuki] # @param icon_only toggle # @param href url - # @param size select [sm, md, lg] + # @param size select {{ Pajamas::BadgeComponent::SIZE_OPTIONS }} # @param text text - # @param variant select [muted, neutral, info, success, warning, danger] + # @param variant select {{ Pajamas::BadgeComponent::VARIANT_OPTIONS }} def default(icon: :tanuki, icon_only: false, href: nil, size: :md, text: "Tanuki", variant: :muted) render Pajamas::BadgeComponent.new( text, diff --git a/spec/components/previews/pajamas/banner_component_preview.rb b/spec/components/previews/pajamas/banner_component_preview.rb index 861e3ff95dc..19f4f5243c0 100644 --- a/spec/components/previews/pajamas/banner_component_preview.rb +++ b/spec/components/previews/pajamas/banner_component_preview.rb @@ -9,7 +9,7 @@ module Pajamas # @param button_link text # @param content textarea # @param embedded toggle - # @param variant select [introduction, promotion] + # @param variant select {{ Pajamas::BannerComponent::VARIANT_OPTIONS }} def default( button_text: "Learn more", button_link: "https://about.gitlab.com/", diff --git a/spec/components/previews/pajamas/button_component_preview.rb b/spec/components/previews/pajamas/button_component_preview.rb index 1f61d9cf2bc..c07d898d9cd 100644 --- a/spec/components/previews/pajamas/button_component_preview.rb +++ b/spec/components/previews/pajamas/button_component_preview.rb @@ -5,10 +5,10 @@ module Pajamas # ---- # See its design reference [here](https://design.gitlab.com/components/banner). # - # @param category select [primary, secondary, tertiary] - # @param variant select [default, confirm, danger, dashed, link, reset] - # @param size select [small, medium] - # @param type select [button, reset, submit] + # @param category select {{ Pajamas::ButtonComponent::CATEGORY_OPTIONS }} + # @param variant select {{ Pajamas::ButtonComponent::VARIANT_OPTIONS }} + # @param size select {{ Pajamas::ButtonComponent::SIZE_OPTIONS }} + # @param type select {{ Pajamas::ButtonComponent::TYPE_OPTIONS }} # @param disabled toggle # @param loading toggle # @param block toggle diff --git a/spec/components/previews/pajamas/progress_component_preview.rb b/spec/components/previews/pajamas/progress_component_preview.rb index 4de07872a80..1562ffddf7e 100644 --- a/spec/components/previews/pajamas/progress_component_preview.rb +++ b/spec/components/previews/pajamas/progress_component_preview.rb @@ -7,8 +7,8 @@ module Pajamas # # See its design reference [here](https://design.gitlab.com/components/progress-bar). # - # @param value number - # @param variant select [primary, success] + # @param value range { min: 0, max: 100, step: 1 } + # @param variant select {{ Pajamas::ProgressComponent::VARIANT_OPTIONS }} def default(value: 50, variant: :primary) render Pajamas::ProgressComponent.new(value: value, variant: variant) end diff --git a/spec/components/previews/pajamas/spinner_component_preview.rb b/spec/components/previews/pajamas/spinner_component_preview.rb index 3ff87786768..34cc386763f 100644 --- a/spec/components/previews/pajamas/spinner_component_preview.rb +++ b/spec/components/previews/pajamas/spinner_component_preview.rb @@ -7,7 +7,7 @@ module Pajamas # # @param inline toggle # @param label text - # @param size select [[small, sm], [medium, md], [large, lg], [extra large, xl]] + # @param size select {{ Pajamas::SpinnerComponent::SIZE_OPTIONS }} def default(inline: false, label: "Loading", size: :md) render Pajamas::SpinnerComponent.new( inline: inline, @@ -18,7 +18,7 @@ module Pajamas # Use a light spinner on dark backgrounds. # - # @display bg_color "#222" + # @display bg_dark true def light render(Pajamas::SpinnerComponent.new(color: :light)) end diff --git a/spec/lib/gitlab/database/background_migration/batched_job_spec.rb b/spec/lib/gitlab/database/background_migration/batched_job_spec.rb index 332c9618cb5..cc9f3d5b7f1 100644 --- a/spec/lib/gitlab/database/background_migration/batched_job_spec.rb +++ b/spec/lib/gitlab/database/background_migration/batched_job_spec.rb @@ -7,7 +7,15 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJob, type: :model d it { is_expected.to be_a Gitlab::Database::SharedModel } - it { expect(described_class::TIMEOUT_EXCEPTIONS).to match_array [ActiveRecord::StatementTimeout, ActiveRecord::ConnectionTimeoutError, ActiveRecord::AdapterTimeout, ActiveRecord::LockWaitTimeout] } + specify do + expect(described_class::TIMEOUT_EXCEPTIONS).to contain_exactly( + ActiveRecord::StatementTimeout, + ActiveRecord::ConnectionTimeoutError, + ActiveRecord::AdapterTimeout, + ActiveRecord::LockWaitTimeout, + ActiveRecord::QueryCanceled + ) + end describe 'associations' do it { is_expected.to belong_to(:batched_migration).with_foreign_key(:batched_background_migration_id) } @@ -279,14 +287,6 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJob, type: :model d let(:exception) { ActiveRecord::QueryCanceled.new } it { expect(subject).to be_truthy } - - context 'when split_background_migration_on_query_canceled feature flag is disabled' do - before do - stub_feature_flags(split_background_migration_on_query_canceled: false) - end - - it { expect(subject).to be_falsey } - end end context 'when is not a timeout exception' do diff --git a/spec/models/concerns/subquery_spec.rb b/spec/models/concerns/subquery_spec.rb new file mode 100644 index 00000000000..95487fd8c2d --- /dev/null +++ b/spec/models/concerns/subquery_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Subquery do + let_it_be(:projects) { create_list :project, 3 } + let_it_be(:project_ids) { projects.map(&:id) } + let(:relation) { Project.where(id: projects) } + + subject { relation.subquery(:id) } + + shared_examples 'subquery as array values' do + specify { is_expected.to match_array project_ids } + specify { expect { subject }.not_to make_queries } + end + + shared_examples 'subquery as relation' do + it { is_expected.to be_a ActiveRecord::Relation } + specify { expect { subject.load }.to make_queries } + end + + shared_context 'when array size exceeds max_limit' do + subject { relation.subquery(:id, max_limit: 1) } + end + + context 'when relation is not loaded' do + it_behaves_like 'subquery as relation' + + context 'when array size exceeds max_limit' do + include_context 'when array size exceeds max_limit' + + it_behaves_like 'subquery as relation' + end + end + + context 'when relation is loaded' do + before do + relation.load + end + + it_behaves_like 'subquery as array values' + + context 'when array size exceeds max_limit' do + include_context 'when array size exceeds max_limit' + + it_behaves_like 'subquery as relation' + end + + context 'with a select' do + let(:relation) { Project.where(id: projects).select(:id) } + + it_behaves_like 'subquery as array values' + + context 'and querying with an unloaded column' do + subject { relation.subquery(:namespace_id) } + + it { expect { subject }.to raise_error(ActiveModel::MissingAttributeError) } + end + end + end +end diff --git a/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb b/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb index 7411bc95147..f1607a83004 100644 --- a/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb +++ b/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb @@ -28,7 +28,7 @@ RSpec.describe Preloaders::UserMaxAccessLevelInProjectsPreloader do end end - describe '#execute', :request_store do + shared_examples '#execute' do let(:projects_arg) { projects } before do @@ -58,4 +58,16 @@ RSpec.describe Preloaders::UserMaxAccessLevelInProjectsPreloader do end end end + + describe '#execute', :request_store do + include_examples '#execute' + + context 'when projects_preloader_fix is disabled' do + before do + stub_feature_flags(projects_preloader_fix: false) + end + + include_examples '#execute' + end + end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 2fffbe578de..c596748b0a5 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1353,7 +1353,7 @@ RSpec.describe Project, factory_default: :keep do end end - describe '#open_issues_count', :aggregate_failures do + describe '#open_issues_count' do let(:project) { build(:project) } it 'provides the issue count' do diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 746fe83e1a4..29713d11f87 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -207,16 +207,28 @@ RSpec.describe API::Projects do let(:current_user) { user } end - it 'includes container_registry_access_level', :aggregate_failures do - project.project_feature.update!(container_registry_access_level: ProjectFeature::DISABLED) + shared_examples 'includes container_registry_access_level', :aggregate_failures do + it do + project.project_feature.update!(container_registry_access_level: ProjectFeature::DISABLED) - get api('/projects', user) - project_response = json_response.find { |p| p['id'] == project.id } + get api('/projects', user) + project_response = json_response.find { |p| p['id'] == project.id } - expect(response).to have_gitlab_http_status(:ok) - expect(json_response).to be_an Array - expect(project_response['container_registry_access_level']).to eq('disabled') - expect(project_response['container_registry_enabled']).to eq(false) + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to be_an Array + expect(project_response['container_registry_access_level']).to eq('disabled') + expect(project_response['container_registry_enabled']).to eq(false) + end + end + + include_examples 'includes container_registry_access_level' + + context 'when projects_preloader_fix is disabled' do + before do + stub_feature_flags(projects_preloader_fix: false) + end + + include_examples 'includes container_registry_access_level' end it 'includes releases_access_level', :aggregate_failures do diff --git a/spec/services/incident_management/timeline_events/create_service_spec.rb b/spec/services/incident_management/timeline_events/create_service_spec.rb index 3a924a40772..877cd41bf83 100644 --- a/spec/services/incident_management/timeline_events/create_service_spec.rb +++ b/spec/services/incident_management/timeline_events/create_service_spec.rb @@ -292,16 +292,6 @@ RSpec.describe IncidentManagement::TimelineEvents::CreateService do let(:expected_action) { 'severity' } it_behaves_like 'successfully created timeline event' - - context 'when feature flag is disabled' do - before do - stub_feature_flags(incident_timeline_events_for_severity: false) - end - - it 'does not create new timeline event' do - expect { execute }.not_to change { incident.incident_management_timeline_events.count } - end - end end describe '.change_labels' do diff --git a/spec/workers/projects/post_creation_worker_spec.rb b/spec/workers/projects/post_creation_worker_spec.rb index de0f54e5e09..3158ac9fa27 100644 --- a/spec/workers/projects/post_creation_worker_spec.rb +++ b/spec/workers/projects/post_creation_worker_spec.rb @@ -82,39 +82,5 @@ RSpec.describe Projects::PostCreationWorker do end end end - - describe 'Incident timeline event tags' do - context 'when project is nil' do - let(:job_args) { [nil] } - - it 'does not create event tags' do - expect { subject }.not_to change { IncidentManagement::TimelineEventTag.count } - end - end - - context 'when project is created', :aggregate_failures do - it 'creates tags for the project' do - expect { subject }.to change { IncidentManagement::TimelineEventTag.count }.by(2) - - expect(project.incident_management_timeline_event_tags.pluck_names).to match_array( - [ - ::IncidentManagement::TimelineEventTag::START_TIME_TAG_NAME, - ::IncidentManagement::TimelineEventTag::END_TIME_TAG_NAME - ] - ) - end - - it 'raises error if record creation fails' do - allow_next_instance_of(IncidentManagement::TimelineEventTag) do |tag| - allow(tag).to receive(:valid?).and_return(false) - end - - expect(Gitlab::ErrorTracking).to receive(:track_exception).with(an_instance_of(ActiveRecord::RecordInvalid), include(extra: { project_id: a_kind_of(Integer) })).twice - subject - - expect(project.incident_management_timeline_event_tags).to be_empty - end - end - end end end