diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2024-01-19 00:08:06 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2024-01-19 00:08:06 +0300 |
commit | af7558b036a53ebb0484e7978694a0b419c38c70 (patch) | |
tree | 198bc423fd5bb7ca04e652f5a0c1d66c7d42d2c4 /spec | |
parent | 055b4c04d5cef7029625c08619df4f3bcdccc6c2 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
74 files changed, 343 insertions, 2672 deletions
diff --git a/spec/bin/feature_flag_spec.rb b/spec/bin/feature_flag_spec.rb index f9caa5549ca..41cf92646a0 100644 --- a/spec/bin/feature_flag_spec.rb +++ b/spec/bin/feature_flag_spec.rb @@ -21,20 +21,20 @@ RSpec.describe 'bin/feature-flag', feature_category: :feature_flags do end describe FeatureFlagCreator do - let(:argv) { %w[feature-flag-name -t gitlab_com_derisk -g group::geo -a https://url -i https://url -m http://url -u username -M 16.6] } + let(:argv) { %w[feature-flag-name -t gitlab_com_derisk -g group::geo -a https://url -i https://url -m http://url -u username -M 16.6 -ee] } let(:options) { FeatureFlagOptionParser.parse(argv) } let(:creator) { described_class.new(options) } let(:existing_flags) do { 'existing_feature_flag' => - File.join('config', 'feature_flags', 'gitlab_com_derisk', 'existing_feature_flag.yml') + File.join('ee', 'config', 'feature_flags', 'gitlab_com_derisk', 'existing_feature_flag.yml') } end before do allow(creator).to receive(:all_feature_flag_names) { existing_flags } - allow(creator).to receive(:branch_name) { 'feature-branch' } - allow(creator).to receive(:editor) { nil } + allow(creator).to receive(:branch_name).and_return('feature-branch') + allow(creator).to receive(:editor).and_return(nil) # ignore writes allow(File).to receive(:write).and_return(true) @@ -47,7 +47,7 @@ RSpec.describe 'bin/feature-flag', feature_category: :feature_flags do it 'properly creates a feature flag' do expect(File).to receive(:write).with( - File.join('config', 'feature_flags', 'gitlab_com_derisk', 'feature_flag_name.yml'), + File.join('ee', 'config', 'feature_flags', 'gitlab_com_derisk', 'feature_flag_name.yml'), anything) expect do @@ -57,7 +57,7 @@ RSpec.describe 'bin/feature-flag', feature_category: :feature_flags do context 'when running on master' do it 'requires feature branch' do - expect(creator).to receive(:branch_name) { 'master' } + expect(creator).to receive(:branch_name).and_return('master') expect { subject }.to raise_error(FeatureFlagHelpers::Abort, /Create a branch first/) end @@ -369,5 +369,18 @@ RSpec.describe 'bin/feature-flag', feature_category: :feature_flags do end end end + + describe '.read_ee' do + context 'with valid ee setting is given' do + let(:ee) { '1' } + + it 'reads ee from stdin' do + expect(Readline).to receive(:readline).and_return(ee) + expect do + expect(described_class.read_ee).to eq(true) + end.to output(/Is this an EE only feature/).to_stdout + end + end + end end end diff --git a/spec/fixtures/migrations/db/migrate/schema_cache_migration_test.rb b/spec/fixtures/migrations/db/migrate/schema_cache_migration_test.rb new file mode 100644 index 00000000000..32f2512c285 --- /dev/null +++ b/spec/fixtures/migrations/db/migrate/schema_cache_migration_test.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module SchemaCacheMigrationTest + def up + execute(<<~SQL) + CREATE OR REPLACE VIEW postgres_foreign_keys AS + SELECT + pg_constraint.oid AS oid, + pg_constraint.conname AS name, + constrained_namespace.nspname::text || '.'::text || constrained_table.relname::text AS constrained_table_identifier, + referenced_namespace.nspname::text || '.'::text || referenced_table.relname::text AS referenced_table_identifier, + constrained_table.relname::text AS constrained_table_name, + referenced_table.relname::text AS referenced_table_name, + constrained_cols.constrained_columns, + referenced_cols.referenced_columns, + pg_constraint.confdeltype AS on_delete_action, + pg_constraint.coninhcount > 0 as is_inherited + FROM pg_constraint + INNER JOIN pg_class constrained_table ON constrained_table.oid = pg_constraint.conrelid + INNER JOIN pg_class referenced_table ON referenced_table.oid = pg_constraint.confrelid + INNER JOIN pg_namespace constrained_namespace ON constrained_table.relnamespace = constrained_namespace.oid + INNER JOIN pg_namespace referenced_namespace ON referenced_table.relnamespace = referenced_namespace.oid + CROSS JOIN LATERAL ( + SELECT array_agg(pg_attribute.attname ORDER BY conkey.idx) -- must order here so that attributes are in correct order in array + FROM unnest(pg_constraint.conkey) WITH ORDINALITY conkey(attnum, idx) + INNER JOIN pg_attribute ON pg_attribute.attnum = conkey.attnum AND pg_attribute.attrelid = constrained_table.oid + ) constrained_cols(constrained_columns) + CROSS JOIN LATERAL ( + SELECT array_agg(pg_attribute.attname ORDER BY confkey.idx) + FROM unnest(pg_constraint.confkey) WITH ORDINALITY confkey(attnum, idx) + INNER JOIN pg_attribute ON pg_attribute.attnum = confkey.attnum AND pg_attribute.attrelid = referenced_table.oid + ) referenced_cols(referenced_columns) + WHERE contype = 'f'; + SQL + end + + def down + execute(<<~SQL) + DROP VIEW IF EXISTS postgres_foreign_keys; + CREATE OR REPLACE VIEW postgres_foreign_keys AS + SELECT + pg_constraint.oid AS oid, + pg_constraint.conname AS name, + constrained_namespace.nspname::text || '.'::text || constrained_table.relname::text AS constrained_table_identifier, + referenced_namespace.nspname::text || '.'::text || referenced_table.relname::text AS referenced_table_identifier + FROM pg_constraint + INNER JOIN pg_class constrained_table ON constrained_table.oid = pg_constraint.conrelid + INNER JOIN pg_class referenced_table ON referenced_table.oid = pg_constraint.confrelid + INNER JOIN pg_namespace constrained_namespace ON constrained_table.relnamespace = constrained_namespace.oid + INNER JOIN pg_namespace referenced_namespace ON referenced_table.relnamespace = referenced_namespace.oid + WHERE contype = 'f'; + SQL + end +end diff --git a/spec/frontend/ci/ci_variable_list/components/ci_variable_drawer_spec.js b/spec/frontend/ci/ci_variable_list/components/ci_variable_drawer_spec.js index 645aaf798d4..809d638a8ea 100644 --- a/spec/frontend/ci/ci_variable_list/components/ci_variable_drawer_spec.js +++ b/spec/frontend/ci/ci_variable_list/components/ci_variable_drawer_spec.js @@ -82,6 +82,7 @@ describe('CI Variable Drawer', () => { const findConfirmBtn = () => wrapper.findByTestId('ci-variable-confirm-button'); const findConfirmDeleteModal = () => wrapper.findComponent(GlModal); const findDeleteBtn = () => wrapper.findByTestId('ci-variable-delete-button'); + const findDescriptionField = () => wrapper.findByTestId('ci-variable-description'); const findDisabledEnvironmentScopeDropdown = () => wrapper.findComponent(GlFormInput); const findDrawer = () => wrapper.findComponent(GlDrawer); const findEnvironmentScopeDropdown = () => wrapper.findComponent(CiEnvironmentsDropdown); @@ -483,6 +484,7 @@ describe('CI Variable Drawer', () => { }); it('dispatches the add-variable event', async () => { + await findDescriptionField().vm.$emit('input', 'NEW_DESCRIPTION'); await findKeyField().vm.$emit('input', 'NEW_VARIABLE'); await findProtectedCheckbox().vm.$emit('input', false); await findExpandedCheckbox().vm.$emit('input', true); @@ -495,6 +497,7 @@ describe('CI Variable Drawer', () => { [ { environmentScope: '*', + description: 'NEW_DESCRIPTION', key: 'NEW_VARIABLE', masked: true, protected: false, @@ -522,6 +525,7 @@ describe('CI Variable Drawer', () => { it('dispatches the edit-variable event', async () => { await findValueField().vm.$emit('input', 'EDITED_VALUE'); + await findDescriptionField().vm.$emit('input', 'EDITED_DESCRIPTION'); findConfirmBtn().vm.$emit('click'); @@ -529,6 +533,7 @@ describe('CI Variable Drawer', () => { [ { ...mockProjectVariableFileType, + description: 'EDITED_DESCRIPTION', value: 'EDITED_VALUE', }, ], diff --git a/spec/frontend/ci/ci_variable_list/components/ci_variable_table_spec.js b/spec/frontend/ci/ci_variable_list/components/ci_variable_table_spec.js index de24c389511..3081fe686e3 100644 --- a/spec/frontend/ci/ci_variable_list/components/ci_variable_table_spec.js +++ b/spec/frontend/ci/ci_variable_list/components/ci_variable_table_spec.js @@ -47,6 +47,8 @@ describe('Ci variable table', () => { const findAttributeByIndex = (rowIndex, attributeIndex) => findAttributesRow(rowIndex).findAllComponents(GlBadge).at(attributeIndex).text(); const findTableColumnText = (index) => wrapper.findAll('th').at(index).text(); + const findVariableRow = (rowIndex) => + wrapper.findAllByTestId('ci-variable-table-row-variable').at(rowIndex); const findGroupCiCdSettingsLink = (rowIndex) => wrapper.findAllByTestId('ci-variable-table-row-cicd-path').at(rowIndex).attributes('href'); const findKeysetPagination = () => wrapper.findComponent(GlKeysetPagination); @@ -132,6 +134,10 @@ describe('Ci variable table', () => { }, ); + it('renders description if variable has one', () => { + expect(findVariableRow(0).text()).toContain('This variable has a description.'); + }); + it('renders action buttons', () => { expect(findRevealButton().exists()).toBe(true); expect(findAddButton().exists()).toBe(true); @@ -186,6 +192,10 @@ describe('Ci variable table', () => { }, ); + it('renders description if variable has one', () => { + expect(findVariableRow(1).text()).toContain('This inherited variable has a description.'); + }); + it('displays link to the group settings', () => { expect(findGroupCiCdSettingsLink(0)).toBe(mockInheritedVariables[0].groupCiCdSettingsPath); expect(findGroupCiCdSettingsLink(1)).toBe(mockInheritedVariables[1].groupCiCdSettingsPath); diff --git a/spec/frontend/ci/ci_variable_list/mocks.js b/spec/frontend/ci/ci_variable_list/mocks.js index 35bca408f17..34afa10b607 100644 --- a/spec/frontend/ci/ci_variable_list/mocks.js +++ b/spec/frontend/ci/ci_variable_list/mocks.js @@ -32,6 +32,7 @@ export const mockVariables = (kind) => { __typename: `Ci${kind}Variable`, id: 1, key: 'my-var', + description: 'This variable has a description.', masked: false, protected: true, raw: false, @@ -42,6 +43,7 @@ export const mockVariables = (kind) => { __typename: `Ci${kind}Variable`, id: 2, key: 'secret', + description: null, masked: true, protected: false, raw: true, @@ -56,6 +58,7 @@ export const mockInheritedVariables = [ id: 'gid://gitlab/Ci::GroupVariable/120', key: 'INHERITED_VAR_1', variableType: 'ENV_VAR', + description: null, environmentScope: '*', masked: true, protected: true, @@ -68,6 +71,7 @@ export const mockInheritedVariables = [ id: 'gid://gitlab/Ci::GroupVariable/121', key: 'INHERITED_VAR_2', variableType: 'ENV_VAR', + description: 'This inherited variable has a description.', environmentScope: 'staging', masked: false, protected: false, @@ -80,6 +84,7 @@ export const mockInheritedVariables = [ id: 'gid://gitlab/Ci::GroupVariable/122', key: 'INHERITED_VAR_3', variableType: 'FILE', + description: null, environmentScope: 'production', masked: false, protected: true, diff --git a/spec/frontend/ci/inherited_ci_variables/mocks.js b/spec/frontend/ci/inherited_ci_variables/mocks.js index 841ba0a0043..be00e64127d 100644 --- a/spec/frontend/ci/inherited_ci_variables/mocks.js +++ b/spec/frontend/ci/inherited_ci_variables/mocks.js @@ -16,6 +16,7 @@ export const mockInheritedCiVariables = ({ withNextPage = false } = {}) => ({ { __typename: `InheritedCiVariable`, id: 'gid://gitlab/Ci::GroupVariable/1', + description: 'This will be inherited by projects', environmentScope: '*', groupName: 'group_abc', groupCiCdSettingsPath: '/groups/group_abc/-/settings/ci_cd', @@ -28,6 +29,7 @@ export const mockInheritedCiVariables = ({ withNextPage = false } = {}) => ({ { __typename: `InheritedCiVariable`, id: 'gid://gitlab/Ci::GroupVariable/2', + description: null, environmentScope: '*', groupName: 'subgroup_xyz', groupCiCdSettingsPath: '/groups/group_abc/subgroup_xyz/-/settings/ci_cd', diff --git a/spec/frontend/vue_shared/directives/safe_html_spec.js b/spec/frontend/vue_shared/directives/safe_html_spec.js index ba1de8e4596..21df11fcc98 100644 --- a/spec/frontend/vue_shared/directives/safe_html_spec.js +++ b/spec/frontend/vue_shared/directives/safe_html_spec.js @@ -113,4 +113,21 @@ describe('safe html directive', () => { expect(wrapper.html()).toEqual('<div>click here</div>'); }); }); + + describe('unbind', () => { + it('should clear the text content during unbind', () => { + createComponent(); + wrapper.destroy(); + + expect(wrapper.element.textContent).toEqual(''); + }); + + it('should clear the text content with custom HTML during unbind', () => { + const customHtml = '<div>custom html</div>'; + createComponent({ html: customHtml }); + wrapper.destroy(); + + expect(wrapper.element.textContent).toEqual(''); + }); + }); }); diff --git a/spec/frontend_integration/ide/ide_integration_spec.js b/spec/frontend_integration/ide/ide_integration_spec.js index 5711b004f70..cb41d4a7e07 100644 --- a/spec/frontend_integration/ide/ide_integration_spec.js +++ b/spec/frontend_integration/ide/ide_integration_spec.js @@ -111,6 +111,11 @@ describe('WebIDE', () => { }); it('persists viewer', async () => { + const checkText = async (text) => { + const el = await waitForText(text); + expect(el).toHaveText(text); + }; + const markdownPreview = 'test preview_markdown result'; mockServer.post('/:namespace/:project/preview_markdown', () => ({ body: markdownPreview, @@ -119,8 +124,7 @@ describe('WebIDE', () => { await ideHelper.openFile('README.md'); ideHelper.clickPreviewMarkdown(); - const el = await waitForText(markdownPreview); - expect(el).toHaveText(markdownPreview); + await checkText(markdownPreview); // Need to wait for monaco editor to load so it doesn't through errors on dispose await ideHelper.openFile('.gitignore'); @@ -128,7 +132,7 @@ describe('WebIDE', () => { await ideHelper.openFile('README.md'); await ideHelper.waitForEditorModelChange(editor); - expect(el).toHaveText(markdownPreview); + await checkText(markdownPreview); }); describe('when editor position changes', () => { diff --git a/spec/lib/gitlab/background_migration/backfill_admin_mode_scope_for_personal_access_tokens_spec.rb b/spec/lib/gitlab/background_migration/backfill_admin_mode_scope_for_personal_access_tokens_spec.rb index 92fec48454c..5aa02e5f8d7 100644 --- a/spec/lib/gitlab/background_migration/backfill_admin_mode_scope_for_personal_access_tokens_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_admin_mode_scope_for_personal_access_tokens_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::BackfillAdminModeScopeForPersonalAccessTokens, - :migration, schema: 20221228103133, feature_category: :system_access do + :migration, schema: 20230216060333, feature_category: :system_access do let(:users) { table(:users) } let(:personal_access_tokens) { table(:personal_access_tokens) } diff --git a/spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb b/spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb index 9026c327e3c..3801ccf0f0d 100644 --- a/spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::BackfillEnvironmentTiers, - :migration, schema: 20221205151917, feature_category: :continuous_delivery do + :migration, schema: 20230216060333, feature_category: :continuous_delivery do let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } let!(:project) { table(:projects).create!(namespace_id: namespace.id, project_namespace_id: namespace.id) } diff --git a/spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb b/spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb deleted file mode 100644 index edf972189b2..00000000000 --- a/spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb +++ /dev/null @@ -1,109 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::BackgroundMigration::BackfillImportedIssueSearchData, - :migration, - schema: 20221111123146 do - let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } - let!(:issue_search_data_table) { table(:issue_search_data) } - - let!(:user) { table(:users).create!(email: 'author@example.com', username: 'author', projects_limit: 10) } - let!(:project) do - table(:projects) - .create!( - namespace_id: namespace.id, - creator_id: user.id, - name: 'projecty', - path: 'path', - project_namespace_id: namespace.id) - end - - let!(:issue) do - table(:issues).create!( - project_id: project.id, - namespace_id: project.project_namespace_id, - title: 'Patterson', - description: FFaker::HipsterIpsum.paragraph - ) - end - - let(:migration) do - described_class.new( - start_id: issue.id, - end_id: issue.id + 30, - batch_table: :issues, - batch_column: :id, - sub_batch_size: 2, - pause_ms: 0, - connection: ApplicationRecord.connection - ) - end - - let(:perform_migration) { migration.perform } - - context 'when issue has search data record' do - let!(:issue_search_data) { issue_search_data_table.create!(project_id: project.id, issue_id: issue.id) } - - it 'does not create or update any search data records' do - expect { perform_migration } - .to not_change { issue_search_data_table.count } - .and not_change { issue_search_data } - - expect(issue_search_data_table.count).to eq(1) - end - end - - context 'when issue has no search data record' do - let(:title_node) { "'#{issue.title.downcase}':1A" } - - it 'creates search data records' do - expect { perform_migration } - .to change { issue_search_data_table.count }.from(0).to(1) - - expect(issue_search_data_table.find_by(project_id: project.id).issue_id) - .to eq(issue.id) - - expect(issue_search_data_table.find_by(project_id: project.id).search_vector) - .to include(title_node) - end - end - - context 'error handling' do - let!(:issue2) do - table(:issues).create!( - project_id: project.id, - namespace_id: project.project_namespace_id, - title: 'Chatterton', - description: FFaker::HipsterIpsum.paragraph - ) - end - - before do - issue.update!(description: Array.new(30_000) { SecureRandom.hex }.join(' ')) - end - - let(:title_node2) { "'#{issue2.title.downcase}':1A" } - - it 'skips insertion for that issue but continues with migration' do - expect_next_instance_of(Gitlab::BackgroundMigration::Logger) do |logger| - expect(logger) - .to receive(:error) - .with(a_hash_including(message: /string is too long for tsvector/, model_id: issue.id)) - end - - expect { perform_migration }.to change { issue_search_data_table.count }.from(0).to(1) - expect(issue_search_data_table.find_by(issue_id: issue.id)).to eq(nil) - expect(issue_search_data_table.find_by(issue_id: issue2.id).search_vector) - .to include(title_node2) - end - - it 're-raises exceptions' do - allow(migration) - .to receive(:update_search_data_individually) - .and_raise(ActiveRecord::StatementTimeout) - - expect { perform_migration }.to raise_error(ActiveRecord::StatementTimeout) - end - end -end diff --git a/spec/lib/gitlab/background_migration/backfill_integrations_enable_ssl_verification_spec.rb b/spec/lib/gitlab/background_migration/backfill_integrations_enable_ssl_verification_spec.rb index 925fb0c9a20..9813e92edc0 100644 --- a/spec/lib/gitlab/background_migration/backfill_integrations_enable_ssl_verification_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_integrations_enable_ssl_verification_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::BackgroundMigration::BackfillIntegrationsEnableSslVerification, schema: 20221111123146 do +RSpec.describe Gitlab::BackgroundMigration::BackfillIntegrationsEnableSslVerification, schema: 20230216060333 do let(:migration) { described_class.new } let(:integrations) { described_class::Integration } diff --git a/spec/lib/gitlab/background_migration/backfill_namespace_id_of_vulnerability_reads_spec.rb b/spec/lib/gitlab/background_migration/backfill_namespace_id_of_vulnerability_reads_spec.rb index c2c5c3e9de0..f92ec7e028b 100644 --- a/spec/lib/gitlab/background_migration/backfill_namespace_id_of_vulnerability_reads_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_namespace_id_of_vulnerability_reads_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceIdOfVulnerabilityReads, schema: 20221111123146 do +RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceIdOfVulnerabilityReads, schema: 20230216060333 do let(:namespaces) { table(:namespaces) } let(:projects) { table(:projects) } let(:users) { table(:users) } diff --git a/spec/lib/gitlab/background_migration/backfill_project_namespace_on_issues_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_namespace_on_issues_spec.rb deleted file mode 100644 index 5fa92759cf9..00000000000 --- a/spec/lib/gitlab/background_migration/backfill_project_namespace_on_issues_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::BackgroundMigration::BackfillProjectNamespaceOnIssues, - :migration, schema: 20221118103352, feature_category: :team_planning do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:issues) { table(:issues) } - let(:issue_base_type_enum_value) { 0 } - let(:issue_type) { table(:work_item_types).find_by!(namespace_id: nil, base_type: issue_base_type_enum_value) } - - let(:namespace1) { namespaces.create!(name: 'batchtest1', type: 'Group', path: 'space1') } - let(:namespace2) { namespaces.create!(name: 'batchtest2', type: 'Group', parent_id: namespace1.id, path: 'space2') } - - let(:proj_namespace1) { namespaces.create!(name: 'proj1', path: 'proj1', type: 'Project', parent_id: namespace1.id) } - let(:proj_namespace2) { namespaces.create!(name: 'proj2', path: 'proj2', type: 'Project', parent_id: namespace2.id) } - - # rubocop:disable Layout/LineLength - let(:proj1) { projects.create!(name: 'proj1', path: 'proj1', namespace_id: namespace1.id, project_namespace_id: proj_namespace1.id) } - let(:proj2) { projects.create!(name: 'proj2', path: 'proj2', namespace_id: namespace2.id, project_namespace_id: proj_namespace2.id) } - - let!(:proj1_issue_with_namespace) { issues.create!(title: 'issue1', project_id: proj1.id, namespace_id: proj_namespace1.id, work_item_type_id: issue_type.id) } - let!(:proj1_issue_without_namespace1) { issues.create!(title: 'issue2', project_id: proj1.id, work_item_type_id: issue_type.id) } - let!(:proj1_issue_without_namespace2) { issues.create!(title: 'issue3', project_id: proj1.id, work_item_type_id: issue_type.id) } - let!(:proj2_issue_with_namespace) { issues.create!(title: 'issue4', project_id: proj2.id, namespace_id: proj_namespace2.id, work_item_type_id: issue_type.id) } - let!(:proj2_issue_without_namespace1) { issues.create!(title: 'issue5', project_id: proj2.id, work_item_type_id: issue_type.id) } - let!(:proj2_issue_without_namespace2) { issues.create!(title: 'issue6', project_id: proj2.id, work_item_type_id: issue_type.id) } - # rubocop:enable Layout/LineLength - - let(:migration) do - described_class.new( - start_id: proj1_issue_with_namespace.id, - end_id: proj2_issue_without_namespace2.id, - batch_table: :issues, - batch_column: :id, - sub_batch_size: 2, - pause_ms: 2, - connection: ApplicationRecord.connection - ) - end - - subject(:perform_migration) { migration.perform } - - it 'backfills namespace_id for the selected records', :aggregate_failures do - perform_migration - - expected_namespaces = [proj_namespace1.id, proj_namespace2.id] - - expect(issues.where.not(namespace_id: nil).count).to eq(6) - expect(issues.where.not(namespace_id: nil).pluck(:namespace_id).uniq).to match_array(expected_namespaces) - end - - it 'tracks timings of queries' do - expect(migration.batch_metrics.timings).to be_empty - - expect { perform_migration }.to change { migration.batch_metrics.timings } - end - - context 'when database timeouts' do - using RSpec::Parameterized::TableSyntax - - where(error_class: [ActiveRecord::StatementTimeout, ActiveRecord::QueryCanceled]) - - with_them do - it 'retries on timeout error' do - expect(migration).to receive(:update_batch).exactly(3).times.and_raise(error_class) - expect(migration).to receive(:sleep).with(5).twice - - expect do - perform_migration - end.to raise_error(error_class) - end - end - end -end diff --git a/spec/lib/gitlab/background_migration/backfill_releases_author_id_spec.rb b/spec/lib/gitlab/background_migration/backfill_releases_author_id_spec.rb index 898f241a930..b86cfa005cd 100644 --- a/spec/lib/gitlab/background_migration/backfill_releases_author_id_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_releases_author_id_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::BackfillReleasesAuthorId, - :migration, schema: 20221215151822, feature_category: :release_orchestration do + :migration, schema: 20230216060333, feature_category: :release_orchestration do let(:releases_table) { table(:releases) } let(:user_table) { table(:users) } let(:date_time) { DateTime.now } diff --git a/spec/lib/gitlab/background_migration/backfill_topics_title_spec.rb b/spec/lib/gitlab/background_migration/backfill_topics_title_spec.rb index 3eb0000877d..d1852d726e0 100644 --- a/spec/lib/gitlab/background_migration/backfill_topics_title_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_topics_title_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::BackgroundMigration::BackfillTopicsTitle, schema: 20221111123146 do +RSpec.describe Gitlab::BackgroundMigration::BackfillTopicsTitle, schema: 20230216060333 do it 'correctly backfills the title of the topics' do topics = table(:topics) diff --git a/spec/lib/gitlab/background_migration/backfill_user_details_fields_spec.rb b/spec/lib/gitlab/background_migration/backfill_user_details_fields_spec.rb deleted file mode 100644 index 1d1853b032c..00000000000 --- a/spec/lib/gitlab/background_migration/backfill_user_details_fields_spec.rb +++ /dev/null @@ -1,222 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::BackgroundMigration::BackfillUserDetailsFields, :migration, schema: 20221111123146 do - let(:users) { table(:users) } - let(:user_details) { table(:user_details) } - - let!(:user_all_fields_backfill) do - users.create!( - name: generate(:name), - email: generate(:email), - projects_limit: 1, - linkedin: 'linked-in', - twitter: '@twitter', - skype: 'skype', - website_url: 'https://example.com', - location: 'Antarctica', - organization: 'Gitlab' - ) - end - - let!(:user_long_details_fields) do - length = UserDetail::DEFAULT_FIELD_LENGTH + 1 - users.create!( - name: generate(:name), - email: generate(:email), - projects_limit: 1, - linkedin: 'l' * length, - twitter: 't' * length, - skype: 's' * length, - website_url: "https://#{'a' * (length - 12)}.com", - location: 'l' * length, - organization: 'o' * length - ) - end - - let!(:user_nil_details_fields) do - users.create!( - name: generate(:name), - email: generate(:email), - projects_limit: 1 - ) - end - - let!(:user_empty_details_fields) do - users.create!( - name: generate(:name), - email: generate(:email), - projects_limit: 1, - linkedin: '', - twitter: '', - skype: '', - website_url: '', - location: '', - organization: '' - ) - end - - let!(:user_with_bio) do - users.create!( - name: generate(:name), - email: generate(:email), - projects_limit: 1, - linkedin: 'linked-in', - twitter: '@twitter', - skype: 'skype', - website_url: 'https://example.com', - location: 'Antarctica', - organization: 'Gitlab' - ) - end - - let!(:bio_user_details) do - user_details - .find_or_create_by!(user_id: user_with_bio.id) - .update!(bio: 'bio') - end - - let!(:user_with_details) do - users.create!( - name: generate(:name), - email: generate(:email), - projects_limit: 1, - linkedin: 'linked-in', - twitter: '@twitter', - skype: 'skype', - website_url: 'https://example.com', - location: 'Antarctica', - organization: 'Gitlab' - ) - end - - let!(:existing_user_details) do - user_details - .find_or_create_by!(user_id: user_with_details.id) - .update!( - linkedin: 'linked-in', - twitter: '@twitter', - skype: 'skype', - website_url: 'https://example.com', - location: 'Antarctica', - organization: 'Gitlab' - ) - end - - let!(:user_different_details) do - users.create!( - name: generate(:name), - email: generate(:email), - projects_limit: 1, - linkedin: 'linked-in', - twitter: '@twitter', - skype: 'skype', - website_url: 'https://example.com', - location: 'Antarctica', - organization: 'Gitlab' - ) - end - - let!(:differing_details) do - user_details - .find_or_create_by!(user_id: user_different_details.id) - .update!( - linkedin: 'details-in', - twitter: '@details', - skype: 'details_skype', - website_url: 'https://details.site', - location: 'Details Location', - organization: 'Details Organization' - ) - end - - let(:user_ids) do - [ - user_all_fields_backfill, - user_long_details_fields, - user_nil_details_fields, - user_empty_details_fields, - user_with_bio, - user_with_details, - user_different_details - ].map(&:id) - end - - subject do - described_class.new( - start_id: user_ids.min, - end_id: user_ids.max, - batch_table: 'users', - batch_column: 'id', - sub_batch_size: 1_000, - pause_ms: 0, - connection: ApplicationRecord.connection - ) - end - - it 'processes all relevant records' do - expect { subject.perform }.to change { user_details.all.size }.to(5) - end - - it 'backfills new user_details fields' do - subject.perform - - user_detail = user_details.find_by!(user_id: user_all_fields_backfill.id) - expect(user_detail.linkedin).to eq('linked-in') - expect(user_detail.twitter).to eq('@twitter') - expect(user_detail.skype).to eq('skype') - expect(user_detail.website_url).to eq('https://example.com') - expect(user_detail.location).to eq('Antarctica') - expect(user_detail.organization).to eq('Gitlab') - end - - it 'does not migrate nil fields' do - subject.perform - - expect(user_details.find_by(user_id: user_nil_details_fields)).to be_nil - end - - it 'does not migrate empty fields' do - subject.perform - - expect(user_details.find_by(user_id: user_empty_details_fields)).to be_nil - end - - it 'backfills new fields without overwriting existing `bio` field' do - subject.perform - - user_detail = user_details.find_by!(user_id: user_with_bio.id) - expect(user_detail.bio).to eq('bio') - expect(user_detail.linkedin).to eq('linked-in') - expect(user_detail.twitter).to eq('@twitter') - expect(user_detail.skype).to eq('skype') - expect(user_detail.website_url).to eq('https://example.com') - expect(user_detail.location).to eq('Antarctica') - expect(user_detail.organization).to eq('Gitlab') - end - - context 'when user details are unchanged' do - it 'does not change existing details' do - expect { subject.perform }.not_to change { - user_details.find_by!(user_id: user_with_details.id).attributes - } - end - end - - context 'when user details are changed' do - it 'updates existing user details' do - expect { subject.perform }.to change { - user_details.find_by!(user_id: user_different_details.id).attributes - } - - user_detail = user_details.find_by!(user_id: user_different_details.id) - expect(user_detail.linkedin).to eq('linked-in') - expect(user_detail.twitter).to eq('@twitter') - expect(user_detail.skype).to eq('skype') - expect(user_detail.website_url).to eq('https://example.com') - expect(user_detail.location).to eq('Antarctica') - expect(user_detail.organization).to eq('Gitlab') - end - end -end diff --git a/spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb b/spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb index 63135971cd3..f43440b9226 100644 --- a/spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::BackgroundMigration::BackfillVulnerabilityReadsClusterAgent, :migration, schema: 20221111123146 do # rubocop:disable Layout/LineLength +RSpec.describe Gitlab::BackgroundMigration::BackfillVulnerabilityReadsClusterAgent, :migration, schema: 20230216060333 do # rubocop:disable Layout/LineLength let(:migration) do described_class.new( start_id: 1, end_id: 10, diff --git a/spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb b/spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb deleted file mode 100644 index 4c1af279804..00000000000 --- a/spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb +++ /dev/null @@ -1,102 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::BackgroundMigration::BackfillWorkItemTypeIdForIssues, - :migration, - schema: 20221111123146, - feature_category: :team_planning do - let(:batch_column) { 'id' } - let(:sub_batch_size) { 2 } - let(:pause_ms) { 0 } - - # let_it_be can't be used in migration specs because all tables but `work_item_types` are deleted after each spec - let(:issue_type_enum) { { issue: 0, incident: 1, test_case: 2, requirement: 3, task: 4 } } - let(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') } - let(:project) { table(:projects).create!(namespace_id: namespace.id, project_namespace_id: namespace.id) } - let(:issues_table) { table(:issues) } - let(:issue_type) { table(:work_item_types).find_by!(namespace_id: nil, base_type: issue_type_enum[:issue]) } - let(:task_type) { table(:work_item_types).find_by!(namespace_id: nil, base_type: issue_type_enum[:task]) } - - let(:issue1) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:issue]) } - let(:issue2) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:issue]) } - let(:issue3) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:issue]) } - let(:incident1) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:incident]) } - # test_case and requirement are EE only, but enum values exist on the FOSS model - let(:test_case1) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:test_case]) } - let(:requirement1) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:requirement]) } - - let(:start_id) { issue1.id } - let(:end_id) { requirement1.id } - - let!(:all_issues) { [issue1, issue2, issue3, incident1, test_case1, requirement1] } - - let(:migration) do - described_class.new( - start_id: start_id, - end_id: end_id, - batch_table: :issues, - batch_column: :id, - sub_batch_size: sub_batch_size, - pause_ms: pause_ms, - job_arguments: [issue_type_enum[:issue], issue_type.id], - connection: ApplicationRecord.connection - ) - end - - subject(:migrate) { migration.perform } - - it 'sets work_item_type_id only for the given type' do - expect(all_issues).to all(have_attributes(work_item_type_id: nil)) - - expect { migrate }.to make_queries_matching(/UPDATE "issues" SET "work_item_type_id"/, 2) - all_issues.each(&:reload) - - expect([issue1, issue2, issue3]).to all(have_attributes(work_item_type_id: issue_type.id)) - expect(all_issues - [issue1, issue2, issue3]).to all(have_attributes(work_item_type_id: nil)) - end - - context 'when a record already had a work_item_type_id assigned' do - let!(:issue4) do - issues_table.create!( - project_id: project.id, - issue_type: issue_type_enum[:issue], - work_item_type_id: task_type.id - ) - end - - let(:end_id) { issue4.id } - - it 'ovewrites the work_item_type_id' do - # creating with the wrong issue_type/work_item_type_id on purpose so we can test - # that the migration is capable of fixing such inconsistencies - expect do - migrate - issue4.reload - end.to change { issue4.work_item_type_id }.from(task_type.id).to(issue_type.id) - end - end - - it 'tracks timings of queries' do - expect(migration.batch_metrics.timings).to be_empty - - expect { migrate }.to change { migration.batch_metrics.timings } - end - - context 'when database timeouts' do - using RSpec::Parameterized::TableSyntax - - where(error_class: [ActiveRecord::StatementTimeout, ActiveRecord::QueryCanceled]) - - with_them do - it 'retries on timeout error' do - expect(migration).to receive(:update_batch).exactly(3).times.and_raise(error_class) - expect(migration).to receive(:sleep).with(30).twice - - expect do - migrate - end.to raise_error(error_class) - end - end - end -end diff --git a/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb b/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb index 95c5a64bc7b..98c814902b4 100644 --- a/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb +++ b/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' # rubocop: disable RSpec/MultipleMemoizedHelpers -RSpec.describe Gitlab::BackgroundMigration::DestroyInvalidMembers, :migration, schema: 20221111123146 do +RSpec.describe Gitlab::BackgroundMigration::DestroyInvalidMembers, :migration, schema: 20230216060333 do let!(:migration_attrs) do { start_id: 1, @@ -124,7 +124,7 @@ RSpec.describe Gitlab::BackgroundMigration::DestroyInvalidMembers, :migration, s expect(Gitlab::AppLogger).to receive(:info).with({ message: 'Removing invalid member records', deleted_count: 4, - deleted_member_data: member_data }) + deleted_member_data: match_array(member_data) }) perform_migration end diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb deleted file mode 100644 index 8afbd7403d3..00000000000 --- a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForNoIssuesNoRepoProjects, - :migration, - schema: 20221111123146 do - let(:namespaces_table) { table(:namespaces) } - let(:projects_table) { table(:projects) } - let(:project_settings_table) { table(:project_settings) } - let(:project_statistics_table) { table(:project_statistics) } - let(:issues_table) { table(:issues) } - - subject(:perform_migration) do - described_class.new( - start_id: projects_table.minimum(:id), - end_id: projects_table.maximum(:id), - batch_table: :projects, - batch_column: :id, - sub_batch_size: 2, - pause_ms: 0, - connection: ActiveRecord::Base.connection - ).perform - end - - it 'sets `legacy_open_source_license_available` to false only for public projects with no issues and no repo', - :aggregate_failures do - project_with_no_issues_no_repo = create_legacy_license_public_project('project-with-no-issues-no-repo') - project_with_repo = create_legacy_license_public_project('project-with-repo', repo_size: 1) - project_with_issues = create_legacy_license_public_project('project-with-issues', with_issue: true) - project_with_issues_and_repo = - create_legacy_license_public_project('project-with-issues-and-repo', repo_size: 1, with_issue: true) - - queries = ActiveRecord::QueryRecorder.new { perform_migration } - - expect(queries.count).to eq(7) - expect(migrated_attribute(project_with_no_issues_no_repo)).to be_falsey - expect(migrated_attribute(project_with_repo)).to be_truthy - expect(migrated_attribute(project_with_issues)).to be_truthy - expect(migrated_attribute(project_with_issues_and_repo)).to be_truthy - end - - def create_legacy_license_public_project(path, repo_size: 0, with_issue: false) - namespace = namespaces_table.create!(name: "namespace-#{path}", path: "namespace-#{path}") - project_namespace = namespaces_table.create!( - name: "-project-namespace-#{path}", path: "project-namespace-#{path}", type: 'Project' - ) - project = projects_table.create!( - name: path, path: path, namespace_id: namespace.id, - project_namespace_id: project_namespace.id, visibility_level: 20 - ) - - project_statistics_table.create!(project_id: project.id, namespace_id: namespace.id, repository_size: repo_size) - issues_table.create!(project_id: project.id, namespace_id: project.project_namespace_id) if with_issue - project_settings_table.create!(project_id: project.id, legacy_open_source_license_available: true) - - project - end - - def migrated_attribute(project) - project_settings_table.find(project.id).legacy_open_source_license_available - end -end diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb index 185e2da6f1d..9ad54c35087 100644 --- a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb +++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForOneMemberNoRepoProjects, :migration, - schema: 20221111123146 do + schema: 20230216060333 do let(:namespaces_table) { table(:namespaces) } let(:projects_table) { table(:projects) } let(:project_settings_table) { table(:project_settings) } diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb index fedee9c5068..0c9c1dbde9a 100644 --- a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb +++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForProjectsLessThanFiveMb, :migration, - schema: 20221018095434, + schema: 20230216060333, feature_category: :groups_and_projects do let(:namespaces_table) { table(:namespaces) } let(:projects_table) { table(:projects) } diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb index f1ec09840ab..16144643296 100644 --- a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb +++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForProjectsLessThanOneMb, :migration, - schema: 20221111123146 do + schema: 20230216060333 do let(:namespaces_table) { table(:namespaces) } let(:projects_table) { table(:projects) } let(:project_settings_table) { table(:project_settings) } diff --git a/spec/lib/gitlab/background_migration/expire_o_auth_tokens_spec.rb b/spec/lib/gitlab/background_migration/expire_o_auth_tokens_spec.rb deleted file mode 100644 index 4997ae3763e..00000000000 --- a/spec/lib/gitlab/background_migration/expire_o_auth_tokens_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::BackgroundMigration::ExpireOAuthTokens, :migration, schema: 20221111123146 do - let(:migration) { described_class.new } - let(:oauth_access_tokens_table) { table(:oauth_access_tokens) } - - let(:table_name) { 'oauth_access_tokens' } - - subject(:perform_migration) do - described_class.new( - start_id: 1, - end_id: 30, - batch_table: :oauth_access_tokens, - batch_column: :id, - sub_batch_size: 2, - pause_ms: 0, - connection: ActiveRecord::Base.connection - ).perform - end - - before do - oauth_access_tokens_table.create!(id: 1, token: 's3cr3t-1', expires_in: nil) - oauth_access_tokens_table.create!(id: 2, token: 's3cr3t-2', expires_in: 42) - oauth_access_tokens_table.create!(id: 3, token: 's3cr3t-3', expires_in: nil) - end - - it 'adds expiry to oauth tokens', :aggregate_failures do - expect(ActiveRecord::QueryRecorder.new { perform_migration }.count).to eq(3) - - expect(oauth_access_tokens_table.find(1).expires_in).to eq(7_200) - expect(oauth_access_tokens_table.find(2).expires_in).to eq(42) - expect(oauth_access_tokens_table.find(3).expires_in).to eq(7_200) - end -end diff --git a/spec/lib/gitlab/background_migration/nullify_creator_id_column_of_orphaned_projects_spec.rb b/spec/lib/gitlab/background_migration/nullify_creator_id_column_of_orphaned_projects_spec.rb index facc3c435da..82a3f548e02 100644 --- a/spec/lib/gitlab/background_migration/nullify_creator_id_column_of_orphaned_projects_spec.rb +++ b/spec/lib/gitlab/background_migration/nullify_creator_id_column_of_orphaned_projects_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::NullifyCreatorIdColumnOfOrphanedProjects, - feature_category: :groups_and_projects, schema: 20230130073109 do + feature_category: :groups_and_projects, schema: 20230216060333 do let(:users) { table(:users) } let(:projects) { table(:projects) } let(:namespaces) { table(:namespaces) } diff --git a/spec/lib/gitlab/background_migration/populate_projects_star_count_spec.rb b/spec/lib/gitlab/background_migration/populate_projects_star_count_spec.rb index 35f93c9982b..c41eb98bc5d 100644 --- a/spec/lib/gitlab/background_migration/populate_projects_star_count_spec.rb +++ b/spec/lib/gitlab/background_migration/populate_projects_star_count_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::BackgroundMigration::PopulateProjectsStarCount, schema: 20221111123146 do +RSpec.describe Gitlab::BackgroundMigration::PopulateProjectsStarCount, schema: 20230216060333 do let(:namespaces) { table(:namespaces) } let(:projects) { table(:projects) } let(:users) { table(:users) } diff --git a/spec/lib/gitlab/background_migration/remove_project_group_link_with_missing_groups_spec.rb b/spec/lib/gitlab/background_migration/remove_project_group_link_with_missing_groups_spec.rb deleted file mode 100644 index 126e928fa77..00000000000 --- a/spec/lib/gitlab/background_migration/remove_project_group_link_with_missing_groups_spec.rb +++ /dev/null @@ -1,124 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::BackgroundMigration::RemoveProjectGroupLinkWithMissingGroups, :migration, - feature_category: :groups_and_projects, schema: 20230206172702 do - let(:projects) { table(:projects) } - let(:namespaces) { table(:namespaces) } - let(:project_group_links) { table(:project_group_links) } - - let!(:group) do - namespaces.create!( - name: 'Group0', type: 'Group', path: 'space0' - ) - end - - let!(:group_1) do - namespaces.create!( - name: 'Group1', type: 'Group', path: 'space1' - ) - end - - let!(:group_2) do - namespaces.create!( - name: 'Group2', type: 'Group', path: 'space2' - ) - end - - let!(:group_3) do - namespaces.create!( - name: 'Group3', type: 'Group', path: 'space3' - ) - end - - let!(:project_namespace_1) do - namespaces.create!( - name: 'project_1', path: 'project_1', type: 'Project' - ) - end - - let!(:project_namespace_2) do - namespaces.create!( - name: 'project_2', path: 'project_2', type: 'Project' - ) - end - - let!(:project_namespace_3) do - namespaces.create!( - name: 'project_3', path: 'project_3', type: 'Project' - ) - end - - let!(:project_1) do - projects.create!( - name: 'project_1', path: 'project_1', namespace_id: group.id, project_namespace_id: project_namespace_1.id - ) - end - - let!(:project_2) do - projects.create!( - name: 'project_2', path: 'project_2', namespace_id: group.id, project_namespace_id: project_namespace_2.id - ) - end - - let!(:project_3) do - projects.create!( - name: 'project_3', path: 'project_3', namespace_id: group.id, project_namespace_id: project_namespace_3.id - ) - end - - let!(:project_group_link_1) do - project_group_links.create!( - project_id: project_1.id, group_id: group_1.id, group_access: Gitlab::Access::DEVELOPER - ) - end - - let!(:project_group_link_2) do - project_group_links.create!( - project_id: project_2.id, group_id: group_2.id, group_access: Gitlab::Access::DEVELOPER - ) - end - - let!(:project_group_link_3) do - project_group_links.create!( - project_id: project_3.id, group_id: group_3.id, group_access: Gitlab::Access::DEVELOPER - ) - end - - let!(:project_group_link_4) do - project_group_links.create!( - project_id: project_3.id, group_id: group_2.id, group_access: Gitlab::Access::DEVELOPER - ) - end - - subject do - described_class.new( - start_id: project_group_link_1.id, - end_id: project_group_link_4.id, - batch_table: :project_group_links, - batch_column: :id, - sub_batch_size: 1, - pause_ms: 0, - connection: ApplicationRecord.connection - ).perform - end - - it 'removes the `project_group_links` records whose associated group does not exist anymore' do - group_2.delete - - # Schema is fixed to `20230206172702` on this spec. - # This expectation is needed to make sure that the orphaned records are indeed deleted via the migration - # and not via the foreign_key relationship introduced after `20230206172702`, in `20230207002330` - expect(project_group_links.count).to eq(4) - - expect { subject } - .to change { project_group_links.count }.from(4).to(2) - .and change { - project_group_links.where(project_id: project_2.id, group_id: group_2.id).present? - }.from(true).to(false) - .and change { - project_group_links.where(project_id: project_3.id, group_id: group_2.id).present? - }.from(true).to(false) - end -end diff --git a/spec/lib/gitlab/background_migration/remove_self_managed_wiki_notes_spec.rb b/spec/lib/gitlab/background_migration/remove_self_managed_wiki_notes_spec.rb index 74fe2c63139..c373323c0e3 100644 --- a/spec/lib/gitlab/background_migration/remove_self_managed_wiki_notes_spec.rb +++ b/spec/lib/gitlab/background_migration/remove_self_managed_wiki_notes_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::BackgroundMigration::RemoveSelfManagedWikiNotes, :migration, schema: 20221111123146 do +RSpec.describe Gitlab::BackgroundMigration::RemoveSelfManagedWikiNotes, :migration, schema: 20230216060333 do let(:notes) { table(:notes) } subject(:perform_migration) do diff --git a/spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb b/spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb index 86c2ab35136..655d8dea739 100644 --- a/spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb +++ b/spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::ResetTooManyTagsSkippedRegistryImports, :migration, :aggregate_failures, - schema: 20221111123146 do + schema: 20230216060333 do let(:namespaces) { table(:namespaces) } let(:projects) { table(:projects) } let(:container_repositories) { table(:container_repositories) } diff --git a/spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb b/spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb index 5f7a699ac0b..91c5b60258f 100644 --- a/spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb +++ b/spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::SetLegacyOpenSourceLicenseAvailableForNonPublicProjects, :migration, - schema: 20221111123146 do + schema: 20230216060333 do let(:namespaces_table) { table(:namespaces) } let(:projects_table) { table(:projects) } let(:project_settings_table) { table(:project_settings) } diff --git a/spec/lib/gitlab/background_migration/truncate_overlong_vulnerability_html_titles_spec.rb b/spec/lib/gitlab/background_migration/truncate_overlong_vulnerability_html_titles_spec.rb index fcd88d523bc..e4be70cb84f 100644 --- a/spec/lib/gitlab/background_migration/truncate_overlong_vulnerability_html_titles_spec.rb +++ b/spec/lib/gitlab/background_migration/truncate_overlong_vulnerability_html_titles_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' # rubocop:disable Layout/LineLength -RSpec.describe Gitlab::BackgroundMigration::TruncateOverlongVulnerabilityHtmlTitles, schema: 20221110100602, feature_category: :vulnerability_management do +RSpec.describe Gitlab::BackgroundMigration::TruncateOverlongVulnerabilityHtmlTitles, schema: 20230216060333, feature_category: :vulnerability_management do # rubocop:enable Layout/LineLength let(:namespaces) { table(:namespaces) } diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index 8bf05f56b3f..13f7178924f 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -1055,11 +1055,16 @@ RSpec.describe Gitlab::Database::MigrationHelpers, feature_category: :database d around do |ex| model.transaction do - require_migration!('add_columns_to_postgres_foreign_keys') - AddColumnsToPostgresForeignKeys.new.down + require_relative '../../../fixtures/migrations/db/migrate/schema_cache_migration_test' + + # Uses the init_schema migration, as it is always present in the codebase (not affected by squashing process) + require_migration!('init_schema') + + InitSchema.prepend(SchemaCacheMigrationTest) + InitSchema.new.down Gitlab::Database::PostgresForeignKey.reset_column_information Gitlab::Database::PostgresForeignKey.columns_hash # Force populate the column hash in the old schema - AddColumnsToPostgresForeignKeys.new.up + InitSchema.new.up # Rolling back reverts the schema cache information, so we need to run the example here before the rollback. ex.run diff --git a/spec/migrations/20221018095434_schedule_disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb b/spec/migrations/20221018095434_schedule_disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb deleted file mode 100644 index ba341ebe5ca..00000000000 --- a/spec/migrations/20221018095434_schedule_disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ScheduleDisableLegacyOpenSourceLicenseForProjectsLessThanFiveMb, feature_category: :groups_and_projects do - let!(:migration) { described_class.new } - let!(:post_migration) { described_class::MIGRATION } - - context 'when on gitlab.com' do - before do - allow(Gitlab).to receive(:com?).and_return(true) - end - - describe '#up' do - it 'schedules background jobs for each batch of project_settings' do - migration.up - - expect(post_migration).to( - have_scheduled_batched_migration( - table_name: :project_settings, - column_name: :project_id, - interval: described_class::INTERVAL, - batch_size: described_class::BATCH_SIZE, - max_batch_size: described_class::MAX_BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE - ) - ) - end - end - - describe '#down' do - it 'deletes all batched migration records' do - migration.down - - expect(post_migration).not_to have_scheduled_batched_migration - end - end - end - - context 'when on self-managed instance' do - before do - allow(Gitlab).to receive(:com?).and_return(false) - end - - describe '#up' do - it 'does not schedule background job' do - expect(migration).not_to receive(:queue_batched_background_migration) - - migration.up - end - end - - describe '#down' do - it 'does not delete background job' do - expect(migration).not_to receive(:delete_batched_background_migration) - - migration.down - end - end - end -end diff --git a/spec/migrations/20221102231130_finalize_backfill_user_details_fields_spec.rb b/spec/migrations/20221102231130_finalize_backfill_user_details_fields_spec.rb deleted file mode 100644 index da2f4364e5c..00000000000 --- a/spec/migrations/20221102231130_finalize_backfill_user_details_fields_spec.rb +++ /dev/null @@ -1,113 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe FinalizeBackfillUserDetailsFields, :migration, feature_category: :user_management do - let(:batched_migrations) { table(:batched_background_migrations) } - let(:batch_failed_status) { 2 } - let(:batch_finalized_status) { 3 } - - let!(:migration) { described_class::BACKFILL_MIGRATION } - - describe '#up' do - shared_examples 'finalizes the migration' do - it 'finalizes the migration' do - expect do - migrate! - - migration_record.reload - failed_job.reload - end.to change { migration_record.status }.from(migration_record.status).to(3).and( - change { failed_job.status }.from(batch_failed_status).to(batch_finalized_status) - ) - end - end - - context 'when migration is missing' do - before do - batched_migrations.where(job_class_name: migration).delete_all - end - - it 'warns migration not found' do - expect(Gitlab::AppLogger) - .to receive(:warn).with(/Could not find batched background migration for the given configuration:/) - - migrate! - end - end - - context 'with migration present' do - let!(:migration_record) do - batched_migrations.create!( - job_class_name: migration, - table_name: :users, - column_name: :id, - job_arguments: [], - interval: 2.minutes, - min_value: 1, - max_value: 2, - batch_size: 1000, - sub_batch_size: 500, - max_batch_size: 5000, - gitlab_schema: :gitlab_main, - status: 3 # finished - ) - end - - context 'when migration finished successfully' do - it 'does not raise exception' do - expect { migrate! }.not_to raise_error - end - end - - context 'when users.linkedin column has already been dropped' do - before do - table(:users).create!(id: 1, email: 'author@example.com', username: 'author', projects_limit: 10) - ActiveRecord::Base.connection.execute("ALTER TABLE users DROP COLUMN linkedin") - migration_record.update_column(:status, 1) - end - - after do - ActiveRecord::Base.connection.execute("ALTER TABLE users ADD COLUMN linkedin text DEFAULT '' NOT NULL") - end - - it 'does not raise exception' do - expect { migrate! }.not_to raise_error - end - end - - context 'with different migration statuses', :redis do - using RSpec::Parameterized::TableSyntax - - where(:status, :description) do - 0 | 'paused' - 1 | 'active' - 4 | 'failed' - 5 | 'finalizing' - end - - with_them do - let!(:failed_job) do - table(:batched_background_migration_jobs).create!( - batched_background_migration_id: migration_record.id, - status: batch_failed_status, - min_value: 1, - max_value: 10, - attempts: 2, - batch_size: 100, - sub_batch_size: 10 - ) - end - - before do - migration_record.update!(status: status) - end - - it_behaves_like 'finalizes the migration' - end - end - end - end -end diff --git a/spec/migrations/20221104115712_backfill_project_statistics_storage_size_without_uploads_size_spec.rb b/spec/migrations/20221104115712_backfill_project_statistics_storage_size_without_uploads_size_spec.rb deleted file mode 100644 index 9658b5a699a..00000000000 --- a/spec/migrations/20221104115712_backfill_project_statistics_storage_size_without_uploads_size_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe BackfillProjectStatisticsStorageSizeWithoutUploadsSize, - feature_category: :consumables_cost_management do - let!(:batched_migration) { described_class::MIGRATION_CLASS } - - it 'does not schedule background jobs when Gitlab.org_or_com? is false' do - allow(Gitlab).to receive(:dev_or_test_env?).and_return(false) - allow(Gitlab).to receive(:org_or_com?).and_return(false) - - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - end - end - - it 'schedules background jobs for each batch of project_statistics' do - allow(Gitlab).to receive(:dev_or_test_env?).and_return(false) - allow(Gitlab).to receive(:org_or_com?).and_return(true) - - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).to have_scheduled_batched_migration( - table_name: :project_statistics, - column_name: :project_id, - interval: described_class::DELAY_INTERVAL - ) - } - end - end -end diff --git a/spec/migrations/20221110152133_delete_orphans_approval_rules_spec.rb b/spec/migrations/20221110152133_delete_orphans_approval_rules_spec.rb deleted file mode 100644 index 3efee67f7af..00000000000 --- a/spec/migrations/20221110152133_delete_orphans_approval_rules_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe DeleteOrphansApprovalRules, feature_category: :source_code_management do - describe '#up' do - it 'schedules background migration for both levels of approval rules' do - migrate! - - expect(described_class::MERGE_REQUEST_MIGRATION).to have_scheduled_batched_migration( - table_name: :approval_merge_request_rules, - column_name: :id, - interval: described_class::INTERVAL) - - expect(described_class::PROJECT_MIGRATION).to have_scheduled_batched_migration( - table_name: :approval_project_rules, - column_name: :id, - interval: described_class::INTERVAL) - end - end -end diff --git a/spec/migrations/20221115173607_ensure_work_item_type_backfill_migration_finished_spec.rb b/spec/migrations/20221115173607_ensure_work_item_type_backfill_migration_finished_spec.rb deleted file mode 100644 index d560da40c21..00000000000 --- a/spec/migrations/20221115173607_ensure_work_item_type_backfill_migration_finished_spec.rb +++ /dev/null @@ -1,106 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe EnsureWorkItemTypeBackfillMigrationFinished, :migration, feature_category: :team_planning do - let(:batched_migrations) { table(:batched_background_migrations) } - let(:work_item_types) { table(:work_item_types) } - let(:batch_failed_status) { 2 } - let(:batch_finalized_status) { 3 } - - let!(:migration_class) { described_class::MIGRATION } - - describe '#up', :redis do - context 'when migration is missing' do - before do - batched_migrations.where(job_class_name: migration_class).delete_all - end - - it 'warns migration not found' do - expect(Gitlab::AppLogger) - .to receive(:warn).with(/Could not find batched background migration for the given configuration:/) - .exactly(5).times - - migrate! - end - end - - context 'with migration present' do - let(:relevant_types) do - { - issue: 0, - incident: 1, - test_case: 2, - requirement: 3, - task: 4 - } - end - - let!(:backfill_migrations) do - relevant_types.map do |_base_type, enum_value| - type_id = work_item_types.find_by!(namespace_id: nil, base_type: enum_value).id - - create_migration_with(status, enum_value, type_id) - end - end - - context 'when migrations have finished' do - let(:status) { 3 } # finished enum value - - it 'does not raise an error' do - expect { migrate! }.not_to raise_error - end - end - - context 'with different migration statuses' do - using RSpec::Parameterized::TableSyntax - - where(:status, :description) do - 0 | 'paused' - 1 | 'active' - 4 | 'failed' - 5 | 'finalizing' - end - - with_them do - it 'finalizes the migration' do - expect do - migrate! - - backfill_migrations.each(&:reload) - end.to change { backfill_migrations.map(&:status).uniq }.from([status]).to([3]) - end - end - end - end - end - - def create_migration_with(status, base_type, type_id) - migration = batched_migrations.create!( - job_class_name: migration_class, - table_name: :issues, - column_name: :id, - job_arguments: [base_type, type_id], - interval: 2.minutes, - min_value: 1, - max_value: 2, - batch_size: 1000, - sub_batch_size: 200, - gitlab_schema: :gitlab_main, - status: status - ) - - table(:batched_background_migration_jobs).create!( - batched_background_migration_id: migration.id, - status: batch_failed_status, - min_value: 1, - max_value: 10, - attempts: 2, - batch_size: 100, - sub_batch_size: 10 - ) - - migration - end -end diff --git a/spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb b/spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb deleted file mode 100644 index 9eaab56de7c..00000000000 --- a/spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe SchedulePruneStaleProjectExportJobs, feature_category: :importers do - let!(:batched_migration) { described_class::MIGRATION } - - it 'schedules a new batched migration' do - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).to have_scheduled_batched_migration( - table_name: :project_export_jobs, - column_name: :id, - interval: described_class::DELAY_INTERVAL - ) - } - end - end -end diff --git a/spec/migrations/20221123133054_queue_reset_status_on_container_repositories_spec.rb b/spec/migrations/20221123133054_queue_reset_status_on_container_repositories_spec.rb deleted file mode 100644 index 2951b738243..00000000000 --- a/spec/migrations/20221123133054_queue_reset_status_on_container_repositories_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe QueueResetStatusOnContainerRepositories, feature_category: :container_registry do - let!(:batched_migration) { described_class::MIGRATION } - - before do - stub_container_registry_config( - enabled: true, - api_url: 'http://example.com', - key: 'spec/fixtures/x509_certificate_pk.key' - ) - end - - it 'schedules a new batched migration' do - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).to have_scheduled_batched_migration( - table_name: :container_repositories, - column_name: :id, - interval: described_class::DELAY_INTERVAL, - sub_batch_size: described_class::BATCH_SIZE - ) - } - end - end - - context 'with the container registry disabled' do - before do - allow(::Gitlab.config.registry).to receive(:enabled).and_return(false) - end - - it 'does not schedule a new batched migration' do - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - end - end - end -end diff --git a/spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb b/spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb deleted file mode 100644 index e03fd9c9daf..00000000000 --- a/spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ScheduleBackfillEnvironmentTier, feature_category: :continuous_delivery do - let!(:batched_migration) { described_class::MIGRATION } - - it 'schedules a new batched migration' do - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).to have_scheduled_batched_migration( - table_name: :environments, - column_name: :id, - interval: described_class::DELAY_INTERVAL - ) - } - end - end -end diff --git a/spec/migrations/20221209110934_update_import_sources_on_application_settings_spec.rb b/spec/migrations/20221209110934_update_import_sources_on_application_settings_spec.rb deleted file mode 100644 index d8270816afe..00000000000 --- a/spec/migrations/20221209110934_update_import_sources_on_application_settings_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe UpdateImportSourcesOnApplicationSettings, feature_category: :importers do - let(:settings) { table(:application_settings) } - let(:import_sources_with_google) { %w[google_code github git bitbucket bitbucket_server] } - let(:import_sources_without_google) { %w[github git bitbucket bitbucket_server] } - - describe "#up" do - it 'removes google_code and preserves existing valid import sources' do - record = settings.create!(import_sources: import_sources_with_google.to_yaml) - - migrate! - - expect(record.reload.import_sources).to start_with('---') - expect(ApplicationSetting.last.import_sources).to eq(import_sources_without_google) - end - end -end diff --git a/spec/migrations/20221209110935_fix_update_import_sources_on_application_settings_spec.rb b/spec/migrations/20221209110935_fix_update_import_sources_on_application_settings_spec.rb deleted file mode 100644 index 1f276109b24..00000000000 --- a/spec/migrations/20221209110935_fix_update_import_sources_on_application_settings_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe FixUpdateImportSourcesOnApplicationSettings, feature_category: :importers do - let(:settings) { table(:application_settings) } - let(:import_sources) { %w[github git bitbucket bitbucket_server] } - - describe "#up" do - shared_examples 'fixes import_sources on application_settings' do - it 'ensures YAML is stored' do - record = settings.create!(import_sources: data) - - migrate! - - expect(record.reload.import_sources).to start_with('---') - expect(ApplicationSetting.last.import_sources).to eq(import_sources) - end - end - - context 'when import_sources is a String' do - let(:data) { import_sources.to_s } - - it_behaves_like 'fixes import_sources on application_settings' - end - - context 'when import_sources is already YAML' do - let(:data) { import_sources.to_yaml } - - it_behaves_like 'fixes import_sources on application_settings' - end - end -end diff --git a/spec/migrations/20221209235940_cleanup_o_auth_access_tokens_with_null_expires_in_spec.rb b/spec/migrations/20221209235940_cleanup_o_auth_access_tokens_with_null_expires_in_spec.rb deleted file mode 100644 index e5890ffce17..00000000000 --- a/spec/migrations/20221209235940_cleanup_o_auth_access_tokens_with_null_expires_in_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe CleanupOAuthAccessTokensWithNullExpiresIn, feature_category: :system_access do - let(:batched_migration) { described_class::MIGRATION } - - it 'schedules background jobs for each batch of oauth_access_tokens' do - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).to have_scheduled_batched_migration( - table_name: :oauth_access_tokens, - column_name: :id, - interval: described_class::INTERVAL - ) - } - end - end -end diff --git a/spec/migrations/20221210154044_update_active_billable_users_index_spec.rb b/spec/migrations/20221210154044_update_active_billable_users_index_spec.rb deleted file mode 100644 index 3341df2ce51..00000000000 --- a/spec/migrations/20221210154044_update_active_billable_users_index_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe UpdateActiveBillableUsersIndex, feature_category: :database do - let(:db) { described_class.new } - let(:table_name) { described_class::TABLE_NAME } - let(:old_index_name) { described_class::OLD_INDEX_NAME } - let(:new_index_name) { described_class::NEW_INDEX_NAME } - let(:old_filter_condition) { "(user_type <> ALL ('{2,6,1,3,7,8}'::smallint[])))" } - let(:new_filter_condition) { "(user_type <> ALL ('{1,2,3,4,5,6,7,8,9,11}'::smallint[])))" } - - it 'correctly migrates up and down' do - reversible_migration do |migration| - migration.before -> { - expect(subject.index_exists_by_name?(table_name, new_index_name)).to be_falsy - expect(subject.index_exists_by_name?(table_name, old_index_name)).to be_truthy - expect(db.connection.indexes(table_name).find do |i| - i.name == old_index_name - end.where).to include(old_filter_condition) - } - - migration.after -> { - expect(subject.index_exists_by_name?(table_name, old_index_name)).to be_falsy - expect(subject.index_exists_by_name?(table_name, new_index_name)).to be_truthy - expect(db.connection.indexes(table_name).find do |i| - i.name == new_index_name - end.where).to include(new_filter_condition) - } - end - end -end diff --git a/spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb b/spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb deleted file mode 100644 index 7cc0bd96a0d..00000000000 --- a/spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ScheduleBackfillReleasesAuthorId, feature_category: :release_orchestration do - context 'when there are releases without author' do - let(:releases_table) { table(:releases) } - let(:user_table) { table(:users) } - let(:date_time) { DateTime.now } - let!(:batched_migration) { described_class::MIGRATION } - let!(:test_user) do - user_table.create!( - name: 'test', - email: 'test@example.com', - username: 'test', - projects_limit: 10 - ) - end - - before do - releases_table.create!( - tag: 'tag1', name: 'tag1', released_at: (date_time - 1.minute), author_id: test_user.id - ) - releases_table.create!( - tag: 'tag2', name: 'tag2', released_at: (date_time - 2.minutes), author_id: test_user.id - ) - releases_table.new( - tag: 'tag3', name: 'tag3', released_at: (date_time - 3.minutes), author_id: nil - ).save!(validate: false) - releases_table.new( - tag: 'tag4', name: 'tag4', released_at: (date_time - 4.minutes), author_id: nil - ).save!(validate: false) - end - - it 'schedules a new batched migration' do - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).to have_scheduled_batched_migration( - table_name: :releases, - column_name: :id, - interval: described_class::JOB_DELAY_INTERVAL, - job_arguments: [User.find_by(user_type: :ghost)&.id] - ) - } - end - end - end - - context 'when there are no releases without author' do - it 'does not schedule batched migration' do - expect(described_class.new.up).not_to have_scheduled_batched_migration - end - end -end diff --git a/spec/migrations/20221219122320_copy_clickhouse_connection_string_to_encrypted_var_spec.rb b/spec/migrations/20221219122320_copy_clickhouse_connection_string_to_encrypted_var_spec.rb deleted file mode 100644 index 48702e866e0..00000000000 --- a/spec/migrations/20221219122320_copy_clickhouse_connection_string_to_encrypted_var_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe CopyClickhouseConnectionStringToEncryptedVar, feature_category: :product_analytics_data_management do - let!(:migration) { described_class.new } - let(:setting) { table(:application_settings).create!(clickhouse_connection_string: 'https://example.com/test') } - - it 'copies the clickhouse_connection_string to the encrypted column' do - expect(setting.clickhouse_connection_string).to eq('https://example.com/test') - - migrate! - - setting.reload - expect(setting.clickhouse_connection_string).to eq('https://example.com/test') - expect(setting.encrypted_product_analytics_clickhouse_connection_string).not_to be_nil - end -end diff --git a/spec/migrations/20221220131020_bump_default_partition_id_value_for_ci_tables_spec.rb b/spec/migrations/20221220131020_bump_default_partition_id_value_for_ci_tables_spec.rb deleted file mode 100644 index c4bd243e79f..00000000000 --- a/spec/migrations/20221220131020_bump_default_partition_id_value_for_ci_tables_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe BumpDefaultPartitionIdValueForCiTables, :migration, feature_category: :continuous_integration do - context 'when on sass' do - before do - allow(Gitlab).to receive(:com?).and_return(true) - end - - it 'changes default values' do - reversible_migration do |migration| - migration.before -> { - expect(default_values).not_to include(101) - } - - migration.after -> { - expect(default_values).to match_array([101]) - } - end - end - - context 'with tables already changed' do - before do - active_record_base.connection.execute(<<~SQL) - ALTER TABLE ci_builds ALTER COLUMN partition_id SET DEFAULT 101 - SQL - end - - after do - schema_migrate_down! - end - - let(:alter_query) do - /ALTER TABLE "ci_builds" ALTER COLUMN "partition_id" SET DEFAULT 101/ - end - - it 'skips updating already changed tables' do - recorder = ActiveRecord::QueryRecorder.new { migrate! } - - expect(recorder.log.any?(alter_query)).to be_falsey - expect(default_values).to match_array([101]) - end - end - end - - context 'when self-managed' do - before do - allow(Gitlab).to receive(:com?).and_return(false) - end - - it 'does not change default values' do - reversible_migration do |migration| - migration.before -> { - expect(default_values).not_to include(101) - } - - migration.after -> { - expect(default_values).not_to include(101) - } - end - end - end - - def default_values - values = described_class::TABLES.flat_map do |table_name, columns| - active_record_base - .connection - .columns(table_name) - .select { |column| columns.include?(column.name.to_sym) } - .map { |column| column.default&.to_i } - end - - values.uniq - end -end diff --git a/spec/migrations/20221221110733_remove_temp_index_for_project_statistics_upload_size_migration_spec.rb b/spec/migrations/20221221110733_remove_temp_index_for_project_statistics_upload_size_migration_spec.rb deleted file mode 100644 index 440a932c76b..00000000000 --- a/spec/migrations/20221221110733_remove_temp_index_for_project_statistics_upload_size_migration_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe RemoveTempIndexForProjectStatisticsUploadSizeMigration, - feature_category: :consumables_cost_management do - let(:table_name) { 'project_statistics' } - let(:index_name) { described_class::INDEX_NAME } - - it 'correctly migrates up and down' do - reversible_migration do |migration| - migration.before -> { - expect(subject.index_exists_by_name?(table_name, index_name)).to be_truthy - } - - migration.after -> { - expect(subject.index_exists_by_name?(table_name, index_name)).to be_falsy - } - end - end -end diff --git a/spec/migrations/20221222092958_sync_new_amount_used_with_amount_used_spec.rb b/spec/migrations/20221222092958_sync_new_amount_used_with_amount_used_spec.rb deleted file mode 100644 index 158560a2432..00000000000 --- a/spec/migrations/20221222092958_sync_new_amount_used_with_amount_used_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe SyncNewAmountUsedWithAmountUsed, migration: :gitlab_ci, feature_category: :continuous_integration do - let(:project_usages) { table(:ci_project_monthly_usages) } - let(:migration) { described_class.new } - - before do - # Disabling the trigger temporarily to allow records being created with out-of-sync - # `new_amount_used` and `amount_used`. This will simulate existing records before - # we add the trigger. - ActiveRecord::Base.connection - .execute("ALTER TABLE ci_project_monthly_usages DISABLE TRIGGER sync_projects_amount_used_columns") - - this_month = Time.now.utc.beginning_of_month - last_month = 1.month.ago.utc.beginning_of_month - last_year = 1.year.ago.utc.beginning_of_month - - project_usages.create!(project_id: 1, date: last_year) - project_usages.create!(project_id: 1, date: this_month, amount_used: 10, new_amount_used: 0) - project_usages.create!(project_id: 1, date: last_month, amount_used: 20, new_amount_used: 0) - - project_usages.create!(project_id: 2, date: last_year) - project_usages.create!(project_id: 2, date: this_month, amount_used: 30, new_amount_used: 0) - project_usages.create!(project_id: 2, date: last_month, amount_used: 40, new_amount_used: 0) - - ActiveRecord::Base.connection - .execute("ALTER TABLE ci_project_monthly_usages ENABLE TRIGGER sync_projects_amount_used_columns") - end - - describe '#up' do - it "doesnt change new_amount_used values" do - data = project_usages.all - data.each do |item| - expect { migration.up }.to not_change { item.new_amount_used } - end - end - end - - describe '#down' do - it 'updates `new_amount_used` with values from `amount_used`' do - expect(project_usages.where(new_amount_used: 0).count).to eq(6) - - migration.down - - expect(project_usages.where(new_amount_used: 0).count).to eq(2) - expect(project_usages.order(:id).pluck(:new_amount_used)) - .to contain_exactly(0, 0, 10, 20, 30, 40) - end - end -end diff --git a/spec/migrations/20221223123019_delete_queued_jobs_for_vulnerabilities_feedback_migration_spec.rb b/spec/migrations/20221223123019_delete_queued_jobs_for_vulnerabilities_feedback_migration_spec.rb deleted file mode 100644 index c5e1a255653..00000000000 --- a/spec/migrations/20221223123019_delete_queued_jobs_for_vulnerabilities_feedback_migration_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe DeleteQueuedJobsForVulnerabilitiesFeedbackMigration, feature_category: :vulnerability_management do - let!(:migration) { described_class.new } - let(:batched_background_migrations) { table(:batched_background_migrations) } - - before do - batched_background_migrations.create!( - max_value: 10, - batch_size: 250, - sub_batch_size: 50, - interval: 300, - job_class_name: 'MigrateVulnerabilitiesFeedbackToVulnerabilitiesStateTransition', - table_name: 'vulnerability_feedback', - column_name: 'id', - job_arguments: [], - gitlab_schema: "gitlab_main" - ) - end - - describe "#up" do - it "deletes all batched migration records" do - expect(batched_background_migrations.count).to eq(1) - - migration.up - - expect(batched_background_migrations.count).to eq(0) - end - end -end diff --git a/spec/migrations/20221226153252_queue_fix_incoherent_packages_size_on_project_statistics_spec.rb b/spec/migrations/20221226153252_queue_fix_incoherent_packages_size_on_project_statistics_spec.rb deleted file mode 100644 index b375546b90e..00000000000 --- a/spec/migrations/20221226153252_queue_fix_incoherent_packages_size_on_project_statistics_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe QueueFixIncoherentPackagesSizeOnProjectStatistics, feature_category: :package_registry do - let(:batched_migration) { described_class::MIGRATION } - - context 'with no packages' do - it 'does not schedule a new batched migration' do - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - end - end - end - - context 'with some packages' do - before do - namespace = table(:namespaces) - .create!(name: 'project', path: 'project', type: 'Project') - project = table(:projects).create!( - name: 'project', - path: 'project', - project_namespace_id: namespace.id, - namespace_id: namespace.id - ) - table(:packages_packages) - .create!(name: 'test', version: '1.2.3', package_type: 2, project_id: project.id) - end - - it 'schedules a new batched migration' do - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).to have_scheduled_batched_migration( - table_name: :project_statistics, - column_name: :id, - interval: described_class::DELAY_INTERVAL, - batch_size: described_class::BATCH_SIZE - ) - } - end - end - end -end diff --git a/spec/migrations/20230105172120_sync_new_amount_used_with_amount_used_on_ci_namespace_monthly_usages_table_spec.rb b/spec/migrations/20230105172120_sync_new_amount_used_with_amount_used_on_ci_namespace_monthly_usages_table_spec.rb deleted file mode 100644 index 70c9c1333b8..00000000000 --- a/spec/migrations/20230105172120_sync_new_amount_used_with_amount_used_on_ci_namespace_monthly_usages_table_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe SyncNewAmountUsedWithAmountUsedOnCiNamespaceMonthlyUsagesTable, migration: :gitlab_ci, - feature_category: :continuous_integration do - let(:namespace_usages) { table(:ci_namespace_monthly_usages) } - let(:migration) { described_class.new } - - before do - # Disabling the trigger temporarily to allow records being created with out-of-sync - # `new_amount_used` and `amount_used`. This will simulate existing records before - # we add the trigger. - ActiveRecord::Base.connection - .execute("ALTER TABLE ci_namespace_monthly_usages DISABLE TRIGGER sync_namespaces_amount_used_columns") - - this_month = Time.now.utc.beginning_of_month - last_month = 1.month.ago.utc.beginning_of_month - last_year = 1.year.ago.utc.beginning_of_month - - namespace_usages.create!(namespace_id: 1, date: last_year) - namespace_usages.create!(namespace_id: 1, date: this_month, amount_used: 10, new_amount_used: 0) - namespace_usages.create!(namespace_id: 1, date: last_month, amount_used: 20, new_amount_used: 0) - - namespace_usages.create!(namespace_id: 2, date: last_year) - namespace_usages.create!(namespace_id: 2, date: this_month, amount_used: 30, new_amount_used: 0) - namespace_usages.create!(namespace_id: 2, date: last_month, amount_used: 40, new_amount_used: 0) - - ActiveRecord::Base.connection - .execute("ALTER TABLE ci_namespace_monthly_usages ENABLE TRIGGER sync_namespaces_amount_used_columns") - end - - describe '#up' do - it "doesnt change new_amount_used values" do - data = namespace_usages.all - data.each do |item| - expect { migration.up }.to not_change { item.new_amount_used } - end - end - end - - describe '#down' do - it 'updates `new_amount_used` with values from `amount_used`' do - expect(namespace_usages.where(new_amount_used: 0).count).to eq(6) - - migration.down - - expect(namespace_usages.where(new_amount_used: 0).count).to eq(2) - expect(namespace_usages.order(:id).pluck(:new_amount_used)) - .to contain_exactly(0, 0, 10, 20, 30, 40) - end - end -end diff --git a/spec/migrations/20230116111252_finalize_todo_sanitization_spec.rb b/spec/migrations/20230116111252_finalize_todo_sanitization_spec.rb deleted file mode 100644 index cd7828bbae4..00000000000 --- a/spec/migrations/20230116111252_finalize_todo_sanitization_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe FinalizeTodoSanitization, :migration, feature_category: :portfolio_management do - let(:batched_migrations) { table(:batched_background_migrations) } - - let!(:migration) { described_class::MIGRATION } - - describe '#up' do - let!(:sanitize_todos_migration) do - batched_migrations.create!( - job_class_name: 'SanitizeConfidentialTodos', - table_name: :notes, - column_name: :id, - job_arguments: [], - interval: 2.minutes, - min_value: 1, - max_value: 2, - batch_size: 1000, - sub_batch_size: 200, - gitlab_schema: :gitlab_main, - status: 3 # finished - ) - end - - context 'when migration finished successfully' do - it 'does not raise exception' do - expect { migrate! }.not_to raise_error - end - end - - context 'with different migration statuses' do - using RSpec::Parameterized::TableSyntax - - where(:status, :description) do - 0 | 'paused' - 1 | 'active' - 4 | 'failed' - 5 | 'finalizing' - end - - with_them do - before do - sanitize_todos_migration.update!(status: status) - end - - it 'finalizes the migration' do - allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner| - expect(runner).to receive(:finalize).with('SanitizeConfidentialTodos', :members, :id, []) - end - end - end - end - end -end diff --git a/spec/migrations/20230117114739_clear_duplicate_jobs_cookies_spec.rb b/spec/migrations/20230117114739_clear_duplicate_jobs_cookies_spec.rb deleted file mode 100644 index 5c572b49d3d..00000000000 --- a/spec/migrations/20230117114739_clear_duplicate_jobs_cookies_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ClearDuplicateJobsCookies, :migration, feature_category: :redis do - def with_redis(&block) - Gitlab::Redis::Queues.with(&block) - end - - it 'deletes duplicate jobs cookies' do - delete = ['resque:gitlab:duplicate:blabla:1:cookie:v2', 'resque:gitlab:duplicate:foobar:2:cookie:v2'] - keep = ['resque:gitlab:duplicate:something', 'something:cookie:v2'] - with_redis { |r| (delete + keep).each { |key| r.set(key, 'value') } } - - expect(with_redis { |r| r.exists(delete + keep) }).to eq(4) - - migrate! - - expect(with_redis { |r| r.exists(delete) }).to eq(0) - expect(with_redis { |r| r.exists(keep) }).to eq(2) - end -end diff --git a/spec/migrations/20230130073109_nullify_creator_id_of_orphaned_projects_spec.rb b/spec/migrations/20230130073109_nullify_creator_id_of_orphaned_projects_spec.rb deleted file mode 100644 index 196bacd99ba..00000000000 --- a/spec/migrations/20230130073109_nullify_creator_id_of_orphaned_projects_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe NullifyCreatorIdOfOrphanedProjects, feature_category: :groups_and_projects do - let!(:migration) { described_class::MIGRATION } - - describe '#up' do - it 'schedules background migration' do - migrate! - - expect(migration).to have_scheduled_batched_migration( - table_name: :projects, - column_name: :id, - interval: described_class::INTERVAL, - batch_size: described_class::BATCH_SIZE, - max_batch_size: described_class::MAX_BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE - ) - end - end - - describe '#down' do - it 'removes scheduled background migrations' do - migrate! - schema_migrate_down! - - expect(migration).not_to have_scheduled_batched_migration - end - end -end diff --git a/spec/migrations/20230131125844_add_project_id_name_id_version_index_to_installable_npm_packages_spec.rb b/spec/migrations/20230131125844_add_project_id_name_id_version_index_to_installable_npm_packages_spec.rb deleted file mode 100644 index 5d8c7ab4745..00000000000 --- a/spec/migrations/20230131125844_add_project_id_name_id_version_index_to_installable_npm_packages_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe AddProjectIdNameIdVersionIndexToInstallableNpmPackages, feature_category: :package_registry do - it 'schedules an index creation' do - reversible_migration do |migration| - migration.before -> { - expect(ActiveRecord::Base.connection.indexes('packages_packages').map(&:name)) - .not_to include('idx_packages_on_project_id_name_id_version_when_installable_npm') - } - - migration.after -> { - expect(ActiveRecord::Base.connection.indexes('packages_packages').map(&:name)) - .to include('idx_packages_on_project_id_name_id_version_when_installable_npm') - } - end - end -end diff --git a/spec/migrations/20230201171450_finalize_backfill_environment_tier_migration_spec.rb b/spec/migrations/20230201171450_finalize_backfill_environment_tier_migration_spec.rb deleted file mode 100644 index e7a78f11f16..00000000000 --- a/spec/migrations/20230201171450_finalize_backfill_environment_tier_migration_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe FinalizeBackfillEnvironmentTierMigration, :migration, feature_category: :continuous_delivery do - let(:batched_migrations) { table(:batched_background_migrations) } - - let!(:migration) { described_class::MIGRATION } - - describe '#up' do - shared_examples 'finalizes the migration' do - it 'finalizes the migration' do - allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner| - expect(runner).to receive(:finalize).with('BackfillEnvironmentTiers', :environments, :id, []) - end - end - end - - context 'when migration is missing' do - before do - batched_migrations.where(job_class_name: migration).delete_all - end - - it 'warns migration not found' do - expect(Gitlab::AppLogger) - .to receive(:warn).with(/Could not find batched background migration for the given configuration:/) - - migrate! - end - end - - context 'with migration present' do - let!(:group_member_namespace_id_backfill) do - batched_migrations.create!( - job_class_name: migration, - table_name: :environments, - column_name: :id, - job_arguments: [], - interval: 2.minutes, - min_value: 1, - max_value: 2, - batch_size: 1000, - sub_batch_size: 200, - gitlab_schema: :gitlab_main, - status: 3 # finished - ) - end - - context 'when migration finished successfully' do - it 'does not raise exception' do - expect { migrate! }.not_to raise_error - end - end - - context 'with different migration statuses' do - using RSpec::Parameterized::TableSyntax - - where(:status, :description) do - 0 | 'paused' - 1 | 'active' - 4 | 'failed' - 5 | 'finalizing' - end - - with_them do - before do - group_member_namespace_id_backfill.update!(status: status) - end - - it_behaves_like 'finalizes the migration' - end - end - end - end -end diff --git a/spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb b/spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb deleted file mode 100644 index 597cd7c1581..00000000000 --- a/spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe EncryptCiTriggerToken, migration: :gitlab_ci, feature_category: :continuous_integration do - let(:batched_migrations) { table(:batched_background_migrations) } - - let!(:migration) { described_class::MIGRATION } - - describe '#up' do - context 'with migration present' do - let!(:ci_trigger_token_encryption_migration) do - batched_migrations.create!( - job_class_name: 'EncryptCiTriggerToken', - table_name: :ci_triggers, - column_name: :token, - job_arguments: [], - interval: 2.minutes, - min_value: 1, - max_value: 2, - batch_size: 1000, - sub_batch_size: 100, - gitlab_schema: :gitlab_ci, - status: 3 # finished - ) - end - - context 'when migration finished successfully' do - it 'does not raise exception' do - expect { migrate! }.not_to raise_error - end - - it 'schedules background jobs for each batch of ci_triggers' do - migrate! - - expect(migration).to have_scheduled_batched_migration( - gitlab_schema: :gitlab_ci, - table_name: :ci_triggers, - column_name: :token, - batch_size: described_class::BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE - ) - end - end - end - end - - describe '#down' do - it 'deletes all batched migration records' do - migrate! - schema_migrate_down! - - expect(migration).not_to have_scheduled_batched_migration - end - end -end diff --git a/spec/migrations/20230203122602_schedule_vulnerabilities_feedback_migration4_spec.rb b/spec/migrations/20230203122602_schedule_vulnerabilities_feedback_migration4_spec.rb deleted file mode 100644 index 26c63e6deb2..00000000000 --- a/spec/migrations/20230203122602_schedule_vulnerabilities_feedback_migration4_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ScheduleVulnerabilitiesFeedbackMigration4, feature_category: :vulnerability_management do - let(:migration) { described_class::MIGRATION } - - describe '#up' do - it 'schedules background jobs for each batch of Vulnerabilities::Feedback' do - migrate! - - expect(migration).to have_scheduled_batched_migration( - table_name: :vulnerability_feedback, - column_name: :id, - interval: described_class::JOB_INTERVAL, - batch_size: described_class::BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE - ) - end - end - - describe '#down' do - it 'deletes all batched migration records' do - migrate! - schema_migrate_down! - - expect(migration).not_to have_scheduled_batched_migration - end - end -end diff --git a/spec/migrations/add_namespaces_emails_enabled_column_data_spec.rb b/spec/migrations/add_namespaces_emails_enabled_column_data_spec.rb deleted file mode 100644 index c63724497c2..00000000000 --- a/spec/migrations/add_namespaces_emails_enabled_column_data_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe AddNamespacesEmailsEnabledColumnData, :migration, feature_category: :database do - let(:migration) { described_class::MIGRATION } - let(:projects) { table(:projects) } - let(:namespace_settings_table) { table(:namespace_settings) } - let(:namespaces) { table(:namespaces) } - - before do - stub_const("#{described_class.name}::SUB_BATCH_SIZE", 2) - end - - it 'schedules background migrations', :aggregate_failures do - migrate! - - expect(migration).to have_scheduled_batched_migration( - table_name: :namespaces, - column_name: :id, - interval: described_class::DELAY_INTERVAL - ) - end - - describe '#down' do - it 'deletes all batched migration records' do - migrate! - schema_migrate_down! - - expect(migration).not_to have_scheduled_batched_migration - end - end - - it 'sets emails_enabled to be the opposite of emails_disabled', type: :task do - Rake.application.rake_require 'active_record/railties/databases' - Rake.application.rake_require 'tasks/gitlab/db' - - disabled_records_to_migrate = 6 - enabled_records_to_migrate = 4 - - disabled_records_to_migrate.times do |i| - namespace = namespaces.create!(name: 'namespace', - path: "namespace#{i}", - emails_disabled: true) - namespace_settings_table.create!(namespace_id: namespace.id) - end - - enabled_records_to_migrate.times do |i| - namespace = namespaces.create!(name: 'namespace', - path: "namespace#{i}", - emails_disabled: false) - namespace_settings_table.create!(namespace_id: namespace.id) - end - - migrate! - run_rake_task('gitlab:db:execute_batched_migrations') - # rubocop: disable CodeReuse/ActiveRecord - expect(namespace_settings_table.where(emails_enabled: true).count).to eq(enabled_records_to_migrate) - expect(namespace_settings_table.where(emails_enabled: false).count).to eq(disabled_records_to_migrate) - # rubocop: enable CodeReuse/ActiveRecord - end -end diff --git a/spec/migrations/add_okr_hierarchy_restrictions_spec.rb b/spec/migrations/add_okr_hierarchy_restrictions_spec.rb deleted file mode 100644 index ace581c7e3c..00000000000 --- a/spec/migrations/add_okr_hierarchy_restrictions_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe AddOkrHierarchyRestrictions, :migration, feature_category: :portfolio_management do - include MigrationHelpers::WorkItemTypesHelper - - let!(:restrictions) { table(:work_item_hierarchy_restrictions) } - let!(:work_item_types) { table(:work_item_types) } - - it 'creates default restrictions' do - restrictions.delete_all - - reversible_migration do |migration| - migration.before -> { - expect(restrictions.count).to eq(0) - } - - migration.after -> { - expect(restrictions.count).to eq(4) - } - end - end - - context 'when work items are missing' do - before do - work_item_types.delete_all - end - - it 'does nothing' do - expect { migrate! }.not_to change { restrictions.count } - end - end -end diff --git a/spec/migrations/add_projects_emails_enabled_column_data_spec.rb b/spec/migrations/add_projects_emails_enabled_column_data_spec.rb deleted file mode 100644 index d10fa78f846..00000000000 --- a/spec/migrations/add_projects_emails_enabled_column_data_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe AddProjectsEmailsEnabledColumnData, :migration, feature_category: :database do - let(:migration) { described_class::MIGRATION } - let(:project_settings) { table(:project_settings) } - let(:projects) { table(:projects) } - let(:namespaces) { table(:namespaces) } - - before do - stub_const("#{described_class.name}::SUB_BATCH_SIZE", 2) - end - - it 'schedules background migrations', :aggregate_failures do - migrate! - - expect(migration).to have_scheduled_batched_migration( - table_name: :projects, - column_name: :id, - interval: described_class::DELAY_INTERVAL - ) - end - - describe '#down' do - it 'deletes all batched migration records' do - migrate! - schema_migrate_down! - - expect(migration).not_to have_scheduled_batched_migration - end - end - - it 'sets emails_enabled to be the opposite of emails_disabled', type: :task do - Rake.application.rake_require 'active_record/railties/databases' - Rake.application.rake_require 'tasks/gitlab/db' - - disabled_records_to_migrate = 4 - enabled_records_to_migrate = 2 - - disabled_records_to_migrate.times do |i| - namespace = namespaces.create!(name: 'namespace', path: "namespace#{i}") - project = projects.create!(name: "Project Disabled #{i}", - path: "projectDisabled#{i}", - namespace_id: namespace.id, - project_namespace_id: namespace.id, - emails_disabled: true) - project_settings.create!(project_id: project.id) - end - - enabled_records_to_migrate.times do |i| - namespace = namespaces.create!(name: 'namespace', path: "namespace#{i}") - project = projects.create!(name: "Project Enabled #{i}", - path: "projectEnabled#{i}", - namespace_id: namespace.id, - project_namespace_id: namespace.id, - emails_disabled: false) - project_settings.create!(project_id: project.id) - end - - migrate! - run_rake_task('gitlab:db:execute_batched_migrations') - # rubocop: disable CodeReuse/ActiveRecord - expect(project_settings.where(emails_enabled: true).count).to eq(enabled_records_to_migrate) - expect(project_settings.where(emails_enabled: false).count).to eq(disabled_records_to_migrate) - # rubocop: enable CodeReuse/ActiveRecord - end -end diff --git a/spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb b/spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb deleted file mode 100644 index 0800a049767..00000000000 --- a/spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe FinalizeIssuesNamespaceIdBackfilling, :migration, feature_category: :team_planning do - let(:batched_migrations) { table(:batched_background_migrations) } - - let!(:migration) { described_class::MIGRATION } - - describe '#up' do - shared_examples 'finalizes the migration' do - it 'finalizes the migration' do - allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner| - expect(runner).to receive(:finalize).with(migration, :projects, :id, []) - end - end - end - - context 'when routes backfilling migration is missing' do - before do - batched_migrations.where(job_class_name: migration).delete_all - end - - it 'warns migration not found' do - expect(Gitlab::AppLogger) - .to receive(:warn).with(/Could not find batched background migration for the given configuration:/) - - migrate! - end - end - - context 'with backfilling migration present' do - let!(:project_namespace_backfill) do - batched_migrations.create!( - job_class_name: migration, - table_name: :routes, - column_name: :id, - job_arguments: [], - interval: 2.minutes, - min_value: 1, - max_value: 2, - batch_size: 1000, - sub_batch_size: 200, - gitlab_schema: :gitlab_main, - status: 3 # finished - ) - end - - context 'when backfilling migration finished successfully' do - it 'does not raise exception' do - expect { migrate! }.not_to raise_error - end - end - - context 'with different backfilling migration statuses' do - using RSpec::Parameterized::TableSyntax - - where(:status, :description) do - 0 | 'paused' - 1 | 'active' - 4 | 'failed' - 5 | 'finalizing' - end - - with_them do - before do - project_namespace_backfill.update!(status: status) - end - - it_behaves_like 'finalizes the migration' - end - end - end - end -end diff --git a/spec/migrations/nullify_last_error_from_project_mirror_data_spec.rb b/spec/migrations/nullify_last_error_from_project_mirror_data_spec.rb deleted file mode 100644 index 6c5679b674e..00000000000 --- a/spec/migrations/nullify_last_error_from_project_mirror_data_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe NullifyLastErrorFromProjectMirrorData, feature_category: :source_code_management do - let(:migration) { described_class::MIGRATION } - - before do - migrate! - end - - describe '#up' do - it 'schedules background jobs for each batch of projects' do - expect(migration).to( - have_scheduled_batched_migration( - table_name: :project_mirror_data, - column_name: :id, - interval: described_class::INTERVAL, - batch_size: described_class::BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE - ) - ) - end - end - - describe '#down' do - before do - schema_migrate_down! - end - - it 'deletes all batched migration records' do - expect(migration).not_to have_scheduled_batched_migration - end - end -end diff --git a/spec/migrations/recount_epic_cache_counts_v3_spec.rb b/spec/migrations/recount_epic_cache_counts_v3_spec.rb deleted file mode 100644 index 24b89ab30ca..00000000000 --- a/spec/migrations/recount_epic_cache_counts_v3_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe RecountEpicCacheCountsV3, :migration, feature_category: :portfolio_management do - let(:migration) { described_class::MIGRATION } - - describe '#up' do - it 'schedules a batched background migration' do - migrate! - - expect(migration).to have_scheduled_batched_migration( - table_name: :epics, - column_name: :id, - interval: described_class::DELAY_INTERVAL, - batch_size: described_class::BATCH_SIZE, - max_batch_size: described_class::MAX_BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE - ) - end - end - - describe '#down' do - it 'deletes all batched migration records' do - migrate! - schema_migrate_down! - - expect(migration).not_to have_scheduled_batched_migration - end - end -end diff --git a/spec/migrations/remove_flowdock_integration_records_spec.rb b/spec/migrations/remove_flowdock_integration_records_spec.rb deleted file mode 100644 index 3f57515d18b..00000000000 --- a/spec/migrations/remove_flowdock_integration_records_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db/post_migrate/20221129124240_remove_flowdock_integration_records.rb') - -RSpec.describe RemoveFlowdockIntegrationRecords, feature_category: :integrations do - let(:integrations) { table(:integrations) } - - before do - integrations.create!(type_new: 'Integrations::Flowdock') - integrations.create!(type_new: 'SomeOtherType') - end - - it 'removes integrations records of type_new Integrations::Flowdock' do - expect(integrations.count).to eq(2) - - migrate! - - expect(integrations.count).to eq(1) - expect(integrations.first.type_new).to eq('SomeOtherType') - expect(integrations.where(type_new: 'Integrations::Flowdock')).to be_empty - end -end diff --git a/spec/migrations/schedule_fixing_security_scan_statuses_spec.rb b/spec/migrations/schedule_fixing_security_scan_statuses_spec.rb deleted file mode 100644 index f43f58d3be2..00000000000 --- a/spec/migrations/schedule_fixing_security_scan_statuses_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ScheduleFixingSecurityScanStatuses, - :suppress_gitlab_schemas_validate_connection, :suppress_partitioning_routing_analyzer, - feature_category: :vulnerability_management do - let!(:namespaces) { table(:namespaces) } - let!(:projects) { table(:projects) } - let!(:pipelines) { table(:ci_pipelines, database: :ci) } - let!(:builds) { table(:ci_builds, database: :ci) { |model| model.primary_key = :id } } - let!(:security_scans) { table(:security_scans) } - - let!(:namespace) { namespaces.create!(name: "foo", path: "bar") } - let!(:project) { projects.create!(namespace_id: namespace.id, project_namespace_id: namespace.id) } - let!(:pipeline) do - pipelines.create!(project_id: project.id, ref: 'master', sha: 'adf43c3a', status: 'success', partition_id: 100) - end - - let!(:ci_build) { builds.create!(commit_id: pipeline.id, retried: false, type: 'Ci::Build', partition_id: 100) } - - let!(:security_scan_1) { security_scans.create!(build_id: ci_build.id, scan_type: 1, created_at: 91.days.ago) } - let!(:security_scan_2) { security_scans.create!(build_id: ci_build.id, scan_type: 2) } - - let(:com?) { false } - let(:dev_or_test_env?) { false } - let(:migration) { described_class::MIGRATION } - - before do - allow(::Gitlab).to receive(:com?).and_return(com?) - allow(::Gitlab).to receive(:dev_or_test_env?).and_return(dev_or_test_env?) - - migrate! - end - - describe '#up' do - shared_examples_for 'scheduler for fixing the security scans status' do - it 'schedules background job' do - expect(migration).to have_scheduled_batched_migration( - table_name: :security_scans, - column_name: :id, - interval: 2.minutes, - batch_size: 10_000, - max_batch_size: 50_000, - sub_batch_size: 100, - batch_min_value: security_scan_2.id - ) - end - end - - context 'when the migration does not run on GitLab.com or development environment' do - it 'does not schedule the migration' do - expect('FixSecurityScanStatuses').not_to have_scheduled_batched_migration - end - end - - context 'when the migration runs on GitLab.com' do - let(:com?) { true } - - it_behaves_like 'scheduler for fixing the security scans status' - end - - context 'when the migration runs on dev environment' do - let(:dev_or_test_env?) { true } - - it_behaves_like 'scheduler for fixing the security scans status' - end - end - - describe '#down' do - it 'deletes all batched migration records' do - schema_migrate_down! - - expect(migration).not_to have_scheduled_batched_migration - end - end -end diff --git a/spec/migrations/second_recount_epic_cache_counts_spec.rb b/spec/migrations/second_recount_epic_cache_counts_spec.rb deleted file mode 100644 index ab4357264be..00000000000 --- a/spec/migrations/second_recount_epic_cache_counts_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe SecondRecountEpicCacheCounts, :migration, feature_category: :portfolio_management do - let(:migration) { described_class::MIGRATION } - - describe '#up' do - it 'schedules a batched background migration' do - migrate! - - expect(migration).to have_scheduled_batched_migration( - table_name: :epics, - column_name: :id, - interval: described_class::DELAY_INTERVAL, - batch_size: described_class::BATCH_SIZE, - max_batch_size: described_class::MAX_BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE - ) - end - end - - describe '#down' do - it 'deletes all batched migration records' do - migrate! - schema_migrate_down! - - expect(migration).not_to have_scheduled_batched_migration - end - end -end diff --git a/spec/migrations/set_email_confirmation_setting_before_removing_send_user_confirmation_email_column_spec.rb b/spec/migrations/set_email_confirmation_setting_before_removing_send_user_confirmation_email_column_spec.rb deleted file mode 100644 index 02ecbe90ee0..00000000000 --- a/spec/migrations/set_email_confirmation_setting_before_removing_send_user_confirmation_email_column_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe SetEmailConfirmationSettingBeforeRemovingSendUserConfirmationEmailColumn, - feature_category: :user_profile do - let(:migration) { described_class.new } - let(:application_settings_table) { table(:application_settings) } - - describe '#up' do - context "when 'send_user_confirmation_email' is set to 'true'" do - it "updates 'email_confirmation_setting' to '2' (hard)" do - application_settings_table.create!(send_user_confirmation_email: true, email_confirmation_setting: 0) - - migration.up - - expect(application_settings_table.last.email_confirmation_setting).to eq 2 - end - end - - context "when 'send_user_confirmation_email' is set to 'false'" do - it "updates 'email_confirmation_setting' to '0' (off)" do - application_settings_table.create!(send_user_confirmation_email: false, email_confirmation_setting: 0) - - migration.up - - expect(application_settings_table.last.email_confirmation_setting).to eq 0 - end - end - end - - describe '#down' do - it "updates 'email_confirmation_setting' to default value: '0' (off)" do - application_settings_table.create!(send_user_confirmation_email: true, email_confirmation_setting: 2) - - migration.down - - expect(application_settings_table.last.email_confirmation_setting).to eq 0 - end - end -end diff --git a/spec/models/ci/bridge_spec.rb b/spec/models/ci/bridge_spec.rb index ae8c5aea858..bc3a5ccddb2 100644 --- a/spec/models/ci/bridge_spec.rb +++ b/spec/models/ci/bridge_spec.rb @@ -552,261 +552,264 @@ RSpec.describe Ci::Bridge, feature_category: :continuous_integration do ) end end - end - - describe '#variables' do - it 'returns bridge scoped variables and pipeline persisted variables' do - expect(bridge.variables.to_hash) - .to eq(bridge.scoped_variables.concat(bridge.pipeline.persisted_variables).to_hash) - end - end - - describe '#pipeline_variables' do - it 'returns the pipeline variables' do - expect(bridge.pipeline_variables).to eq(bridge.pipeline.variables) - end - end - - describe '#pipeline_schedule_variables' do - context 'when pipeline is on a schedule' do - let(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project) } - let(:pipeline) { create(:ci_pipeline, pipeline_schedule: pipeline_schedule) } - - it 'returns the pipeline schedule variables' do - create(:ci_pipeline_schedule_variable, key: 'FOO', value: 'foo', pipeline_schedule: pipeline.pipeline_schedule) - - pipeline_schedule_variables = bridge.reload.pipeline_schedule_variables - expect(pipeline_schedule_variables).to match_array([have_attributes({ key: 'FOO', value: 'foo' })]) - end - end - - context 'when pipeline is not on a schedule' do - it 'returns empty array' do - expect(bridge.pipeline_schedule_variables).to eq([]) - end - end - end - describe '#forward_yaml_variables?' do - using RSpec::Parameterized::TableSyntax - - where(:forward, :result) do - true | true - false | false - nil | true - end - - with_them do + describe 'variables expansion' do let(:options) do { trigger: { project: 'my/project', branch: 'master', - forward: { yaml_variables: forward }.compact + forward: { yaml_variables: true, + pipeline_variables: true }.compact } } end - let(:bridge) { build(:ci_bridge, options: options) } + let(:yaml_variables) do + [ + { + key: 'EXPANDED_PROJECT_VAR6', + value: 'project value6 $PROJECT_PROTECTED_VAR' + }, + { + key: 'EXPANDED_GROUP_VAR6', + value: 'group value6 $GROUP_PROTECTED_VAR' + }, - it { expect(bridge.forward_yaml_variables?).to eq(result) } - end - end + { + key: 'VAR7', + value: 'value7 $VAR1', + raw: true + } + ] + end - describe 'variables expansion' do - let(:options) do - { - trigger: { - project: 'my/project', - branch: 'master', - forward: { yaml_variables: true, - pipeline_variables: true }.compact - } - } - end + let_it_be(:downstream_creator_user) { create(:user) } + let_it_be(:bridge_creator_user) { create(:user) } - let(:yaml_variables) do - [ - { - key: 'EXPANDED_PROJECT_VAR6', - value: 'project value6 $PROJECT_PROTECTED_VAR' - }, - { - key: 'EXPANDED_GROUP_VAR6', - value: 'group value6 $GROUP_PROTECTED_VAR' - }, + let_it_be(:bridge_group) { create(:group) } + let_it_be(:downstream_group) { create(:group) } + let_it_be(:downstream_project) { create(:project, creator: downstream_creator_user, group: downstream_group) } + let_it_be(:project) do + create(:project, :repository, :in_group, creator: bridge_creator_user, group: bridge_group) + end - { - key: 'VAR7', - value: 'value7 $VAR1', - raw: true - } - ] - end + let(:bridge) { build(:ci_bridge, :playable, pipeline: pipeline, downstream: downstream_project) } + let!(:pipeline) { create(:ci_pipeline, project: project) } - let_it_be(:downstream_creator_user) { create(:user) } - let_it_be(:bridge_creator_user) { create(:user) } - - let_it_be(:bridge_group) { create(:group) } - let_it_be(:downstream_group) { create(:group) } - let_it_be(:downstream_project) { create(:project, creator: downstream_creator_user, group: downstream_group) } - let_it_be(:project) { create(:project, :repository, :in_group, creator: bridge_creator_user, group: bridge_group) } - let(:bridge) { build(:ci_bridge, :playable, pipeline: pipeline, downstream: downstream_project) } - let!(:pipeline) { create(:ci_pipeline, project: project) } - - let!(:ci_variable) do - create(:ci_variable, - project: project, - key: 'PROJECT_PROTECTED_VAR', - value: 'this is a secret', - protected: is_variable_protected?) - end + let!(:ci_variable) do + create(:ci_variable, + project: project, + key: 'PROJECT_PROTECTED_VAR', + value: 'this is a secret', + protected: is_variable_protected?) + end - let!(:ci_group_variable) do - create(:ci_group_variable, - group: bridge_group, - key: 'GROUP_PROTECTED_VAR', - value: 'this is a secret', - protected: is_variable_protected?) - end + let!(:ci_group_variable) do + create(:ci_group_variable, + group: bridge_group, + key: 'GROUP_PROTECTED_VAR', + value: 'this is a secret', + protected: is_variable_protected?) + end - before do - bridge.yaml_variables = yaml_variables - allow(bridge.project).to receive(:protected_for?).and_return(true) - end + before do + bridge.yaml_variables = yaml_variables + allow(bridge.project).to receive(:protected_for?).and_return(true) + end - shared_examples 'expands variables from a project downstream' do - it do - vars = bridge.downstream_variables - expect(vars).to include({ key: 'EXPANDED_PROJECT_VAR6', value: 'project value6 this is a secret' }) + shared_examples 'expands variables from a project downstream' do + it do + vars = bridge.downstream_variables + expect(vars).to include({ key: 'EXPANDED_PROJECT_VAR6', value: 'project value6 this is a secret' }) + end end - end - shared_examples 'expands variables from a group downstream' do - it do - vars = bridge.downstream_variables - expect(vars).to include({ key: 'EXPANDED_GROUP_VAR6', value: 'group value6 this is a secret' }) + shared_examples 'expands variables from a group downstream' do + it do + vars = bridge.downstream_variables + expect(vars).to include({ key: 'EXPANDED_GROUP_VAR6', value: 'group value6 this is a secret' }) + end end - end - shared_examples 'expands project and group variables downstream' do - it_behaves_like 'expands variables from a project downstream' + shared_examples 'expands project and group variables downstream' do + it_behaves_like 'expands variables from a project downstream' - it_behaves_like 'expands variables from a group downstream' - end + it_behaves_like 'expands variables from a group downstream' + end - shared_examples 'does not expand variables from a project downstream' do - it do - vars = bridge.downstream_variables - expect(vars).not_to include({ key: 'EXPANDED_PROJECT_VAR6', value: 'project value6 this is a secret' }) + shared_examples 'does not expand variables from a project downstream' do + it do + vars = bridge.downstream_variables + expect(vars).not_to include({ key: 'EXPANDED_PROJECT_VAR6', value: 'project value6 this is a secret' }) + end end - end - shared_examples 'does not expand variables from a group downstream' do - it do - vars = bridge.downstream_variables - expect(vars).not_to include({ key: 'EXPANDED_GROUP_VAR6', value: 'group value6 this is a secret' }) + shared_examples 'does not expand variables from a group downstream' do + it do + vars = bridge.downstream_variables + expect(vars).not_to include({ key: 'EXPANDED_GROUP_VAR6', value: 'group value6 this is a secret' }) + end + end + + shared_examples 'feature flag is disabled' do + before do + stub_feature_flags(exclude_protected_variables_from_multi_project_pipeline_triggers: false) + end + + it_behaves_like 'expands project and group variables downstream' end - end - shared_examples 'feature flag is disabled' do - before do - stub_feature_flags(exclude_protected_variables_from_multi_project_pipeline_triggers: false) + shared_examples 'does not expand project and group variables downstream' do + it_behaves_like 'does not expand variables from a project downstream' + + it_behaves_like 'does not expand variables from a group downstream' end - it_behaves_like 'expands project and group variables downstream' - end + context 'when they are protected' do + let!(:is_variable_protected?) { true } - shared_examples 'does not expand project and group variables downstream' do - it_behaves_like 'does not expand variables from a project downstream' + context 'and downstream project group is different from bridge group' do + it_behaves_like 'does not expand project and group variables downstream' - it_behaves_like 'does not expand variables from a group downstream' - end + it_behaves_like 'feature flag is disabled' + end - context 'when they are protected' do - let!(:is_variable_protected?) { true } + context 'and there is no downstream project' do + let(:downstream_project) { nil } - context 'and downstream project group is different from bridge group' do - it_behaves_like 'does not expand project and group variables downstream' + it_behaves_like 'expands project and group variables downstream' - it_behaves_like 'feature flag is disabled' - end + it_behaves_like 'feature flag is disabled' + end - context 'and there is no downstream project' do - let(:downstream_project) { nil } + context 'and downstream project equals bridge project' do + let(:downstream_project) { project } - it_behaves_like 'expands project and group variables downstream' + it_behaves_like 'expands project and group variables downstream' - it_behaves_like 'feature flag is disabled' - end + it_behaves_like 'feature flag is disabled' + end - context 'and downstream project equals bridge project' do - let(:downstream_project) { project } + context 'and downstream project group is equal to bridge project group' do + let_it_be(:downstream_project) { create(:project, creator: downstream_creator_user, group: bridge_group) } - it_behaves_like 'expands project and group variables downstream' + it_behaves_like 'expands variables from a group downstream' - it_behaves_like 'feature flag is disabled' - end + it_behaves_like 'does not expand variables from a project downstream' - context 'and downstream project group is equal to bridge project group' do - let_it_be(:downstream_project) { create(:project, creator: downstream_creator_user, group: bridge_group) } + it_behaves_like 'feature flag is disabled' + end - it_behaves_like 'expands variables from a group downstream' + context 'and downstream project has no group' do + let_it_be(:downstream_project) { create(:project, creator: downstream_creator_user) } - it_behaves_like 'does not expand variables from a project downstream' + it_behaves_like 'does not expand project and group variables downstream' - it_behaves_like 'feature flag is disabled' + it_behaves_like 'feature flag is disabled' + end end - context 'and downstream project has no group' do - let_it_be(:downstream_project) { create(:project, creator: downstream_creator_user) } + context 'when they are not protected' do + let!(:is_variable_protected?) { false } - it_behaves_like 'does not expand project and group variables downstream' + context 'and downstream project group is different from bridge group' do + it_behaves_like 'expands project and group variables downstream' - it_behaves_like 'feature flag is disabled' - end - end + it_behaves_like 'feature flag is disabled' + end - context 'when they are not protected' do - let!(:is_variable_protected?) { false } + context 'and there is no downstream project' do + let(:downstream_project) { nil } - context 'and downstream project group is different from bridge group' do - it_behaves_like 'expands project and group variables downstream' + it_behaves_like 'expands project and group variables downstream' - it_behaves_like 'feature flag is disabled' - end + it_behaves_like 'feature flag is disabled' + end - context 'and there is no downstream project' do - let(:downstream_project) { nil } + context 'and downstream project equals bridge project' do + let(:downstream_project) { project } - it_behaves_like 'expands project and group variables downstream' + it_behaves_like 'expands project and group variables downstream' - it_behaves_like 'feature flag is disabled' - end + it_behaves_like 'feature flag is disabled' + end - context 'and downstream project equals bridge project' do - let(:downstream_project) { project } + context 'and downstream project group is equal to bridge project group' do + let_it_be(:downstream_project) { create(:project, creator: downstream_creator_user, group: bridge_group) } - it_behaves_like 'expands project and group variables downstream' + it_behaves_like 'expands project and group variables downstream' - it_behaves_like 'feature flag is disabled' + it_behaves_like 'feature flag is disabled' + end + + context 'and downstream project has no group' do + let_it_be(:downstream_project) { create(:project, creator: downstream_creator_user) } + + it_behaves_like 'expands project and group variables downstream' + + it_behaves_like 'feature flag is disabled' + end end + end + end + + describe '#variables' do + it 'returns bridge scoped variables and pipeline persisted variables' do + expect(bridge.variables.to_hash) + .to eq(bridge.scoped_variables.concat(bridge.pipeline.persisted_variables).to_hash) + end + end - context 'and downstream project group is equal to bridge project group' do - let_it_be(:downstream_project) { create(:project, creator: downstream_creator_user, group: bridge_group) } + describe '#pipeline_variables' do + it 'returns the pipeline variables' do + expect(bridge.pipeline_variables).to eq(bridge.pipeline.variables) + end + end - it_behaves_like 'expands project and group variables downstream' + describe '#pipeline_schedule_variables' do + context 'when pipeline is on a schedule' do + let(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project) } + let(:pipeline) { create(:ci_pipeline, pipeline_schedule: pipeline_schedule) } - it_behaves_like 'feature flag is disabled' + it 'returns the pipeline schedule variables' do + create(:ci_pipeline_schedule_variable, key: 'FOO', value: 'foo', pipeline_schedule: pipeline.pipeline_schedule) + + pipeline_schedule_variables = bridge.reload.pipeline_schedule_variables + expect(pipeline_schedule_variables).to match_array([have_attributes({ key: 'FOO', value: 'foo' })]) + end + end + + context 'when pipeline is not on a schedule' do + it 'returns empty array' do + expect(bridge.pipeline_schedule_variables).to eq([]) end + end + end - context 'and downstream project has no group' do - let_it_be(:downstream_project) { create(:project, creator: downstream_creator_user) } + describe '#forward_yaml_variables?' do + using RSpec::Parameterized::TableSyntax - it_behaves_like 'expands project and group variables downstream' + where(:forward, :result) do + true | true + false | false + nil | true + end - it_behaves_like 'feature flag is disabled' + with_them do + let(:options) do + { + trigger: { + project: 'my/project', + branch: 'master', + forward: { yaml_variables: forward }.compact + } + } end + + let(:bridge) { build(:ci_bridge, options: options) } + + it { expect(bridge.forward_yaml_variables?).to eq(result) } end end diff --git a/spec/services/reset_project_cache_service_spec.rb b/spec/services/reset_project_cache_service_spec.rb index 6540b93bcc5..c8d99eca4b5 100644 --- a/spec/services/reset_project_cache_service_spec.rb +++ b/spec/services/reset_project_cache_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe ResetProjectCacheService, feature_category: :groups_and_projects do +RSpec.describe ResetProjectCacheService, feature_category: :continuous_integration do let(:project) { create(:project) } let(:user) { create(:user) } diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index d67eaf6920c..d4f7cbd8e0c 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -5315,7 +5315,6 @@ - './spec/lib/gitlab/auth/unique_ips_limiter_spec.rb' - './spec/lib/gitlab/auth/user_access_denied_reason_spec.rb' - './spec/lib/gitlab/avatar_cache_spec.rb' -- './spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb' - './spec/lib/gitlab/background_migration/backfill_integrations_enable_ssl_verification_spec.rb' - './spec/lib/gitlab/background_migration/backfill_namespace_id_of_vulnerability_reads_spec.rb' - './spec/lib/gitlab/background_migration/backfill_note_discussion_id_spec.rb' @@ -5325,7 +5324,6 @@ - './spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb' - './spec/lib/gitlab/background_migration/backfill_topics_title_spec.rb' - './spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb' -- './spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb' - './spec/lib/gitlab/background_migration/base_job_spec.rb' - './spec/lib/gitlab/background_migration/batched_migration_job_spec.rb' - './spec/lib/gitlab/background_migration/batching_strategies/backfill_project_statistics_with_container_registry_size_batching_strategy_spec.rb' @@ -5336,9 +5334,7 @@ - './spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb' - './spec/lib/gitlab/background_migration/disable_legacy_open_source_licence_for_recent_public_projects_spec.rb' - './spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_inactive_public_projects_spec.rb' -- './spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb' - './spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb' -- './spec/lib/gitlab/background_migration/expire_o_auth_tokens_spec.rb' - './spec/lib/gitlab/background_migration/job_coordinator_spec.rb' - './spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb' - './spec/lib/gitlab/background_migration/legacy_uploads_migrator_spec.rb' diff --git a/spec/support/shared_examples/features/variable_list_drawer_shared_examples.rb b/spec/support/shared_examples/features/variable_list_drawer_shared_examples.rb index 1fb4c42ee16..5bc137a5f00 100644 --- a/spec/support/shared_examples/features/variable_list_drawer_shared_examples.rb +++ b/spec/support/shared_examples/features/variable_list_drawer_shared_examples.rb @@ -10,13 +10,14 @@ RSpec.shared_examples 'variable list drawer' do it 'adds a new CI variable' do open_drawer - fill_variable('NEW_KEY', 'NEW_VALUE') + fill_variable('NEW_KEY', 'NEW_VALUE', 'NEW_DESCRIPTION') click_add_variable wait_for_requests page.within('[data-testid="ci-variable-table"]') do expect(first(".js-ci-variable-row td[data-label='#{s_('CiVariables|Key')}']")).to have_content('NEW_KEY') + expect(first(".js-ci-variable-row td[data-label='#{s_('CiVariables|Key')}']")).to have_content('NEW_DESCRIPTION') click_button('Reveal values') @@ -95,7 +96,7 @@ RSpec.shared_examples 'variable list drawer' do click_button('Edit') - fill_variable('EDITED_KEY', 'EDITED_VALUE') + fill_variable('EDITED_KEY', 'EDITED_VALUE', 'EDITED_DESCRIPTION') toggle_protected toggle_masked toggle_expanded @@ -105,6 +106,7 @@ RSpec.shared_examples 'variable list drawer' do page.within('[data-testid="ci-variable-table"]') do expect(key_column).to have_content('EDITED_KEY') + expect(key_column).to have_content('EDITED_DESCRIPTION') expect(key_column).to have_content(s_('CiVariables|Protected')) expect(key_column).not_to have_content(s_('CiVariables|Masked')) expect(key_column).not_to have_content(s_('CiVariables|Expanded')) @@ -211,12 +213,13 @@ RSpec.shared_examples 'variable list drawer' do end end - def fill_variable(key, value = '') + def fill_variable(key, value = '', description = '') wait_for_requests page.within('[data-testid="ci-variable-drawer"]') do find('[data-testid="ci-variable-key"] input').set(key) find('[data-testid="ci-variable-value"]').set(value) if value.present? + find('[data-testid="ci-variable-description"]').set(description) if description.present? end end |