diff options
Diffstat (limited to 'spec')
27 files changed, 506 insertions, 326 deletions
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 |