diff options
47 files changed, 616 insertions, 379 deletions
diff --git a/.rubocop_todo/layout/first_array_element_indentation.yml b/.rubocop_todo/layout/first_array_element_indentation.yml deleted file mode 100644 index d4c332476ad..00000000000 --- a/.rubocop_todo/layout/first_array_element_indentation.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -# Cop supports --autocorrect. -Layout/FirstArrayElementIndentation: - Exclude: - - 'spec/lib/gitlab/github_import/importer/issues_importer_spec.rb' - - 'spec/lib/gitlab/search/found_blob_spec.rb' - - 'spec/models/ci/runner_version_spec.rb' - - 'spec/models/repository_spec.rb' - - 'spec/requests/api/task_completion_status_spec.rb' - - 'spec/services/security/merge_reports_service_spec.rb' - - 'spec/simplecov_env.rb' - - 'spec/support/atlassian/jira_connect/schemata.rb' - - 'spec/support/capybara.rb' - - 'spec/support/helpers/project_template_test_helper.rb' - - 'spec/support/helpers/test_env.rb' - - 'spec/support/helpers/usage_data_helpers.rb' - - 'spec/support/matchers/exceed_query_limit.rb' - - 'spec/support/migrations_helpers/vulnerabilities_findings_helper.rb' - - 'spec/support/prometheus/additional_metrics_shared_examples.rb' - - 'spec/support/shared_contexts/policies/group_policy_shared_context.rb' - - 'spec/support/shared_examples/graphql/label_fields.rb' - - 'spec/support/shared_examples/lib/gitlab/middleware/multipart_shared_examples.rb' - - 'spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb' - - 'spec/views/projects/issues/_related_branches.html.haml_spec.rb' - - 'tooling/lib/tooling/helm3_client.rb' diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 0cac7ba6c87..6235a55bd86 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -22722e29aa21a554ed1e729f9b23a485929ac4cf +434051eb74b0043267538213192a790095caf671 diff --git a/app/assets/javascripts/work_items/components/work_item_milestone.vue b/app/assets/javascripts/work_items/components/work_item_milestone.vue index a8d3b57aae0..6a6d8d210e8 100644 --- a/app/assets/javascripts/work_items/components/work_item_milestone.vue +++ b/app/assets/javascripts/work_items/components/work_item_milestone.vue @@ -118,6 +118,7 @@ export default { return { 'gl-text-gray-500!': this.canUpdate && this.isNoMilestone, 'is-not-focused': !this.isFocused, + 'gl-min-w-20': true, }; }, }, @@ -214,9 +215,10 @@ export default { <template> <gl-form-group - class="work-item-dropdown" + class="work-item-dropdown gl-flex-nowrap" :label="$options.i18n.MILESTONE" - label-class="gl-pb-0! gl-overflow-wrap-break gl-mt-3" + label-for="milestone-value" + label-class="gl-pb-0! gl-mt-3 gl-overflow-wrap-break" label-cols="3" label-cols-lg="2" > @@ -229,6 +231,8 @@ export default { </span> <gl-dropdown v-else + id="milestone-value" + class="col-9 gl-pl-0" :toggle-class="dropdownClasses" :text="dropdownText" :loading="updateInProgress" diff --git a/app/controllers/concerns/import/github_oauth.rb b/app/controllers/concerns/import/github_oauth.rb index d53022aabf2..c233f5d09fa 100644 --- a/app/controllers/concerns/import/github_oauth.rb +++ b/app/controllers/concerns/import/github_oauth.rb @@ -53,6 +53,7 @@ module Import def authorize_url state = SecureRandom.base64(64) session[auth_state_key] = state + session[:auth_on_failure_path] = "#{new_project_path}#import_project" if Feature.enabled?(:remove_legacy_github_client) oauth_client.auth_code.authorize_url( redirect_uri: callback_import_url, diff --git a/app/models/postgresql/detached_partition.rb b/app/models/postgresql/detached_partition.rb index b0dd52c9657..d26778957d5 100644 --- a/app/models/postgresql/detached_partition.rb +++ b/app/models/postgresql/detached_partition.rb @@ -7,5 +7,9 @@ module Postgresql def fully_qualified_table_name "#{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.#{table_name}" end + + def table_schema + Gitlab::Database::GitlabSchema.table_schema(table_name) + end end end diff --git a/config/feature_flags/development/linear_group_descendants_finder_upto.yml b/config/feature_flags/development/linear_group_descendants_finder_upto.yml index ef045ebfa7a..db3a37191ff 100644 --- a/config/feature_flags/development/linear_group_descendants_finder_upto.yml +++ b/config/feature_flags/development/linear_group_descendants_finder_upto.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78991 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350972 milestone: '14.8' type: development -group: group::authentication and authorization +group: group::workspace default_enabled: false diff --git a/config/feature_flags/development/project_list_filter_bar.yml b/config/feature_flags/development/project_list_filter_bar.yml index 86b8a61b1e4..370074a914c 100644 --- a/config/feature_flags/development/project_list_filter_bar.yml +++ b/config/feature_flags/development/project_list_filter_bar.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/11209 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/321404 milestone: '11.11' type: development -group: group::authentication and authorization +group: group::workspace default_enabled: false diff --git a/config/feature_flags/development/use_traversal_ids_for_descendants_scopes.yml b/config/feature_flags/development/use_traversal_ids_for_descendants_scopes.yml index b2262c9707e..3eece0b906a 100644 --- a/config/feature_flags/development/use_traversal_ids_for_descendants_scopes.yml +++ b/config/feature_flags/development/use_traversal_ids_for_descendants_scopes.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78542 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350637 milestone: '14.8' type: development -group: group::authentication and authorization +group: group::workspace default_enabled: true diff --git a/config/feature_flags/development/user_time_settings.yml b/config/feature_flags/development/user_time_settings.yml index bd2b94fe015..77ee79fe80a 100644 --- a/config/feature_flags/development/user_time_settings.yml +++ b/config/feature_flags/development/user_time_settings.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/25 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/321407 milestone: '11.11' type: development -group: group::authentication and authorization +group: group::workspace default_enabled: false diff --git a/config/feature_flags/ops/legacy_open_source_license_available.yml b/config/feature_flags/ops/legacy_open_source_license_available.yml index 2408e31633a..36ee6c230bf 100644 --- a/config/feature_flags/ops/legacy_open_source_license_available.yml +++ b/config/feature_flags/ops/legacy_open_source_license_available.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79855 rollout_issue_url: milestone: '14.8' type: ops -group: 'group::authentication and authorization' +group: 'group::workspace' default_enabled: true diff --git a/config/routes/user.rb b/config/routes/user.rb index 0c1bc1956a9..1c122ea0c94 100644 --- a/config/routes/user.rb +++ b/config/routes/user.rb @@ -55,6 +55,22 @@ devise_scope :user do get '/users/almost_there' => 'confirmations#almost_there' post '/users/resend_verification_code', to: 'sessions#resend_verification_code' get '/users/successful_verification', to: 'sessions#successful_verification' + + # Redirect on GitHub authorization request errors. E.g. it could happen when user: + # 1. cancel authorization the GitLab OAuth app via GitHub to import GitHub repos + # (they'll be redirected to /projects/new#import_project) + # 2. cancel signing in to GitLab using GitHub account + # (they'll be redirected to /users/sign_in) + # In these cases, GitHub redirects user to the GitLab OAuth app's + # registered callback URL - /users/auth, which is the url to the auth user's profile page + get '/users/auth', + constraints: ->(req) { + req.params[:error].present? && req.params[:state].present? + }, + to: redirect { |_params, req| + redirect_path = req.session.delete(:auth_on_failure_path) + redirect_path || Rails.application.routes.url_helpers.new_user_session_path + } end scope '-/users', module: :users do diff --git a/db/post_migrate/20221206012013_add_index_author_id_created_at_on_merge_requests.rb b/db/post_migrate/20221206012013_add_index_author_id_created_at_on_merge_requests.rb new file mode 100644 index 00000000000..886d8aed71a --- /dev/null +++ b/db/post_migrate/20221206012013_add_index_author_id_created_at_on_merge_requests.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddIndexAuthorIdCreatedAtOnMergeRequests < Gitlab::Database::Migration[2.0] + INDEX_NAME = 'index_merge_requests_on_author_id_and_created_at' + + disable_ddl_transaction! + + def up + add_concurrent_index :merge_requests, %i[author_id created_at], name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :merge_requests, INDEX_NAME + end +end diff --git a/db/schema_migrations/20221206012013 b/db/schema_migrations/20221206012013 new file mode 100644 index 00000000000..a7cfcc43f7c --- /dev/null +++ b/db/schema_migrations/20221206012013 @@ -0,0 +1 @@ +52294ac9fd807fdff49d918d6b49c071b53e683a479af6beef9449302080e44f
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 3c884e05285..f7523d18f6b 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -29844,6 +29844,8 @@ CREATE INDEX index_merge_requests_on_assignee_id ON merge_requests USING btree ( CREATE INDEX index_merge_requests_on_author_id ON merge_requests USING btree (author_id); +CREATE INDEX index_merge_requests_on_author_id_and_created_at ON merge_requests USING btree (author_id, created_at); + CREATE INDEX index_merge_requests_on_author_id_and_id ON merge_requests USING btree (author_id, id); CREATE INDEX index_merge_requests_on_author_id_and_target_project_id ON merge_requests USING btree (author_id, target_project_id); diff --git a/lib/gitlab/database/lock_writes_manager.rb b/lib/gitlab/database/lock_writes_manager.rb index 2594ee04b35..e3ae2892668 100644 --- a/lib/gitlab/database/lock_writes_manager.rb +++ b/lib/gitlab/database/lock_writes_manager.rb @@ -10,18 +10,34 @@ module Gitlab # See https://www.postgresql.org/message-id/16934.1568989957%40sss.pgh.pa.us EXPECTED_TRIGGER_RECORD_COUNT = 3 + def self.tables_to_lock(connection) + Gitlab::Database::GitlabSchema.tables_to_schema.each do |table_name, schema_name| + yield table_name, schema_name + end + + Gitlab::Database::SharedModel.using_connection(connection) do + Postgresql::DetachedPartition.find_each do |detached_partition| + yield detached_partition.fully_qualified_table_name, detached_partition.table_schema + end + end + end + def initialize(table_name:, connection:, database_name:, logger: nil, dry_run: false) @table_name = table_name @connection = connection @database_name = database_name @logger = logger @dry_run = dry_run + + @table_name_without_schema = ActiveRecord::ConnectionAdapters::PostgreSQL::Utils + .extract_schema_qualified_name(table_name) + .identifier end def table_locked_for_writes?(table_name) query = <<~SQL SELECT COUNT(*) from information_schema.triggers - WHERE event_object_table = '#{table_name}' + WHERE event_object_table = '#{table_name_without_schema}' AND trigger_name = '#{write_trigger_name(table_name)}' SQL @@ -56,7 +72,7 @@ module Gitlab private - attr_reader :table_name, :connection, :database_name, :logger, :dry_run + attr_reader :table_name, :connection, :database_name, :logger, :dry_run, :table_name_without_schema def execute_sql_statement(sql) if dry_run @@ -99,7 +115,7 @@ module Gitlab end def write_trigger_name(table_name) - "gitlab_schema_write_trigger_for_#{table_name}" + "gitlab_schema_write_trigger_for_#{table_name_without_schema}" end end end diff --git a/lib/gitlab/database/tables_sorted_by_foreign_keys.rb b/lib/gitlab/database/tables_sorted_by_foreign_keys.rb index 9f096904d31..c614bb00c8d 100644 --- a/lib/gitlab/database/tables_sorted_by_foreign_keys.rb +++ b/lib/gitlab/database/tables_sorted_by_foreign_keys.rb @@ -27,14 +27,31 @@ module Gitlab # it maps the tables to the tables that depend on it def tables_dependencies @tables.to_h do |table_name| - [table_name, all_foreign_keys[table_name]&.map(&:from_table).to_a] + [table_name, all_foreign_keys[table_name]] end end def all_foreign_keys - @all_foreign_keys ||= @tables.flat_map do |table_name| - @connection.foreign_keys(table_name) - end.group_by(&:to_table) + @all_foreign_keys ||= @tables.each_with_object(Hash.new { |h, k| h[k] = [] }) do |table, hash| + foreign_keys_for(table).each do |fk| + hash[fk.to_table] << table + end + end + end + + def foreign_keys_for(table) + # Detached partitions like gitlab_partitions_dynamic._test_gitlab_partition_20220101 + # store their foreign keys in the public schema. + # + # See spec/lib/gitlab/database/tables_sorted_by_foreign_keys_spec.rb + # for an example + name = ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(table) + + if name.schema == ::Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA.to_s + @connection.foreign_keys(name.identifier) + else + @connection.foreign_keys(table) + end end end end diff --git a/lib/gitlab/database/tables_truncate.rb b/lib/gitlab/database/tables_truncate.rb index 61ec9769694..807ecdb862a 100644 --- a/lib/gitlab/database/tables_truncate.rb +++ b/lib/gitlab/database/tables_truncate.rb @@ -24,6 +24,14 @@ module Gitlab GITLAB_SCHEMAS_TO_IGNORE.union(schemas_for_connection).include?(schema_name) end.keys + Gitlab::Database::SharedModel.using_connection(connection) do + Postgresql::DetachedPartition.find_each do |detached_partition| + next if GITLAB_SCHEMAS_TO_IGNORE.union(schemas_for_connection).include?(detached_partition.table_schema) + + tables_to_truncate << detached_partition.fully_qualified_table_name + end + end + tables_sorted = Gitlab::Database::TablesSortedByForeignKeys.new(connection, tables_to_truncate).execute # Checking if all the tables have the write-lock triggers # to make sure we are deleting the right tables on the right database. @@ -66,7 +74,11 @@ module Gitlab truncated_tables = [] tables_sorted.flatten.each do |table| - sql_statement = "SELECT set_config('lock_writes.#{table}', 'false', false)" + table_name_without_schema = ActiveRecord::ConnectionAdapters::PostgreSQL::Utils + .extract_schema_qualified_name(table) + .identifier + + sql_statement = "SELECT set_config('lock_writes.#{table_name_without_schema}', 'false', false)" logger&.info(sql_statement) connection.execute(sql_statement) unless dry_run end diff --git a/lib/tasks/gitlab/db/lock_writes.rake b/lib/tasks/gitlab/db/lock_writes.rake index 421c6a90fdd..a856aa77abc 100644 --- a/lib/tasks/gitlab/db/lock_writes.rake +++ b/lib/tasks/gitlab/db/lock_writes.rake @@ -6,7 +6,8 @@ namespace :gitlab do task lock_writes: [:environment, 'gitlab:db:validate_config'] do Gitlab::Database::EachDatabase.each_database_connection(include_shared: false) do |connection, database_name| schemas_for_connection = Gitlab::Database.gitlab_schemas_for_connection(connection) - Gitlab::Database::GitlabSchema.tables_to_schema.each do |table_name, schema_name| + + Gitlab::Database::LockWritesManager.tables_to_lock(connection) do |table_name, schema_name| # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/366834 next if schema_name == :gitlab_geo @@ -30,7 +31,7 @@ namespace :gitlab do desc "GitLab | DB | Remove all triggers that prevents writes from all databases" task unlock_writes: :environment do Gitlab::Database::EachDatabase.each_database_connection do |connection, database_name| - Gitlab::Database::GitlabSchema.tables_to_schema.each do |table_name, schema_name| + Gitlab::Database::LockWritesManager.tables_to_lock(connection) do |table_name, schema_name| # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/366834 next if schema_name == :gitlab_geo diff --git a/lib/version_check.rb b/lib/version_check.rb index eddcddbeb49..35014f3ddf0 100644 --- a/lib/version_check.rb +++ b/lib/version_check.rb @@ -69,17 +69,13 @@ class VersionCheck case response&.code when 200 - Gitlab::Json.parse(response.body) - else - { error: 'version check failed', status: response&.code } + response.body end end def response with_reactive_cache do |data| - raise InvalidateReactiveCache if data[:error] - - data + Gitlab::Json.parse(data) if data end end end diff --git a/spec/lib/gitlab/database/lock_writes_manager_spec.rb b/spec/lib/gitlab/database/lock_writes_manager_spec.rb index b1cc8add55a..242b2040eaa 100644 --- a/spec/lib/gitlab/database/lock_writes_manager_spec.rb +++ b/spec/lib/gitlab/database/lock_writes_manager_spec.rb @@ -37,6 +37,14 @@ RSpec.describe Gitlab::Database::LockWritesManager do it 'returns true for a table that is locked for writes' do expect { subject.lock_writes }.to change { subject.table_locked_for_writes?(test_table) }.from(false).to(true) end + + context 'for detached partition tables in another schema' do + let(:test_table) { 'gitlab_partitions_dynamic._test_table_20220101' } + + it 'returns true for a table that is locked for writes' do + expect { subject.lock_writes }.to change { subject.table_locked_for_writes?(test_table) }.from(false).to(true) + end + end end describe '#lock_writes' do diff --git a/spec/lib/gitlab/database/tables_sorted_by_foreign_keys_spec.rb b/spec/lib/gitlab/database/tables_sorted_by_foreign_keys_spec.rb index 97abd6d23bd..aa25590ed58 100644 --- a/spec/lib/gitlab/database/tables_sorted_by_foreign_keys_spec.rb +++ b/spec/lib/gitlab/database/tables_sorted_by_foreign_keys_spec.rb @@ -4,7 +4,10 @@ require 'spec_helper' RSpec.describe Gitlab::Database::TablesSortedByForeignKeys do let(:connection) { ApplicationRecord.connection } - let(:tables) { %w[_test_gitlab_main_items _test_gitlab_main_references] } + let(:tables) do + %w[_test_gitlab_main_items _test_gitlab_main_references _test_gitlab_partition_parent + gitlab_partitions_dynamic._test_gitlab_partition_20220101] + end subject do described_class.new(connection, tables).execute @@ -19,13 +22,33 @@ RSpec.describe Gitlab::Database::TablesSortedByForeignKeys do item_id BIGINT NOT NULL, CONSTRAINT fk_constrained_1 FOREIGN KEY(item_id) REFERENCES _test_gitlab_main_items(id) ); + + CREATE TABLE _test_gitlab_partition_parent ( + id bigserial not null, + created_at timestamptz not null, + item_id BIGINT NOT NULL, + primary key (id, created_at), + CONSTRAINT fk_constrained_1 FOREIGN KEY(item_id) REFERENCES _test_gitlab_main_items(id) + ) PARTITION BY RANGE(created_at); + + CREATE TABLE gitlab_partitions_dynamic._test_gitlab_partition_20220101 + PARTITION OF _test_gitlab_partition_parent + FOR VALUES FROM ('20220101') TO ('20220131'); + + ALTER TABLE _test_gitlab_partition_parent DETACH PARTITION gitlab_partitions_dynamic._test_gitlab_partition_20220101; SQL connection.execute(statement) end describe '#execute' do it 'returns the tables sorted by the foreign keys dependency' do - expect(subject).to eq([['_test_gitlab_main_references'], ['_test_gitlab_main_items']]) + expect(subject).to eq( + [ + ['_test_gitlab_main_references'], + ['_test_gitlab_partition_parent'], + ['gitlab_partitions_dynamic._test_gitlab_partition_20220101'], + ['_test_gitlab_main_items'] + ]) end it 'returns both tables together if they are strongly connected' do @@ -35,7 +58,12 @@ RSpec.describe Gitlab::Database::TablesSortedByForeignKeys do SQL connection.execute(statement) - expect(subject).to eq([tables]) + expect(subject).to eq( + [ + ['_test_gitlab_partition_parent'], + ['gitlab_partitions_dynamic._test_gitlab_partition_20220101'], + %w[_test_gitlab_main_items _test_gitlab_main_references] + ]) end end end diff --git a/spec/lib/gitlab/database/tables_truncate_spec.rb b/spec/lib/gitlab/database/tables_truncate_spec.rb index 4f68cd93a8e..fa366a6e32f 100644 --- a/spec/lib/gitlab/database/tables_truncate_spec.rb +++ b/spec/lib/gitlab/database/tables_truncate_spec.rb @@ -6,14 +6,9 @@ RSpec.describe Gitlab::Database::TablesTruncate, :reestablished_active_record_ba :suppress_gitlab_schemas_validate_connection do include MigrationsHelpers - let(:logger) { instance_double(Logger) } - let(:dry_run) { false } - let(:until_table) { nil } let(:min_batch_size) { 1 } let(:main_connection) { ApplicationRecord.connection } let(:ci_connection) { Ci::ApplicationRecord.connection } - let(:test_gitlab_main_table) { '_test_gitlab_main_table' } - let(:test_gitlab_ci_table) { '_test_gitlab_ci_table' } # Main Database let(:main_db_main_item_model) { table("_test_gitlab_main_items", database: "main") } @@ -21,24 +16,37 @@ RSpec.describe Gitlab::Database::TablesTruncate, :reestablished_active_record_ba let(:main_db_ci_item_model) { table("_test_gitlab_ci_items", database: "main") } let(:main_db_ci_reference_model) { table("_test_gitlab_ci_references", database: "main") } let(:main_db_shared_item_model) { table("_test_gitlab_shared_items", database: "main") } + let(:main_db_partitioned_item) { table("_test_gitlab_hook_logs", database: "main") } + let(:main_db_partitioned_item_detached) do + table("gitlab_partitions_dynamic._test_gitlab_hook_logs_20220101", database: "main") + end + # CI Database let(:ci_db_main_item_model) { table("_test_gitlab_main_items", database: "ci") } let(:ci_db_main_reference_model) { table("_test_gitlab_main_references", database: "ci") } let(:ci_db_ci_item_model) { table("_test_gitlab_ci_items", database: "ci") } let(:ci_db_ci_reference_model) { table("_test_gitlab_ci_references", database: "ci") } let(:ci_db_shared_item_model) { table("_test_gitlab_shared_items", database: "ci") } - - subject(:truncate_legacy_tables) do - described_class.new( - database_name: database_name, - min_batch_size: min_batch_size, - logger: logger, - dry_run: dry_run, - until_table: until_table - ).execute + let(:ci_db_partitioned_item) { table("_test_gitlab_hook_logs", database: "ci") } + let(:ci_db_partitioned_item_detached) do + table("gitlab_partitions_dynamic._test_gitlab_hook_logs_20220101", database: "ci") end shared_examples 'truncating legacy tables on a database' do + let(:logger) { instance_double(Logger) } + let(:dry_run) { false } + let(:until_table) { nil } + + subject(:truncate_legacy_tables) do + described_class.new( + database_name: connection.pool.db_config.name, + min_batch_size: min_batch_size, + logger: logger, + dry_run: dry_run, + until_table: until_table + ).execute + end + before do skip_if_multiple_databases_not_setup @@ -51,6 +59,24 @@ RSpec.describe Gitlab::Database::TablesTruncate, :reestablished_active_record_ba item_id BIGINT NOT NULL, CONSTRAINT fk_constrained_1 FOREIGN KEY(item_id) REFERENCES _test_gitlab_main_items(id) ); + + CREATE TABLE _test_gitlab_hook_logs ( + id bigserial not null, + created_at timestamptz not null, + item_id BIGINT NOT NULL, + primary key (id, created_at), + CONSTRAINT fk_constrained_1 FOREIGN KEY(item_id) REFERENCES _test_gitlab_main_items(id) + ) PARTITION BY RANGE(created_at); + + CREATE TABLE gitlab_partitions_dynamic._test_gitlab_hook_logs_20220101 + PARTITION OF _test_gitlab_hook_logs + FOR VALUES FROM ('20220101') TO ('20220131'); + + CREATE TABLE gitlab_partitions_dynamic._test_gitlab_hook_logs_20220201 + PARTITION OF _test_gitlab_hook_logs + FOR VALUES FROM ('20220201') TO ('20220228'); + + ALTER TABLE _test_gitlab_hook_logs DETACH PARTITION gitlab_partitions_dynamic._test_gitlab_hook_logs_20220101; SQL main_connection.execute(main_tables_sql) @@ -84,18 +110,37 @@ RSpec.describe Gitlab::Database::TablesTruncate, :reestablished_active_record_ba main_db_ci_item_model.create!(id: i) main_db_ci_reference_model.create!(item_id: i) main_db_shared_item_model.create!(id: i) + main_db_partitioned_item.create!(item_id: i, created_at: '2022-02-02 02:00') + main_db_partitioned_item_detached.create!(item_id: i, created_at: '2022-01-01 01:00') # CI Database ci_db_main_item_model.create!(id: i) ci_db_main_reference_model.create!(item_id: i) ci_db_ci_item_model.create!(id: i) ci_db_ci_reference_model.create!(item_id: i) ci_db_shared_item_model.create!(id: i) + ci_db_partitioned_item.create!(item_id: i, created_at: '2022-02-02 02:00') + ci_db_partitioned_item_detached.create!(item_id: i, created_at: '2022-01-01 01:00') + end + + Gitlab::Database::SharedModel.using_connection(main_connection) do + Postgresql::DetachedPartition.create!( + table_name: '_test_gitlab_hook_logs_20220101', + drop_after: Time.current + ) + end + + Gitlab::Database::SharedModel.using_connection(ci_connection) do + Postgresql::DetachedPartition.create!( + table_name: '_test_gitlab_hook_logs_20220101', + drop_after: Time.current + ) end allow(Gitlab::Database::GitlabSchema).to receive(:tables_to_schema).and_return( { "_test_gitlab_main_items" => :gitlab_main, "_test_gitlab_main_references" => :gitlab_main, + "_test_gitlab_hook_logs" => :gitlab_main, "_test_gitlab_ci_items" => :gitlab_ci, "_test_gitlab_ci_references" => :gitlab_ci, "_test_gitlab_shared_items" => :gitlab_shared, @@ -119,7 +164,7 @@ RSpec.describe Gitlab::Database::TablesTruncate, :reestablished_active_record_ba Gitlab::Database::LockWritesManager.new( table_name: table, connection: connection, - database_name: database_name + database_name: connection.pool.db_config.name ).lock_writes end end @@ -199,7 +244,6 @@ RSpec.describe Gitlab::Database::TablesTruncate, :reestablished_active_record_ba context 'when truncating gitlab_ci tables on the main database' do let(:connection) { ApplicationRecord.connection } - let(:database_name) { "main" } let(:legacy_tables_models) { [main_db_ci_item_model, main_db_ci_reference_model] } let(:referencing_table_model) { main_db_ci_reference_model } let(:referenced_table_model) { main_db_ci_item_model } @@ -217,8 +261,10 @@ RSpec.describe Gitlab::Database::TablesTruncate, :reestablished_active_record_ba context 'when truncating gitlab_main tables on the ci database' do let(:connection) { Ci::ApplicationRecord.connection } - let(:database_name) { "ci" } - let(:legacy_tables_models) { [ci_db_main_item_model, ci_db_main_reference_model] } + let(:legacy_tables_models) do + [ci_db_main_item_model, ci_db_main_reference_model, ci_db_partitioned_item, ci_db_partitioned_item_detached] + end + let(:referencing_table_model) { ci_db_main_reference_model } let(:referenced_table_model) { ci_db_main_item_model } let(:other_tables_models) do diff --git a/spec/lib/gitlab/github_import/importer/issues_importer_spec.rb b/spec/lib/gitlab/github_import/importer/issues_importer_spec.rb index 308b8185589..4a5525c250e 100644 --- a/spec/lib/gitlab/github_import/importer/issues_importer_spec.rb +++ b/spec/lib/gitlab/github_import/importer/issues_importer_spec.rb @@ -90,9 +90,13 @@ RSpec.describe Gitlab::GithubImport::Importer::IssuesImporter do .to receive(:each_object_to_import) .and_yield(github_issue) - expect(Gitlab::GithubImport::ImportIssueWorker).to receive(:bulk_perform_in).with(1.second, [ - [project.id, an_instance_of(Hash), an_instance_of(String)] - ], batch_size: 1000, batch_delay: 1.minute) + expect(Gitlab::GithubImport::ImportIssueWorker) + .to receive(:bulk_perform_in) + .with(1.second, + [[project.id, an_instance_of(Hash), an_instance_of(String)]], + batch_size: 1000, + batch_delay: 1.minute + ) waiter = importer.parallel_import diff --git a/spec/lib/gitlab/search/found_blob_spec.rb b/spec/lib/gitlab/search/found_blob_spec.rb index 8b1c91f689d..c41a051bc42 100644 --- a/spec/lib/gitlab/search/found_blob_spec.rb +++ b/spec/lib/gitlab/search/found_blob_spec.rb @@ -141,9 +141,8 @@ RSpec.describe Gitlab::Search::FoundBlob do subject { described_class.new(blob_path: path, project: project, ref: 'master') } before do - allow(Gitlab::Git::Blob).to receive(:batch).and_return([ - Gitlab::Git::Blob.new(path: path) - ]) + allow(Gitlab::Git::Blob) + .to receive(:batch).and_return([Gitlab::Git::Blob.new(path: path)]) end it { expect(subject.path).to eq('a/b/c.md') } diff --git a/spec/lib/version_check_spec.rb b/spec/lib/version_check_spec.rb index f14b38c55dd..1803dd66ba7 100644 --- a/spec/lib/version_check_spec.rb +++ b/spec/lib/version_check_spec.rb @@ -2,9 +2,7 @@ require 'spec_helper' -RSpec.describe VersionCheck, :use_clean_rails_memory_store_caching do - include ReactiveCachingHelpers - +RSpec.describe VersionCheck do describe '.url' do it 'returns the correct URL' do expect(described_class.url).to match(%r{\A#{Regexp.escape(described_class.host)}/check\.json\?gitlab_info=\w+}) @@ -32,7 +30,7 @@ RSpec.describe VersionCheck, :use_clean_rails_memory_store_caching do end it 'returns the response object' do - expect(described_class.new.calculate_reactive_cache).to eq({ "status" => "success" }) + expect(described_class.new.calculate_reactive_cache).to eq("{ \"status\": \"success\" }") end end @@ -41,31 +39,38 @@ RSpec.describe VersionCheck, :use_clean_rails_memory_store_caching do stub_request(:get, described_class.url).to_return(status: 500, body: nil, headers: {}) end - it 'returns an error hash' do - expect(described_class.new.calculate_reactive_cache).to eq({ error: 'version check failed', status: 500 }) + it 'returns nil' do + expect(described_class.new.calculate_reactive_cache).to be(nil) end end end describe '#response' do context 'cache returns value' do - it 'returns the response object' do - version_check = described_class.new - data = { status: 'success' } - stub_reactive_cache(version_check, data) + let(:response) { { "severity" => "success" }.to_json } - expect(version_check.response).to eq(data) + before do + allow_next_instance_of(described_class) do |instance| + allow(instance).to receive(:with_reactive_cache).and_return(response) + end + end + + it 'returns the response object' do + expect(described_class.new.response).to be(response) end end - context 'cache returns error' do - it 'returns nil and invalidates the reactive cache' do - version_check = described_class.new - stub_reactive_cache(version_check, error: 'version check failed') + context 'cache returns nil' do + let(:response) { nil } + + before do + allow_next_instance_of(described_class) do |instance| + allow(instance).to receive(:with_reactive_cache).and_return(response) + end + end - expect(version_check).to receive(:refresh_reactive_cache!).and_call_original - expect(version_check.response).to be_nil - expect(read_reactive_cache(version_check)).to be_nil + it 'returns nil' do + expect(described_class.new.response).to be(nil) end end end diff --git a/spec/models/ci/runner_version_spec.rb b/spec/models/ci/runner_version_spec.rb index baa37b026c7..80d72de3b14 100644 --- a/spec/models/ci/runner_version_spec.rb +++ b/spec/models/ci/runner_version_spec.rb @@ -28,11 +28,9 @@ RSpec.describe Ci::RunnerVersion, feature_category: :runner do end it 'contains any valid or unprocessed runner version that is not already recommended' do - is_expected.to match_array([ - runner_version_nil, - runner_version_not_available, - runner_version_available - ]) + is_expected.to match_array( + [runner_version_nil, runner_version_not_available, runner_version_available] + ) end end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 01e5c3d04db..202208a0d83 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -2224,32 +2224,34 @@ RSpec.describe Repository do describe '#after_change_head' do it 'flushes the method caches' do - expect(repository).to receive(:expire_method_caches).with([ - :size, - :commit_count, - :readme_path, - :contribution_guide, - :changelog, - :license_blob, - :license_licensee, - :license_gitaly, - :gitignore, - :gitlab_ci_yml, - :branch_names, - :tag_names, - :branch_count, - :tag_count, - :avatar, - :exists?, - :root_ref, - :merged_branch_names, - :has_visible_content?, - :issue_template_names_hash, - :merge_request_template_names_hash, - :user_defined_metrics_dashboard_paths, - :xcode_project?, - :has_ambiguous_refs? - ]) + expect(repository).to receive(:expire_method_caches).with( + [ + :size, + :commit_count, + :readme_path, + :contribution_guide, + :changelog, + :license_blob, + :license_licensee, + :license_gitaly, + :gitignore, + :gitlab_ci_yml, + :branch_names, + :tag_names, + :branch_count, + :tag_count, + :avatar, + :exists?, + :root_ref, + :merged_branch_names, + :has_visible_content?, + :issue_template_names_hash, + :merge_request_template_names_hash, + :user_defined_metrics_dashboard_paths, + :xcode_project?, + :has_ambiguous_refs? + ] + ) repository.after_change_head end diff --git a/spec/requests/api/task_completion_status_spec.rb b/spec/requests/api/task_completion_status_spec.rb index 97ce858ba12..6cc1fb6c713 100644 --- a/spec/requests/api/task_completion_status_spec.rb +++ b/spec/requests/api/task_completion_status_spec.rb @@ -10,44 +10,44 @@ RSpec.describe 'task completion status response' do shared_examples 'taskable completion status provider' do |path| samples = [ - { - description: '', - expected_count: 0, - expected_completed_count: 0 - }, - { - description: 'Lorem ipsum', - expected_count: 0, - expected_completed_count: 0 - }, - { - description: %{- [ ] task 1 + { + description: '', + expected_count: 0, + expected_completed_count: 0 + }, + { + description: 'Lorem ipsum', + expected_count: 0, + expected_completed_count: 0 + }, + { + description: %{- [ ] task 1 - [x] task 2 }, - expected_count: 2, - expected_completed_count: 1 - }, - { - description: %{- [ ] task 1 + expected_count: 2, + expected_completed_count: 1 + }, + { + description: %{- [ ] task 1 - [ ] task 2 }, - expected_count: 2, - expected_completed_count: 0 - }, - { - description: %{- [x] task 1 + expected_count: 2, + expected_completed_count: 0 + }, + { + description: %{- [x] task 1 - [x] task 2 }, - expected_count: 2, - expected_completed_count: 2 - }, - { - description: %{- [ ] task 1}, - expected_count: 1, - expected_completed_count: 0 - }, - { - description: %{- [x] task 1}, - expected_count: 1, - expected_completed_count: 1 - } + expected_count: 2, + expected_completed_count: 2 + }, + { + description: %{- [ ] task 1}, + expected_count: 1, + expected_completed_count: 0 + }, + { + description: %{- [x] task 1}, + expected_count: 1, + expected_completed_count: 1 + } ] samples.each do |sample_data| context "with a description of #{sample_data[:description].inspect}" do diff --git a/spec/routing/user_routing_spec.rb b/spec/routing/user_routing_spec.rb new file mode 100644 index 00000000000..7bb589565fa --- /dev/null +++ b/spec/routing/user_routing_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'user routing', :clean_gitlab_redis_sessions, feature_category: :authentication_and_authorization do + include SessionHelpers + + context 'when GitHub OAuth on project import is cancelled' do + it_behaves_like 'redirecting a legacy path', '/users/auth?error=access_denied&state=xyz', '/users/sign_in' + end + + context 'when GitHub OAuth on sign in is cancelled' do + before do + stub_session(auth_on_failure_path: '/projects/new#import_project') + end + + context 'when all required parameters are present' do + it_behaves_like 'redirecting a legacy path', + '/users/auth?error=access_denied&state=xyz', + '/projects/new#import_project' + end + + context 'when one of the required parameters is missing' do + it_behaves_like 'redirecting a legacy path', + '/users/auth?error=access_denied&state=', + '/auth' + end + end +end diff --git a/spec/services/security/merge_reports_service_spec.rb b/spec/services/security/merge_reports_service_spec.rb index 8415ed8a22f..249f4da5f34 100644 --- a/spec/services/security/merge_reports_service_spec.rb +++ b/spec/services/security/merge_reports_service_spec.rb @@ -187,25 +187,25 @@ RSpec.describe Security::MergeReportsService, '#execute' do it 'deduplicates (except cwe and wasc) and sorts the vulnerabilities by severity (desc) then by compare key' do expect(merged_report.findings).to( eq([ - finding_cwe_2, - finding_wasc_2, - finding_cwe_1, - finding_id_2_loc_2, - finding_id_2_loc_1, - finding_wasc_1, - finding_id_1 - ]) + finding_cwe_2, + finding_wasc_2, + finding_cwe_1, + finding_id_2_loc_2, + finding_id_2_loc_1, + finding_wasc_1, + finding_id_1 + ]) ) end it 'deduplicates scanned resources' do expect(merged_report.scanned_resources).to( eq([ - scanned_resource, - scanned_resource_1, - scanned_resource_2, - scanned_resource_3 - ]) + scanned_resource, + scanned_resource_1, + scanned_resource_2, + scanned_resource_3 + ]) ) end diff --git a/spec/simplecov_env.rb b/spec/simplecov_env.rb index dbaecc6a233..70bd01091ba 100644 --- a/spec/simplecov_env.rb +++ b/spec/simplecov_env.rb @@ -21,12 +21,14 @@ module SimpleCovEnv def configure_formatter SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true - SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([ - SimpleCov::Formatter::SimpleFormatter, - SimpleCov::Formatter::HTMLFormatter, - SimpleCov::Formatter::CoberturaFormatter, - SimpleCov::Formatter::LcovFormatter - ]) + SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new( + [ + SimpleCov::Formatter::SimpleFormatter, + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::CoberturaFormatter, + SimpleCov::Formatter::LcovFormatter + ] + ) end def configure_job diff --git a/spec/support/atlassian/jira_connect/schemata.rb b/spec/support/atlassian/jira_connect/schemata.rb index 61e8aa8e15c..73a6833b7cc 100644 --- a/spec/support/atlassian/jira_connect/schemata.rb +++ b/spec/support/atlassian/jira_connect/schemata.rb @@ -11,7 +11,7 @@ module Atlassian schemaVersion pipelineId buildNumber updateSequenceNumber displayName url state issueKeys testInfo references lastUpdated - ), + ), 'properties' => { 'schemaVersion' => schema_version_type, 'pipelineId' => { 'type' => 'string' }, diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 57065400220..aea853d1c23 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -16,15 +16,17 @@ Capybara.server_port = ENV['CAPYBARA_PORT'] if ENV['CAPYBARA_PORT'] JSConsoleError = Class.new(StandardError) # Filter out innocuous JS console messages -JS_CONSOLE_FILTER = Regexp.union([ - '"[HMR] Waiting for update signal from WDS..."', - '"[WDS] Hot Module Replacement enabled."', - '"[WDS] Live Reloading enabled."', - 'Download the Vue Devtools extension', - 'Download the Apollo DevTools', - "Unrecognized feature: 'interest-cohort'", - 'Does this page need fixes or improvements?' -]) +JS_CONSOLE_FILTER = Regexp.union( + [ + '"[HMR] Waiting for update signal from WDS..."', + '"[WDS] Hot Module Replacement enabled."', + '"[WDS] Live Reloading enabled."', + 'Download the Vue Devtools extension', + 'Download the Apollo DevTools', + "Unrecognized feature: 'interest-cohort'", + 'Does this page need fixes or improvements?' + ] +) CAPYBARA_WINDOW_SIZE = [1366, 768].freeze diff --git a/spec/support/finder_collection_allowlist.yml b/spec/support/finder_collection_allowlist.yml index c8af07905c2..750295e16c4 100644 --- a/spec/support/finder_collection_allowlist.yml +++ b/spec/support/finder_collection_allowlist.yml @@ -1,8 +1,10 @@ # Allow list for spec/support/finder_collection.rb -# Permenant excludes +# Permanent excludes # For example: # FooFinder # Reason: It uses a memory backend +- Namespaces::BilledUsersFinder # Reason: There is no need to have anything else besides the ids is current structure +- Namespaces::FreeUserCap::UsersFinder # Reason: There is no need to have anything else besides the count # Temporary excludes (aka TODOs) # For example: diff --git a/spec/support/helpers/project_template_test_helper.rb b/spec/support/helpers/project_template_test_helper.rb index 1990cd4551a..bd2fd367fae 100644 --- a/spec/support/helpers/project_template_test_helper.rb +++ b/spec/support/helpers/project_template_test_helper.rb @@ -3,14 +3,14 @@ module ProjectTemplateTestHelper def all_templates %w[ - rails spring express iosswift dotnetcore android - gomicro gatsby hugo jekyll plainhtml gitbook - hexo middleman gitpod_spring_petclinic nfhugo - nfjekyll nfplainhtml nfgitbook nfhexo salesforcedx - serverless_framework tencent_serverless_framework - jsonnet cluster_management kotlin_native_linux - pelican bridgetown - ] + rails spring express iosswift dotnetcore android + gomicro gatsby hugo jekyll plainhtml gitbook + hexo middleman gitpod_spring_petclinic nfhugo + nfjekyll nfplainhtml nfgitbook nfhexo salesforcedx + serverless_framework tencent_serverless_framework + jsonnet cluster_management kotlin_native_linux + pelican bridgetown + ] end end diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb index 4f85eef31fa..1bd468ccfc3 100644 --- a/spec/support/helpers/test_env.rb +++ b/spec/support/helpers/test_env.rb @@ -490,12 +490,14 @@ module TestEnv # The HEAD of the component_folder will be used as heuristic for the version # of the binaries, allowing to use Git to determine if HEAD is later than # the expected version. Note: Git considers HEAD to be an anchestor of HEAD. - _out, exit_status = Gitlab::Popen.popen(%W[ - #{Gitlab.config.git.bin_path} - -C #{component_folder} - merge-base --is-ancestor - #{expected_version} HEAD -]) + _out, exit_status = Gitlab::Popen.popen( + %W[ + #{Gitlab.config.git.bin_path} + -C #{component_folder} + merge-base --is-ancestor + #{expected_version} HEAD + ] + ) exit_status == 0 end diff --git a/spec/support/helpers/usage_data_helpers.rb b/spec/support/helpers/usage_data_helpers.rb index e7b5e3717a6..78ceaf297a8 100644 --- a/spec/support/helpers/usage_data_helpers.rb +++ b/spec/support/helpers/usage_data_helpers.rb @@ -2,118 +2,118 @@ module UsageDataHelpers COUNTS_KEYS = %i( - assignee_lists - ci_builds - ci_internal_pipelines - ci_external_pipelines - ci_pipeline_config_auto_devops - ci_pipeline_config_repository - ci_runners - ci_triggers - ci_pipeline_schedules - auto_devops_enabled - auto_devops_disabled - deploy_keys - deployments - successful_deployments - failed_deployments - environments - clusters - clusters_enabled - project_clusters_enabled - group_clusters_enabled - instance_clusters_enabled - clusters_disabled - project_clusters_disabled - group_clusters_disabled - instance_clusters_disabled - clusters_platforms_eks - clusters_platforms_gke - clusters_platforms_user - clusters_integrations_prometheus - clusters_management_project - in_review_folder - grafana_integrated_projects - groups - issues - issues_created_from_gitlab_error_tracking_ui - issues_with_associated_zoom_link - issues_using_zoom_quick_actions - issues_with_embedded_grafana_charts_approx - incident_issues - keys - label_lists - labels - lfs_objects - merge_requests - milestone_lists - milestones - notes - pool_repositories - projects - projects_imported_from_github - projects_asana_active - projects_jenkins_active - projects_jira_active - projects_jira_server_active - projects_jira_cloud_active - projects_jira_dvcs_cloud_active - projects_jira_dvcs_server_active - projects_slack_active - projects_slack_slash_commands_active - projects_custom_issue_tracker_active - projects_mattermost_active - projects_prometheus_active - projects_with_repositories_enabled - projects_with_error_tracking_enabled - projects_with_enabled_alert_integrations - projects_with_terraform_reports - projects_with_terraform_states - pages_domains - protected_branches - protected_branches_except_default - releases - remote_mirrors - snippets - personal_snippets - project_snippets - suggestions - terraform_reports - terraform_states - todos - uploads - web_hooks - user_preferences_user_gitpod_enabled - ).freeze + assignee_lists + ci_builds + ci_internal_pipelines + ci_external_pipelines + ci_pipeline_config_auto_devops + ci_pipeline_config_repository + ci_runners + ci_triggers + ci_pipeline_schedules + auto_devops_enabled + auto_devops_disabled + deploy_keys + deployments + successful_deployments + failed_deployments + environments + clusters + clusters_enabled + project_clusters_enabled + group_clusters_enabled + instance_clusters_enabled + clusters_disabled + project_clusters_disabled + group_clusters_disabled + instance_clusters_disabled + clusters_platforms_eks + clusters_platforms_gke + clusters_platforms_user + clusters_integrations_prometheus + clusters_management_project + in_review_folder + grafana_integrated_projects + groups + issues + issues_created_from_gitlab_error_tracking_ui + issues_with_associated_zoom_link + issues_using_zoom_quick_actions + issues_with_embedded_grafana_charts_approx + incident_issues + keys + label_lists + labels + lfs_objects + merge_requests + milestone_lists + milestones + notes + pool_repositories + projects + projects_imported_from_github + projects_asana_active + projects_jenkins_active + projects_jira_active + projects_jira_server_active + projects_jira_cloud_active + projects_jira_dvcs_cloud_active + projects_jira_dvcs_server_active + projects_slack_active + projects_slack_slash_commands_active + projects_custom_issue_tracker_active + projects_mattermost_active + projects_prometheus_active + projects_with_repositories_enabled + projects_with_error_tracking_enabled + projects_with_enabled_alert_integrations + projects_with_terraform_reports + projects_with_terraform_states + pages_domains + protected_branches + protected_branches_except_default + releases + remote_mirrors + snippets + personal_snippets + project_snippets + suggestions + terraform_reports + terraform_states + todos + uploads + web_hooks + user_preferences_user_gitpod_enabled + ).freeze USAGE_DATA_KEYS = %i( - active_user_count - counts - counts_monthly - recorded_at - edition - version - installation_type - uuid - hostname - mattermost_enabled - signup_enabled - ldap_enabled - gravatar_enabled - omniauth_enabled - reply_by_email_enabled - container_registry_enabled - dependency_proxy_enabled - gitlab_shared_runners_enabled - gitlab_pages - git - gitaly - database - prometheus_metrics_enabled - web_ide_clientside_preview_enabled - object_store - topology - ).freeze + active_user_count + counts + counts_monthly + recorded_at + edition + version + installation_type + uuid + hostname + mattermost_enabled + signup_enabled + ldap_enabled + gravatar_enabled + omniauth_enabled + reply_by_email_enabled + container_registry_enabled + dependency_proxy_enabled + gitlab_shared_runners_enabled + gitlab_pages + git + gitaly + database + prometheus_metrics_enabled + web_ide_clientside_preview_enabled + object_store + topology + ).freeze def stub_usage_data_connections allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false) diff --git a/spec/support/matchers/exceed_query_limit.rb b/spec/support/matchers/exceed_query_limit.rb index 6d7658b7c33..4fd43d7b107 100644 --- a/spec/support/matchers/exceed_query_limit.rb +++ b/spec/support/matchers/exceed_query_limit.rb @@ -65,12 +65,14 @@ module ExceedQueryLimitHelpers MARGINALIA_ANNOTATION_REGEX = %r{\s*\/\*.*\*\/}.freeze - DB_QUERY_RE = Regexp.union([ - /^(?<prefix>SELECT .* FROM "?[a-z_]+"?) (?<suffix>.*)$/m, - /^(?<prefix>UPDATE "?[a-z_]+"?) (?<suffix>.*)$/m, - /^(?<prefix>INSERT INTO "[a-z_]+" \((?:"[a-z_]+",?\s?)+\)) (?<suffix>.*)$/m, - /^(?<prefix>DELETE FROM "[a-z_]+") (?<suffix>.*)$/m - ]).freeze + DB_QUERY_RE = Regexp.union( + [ + /^(?<prefix>SELECT .* FROM "?[a-z_]+"?) (?<suffix>.*)$/m, + /^(?<prefix>UPDATE "?[a-z_]+"?) (?<suffix>.*)$/m, + /^(?<prefix>INSERT INTO "[a-z_]+" \((?:"[a-z_]+",?\s?)+\)) (?<suffix>.*)$/m, + /^(?<prefix>DELETE FROM "[a-z_]+") (?<suffix>.*)$/m + ] + ).freeze def with_threshold(threshold) @threshold = threshold diff --git a/spec/support/migrations_helpers/vulnerabilities_findings_helper.rb b/spec/support/migrations_helpers/vulnerabilities_findings_helper.rb index a3cccc3a75d..9a5313c3fa4 100644 --- a/spec/support/migrations_helpers/vulnerabilities_findings_helper.rb +++ b/spec/support/migrations_helpers/vulnerabilities_findings_helper.rb @@ -92,10 +92,10 @@ module MigrationHelpers "url" => "http://goat:8080/WebGoat/logout", "body" => "", "headers" => [ - { - "name" => "Accept", - "value" => "*/*" - } + { + "name" => "Accept", + "value" => "*/*" + } ] }, "response" => { diff --git a/spec/support/prometheus/additional_metrics_shared_examples.rb b/spec/support/prometheus/additional_metrics_shared_examples.rb index 3a5909cd908..6aba9b16313 100644 --- a/spec/support/prometheus/additional_metrics_shared_examples.rb +++ b/spec/support/prometheus/additional_metrics_shared_examples.rb @@ -92,9 +92,9 @@ RSpec.shared_examples 'additional metrics query' do metrics: [ { title: 'title', weight: 1, y_label: 'Values', queries: [ - { query_range: 'query_range_a', result: query_range_result }, - { query_range: 'query_range_b', label: 'label', unit: 'unit', result: query_range_result } - ] + { query_range: 'query_range_a', result: query_range_result }, + { query_range: 'query_range_b', label: 'label', unit: 'unit', result: query_range_result } + ] } ] } diff --git a/spec/support/shared_contexts/policies/group_policy_shared_context.rb b/spec/support/shared_contexts/policies/group_policy_shared_context.rb index a6226fe903b..f6ac98c7669 100644 --- a/spec/support/shared_contexts/policies/group_policy_shared_context.rb +++ b/spec/support/shared_contexts/policies/group_policy_shared_context.rb @@ -14,7 +14,7 @@ RSpec.shared_context 'GroupPolicy context' do %i[ read_group read_counts read_label read_issue_board_list read_milestone read_issue_board - ] + ] end let(:guest_permissions) do @@ -22,32 +22,32 @@ RSpec.shared_context 'GroupPolicy context' do read_label read_group upload_file read_namespace read_group_activity read_group_issues read_group_boards read_group_labels read_group_milestones read_group_merge_requests - ] + ] end let(:reporter_permissions) do %i[ - admin_label - admin_milestone - admin_issue_board - read_container_image - read_harbor_registry - read_metrics_dashboard_annotation - read_prometheus - read_crm_contact - read_crm_organization - ] + admin_label + admin_milestone + admin_issue_board + read_container_image + read_harbor_registry + read_metrics_dashboard_annotation + read_prometheus + read_crm_contact + read_crm_organization + ] end let(:developer_permissions) do %i[ - create_metrics_dashboard_annotation - delete_metrics_dashboard_annotation - update_metrics_dashboard_annotation - create_custom_emoji - create_package - read_cluster - ] + create_metrics_dashboard_annotation + delete_metrics_dashboard_annotation + update_metrics_dashboard_annotation + create_custom_emoji + create_package + read_cluster + ] end let(:maintainer_permissions) do diff --git a/spec/support/shared_examples/graphql/label_fields.rb b/spec/support/shared_examples/graphql/label_fields.rb index 4159e4e03ab..030a2feafcd 100644 --- a/spec/support/shared_examples/graphql/label_fields.rb +++ b/spec/support/shared_examples/graphql/label_fields.rb @@ -42,9 +42,7 @@ RSpec.shared_examples 'querying a GraphQL type with labels' do make_query( [ query_graphql_field(:label, label_params, all_graphql_fields_for(Label)), - query_graphql_field(:labels, labels_params, [ - query_graphql_field(:nodes, nil, all_graphql_fields_for(Label)) - ]) + query_graphql_field(:labels, labels_params, [query_graphql_field(:nodes, nil, all_graphql_fields_for(Label))]) ] ) end diff --git a/spec/support/shared_examples/lib/gitlab/middleware/multipart_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/middleware/multipart_shared_examples.rb index 40deaa27955..16b048ae325 100644 --- a/spec/support/shared_examples/lib/gitlab/middleware/multipart_shared_examples.rb +++ b/spec/support/shared_examples/lib/gitlab/middleware/multipart_shared_examples.rb @@ -25,10 +25,12 @@ RSpec.shared_examples 'handling all upload parameters conditions' do end it 'builds UploadedFiles' do - expect_uploaded_files([ - { filepath: uploaded_filepath, original_filename: filename, remote_id: remote_id, size: uploaded_file.size, params_path: %w(file1) }, - { filepath: uploaded_filepath2, original_filename: filename2, remote_id: remote_id2, size: uploaded_file2.size, params_path: %w(file2) } - ]) + expect_uploaded_files( + [ + { filepath: uploaded_filepath, original_filename: filename, remote_id: remote_id, size: uploaded_file.size, params_path: %w(file1) }, + { filepath: uploaded_filepath2, original_filename: filename2, remote_id: remote_id2, size: uploaded_file2.size, params_path: %w(file2) } + ] + ) subject end @@ -61,10 +63,12 @@ RSpec.shared_examples 'handling all upload parameters conditions' do end it 'builds UploadedFiles' do - expect_uploaded_files([ - { filepath: uploaded_filepath, original_filename: filename, remote_id: remote_id, size: uploaded_file.size, params_path: %w(user avatar) }, - { filepath: uploaded_filepath2, original_filename: filename2, remote_id: remote_id2, size: uploaded_file2.size, params_path: %w(user screenshot) } - ]) + expect_uploaded_files( + [ + { filepath: uploaded_filepath, original_filename: filename, remote_id: remote_id, size: uploaded_file.size, params_path: %w(user avatar) }, + { filepath: uploaded_filepath2, original_filename: filename2, remote_id: remote_id2, size: uploaded_file2.size, params_path: %w(user screenshot) } + ] + ) subject end @@ -101,10 +105,12 @@ RSpec.shared_examples 'handling all upload parameters conditions' do end it 'builds UploadedFiles' do - expect_uploaded_files([ - { filepath: uploaded_file, original_filename: filename, remote_id: remote_id, size: uploaded_file.size, params_path: %w(user avatar bananas) }, - { filepath: uploaded_file2, original_filename: filename2, remote_id: remote_id2, size: uploaded_file2.size, params_path: %w(user friend ananas) } - ]) + expect_uploaded_files( + [ + { filepath: uploaded_file, original_filename: filename, remote_id: remote_id, size: uploaded_file.size, params_path: %w(user avatar bananas) }, + { filepath: uploaded_file2, original_filename: filename2, remote_id: remote_id2, size: uploaded_file2.size, params_path: %w(user friend ananas) } + ] + ) subject end @@ -133,11 +139,13 @@ RSpec.shared_examples 'handling all upload parameters conditions' do end it 'builds UploadedFiles' do - expect_uploaded_files([ - { filepath: uploaded_filepath, original_filename: filename, remote_id: remote_id, size: uploaded_file.size, params_path: %w(file) }, - { filepath: uploaded_filepath2, original_filename: filename2, remote_id: remote_id2, size: uploaded_file2.size, params_path: %w(user avatar) }, - { filepath: uploaded_filepath3, original_filename: filename3, remote_id: remote_id3, size: uploaded_file3.size, params_path: %w(user friend avatar) } - ]) + expect_uploaded_files( + [ + { filepath: uploaded_filepath, original_filename: filename, remote_id: remote_id, size: uploaded_file.size, params_path: %w(file) }, + { filepath: uploaded_filepath2, original_filename: filename2, remote_id: remote_id2, size: uploaded_file2.size, params_path: %w(user avatar) }, + { filepath: uploaded_filepath3, original_filename: filename3, remote_id: remote_id3, size: uploaded_file3.size, params_path: %w(user friend avatar) } + ] + ) subject end diff --git a/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb b/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb index 2d036cb2aa3..2154a76d765 100644 --- a/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb @@ -71,11 +71,7 @@ RSpec.shared_examples 'repository_storage_moves API' do |container_type| get_container_repository_storage_moves json_ids = json_response.map { |storage_move| storage_move['id'] } - expect(json_ids).to eq([ - storage_move.id, - storage_move_middle.id, - storage_move_oldest.id - ]) + expect(json_ids).to eq([storage_move.id, storage_move_middle.id, storage_move_oldest.id]) end describe 'permissions' do diff --git a/spec/tasks/gitlab/db/lock_writes_rake_spec.rb b/spec/tasks/gitlab/db/lock_writes_rake_spec.rb index ebea644bbf0..e3155d3c377 100644 --- a/spec/tasks/gitlab/db/lock_writes_rake_spec.rb +++ b/spec/tasks/gitlab/db/lock_writes_rake_spec.rb @@ -19,6 +19,30 @@ RSpec.describe 'gitlab:db:lock_writes', :silence_stdout, :reestablished_active_r let(:main_connection) { ApplicationRecord.connection } let(:ci_connection) { Ci::ApplicationRecord.connection } + let(:detached_partition_table) { '_test_gitlab_main_part_20220101' } + + before do + create_detached_partition_sql = <<~SQL + CREATE TABLE IF NOT EXISTS gitlab_partitions_dynamic._test_gitlab_main_part_20220101 ( + id bigserial primary key not null + ) + SQL + + main_connection.execute(create_detached_partition_sql) + ci_connection.execute(create_detached_partition_sql) + + Gitlab::Database::SharedModel.using_connection(main_connection) do + Postgresql::DetachedPartition.create!( + table_name: detached_partition_table, + drop_after: Time.current + ) + end + + allow(Gitlab::Database::GitlabSchema).to receive(:table_schema).and_call_original + allow(Gitlab::Database::GitlabSchema).to receive(:table_schema) + .with(detached_partition_table).and_return(:gitlab_main) + end + context 'single database' do before do skip_if_multiple_databases_are_setup @@ -46,6 +70,13 @@ RSpec.describe 'gitlab:db:lock_writes', :silence_stdout, :reestablished_active_r context 'multiple databases' do before do skip_if_multiple_databases_not_setup + + Gitlab::Database::SharedModel.using_connection(ci_connection) do + Postgresql::DetachedPartition.create!( + table_name: detached_partition_table, + drop_after: Time.current + ) + end end context 'when locking writes' do @@ -87,6 +118,13 @@ RSpec.describe 'gitlab:db:lock_writes', :silence_stdout, :reestablished_active_r main_connection.execute("truncate ci_build_needs") end.to raise_error(ActiveRecord::StatementInvalid, /Table: "ci_build_needs" is write protected/) end + + it 'prevents writes to detached partitions' do + run_rake_task('gitlab:db:lock_writes') + expect do + ci_connection.execute("INSERT INTO gitlab_partitions_dynamic.#{detached_partition_table} DEFAULT VALUES") + end.to raise_error(ActiveRecord::StatementInvalid, /Table: "#{detached_partition_table}" is write protected/) + end end context 'when running in dry_run mode' do @@ -138,6 +176,14 @@ RSpec.describe 'gitlab:db:lock_writes', :silence_stdout, :reestablished_active_r main_connection.execute("delete from ci_builds") end.not_to raise_error end + + it 'allows writes again to detached partitions' do + run_rake_task('gitlab:db:unlock_writes') + + expect do + ci_connection.execute("INSERT INTO gitlab_partitions_dynamic._test_gitlab_main_part_20220101 DEFAULT VALUES") + end.not_to raise_error + end end end diff --git a/spec/views/projects/issues/_related_branches.html.haml_spec.rb b/spec/views/projects/issues/_related_branches.html.haml_spec.rb index ba6f7068024..deec2db6865 100644 --- a/spec/views/projects/issues/_related_branches.html.haml_spec.rb +++ b/spec/views/projects/issues/_related_branches.html.haml_spec.rb @@ -9,10 +9,13 @@ RSpec.describe 'projects/issues/_related_branches' do let(:status) { pipeline.detailed_status(build(:user)) } before do - assign(:related_branches, [ - { name: 'other', link: 'link-to-other', pipeline_status: nil }, - { name: 'feature', link: 'link-to-feature', pipeline_status: status } - ]) + assign(:related_branches, + [ + { name: 'other', link: 'link-to-other', pipeline_status: nil }, + { name: 'feature', link: 'link-to-feature', pipeline_status: status } + + ] + ) render end diff --git a/tooling/lib/tooling/helm3_client.rb b/tooling/lib/tooling/helm3_client.rb index d83dbeac76b..d4e7faa802e 100644 --- a/tooling/lib/tooling/helm3_client.rb +++ b/tooling/lib/tooling/helm3_client.rb @@ -35,10 +35,7 @@ module Tooling end def delete(release_name:) - run_command([ - 'uninstall', - release_name - ]) + run_command(['uninstall', release_name]) end private |