diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-05 12:08:29 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-05 12:08:29 +0300 |
commit | dea522994156f9d427b1acc0a22b0e75ffe92c68 (patch) | |
tree | f1496d9c2151bf1096ef8c4234a2698d51eb24c6 /spec | |
parent | dfebbcd6b1e2fc7584d9cca1b982f5f12bd648cb (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
6 files changed, 451 insertions, 26 deletions
diff --git a/spec/fixtures/achievements.yml b/spec/fixtures/achievements.yml new file mode 100644 index 00000000000..a24cf42413b --- /dev/null +++ b/spec/fixtures/achievements.yml @@ -0,0 +1,10 @@ +--- +table_name: achievements +classes: +- Achievements::Achievement +feature_categories: +- feature_category_example +description: Achievements which can be created by namespaces to award them to users +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/105871 +milestone: '15.7' +gitlab_schema: gitlab_main diff --git a/spec/frontend/pipelines/graph/job_item_spec.js b/spec/frontend/pipelines/graph/job_item_spec.js index 2a5dfd7e0ee..8a8b0e9aa63 100644 --- a/spec/frontend/pipelines/graph/job_item_spec.js +++ b/spec/frontend/pipelines/graph/job_item_spec.js @@ -1,5 +1,4 @@ import MockAdapter from 'axios-mock-adapter'; -import { shallowMount, mount } from '@vue/test-utils'; import Vue, { nextTick } from 'vue'; import { GlBadge, GlModal, GlToast } from '@gitlab/ui'; import JobItem from '~/pipelines/components/graph/job_item.vue'; @@ -7,7 +6,7 @@ import axios from '~/lib/utils/axios_utils'; import { useLocalStorageSpy } from 'helpers/local_storage_helper'; import ActionComponent from '~/pipelines/components/jobs_shared/action_component.vue'; -import { extendedWrapper } from 'helpers/vue_test_utils_helper'; +import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { delayedJob, mockJob, @@ -44,23 +43,21 @@ describe('pipeline graph job item', () => { job: mockJob, }; - const createWrapper = ({ props, data, mountFn = mount, mocks = {} } = {}) => { - wrapper = extendedWrapper( - mountFn(JobItem, { - data() { - return { - ...data, - }; - }, - propsData: { - ...defaultProps, - ...props, - }, - mocks: { - ...mocks, - }, - }), - ); + const createWrapper = ({ props, data, mountFn = mountExtended, mocks = {} } = {}) => { + wrapper = mountFn(JobItem, { + data() { + return { + ...data, + }; + }, + propsData: { + ...defaultProps, + ...props, + }, + mocks: { + ...mocks, + }, + }); }; const triggerActiveClass = 'gl-shadow-x0-y0-b3-s1-blue-500'; @@ -219,7 +216,7 @@ describe('pipeline graph job item', () => { }); expect(findJobWithLink().attributes('title')).toBe( - `delayed job - delayed manual action (${wrapper.vm.remainingTime})`, + `delayed job - delayed manual action (00:00:00)`, ); }); }); @@ -249,10 +246,7 @@ describe('pipeline graph job item', () => { beforeEach(async () => { createWrapper({ - mountFn: shallowMount, - data: { - currentSkipModalValue: true, - }, + mountFn: shallowMountExtended, props: { skipRetryModal: true, job: triggerJobWithRetryAction, @@ -264,8 +258,6 @@ describe('pipeline graph job item', () => { }, }); - jest.spyOn(wrapper.vm.$toast, 'show'); - await findActionVueComponent().vm.$emit('pipelineActionRequestComplete'); await nextTick(); }); diff --git a/spec/lib/gitlab/background_migration/backfill_root_storage_statistics_fork_storage_sizes_spec.rb b/spec/lib/gitlab/background_migration/backfill_root_storage_statistics_fork_storage_sizes_spec.rb new file mode 100644 index 00000000000..a464f89ee69 --- /dev/null +++ b/spec/lib/gitlab/background_migration/backfill_root_storage_statistics_fork_storage_sizes_spec.rb @@ -0,0 +1,302 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::BackgroundMigration::BackfillRootStorageStatisticsForkStorageSizes, schema: 20230517163300, feature_category: :consumables_cost_management do # rubocop:disable Layout/LineLength + describe '#perform' do + let(:namespaces_table) { table(:namespaces) } + let(:root_storage_statistics_table) { table(:namespace_root_storage_statistics) } + let(:projects_table) { table(:projects) } + let(:project_statistics_table) { table(:project_statistics) } + let(:fork_networks_table) { table(:fork_networks) } + let(:fork_network_members_table) { table(:fork_network_members) } + + it 'updates the public_forks_storage_size' do + namespace, root_storage_statistics = create_namespace! + project = create_project!(namespace: namespace, visibility_level: Gitlab::VisibilityLevel::PUBLIC) + create_fork!(project, storage_size: 100) + + migrate + + expect(root_storage_statistics.reload.public_forks_storage_size).to eq(100) + end + + it 'totals the size of public forks in the namespace' do + namespace, root_storage_statistics = create_namespace! + project = create_project!(namespace: namespace, visibility_level: Gitlab::VisibilityLevel::PUBLIC) + create_fork!(project, name: 'my fork', storage_size: 100) + create_fork!(project, name: 'my other fork', storage_size: 100) + + migrate + + expect(root_storage_statistics.reload.public_forks_storage_size).to eq(200) + end + + it 'updates the internal_forks_storage_size' do + namespace, root_storage_statistics = create_namespace! + project = create_project!(namespace: namespace, visibility_level: Gitlab::VisibilityLevel::INTERNAL) + create_fork!(project, storage_size: 250) + + migrate + + expect(root_storage_statistics.reload.internal_forks_storage_size).to eq(250) + end + + it 'totals the size of internal forks in the namespace' do + namespace, root_storage_statistics = create_namespace! + project = create_project!(namespace: namespace, visibility_level: Gitlab::VisibilityLevel::INTERNAL) + create_fork!(project, name: 'my fork', storage_size: 300) + create_fork!(project, name: 'my other fork', storage_size: 300) + + migrate + + expect(root_storage_statistics.reload.internal_forks_storage_size).to eq(600) + end + + it 'updates the private_forks_storage_size' do + namespace, root_storage_statistics = create_namespace! + project = create_project!(namespace: namespace, visibility_level: Gitlab::VisibilityLevel::PRIVATE) + create_fork!(project, storage_size: 50) + + migrate + + expect(root_storage_statistics.reload.private_forks_storage_size).to eq(50) + end + + it 'totals the size of private forks in the namespace' do + namespace, root_storage_statistics = create_namespace! + project = create_project!(namespace: namespace, visibility_level: Gitlab::VisibilityLevel::PRIVATE) + create_fork!(project, name: 'my fork', storage_size: 350) + create_fork!(project, name: 'my other fork', storage_size: 400) + + migrate + + expect(root_storage_statistics.reload.private_forks_storage_size).to eq(750) + end + + it 'counts only the size of forks' do + namespace, root_storage_statistics = create_namespace! + project = create_project!(namespace: namespace, storage_size: 100, + visibility_level: Gitlab::VisibilityLevel::PUBLIC) + create_fork!(project, name: 'my public fork', storage_size: 150, + visibility_level: Gitlab::VisibilityLevel::PUBLIC) + create_fork!(project, name: 'my internal fork', storage_size: 250, + visibility_level: Gitlab::VisibilityLevel::INTERNAL) + create_fork!(project, name: 'my private fork', storage_size: 350, + visibility_level: Gitlab::VisibilityLevel::PRIVATE) + + migrate + + root_storage_statistics.reload + expect(root_storage_statistics.public_forks_storage_size).to eq(150) + expect(root_storage_statistics.internal_forks_storage_size).to eq(250) + expect(root_storage_statistics.private_forks_storage_size).to eq(350) + end + + it 'sums forks for multiple namespaces' do + namespace_a, root_storage_statistics_a = create_namespace! + namespace_b, root_storage_statistics_b = create_namespace! + project = create_project!(namespace: namespace_a) + create_fork!(project, namespace: namespace_a, storage_size: 100) + create_fork!(project, namespace: namespace_b, storage_size: 200) + + migrate + + expect(root_storage_statistics_a.reload.private_forks_storage_size).to eq(100) + expect(root_storage_statistics_b.reload.private_forks_storage_size).to eq(200) + end + + it 'counts the size of forks in subgroups' do + group, root_storage_statistics = create_group! + subgroup = create_group!(parent: group) + project = create_project!(namespace: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) + create_fork!(project, namespace: subgroup, name: 'my fork A', + storage_size: 123, visibility_level: Gitlab::VisibilityLevel::PUBLIC) + create_fork!(project, namespace: subgroup, name: 'my fork B', + storage_size: 456, visibility_level: Gitlab::VisibilityLevel::INTERNAL) + create_fork!(project, namespace: subgroup, name: 'my fork C', + storage_size: 789, visibility_level: Gitlab::VisibilityLevel::PRIVATE) + + migrate + + root_storage_statistics.reload + expect(root_storage_statistics.public_forks_storage_size).to eq(123) + expect(root_storage_statistics.internal_forks_storage_size).to eq(456) + expect(root_storage_statistics.private_forks_storage_size).to eq(789) + end + + it 'counts the size of forks in more nested subgroups' do + root, root_storage_statistics = create_group! + child = create_group!(parent: root) + grand_child = create_group!(parent: child) + great_grand_child = create_group!(parent: grand_child) + project = create_project!(namespace: root, visibility_level: Gitlab::VisibilityLevel::PUBLIC) + create_fork!(project, namespace: grand_child, name: 'my fork A', + storage_size: 200, visibility_level: Gitlab::VisibilityLevel::PUBLIC) + create_fork!(project, namespace: great_grand_child, name: 'my fork B', + storage_size: 300, visibility_level: Gitlab::VisibilityLevel::INTERNAL) + create_fork!(project, namespace: great_grand_child, name: 'my fork C', + storage_size: 400, visibility_level: Gitlab::VisibilityLevel::PRIVATE) + + migrate + + root_storage_statistics.reload + expect(root_storage_statistics.public_forks_storage_size).to eq(200) + expect(root_storage_statistics.internal_forks_storage_size).to eq(300) + expect(root_storage_statistics.private_forks_storage_size).to eq(400) + end + + it 'counts forks of forks' do + group, root_storage_statistics = create_group! + other_group, other_root_storage_statistics = create_group! + project = create_project!(namespace: group) + fork_a = create_fork!(project, namespace: group, storage_size: 100) + fork_b = create_fork!(fork_a, name: 'my other fork', namespace: group, storage_size: 50) + create_fork!(fork_b, namespace: other_group, storage_size: 27) + + migrate + + expect(root_storage_statistics.reload.private_forks_storage_size).to eq(150) + expect(other_root_storage_statistics.reload.private_forks_storage_size).to eq(27) + end + + it 'counts multiple forks of the same project' do + group, root_storage_statistics = create_group! + project = create_project!(namespace: group) + create_fork!(project, storage_size: 200) + create_fork!(project, name: 'my other fork', storage_size: 88) + + migrate + + expect(root_storage_statistics.reload.private_forks_storage_size).to eq(288) + end + + it 'updates a namespace with no forks' do + namespace, root_storage_statistics = create_namespace! + create_project!(namespace: namespace) + + migrate + + root_storage_statistics.reload + expect(root_storage_statistics.public_forks_storage_size).to eq(0) + expect(root_storage_statistics.internal_forks_storage_size).to eq(0) + expect(root_storage_statistics.private_forks_storage_size).to eq(0) + end + + it 'skips the update if the public_forks_storage_size has already been set' do + namespace, root_storage_statistics = create_namespace! + project = create_project!(namespace: namespace, visibility_level: Gitlab::VisibilityLevel::PUBLIC) + create_fork!(project, storage_size: 200) + root_storage_statistics.update!(public_forks_storage_size: 100) + + migrate + + root_storage_statistics.reload + expect(root_storage_statistics.public_forks_storage_size).to eq(100) + end + + it 'skips the update if the internal_forks_storage_size has already been set' do + namespace, root_storage_statistics = create_namespace! + project = create_project!(namespace: namespace, visibility_level: Gitlab::VisibilityLevel::INTERNAL) + create_fork!(project, storage_size: 200) + root_storage_statistics.update!(internal_forks_storage_size: 100) + + migrate + + root_storage_statistics.reload + expect(root_storage_statistics.internal_forks_storage_size).to eq(100) + end + + it 'skips the update if the private_forks_storage_size has already been set' do + namespace, root_storage_statistics = create_namespace! + project = create_project!(namespace: namespace, visibility_level: Gitlab::VisibilityLevel::PRIVATE) + create_fork!(project, storage_size: 200) + root_storage_statistics.update!(private_forks_storage_size: 100) + + migrate + + root_storage_statistics.reload + expect(root_storage_statistics.private_forks_storage_size).to eq(100) + end + + it 'skips the update if the namespace is not found' do + namespace, root_storage_statistics = create_namespace! + project = create_project!(namespace: namespace) + create_fork!(project, storage_size: 100) + allow(::ApplicationRecord.connection).to receive(:execute) + .with("SELECT type FROM namespaces WHERE id = #{namespace.id}") + .and_return([]) + + migrate + + root_storage_statistics.reload + expect(root_storage_statistics.public_forks_storage_size).to eq(0) + expect(root_storage_statistics.internal_forks_storage_size).to eq(0) + expect(root_storage_statistics.private_forks_storage_size).to eq(0) + end + end + + def create_namespace!(name: 'abc', path: 'abc') + namespace = namespaces_table.create!(name: name, path: path) + namespace.update!(traversal_ids: [namespace.id]) + root_storage_statistics = root_storage_statistics_table.create!(namespace_id: namespace.id) + + [namespace, root_storage_statistics] + end + + def create_group!(name: 'abc', path: 'abc', parent: nil) + parent_id = parent.try(:id) + group = namespaces_table.create!(name: name, path: path, type: 'Group', parent_id: parent_id) + + if parent_id + parent_traversal_ids = namespaces_table.find(parent_id).traversal_ids + group.update!(traversal_ids: parent_traversal_ids + [group.id]) + group + else + group.update!(traversal_ids: [group.id]) + root_storage_statistics = root_storage_statistics_table.create!(namespace_id: group.id) + [group, root_storage_statistics] + end + end + + def create_project!( + namespace:, storage_size: 100, name: 'my project', + visibility_level: Gitlab::VisibilityLevel::PRIVATE) + project_namespace = namespaces_table.create!(name: name, path: name) + project = projects_table.create!(name: name, namespace_id: namespace.id, project_namespace_id: project_namespace.id, + visibility_level: visibility_level) + project_statistics_table.create!(project_id: project.id, namespace_id: project.namespace_id, + storage_size: storage_size) + + project + end + + def create_fork!(project, storage_size:, name: 'my fork', visibility_level: nil, namespace: nil) + fork_namespace = namespace || namespaces_table.find(project.namespace_id) + fork_visibility_level = visibility_level || project.visibility_level + + project_fork = create_project!(name: name, namespace: fork_namespace, + visibility_level: fork_visibility_level, storage_size: storage_size) + + fork_network_id = if membership = fork_network_members_table.find_by(project_id: project.id) + membership.fork_network_id + else + fork_network = fork_networks_table.create!(root_project_id: project.id) + fork_network_members_table.create!(fork_network_id: fork_network.id, project_id: project.id) + fork_network.id + end + + fork_network_members_table.create!(fork_network_id: fork_network_id, project_id: project_fork.id, + forked_from_project_id: project.id) + + project_fork + end + + def migrate + described_class.new(start_id: 1, end_id: root_storage_statistics_table.last.id, + batch_table: 'namespace_root_storage_statistics', + batch_column: 'namespace_id', + sub_batch_size: 100, pause_ms: 0, + connection: ApplicationRecord.connection).perform + end +end diff --git a/spec/lib/gitlab/database/convert_feature_category_to_group_label_spec.rb b/spec/lib/gitlab/database/convert_feature_category_to_group_label_spec.rb new file mode 100644 index 00000000000..32766b0d937 --- /dev/null +++ b/spec/lib/gitlab/database/convert_feature_category_to_group_label_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Database::ConvertFeatureCategoryToGroupLabel, feature_category: :database do + describe '#execute' do + subject(:group_label) { described_class.new(feature_category).execute } + + let_it_be(:stages_fixture) do + { stages: { manage: { groups: { database: { categories: ['database'] } } } } } + end + + before do + stub_request(:get, 'https://gitlab.com/gitlab-com/www-gitlab-com/-/raw/master/data/stages.yml') + .to_return(status: 200, body: stages_fixture.to_json, headers: {}) + end + + context 'when the group label exists' do + let(:feature_category) { 'database' } + + it 'returns a group label' do + expect(group_label).to eql 'group::database' + end + end + + context 'when the group label does not exist' do + let(:feature_category) { 'non_existing_feature_category_test' } + + it 'returns nil' do + expect(group_label).to be nil + end + end + end +end diff --git a/spec/lib/gitlab/database/schema_validation/track_inconsistency_spec.rb b/spec/lib/gitlab/database/schema_validation/track_inconsistency_spec.rb index 8348ad9a1bc..315e687b8ae 100644 --- a/spec/lib/gitlab/database/schema_validation/track_inconsistency_spec.rb +++ b/spec/lib/gitlab/database/schema_validation/track_inconsistency_spec.rb @@ -39,7 +39,12 @@ RSpec.describe Gitlab::Database::SchemaValidation::TrackInconsistency, feature_c context 'when the issue creation fails' do let(:issue_creation) { instance_double(Mutations::Issues::Create, resolve: { errors: 'error' }) } + let(:convert_object) do + instance_double('Gitlab::Database::ConvertFeatureCategoryToGroupLabel', execute: 'group_label') + end + before do + allow(Gitlab::Database::ConvertFeatureCategoryToGroupLabel).to receive(:new).and_return(convert_object) allow(Mutations::Issues::Create).to receive(:new).and_return(issue_creation) end @@ -51,7 +56,12 @@ RSpec.describe Gitlab::Database::SchemaValidation::TrackInconsistency, feature_c end context 'when a new inconsistency is found' do + let(:convert_object) do + instance_double('Gitlab::Database::ConvertFeatureCategoryToGroupLabel', execute: 'group_label') + end + before do + allow(Gitlab::Database::ConvertFeatureCategoryToGroupLabel).to receive(:new).and_return(convert_object) project.add_developer(user) end @@ -116,6 +126,15 @@ RSpec.describe Gitlab::Database::SchemaValidation::TrackInconsistency, feature_c end context 'when the GitLab is not open' do + let(:convert_object) do + instance_double('Gitlab::Database::ConvertFeatureCategoryToGroupLabel', execute: 'group_label') + end + + before do + allow(Gitlab::Database::ConvertFeatureCategoryToGroupLabel).to receive(:new).and_return(convert_object) + project.add_developer(user) + end + it 'creates a new schema inconsistency record' do allow(Gitlab).to receive(:com?).and_return(true) schema_inconsistency.issue.update!(state_id: Issue.available_states[:closed]) @@ -124,5 +143,47 @@ RSpec.describe Gitlab::Database::SchemaValidation::TrackInconsistency, feature_c end end end + + context 'when the dictionary file is not present' do + before do + allow(Gitlab::Database::GitlabSchema).to receive(:dictionary_paths).and_return(['dictionary_not_found_path/']) + + project.add_developer(user) + end + + it 'add the default labels' do + allow(Gitlab).to receive(:com?).and_return(true) + + inconsistency = execute + + labels = inconsistency.issue.labels.map(&:name) + + expect(labels).to eq %w[database database-inconsistency-report type::maintenance severity::4] + end + end + + context 'when dictionary feature_categories are available' do + let(:convert_object) do + instance_double('Gitlab::Database::ConvertFeatureCategoryToGroupLabel', execute: 'group_label') + end + + before do + allow(Gitlab::Database::ConvertFeatureCategoryToGroupLabel).to receive(:new).and_return(convert_object) + + allow(Gitlab::Database::GitlabSchema).to receive(:dictionary_paths).and_return(['spec/fixtures/']) + + project.add_developer(user) + end + + it 'add the default labels + group labels' do + allow(Gitlab).to receive(:com?).and_return(true) + + inconsistency = execute + + labels = inconsistency.issue.labels.map(&:name) + + expect(labels).to eq %w[database database-inconsistency-report type::maintenance severity::4 group_label] + end + end end end diff --git a/spec/migrations/20230517163300_queue_backfill_root_storage_statistics_fork_storage_sizes_spec.rb b/spec/migrations/20230517163300_queue_backfill_root_storage_statistics_fork_storage_sizes_spec.rb new file mode 100644 index 00000000000..f7052020005 --- /dev/null +++ b/spec/migrations/20230517163300_queue_backfill_root_storage_statistics_fork_storage_sizes_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe QueueBackfillRootStorageStatisticsForkStorageSizes, feature_category: :consumables_cost_management 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: :namespace_root_storage_statistics, + column_name: :namespace_id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + } + end + end +end |