Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-10-03 21:08:19 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-10-03 21:08:19 +0300
commitd83bbccfcd07ddab93be73959e3b149b75831e28 (patch)
treed8156497696dd1951f6556307cb3689952933eed /spec
parenta99d0fa6922be88307b1c80330a257c55c5d8270 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/groups/runners_controller_spec.rb89
-rw-r--r--spec/factories/ci/build_metadata.rb4
-rw-r--r--spec/factories/ci/builds.rb26
-rw-r--r--spec/factories/ci/pipelines.rb2
-rw-r--r--spec/features/milestones/user_creates_milestone_spec.rb99
-rw-r--r--spec/frontend/flash_spec.js7
-rw-r--r--spec/graphql/types/branch_rule_type_spec.rb1
-rw-r--r--spec/lib/gitlab/background_migration/update_ci_pipeline_artifacts_unknown_locked_status_spec.rb62
-rw-r--r--spec/migrations/20220928225711_schedule_update_ci_pipeline_artifacts_locked_status_spec.rb31
-rw-r--r--spec/models/ci/build_metadata_spec.rb57
-rw-r--r--spec/models/ci/build_spec.rb8
-rw-r--r--spec/models/ci/pipeline_spec.rb2
-rw-r--r--spec/models/concerns/ci/partitionable_spec.rb26
-rw-r--r--spec/models/protected_branch_spec.rb24
-rw-r--r--spec/requests/api/graphql/project/branch_rules_spec.rb68
-rw-r--r--spec/services/ci/job_artifacts/create_service_spec.rb3
-rw-r--r--spec/services/packages/rpm/repository_metadata/build_repomd_xml_spec.rb20
-rw-r--r--spec/support/models/partitionable_check.rb46
-rw-r--r--spec/views/registrations/welcome/show.html.haml_spec.rb1
19 files changed, 484 insertions, 92 deletions
diff --git a/spec/controllers/groups/runners_controller_spec.rb b/spec/controllers/groups/runners_controller_spec.rb
index 77c62c0d930..1da868c6c4b 100644
--- a/spec/controllers/groups/runners_controller_spec.rb
+++ b/spec/controllers/groups/runners_controller_spec.rb
@@ -8,9 +8,11 @@ RSpec.describe Groups::RunnersController do
let_it_be(:project) { create(:project, group: group) }
let!(:runner) { create(:ci_runner, :group, groups: [group]) }
- let!(:runner_project) { create(:ci_runner, :project, projects: [project]) }
+ let!(:project_runner) { create(:ci_runner, :project, projects: [project]) }
+ let!(:instance_runner) { create(:ci_runner, :instance) }
- let(:params_runner_project) { { group_id: group, id: runner_project } }
+ let(:params_runner_project) { { group_id: group, id: project_runner } }
+ let(:params_runner_instance) { { group_id: group, id: instance_runner } }
let(:params) { { group_id: group, id: runner } }
before do
@@ -70,8 +72,33 @@ RSpec.describe Groups::RunnersController do
expect(response).to render_template(:show)
end
+ context 'when runners_finder_all_available is enabled' do
+ before do
+ stub_feature_flags(runners_finder_all_available: true)
+ end
+
+ it 'renders show with 200 status code instance runner' do
+ get :show, params: { group_id: group, id: instance_runner }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to render_template(:show)
+ end
+ end
+
+ context 'when runners_finder_all_available is disabled' do
+ before do
+ stub_feature_flags(runners_finder_all_available: false)
+ end
+
+ it 'renders show with a 404 instance runner' do
+ get :show, params: { group_id: group, id: instance_runner }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
it 'renders show with 200 status code project runner' do
- get :show, params: { group_id: group, id: runner_project }
+ get :show, params: { group_id: group, id: project_runner }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:show)
@@ -89,8 +116,14 @@ RSpec.describe Groups::RunnersController do
expect(response).to have_gitlab_http_status(:not_found)
end
+ it 'renders a 404 instance runner' do
+ get :show, params: { group_id: group, id: instance_runner }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
it 'renders a 404 project runner' do
- get :show, params: { group_id: group, id: runner_project }
+ get :show, params: { group_id: group, id: project_runner }
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -103,15 +136,21 @@ RSpec.describe Groups::RunnersController do
group.add_owner(user)
end
- it 'renders show with 200 status code' do
+ it 'renders edit with 200 status code' do
get :edit, params: { group_id: group, id: runner }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:edit)
end
- it 'renders show with 200 status code project runner' do
- get :edit, params: { group_id: group, id: runner_project }
+ it 'renders a 404 instance runner' do
+ get :edit, params: { group_id: group, id: instance_runner }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ it 'renders edit with 200 status code project runner' do
+ get :edit, params: { group_id: group, id: project_runner }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:edit)
@@ -130,7 +169,7 @@ RSpec.describe Groups::RunnersController do
end
it 'renders a 404 project runner' do
- get :edit, params: { group_id: group, id: runner_project }
+ get :edit, params: { group_id: group, id: project_runner }
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -154,15 +193,26 @@ RSpec.describe Groups::RunnersController do
expect(runner.reload.description).to eq(new_desc)
end
+ it 'does not update the instance runner' do
+ new_desc = instance_runner.description.swapcase
+
+ expect do
+ post :update, params: params_runner_instance.merge(runner: { description: new_desc } )
+ end.to not_change { instance_runner.ensure_runner_queue_value }
+ .and not_change { instance_runner.description }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
it 'updates the project runner, ticks the queue, and redirects project runner' do
- new_desc = runner_project.description.swapcase
+ new_desc = project_runner.description.swapcase
expect do
post :update, params: params_runner_project.merge(runner: { description: new_desc } )
- end.to change { runner_project.ensure_runner_queue_value }
+ end.to change { project_runner.ensure_runner_queue_value }
expect(response).to have_gitlab_http_status(:found)
- expect(runner_project.reload.description).to eq(new_desc)
+ expect(project_runner.reload.description).to eq(new_desc)
end
end
@@ -182,15 +232,26 @@ RSpec.describe Groups::RunnersController do
expect(runner.reload.description).to eq(old_desc)
end
+ it 'rejects the update and responds 404 instance runner' do
+ old_desc = instance_runner.description
+
+ expect do
+ post :update, params: params_runner_instance.merge(runner: { description: old_desc.swapcase } )
+ end.not_to change { instance_runner.ensure_runner_queue_value }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(instance_runner.reload.description).to eq(old_desc)
+ end
+
it 'rejects the update and responds 404 project runner' do
- old_desc = runner_project.description
+ old_desc = project_runner.description
expect do
post :update, params: params_runner_project.merge(runner: { description: old_desc.swapcase } )
- end.not_to change { runner_project.ensure_runner_queue_value }
+ end.not_to change { project_runner.ensure_runner_queue_value }
expect(response).to have_gitlab_http_status(:not_found)
- expect(runner_project.reload.description).to eq(old_desc)
+ expect(project_runner.reload.description).to eq(old_desc)
end
end
end
diff --git a/spec/factories/ci/build_metadata.rb b/spec/factories/ci/build_metadata.rb
index cfc86c4ef4b..a0a5305ef39 100644
--- a/spec/factories/ci/build_metadata.rb
+++ b/spec/factories/ci/build_metadata.rb
@@ -3,5 +3,9 @@
FactoryBot.define do
factory :ci_build_metadata, class: 'Ci::BuildMetadata' do
build { association(:ci_build, strategy: :build, metadata: instance) }
+
+ after(:build) do |metadata|
+ metadata.build&.valid?
+ end
end
end
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index 8c2edc8cd9f..9a3b2837ab8 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -424,79 +424,79 @@ FactoryBot.define do
trait :codequality_report do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :codequality, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :codequality, job: build)
end
end
trait :sast_report do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :sast, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :sast, job: build)
end
end
trait :secret_detection_report do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :secret_detection, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :secret_detection, job: build)
end
end
trait :test_reports do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :junit, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :junit, job: build)
end
end
trait :test_reports_with_attachment do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :junit_with_attachment, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :junit_with_attachment, job: build)
end
end
trait :broken_test_reports do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :junit_with_corrupted_data, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :junit_with_corrupted_data, job: build)
end
end
trait :test_reports_with_duplicate_failed_test_names do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :junit_with_duplicate_failed_test_names, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :junit_with_duplicate_failed_test_names, job: build)
end
end
trait :test_reports_with_three_failures do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :junit_with_three_failures, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :junit_with_three_failures, job: build)
end
end
trait :accessibility_reports do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :accessibility, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :accessibility, job: build)
end
end
trait :coverage_reports do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :cobertura, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :cobertura, job: build)
end
end
trait :codequality_reports do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :codequality, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :codequality, job: build)
end
end
trait :codequality_reports_without_degradation do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :codequality_without_errors, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :codequality_without_errors, job: build)
end
end
trait :terraform_reports do
after(:build) do |build|
- build.job_artifacts << create(:ci_job_artifact, :terraform, job: build)
+ build.job_artifacts << build(:ci_job_artifact, :terraform, job: build)
end
end
diff --git a/spec/factories/ci/pipelines.rb b/spec/factories/ci/pipelines.rb
index 5b20010ef7e..650b8647237 100644
--- a/spec/factories/ci/pipelines.rb
+++ b/spec/factories/ci/pipelines.rb
@@ -8,6 +8,7 @@ FactoryBot.define do
sha { 'b83d6e391c22777fca1ed3012fce84f633d7fed0' }
status { 'pending' }
add_attribute(:protected) { false }
+ partition_id { 1234 }
project
@@ -53,6 +54,7 @@ FactoryBot.define do
end
factory :ci_pipeline do
+ partition_id { 1234 }
transient { ci_ref_presence { true } }
before(:create) do |pipeline, evaluator|
diff --git a/spec/features/milestones/user_creates_milestone_spec.rb b/spec/features/milestones/user_creates_milestone_spec.rb
index dd377aa4a26..1ab231632fb 100644
--- a/spec/features/milestones/user_creates_milestone_spec.rb
+++ b/spec/features/milestones/user_creates_milestone_spec.rb
@@ -3,29 +3,100 @@
require 'spec_helper'
RSpec.describe "User creates milestone", :js do
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:inherited_guest) { create(:user) }
+ let_it_be(:inherited_developer) { create(:user) }
+ let_it_be(:group) { create(:group, :public) }
+
+ shared_examples 'creates milestone' do
+ specify do
+ title = "v2.3"
+
+ fill_in("Title", with: title)
+ fill_in("Description", with: "# Description header")
+ click_button("Create milestone")
+
+ expect(page).to have_content(title)
+ .and have_content("Issues")
+ .and have_header_with_correct_id_and_link(1, "Description header", "description-header")
+
+ visit(activity_project_path(project))
+
+ expect(page).to have_content("#{user.name} #{user.to_reference} opened milestone")
+ end
+ end
+
+ shared_examples 'renders not found' do
+ specify do
+ expect(page).to have_title('Not Found')
+ expect(page).to have_content('Page Not Found')
+ end
+ end
+
+ before_all do
+ group.add_guest(inherited_guest)
+ group.add_developer(inherited_developer)
+ end
before do
- project.add_developer(user)
sign_in(user)
-
visit(new_project_milestone_path(project))
end
- it "creates milestone" do
- title = "v2.3"
+ context 'when project is public' do
+ let_it_be(:project) { create(:project, :public, group: group) }
+
+ context 'and issues and merge requests are private' do
+ before_all do
+ project.project_feature.update!(
+ issues_access_level: ProjectFeature::PRIVATE,
+ merge_requests_access_level: ProjectFeature::PRIVATE
+ )
+ end
+
+ context 'when user is an inherited member from the group' do
+ context 'and user is a guest' do
+ let(:user) { inherited_guest }
+
+ it_behaves_like 'renders not found'
+ end
+
+ context 'and user is a developer' do
+ let(:user) { inherited_developer }
+
+ it_behaves_like 'creates milestone'
+ end
+ end
+ end
+ end
+
+ context 'when project is private' do
+ let_it_be(:project) { create(:project, :private, group: group) }
+
+ context 'and user is a direct project member' do
+ before_all do
+ project.add_developer(developer)
+ end
+
+ context 'when user is a developer' do
+ let(:user) { developer }
+
+ it_behaves_like 'creates milestone'
+ end
+ end
- fill_in("Title", with: title)
- fill_in("Description", with: "# Description header")
- click_button("Create milestone")
+ context 'and user is an inherited member from the group' do
+ context 'when user is a guest' do
+ let(:user) { inherited_guest }
- expect(page).to have_content(title)
- .and have_content("Issues")
- .and have_header_with_correct_id_and_link(1, "Description header", "description-header")
+ it_behaves_like 'renders not found'
+ end
- visit(activity_project_path(project))
+ context 'when user is a developer' do
+ let(:user) { inherited_developer }
- expect(page).to have_content("#{user.name} #{user.to_reference} opened milestone")
+ it_behaves_like 'creates milestone'
+ end
+ end
end
end
diff --git a/spec/frontend/flash_spec.js b/spec/frontend/flash_spec.js
index e26c52f0bf7..a809bf248bf 100644
--- a/spec/frontend/flash_spec.js
+++ b/spec/frontend/flash_spec.js
@@ -285,6 +285,13 @@ describe('Flash', () => {
expect(document.querySelector('.gl-alert')).toBeNull();
});
+ it('does not crash if calling .dismiss() twice', () => {
+ alert = createAlert({ message: mockMessage });
+
+ alert.dismiss();
+ expect(() => alert.dismiss()).not.toThrow();
+ });
+
it('calls onDismiss when dismissed', () => {
const dismissHandler = jest.fn();
diff --git a/spec/graphql/types/branch_rule_type_spec.rb b/spec/graphql/types/branch_rule_type_spec.rb
index 277901f00bf..12a2c8dfe12 100644
--- a/spec/graphql/types/branch_rule_type_spec.rb
+++ b/spec/graphql/types/branch_rule_type_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe GitlabSchema.types['BranchRule'] do
let(:fields) do
%i[
name
+ isDefault
branch_protection
created_at
updated_at
diff --git a/spec/lib/gitlab/background_migration/update_ci_pipeline_artifacts_unknown_locked_status_spec.rb b/spec/lib/gitlab/background_migration/update_ci_pipeline_artifacts_unknown_locked_status_spec.rb
new file mode 100644
index 00000000000..98939e15952
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/update_ci_pipeline_artifacts_unknown_locked_status_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::UpdateCiPipelineArtifactsUnknownLockedStatus do
+ describe '#perform' do
+ let(:batch_table) { :ci_pipeline_artifacts }
+ let(:batch_column) { :id }
+
+ let(:sub_batch_size) { 1 }
+ let(:pause_ms) { 0 }
+ let(:connection) { Ci::ApplicationRecord.connection }
+
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:pipelines) { table(:ci_pipelines, database: :ci) }
+ let(:pipeline_artifacts) { table(:ci_pipeline_artifacts, database: :ci) }
+
+ let(:namespace) { namespaces.create!(name: 'name', path: 'path') }
+ let(:project) do
+ projects
+ .create!(name: "project", path: "project", namespace_id: namespace.id, project_namespace_id: namespace.id)
+ end
+
+ let(:unlocked) { 0 }
+ let(:locked) { 1 }
+ let(:unknown) { 2 }
+
+ let(:unlocked_pipeline) { pipelines.create!(locked: unlocked) }
+ let(:locked_pipeline) { pipelines.create!(locked: locked) }
+
+ # rubocop:disable Layout/LineLength
+ let!(:locked_artifact) { pipeline_artifacts.create!(project_id: project.id, pipeline_id: locked_pipeline.id, size: 1024, file_type: 0, file_format: 'gzip', file: 'a.gz', locked: unknown) }
+ let!(:unlocked_artifact_1) { pipeline_artifacts.create!(project_id: project.id, pipeline_id: unlocked_pipeline.id, size: 2048, file_type: 1, file_format: 'raw', file: 'b', locked: unknown) }
+ let!(:unlocked_artifact_2) { pipeline_artifacts.create!(project_id: project.id, pipeline_id: unlocked_pipeline.id, size: 4096, file_type: 2, file_format: 'gzip', file: 'c.gz', locked: unknown) }
+ let!(:already_unlocked_artifact) { pipeline_artifacts.create!(project_id: project.id, pipeline_id: unlocked_pipeline.id, size: 8192, file_type: 3, file_format: 'raw', file: 'd', locked: unlocked) }
+ let!(:already_locked_artifact) { pipeline_artifacts.create!(project_id: project.id, pipeline_id: locked_pipeline.id, size: 8192, file_type: 3, file_format: 'raw', file: 'd', locked: locked) }
+ # rubocop:enable Layout/LineLength
+
+ subject do
+ described_class.new(
+ start_id: locked_artifact.id,
+ end_id: already_locked_artifact.id,
+ batch_table: batch_table,
+ batch_column: batch_column,
+ sub_batch_size: sub_batch_size,
+ pause_ms: pause_ms,
+ connection: connection
+ ).perform
+ end
+
+ it 'updates ci_pipeline_artifacts with unknown lock status' do
+ subject
+
+ expect(locked_artifact.reload.locked).to eq(locked)
+ expect(unlocked_artifact_1.reload.locked).to eq(unlocked)
+ expect(unlocked_artifact_2.reload.locked).to eq(unlocked)
+ expect(already_unlocked_artifact.reload.locked).to eq(unlocked)
+ expect(already_locked_artifact.reload.locked).to eq(locked)
+ end
+ end
+end
diff --git a/spec/migrations/20220928225711_schedule_update_ci_pipeline_artifacts_locked_status_spec.rb b/spec/migrations/20220928225711_schedule_update_ci_pipeline_artifacts_locked_status_spec.rb
new file mode 100644
index 00000000000..7e3f8caa966
--- /dev/null
+++ b/spec/migrations/20220928225711_schedule_update_ci_pipeline_artifacts_locked_status_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleUpdateCiPipelineArtifactsLockedStatus, migration: :gitlab_ci do
+ let_it_be(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules background jobs for each batch of ci_pipeline_artifacts' do
+ migrate!
+
+ expect(migration).to have_scheduled_batched_migration(
+ gitlab_schema: :gitlab_ci,
+ table_name: :ci_pipeline_artifacts,
+ column_name: :id,
+ 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/models/ci/build_metadata_spec.rb b/spec/models/ci/build_metadata_spec.rb
index e904463a5ca..16cff72db64 100644
--- a/spec/models/ci/build_metadata_spec.rb
+++ b/spec/models/ci/build_metadata_spec.rb
@@ -14,8 +14,8 @@ RSpec.describe Ci::BuildMetadata do
status: 'success')
end
- let(:build) { create(:ci_build, pipeline: pipeline) }
- let(:metadata) { build.metadata }
+ let(:job) { create(:ci_build, pipeline: pipeline) }
+ let(:metadata) { job.metadata }
it_behaves_like 'having unique enum values'
@@ -35,7 +35,7 @@ RSpec.describe Ci::BuildMetadata do
context 'when project timeout is set' do
context 'when runner is assigned to the job' do
before do
- build.update!(runner: runner)
+ job.update!(runner: runner)
end
context 'when runner timeout is not set' do
@@ -59,13 +59,13 @@ RSpec.describe Ci::BuildMetadata do
context 'when job timeout is set' do
context 'when job timeout is higher than project timeout' do
- let(:build) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 3000 }) }
+ let(:job) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 3000 }) }
it_behaves_like 'sets timeout', 'job_timeout_source', 3000
end
context 'when job timeout is lower than project timeout' do
- let(:build) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 1000 }) }
+ let(:job) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 1000 }) }
it_behaves_like 'sets timeout', 'job_timeout_source', 1000
end
@@ -73,18 +73,18 @@ RSpec.describe Ci::BuildMetadata do
context 'when both runner and job timeouts are set' do
before do
- build.update!(runner: runner)
+ job.update!(runner: runner)
end
context 'when job timeout is higher than runner timeout' do
- let(:build) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 3000 }) }
+ let(:job) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 3000 }) }
let(:runner) { create(:ci_runner, maximum_timeout: 2100) }
it_behaves_like 'sets timeout', 'runner_timeout_source', 2100
end
context 'when job timeout is lower than runner timeout' do
- let(:build) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 1900 }) }
+ let(:job) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 1900 }) }
let(:runner) { create(:ci_runner, maximum_timeout: 2100) }
it_behaves_like 'sets timeout', 'job_timeout_source', 1900
@@ -135,20 +135,51 @@ RSpec.describe Ci::BuildMetadata do
describe 'set_cancel_gracefully' do
it 'sets cancel_gracefully' do
- build.set_cancel_gracefully
+ job.set_cancel_gracefully
- expect(build.cancel_gracefully?).to be true
+ expect(job.cancel_gracefully?).to be true
end
it 'returns false' do
- expect(build.cancel_gracefully?).to be false
+ expect(job.cancel_gracefully?).to be false
end
end
context 'loose foreign key on ci_builds_metadata.project_id' do
it_behaves_like 'cleanup by a loose foreign key' do
- let!(:parent) { create(:project) }
- let!(:model) { create(:ci_build_metadata, project: parent) }
+ let!(:parent) { project }
+ let!(:model) { metadata }
+ end
+ end
+
+ describe 'partitioning' do
+ context 'with job' do
+ let(:status) { build(:commit_status, partition_id: 123) }
+ let(:metadata) { build(:ci_build_metadata, build: status) }
+
+ it 'copies the partition_id from job' do
+ expect { metadata.valid? }.to change(metadata, :partition_id).to(123)
+ end
+
+ context 'when it is already set' do
+ let(:metadata) { build(:ci_build_metadata, build: status, partition_id: 125) }
+
+ it 'does not change the partition_id value' do
+ expect { metadata.valid? }.not_to change(metadata, :partition_id)
+ end
+ end
+ end
+
+ context 'without job' do
+ subject(:metadata) do
+ build(:ci_build_metadata, build: nil)
+ end
+
+ it { is_expected.to validate_presence_of(:partition_id) }
+
+ it 'does not change the partition_id value' do
+ expect { metadata.valid? }.not_to change(metadata, :partition_id)
+ end
end
end
end
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 41b817f231b..52142278c15 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -320,10 +320,10 @@ RSpec.describe Ci::Build do
let(:artifact_scope) { Ci::JobArtifact.where(file_type: 'archive') }
- let!(:build_1) { create(:ci_build, :artifacts) }
- let!(:build_2) { create(:ci_build, :codequality_reports) }
- let!(:build_3) { create(:ci_build, :test_reports) }
- let!(:build_4) { create(:ci_build, :artifacts) }
+ let!(:build_1) { create(:ci_build, :artifacts, pipeline: pipeline) }
+ let!(:build_2) { create(:ci_build, :codequality_reports, pipeline: pipeline) }
+ let!(:build_3) { create(:ci_build, :test_reports, pipeline: pipeline) }
+ let!(:build_4) { create(:ci_build, :artifacts, pipeline: pipeline) }
it 'returns artifacts matching the given scope' do
expect(builds).to contain_exactly(build_1, build_4)
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 3fc1883c1e6..8bf32527342 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -5488,7 +5488,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
describe 'partitioning' do
- let(:pipeline) { build(:ci_pipeline) }
+ let(:pipeline) { build(:ci_pipeline, partition_id: nil) }
before do
allow(described_class).to receive(:current_partition_value) { 123 }
diff --git a/spec/models/concerns/ci/partitionable_spec.rb b/spec/models/concerns/ci/partitionable_spec.rb
new file mode 100644
index 00000000000..d53501ccc3d
--- /dev/null
+++ b/spec/models/concerns/ci/partitionable_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::Partitionable do
+ describe 'partitionable models inclusion' do
+ let(:ci_model) { Class.new(Ci::ApplicationRecord) }
+
+ subject { ci_model.include(described_class) }
+
+ it 'raises an exception' do
+ expect { subject }
+ .to raise_error(/must be included in PARTITIONABLE_MODELS/)
+ end
+
+ context 'when is included in the models list' do
+ before do
+ stub_const("#{described_class}::Testing::PARTITIONABLE_MODELS", [ci_model.name])
+ end
+
+ it 'does not raise exceptions' do
+ expect { subject }.not_to raise_error
+ end
+ end
+ end
+end
diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb
index 54a90ca6049..b88367b9ca2 100644
--- a/spec/models/protected_branch_spec.rb
+++ b/spec/models/protected_branch_spec.rb
@@ -435,4 +435,28 @@ RSpec.describe ProtectedBranch do
expect(described_class.downcase_humanized_name).to eq 'protected branch'
end
end
+
+ describe '.default_branch?' do
+ before do
+ allow(subject.project).to receive(:default_branch).and_return(branch)
+ end
+
+ context 'when the name matches the default branch' do
+ let(:branch) { subject.name }
+
+ it { is_expected.to be_default_branch }
+ end
+
+ context 'when the name does not match the default branch' do
+ let(:branch) { "#{subject.name}qwerty" }
+
+ it { is_expected.not_to be_default_branch }
+ end
+
+ context 'when a wildcard name matches the default branch' do
+ let(:branch) { "#{subject.name}*" }
+
+ it { is_expected.not_to be_default_branch }
+ end
+ end
end
diff --git a/spec/requests/api/graphql/project/branch_rules_spec.rb b/spec/requests/api/graphql/project/branch_rules_spec.rb
index 70fb37941e2..1aaf0e9edc7 100644
--- a/spec/requests/api/graphql/project/branch_rules_spec.rb
+++ b/spec/requests/api/graphql/project/branch_rules_spec.rb
@@ -21,27 +21,24 @@ RSpec.describe 'getting list of branch rules for a project' do
let(:branch_rules_data) { graphql_data_at('project', 'branchRules', 'edges') }
let(:variables) { { path: project.full_path } }
-
- let(:fields) do
- <<~QUERY
- pageInfo {
- hasNextPage
- hasPreviousPage
- }
- edges {
- cursor
- node {
- #{all_graphql_fields_for('branch_rules'.classify)}
- }
- }
- QUERY
- end
-
+ # fields must use let as the all_graphql_fields_for also configures some spies
+ let(:fields) { all_graphql_fields_for('BranchRule') }
let(:query) do
<<~GQL
query($path: ID!, $n: Int, $cursor: String) {
project(fullPath: $path) {
- branchRules(first: $n, after: $cursor) { #{fields} }
+ branchRules(first: $n, after: $cursor) {
+ pageInfo {
+ hasNextPage
+ hasPreviousPage
+ }
+ edges {
+ cursor
+ node {
+ #{fields}
+ }
+ }
+ }
}
}
GQL
@@ -55,7 +52,9 @@ RSpec.describe 'getting list of branch rules for a project' do
it_behaves_like 'a working graphql query'
- it { expect(branch_rules_data).to be_empty }
+ it 'hides branch rules data' do
+ expect(branch_rules_data).to be_empty
+ end
end
context 'when the user does have read_protected_branch abilities' do
@@ -66,12 +65,17 @@ RSpec.describe 'getting list of branch rules for a project' do
it_behaves_like 'a working graphql query'
- it 'includes a name' do
+ it 'returns branch rules data' do
expect(branch_rules_data.dig(0, 'node', 'name')).to be_present
- end
-
- it 'includes created_at and updated_at' do
+ expect(branch_rules_data.dig(0, 'node', 'isDefault')).to be(true).or be(false)
+ expect(branch_rules_data.dig(0, 'node', 'branchProtection')).to be_present
expect(branch_rules_data.dig(0, 'node', 'createdAt')).to be_present
+ expect(branch_rules_data.dig(0, 'node', 'updatedAt')).to be_present
+
+ expect(branch_rules_data.dig(1, 'node', 'name')).to be_present
+ expect(branch_rules_data.dig(1, 'node', 'isDefault')).to be(true).or be(false)
+ expect(branch_rules_data.dig(1, 'node', 'branchProtection')).to be_present
+ expect(branch_rules_data.dig(1, 'node', 'createdAt')).to be_present
expect(branch_rules_data.dig(1, 'node', 'updatedAt')).to be_present
end
@@ -82,16 +86,16 @@ RSpec.describe 'getting list of branch rules for a project' do
{ path: project.full_path, n: branch_rule_limit, cursor: last_cursor }
end
- it_behaves_like 'a working graphql query' do
- it 'only returns N branch_rules' do
- expect(branch_rules_data.size).to eq(branch_rule_limit)
- expect(has_next_page).to be_truthy
- expect(has_prev_page).to be_falsey
- post_graphql(query, current_user: current_user, variables: next_variables)
- expect(branch_rules_data.size).to eq(branch_rule_limit)
- expect(has_next_page).to be_falsey
- expect(has_prev_page).to be_truthy
- end
+ it_behaves_like 'a working graphql query'
+
+ it 'returns pagination information' do
+ expect(branch_rules_data.size).to eq(branch_rule_limit)
+ expect(has_next_page).to be_truthy
+ expect(has_prev_page).to be_falsey
+ post_graphql(query, current_user: current_user, variables: next_variables)
+ expect(branch_rules_data.size).to eq(branch_rule_limit)
+ expect(has_next_page).to be_falsey
+ expect(has_prev_page).to be_truthy
end
context 'when no limit is provided' do
diff --git a/spec/services/ci/job_artifacts/create_service_spec.rb b/spec/services/ci/job_artifacts/create_service_spec.rb
index a2259f9813b..030ba84951e 100644
--- a/spec/services/ci/job_artifacts/create_service_spec.rb
+++ b/spec/services/ci/job_artifacts/create_service_spec.rb
@@ -182,7 +182,8 @@ RSpec.describe Ci::JobArtifacts::CreateService do
end
context 'with job partitioning' do
- let(:job) { create(:ci_build, project: project, partition_id: 123) }
+ let(:pipeline) { create(:ci_pipeline, project: project, partition_id: 123) }
+ let(:job) { create(:ci_build, pipeline: pipeline) }
it 'sets partition_id on artifacts' do
expect { subject }.to change { Ci::JobArtifact.count }
diff --git a/spec/services/packages/rpm/repository_metadata/build_repomd_xml_spec.rb b/spec/services/packages/rpm/repository_metadata/build_repomd_xml_spec.rb
index 29b0f73e3c1..0843a983b7e 100644
--- a/spec/services/packages/rpm/repository_metadata/build_repomd_xml_spec.rb
+++ b/spec/services/packages/rpm/repository_metadata/build_repomd_xml_spec.rb
@@ -62,5 +62,25 @@ RSpec.describe Packages::Rpm::RepositoryMetadata::BuildRepomdXml do
end
end
end
+
+ context 'when data values has unexpected keys' do
+ let(:data) do
+ {
+ filelists: described_class::ALLOWED_DATA_VALUE_KEYS.each_with_object({}) do |key, result|
+ result[:"#{key}-wrong"] = { value: 'value' }
+ end
+ }
+ end
+
+ it 'ignores wrong keys' do
+ result = Nokogiri::XML::Document.parse(subject).remove_namespaces!
+
+ data.each do |tag_name, tag_attributes|
+ tag_attributes.each_key do |key|
+ expect(result.at("//repomd/data[@type=\"#{tag_name}\"]/#{key}")).to be_nil
+ end
+ end
+ end
+ end
end
end
diff --git a/spec/support/models/partitionable_check.rb b/spec/support/models/partitionable_check.rb
new file mode 100644
index 00000000000..2c09c1b3408
--- /dev/null
+++ b/spec/support/models/partitionable_check.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module PartitioningTesting
+ module CascadeCheck
+ extend ActiveSupport::Concern
+
+ included do
+ after_create :check_partition_cascade_value
+ end
+
+ def check_partition_cascade_value
+ raise 'Partition value not found' unless partition_scope_value
+ raise 'Default value detected' if partition_id == 100
+
+ return if partition_id == partition_scope_value
+
+ raise "partition_id was expected to equal #{partition_scope_value} but it was #{partition_id}."
+ end
+ end
+
+ module DefaultPartitionValue
+ extend ActiveSupport::Concern
+
+ class_methods do
+ def current_partition_value
+ current = super
+
+ if current == 100
+ 54321
+ else
+ current
+ end
+ end
+ end
+ end
+end
+
+Ci::Partitionable::Testing::PARTITIONABLE_MODELS.each do |klass|
+ model = klass.safe_constantize
+
+ if klass == 'Ci::Pipeline'
+ model.prepend(PartitioningTesting::DefaultPartitionValue)
+ else
+ model.include(PartitioningTesting::CascadeCheck)
+ end
+end
diff --git a/spec/views/registrations/welcome/show.html.haml_spec.rb b/spec/views/registrations/welcome/show.html.haml_spec.rb
index d9c5d348e15..99d87ac449b 100644
--- a/spec/views/registrations/welcome/show.html.haml_spec.rb
+++ b/spec/views/registrations/welcome/show.html.haml_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe 'registrations/welcome/show' do
allow(view).to receive(:in_trial_flow?).and_return(false)
allow(view).to receive(:user_has_memberships?).and_return(false)
allow(view).to receive(:in_oauth_flow?).and_return(false)
+ allow(view).to receive(:glm_tracking_params).and_return({})
render
end