mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-06 10:19:48 +00:00
Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
@ -1 +1 @@
|
|||||||
e2311699c249ba79ad2304e0dd71062ef3b785a7
|
44d3dc3e3f58563c0468f65bfb4dd6c18dabfcf5
|
||||||
|
@ -142,47 +142,6 @@ The optimization underlying mechanic is based on the concept of time efficiency.
|
|||||||
the exponential moving average of time efficiencies for the last N jobs and updates the batch
|
the exponential moving average of time efficiencies for the last N jobs and updates the batch
|
||||||
size of the batched background migration to its optimal value.
|
size of the batched background migration to its optimal value.
|
||||||
|
|
||||||
#### For GitLab SAAS
|
|
||||||
|
|
||||||
When updating a large dataset specify different batch sizes for GitLab SAAS.
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class BatchedMigration < Gitlab::Database::Migration[2.2]
|
|
||||||
BATCH_SIZE = 1000
|
|
||||||
SUB_BATCH_SIZE = 100
|
|
||||||
GITLAB_OPTIMIZED_BATCH_SIZE = 75_000
|
|
||||||
GITLAB_OPTIMIZED_SUB_BATCH_SIZE = 250
|
|
||||||
|
|
||||||
def up
|
|
||||||
queue_batched_background_migration(
|
|
||||||
MIGRATION,
|
|
||||||
TABLE_NAME,
|
|
||||||
COLUMN_NAME,
|
|
||||||
job_interval: DELAY_INTERVAL,
|
|
||||||
**batch_sizes
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def batch_sizes
|
|
||||||
if Gitlab.com_except_jh?
|
|
||||||
{
|
|
||||||
batch_size: GITLAB_OPTIMIZED_BATCH_SIZE,
|
|
||||||
sub_batch_size: GITLAB_OPTIMIZED_SUB_BATCH_SIZE
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
batch_size: BATCH_SIZE,
|
|
||||||
sub_batch_size: SUB_BATCH_SIZE
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
### Job retry mechanism
|
### Job retry mechanism
|
||||||
|
|
||||||
The batched background migrations retry mechanism ensures that a job is executed again in case of failure.
|
The batched background migrations retry mechanism ensures that a job is executed again in case of failure.
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe ProtectedBranch::MergeAccessLevel, feature_category: :source_code_management do
|
RSpec.describe ProtectedBranch::MergeAccessLevel, feature_category: :source_code_management do
|
||||||
include_examples 'protected branch access'
|
it_behaves_like 'protected branch access'
|
||||||
include_examples 'protected ref access allowed_access_levels'
|
it_behaves_like 'protected ref access allowed_access_levels'
|
||||||
end
|
end
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe ProtectedBranch::PushAccessLevel, feature_category: :source_code_management do
|
RSpec.describe ProtectedBranch::PushAccessLevel, feature_category: :source_code_management do
|
||||||
include_examples 'protected branch access'
|
it_behaves_like 'protected branch access'
|
||||||
include_examples 'protected ref deploy_key access'
|
it_behaves_like 'protected ref deploy_key access'
|
||||||
include_examples 'protected ref access allowed_access_levels'
|
it_behaves_like 'protected ref access allowed_access_levels'
|
||||||
end
|
end
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
RSpec.shared_context 'for protected ref access' do
|
||||||
|
let_it_be(:project) { create(:project, :public, :in_group) }
|
||||||
|
let_it_be(:described_factory) { described_class.model_name.singular }
|
||||||
|
let_it_be(:protected_ref_name) { described_class.module_parent.model_name.singular }
|
||||||
|
let_it_be(:protected_ref_fk) { "#{protected_ref_name}_id" }
|
||||||
|
let_it_be(:protected_ref) { create(protected_ref_name, default_access_level: false, project: project) }
|
||||||
|
end
|
@ -1,11 +1,13 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.shared_examples 'protected branch access' do
|
RSpec.shared_examples 'protected branch access' do
|
||||||
include_examples 'protected ref access', :protected_branch
|
it_behaves_like 'protected ref access'
|
||||||
|
|
||||||
it { is_expected.to belong_to(:protected_branch) }
|
it { is_expected.to belong_to(:protected_branch) }
|
||||||
|
|
||||||
describe '#project' do
|
describe '#project' do
|
||||||
|
include_context 'for protected ref access'
|
||||||
|
|
||||||
it 'delegates project to protected_branch association' do
|
it 'delegates project to protected_branch association' do
|
||||||
allow(protected_ref).to receive(:project)
|
allow(protected_ref).to receive(:project)
|
||||||
|
|
||||||
@ -20,6 +22,8 @@ RSpec.shared_examples 'protected branch access' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe '#protected_branch_group' do
|
describe '#protected_branch_group' do
|
||||||
|
include_context 'for protected ref access'
|
||||||
|
|
||||||
it 'looks for the group attached to protected_branch' do
|
it 'looks for the group attached to protected_branch' do
|
||||||
allow(protected_ref).to receive(:group)
|
allow(protected_ref).to receive(:group)
|
||||||
|
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.shared_examples 'protected ref access' do |association|
|
RSpec.shared_examples 'protected ref access' do
|
||||||
include ExternalAuthorizationServiceHelpers
|
include ExternalAuthorizationServiceHelpers
|
||||||
|
|
||||||
let_it_be(:project) { create(:project) }
|
include_context 'for protected ref access'
|
||||||
let_it_be(:protected_ref) { create(association, project: project) } # rubocop:disable Rails/SaveBang -- False positive because factory name is dynamic
|
|
||||||
|
|
||||||
describe 'validations' do
|
describe 'validations' do
|
||||||
subject { build(described_class.model_name.singular) }
|
subject { build(described_factory) }
|
||||||
|
|
||||||
context 'when role?' do
|
context 'when role?' do
|
||||||
it { is_expected.to validate_inclusion_of(:access_level).in_array(described_class.allowed_access_levels) }
|
it { is_expected.to validate_inclusion_of(:access_level).in_array(described_class.allowed_access_levels) }
|
||||||
@ -15,8 +14,7 @@ RSpec.shared_examples 'protected ref access' do |association|
|
|||||||
it { is_expected.to validate_presence_of(:access_level) }
|
it { is_expected.to validate_presence_of(:access_level) }
|
||||||
|
|
||||||
it do
|
it do
|
||||||
is_expected.to validate_uniqueness_of(:access_level)
|
is_expected.to validate_uniqueness_of(:access_level).scoped_to(protected_ref_fk)
|
||||||
.scoped_to("#{described_class.module_parent.model_name.singular}_id")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -30,8 +28,7 @@ RSpec.shared_examples 'protected ref access' do |association|
|
|||||||
it { is_expected.not_to validate_inclusion_of(:access_level).in_array(described_class.allowed_access_levels) }
|
it { is_expected.not_to validate_inclusion_of(:access_level).in_array(described_class.allowed_access_levels) }
|
||||||
|
|
||||||
it do
|
it do
|
||||||
is_expected.not_to validate_uniqueness_of(:access_level)
|
is_expected.not_to validate_uniqueness_of(:access_level).scoped_to(protected_ref_fk)
|
||||||
.scoped_to("#{described_class.module_parent.model_name.singular}_id")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -52,27 +49,19 @@ RSpec.shared_examples 'protected ref access' do |association|
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe '#check_access(user, current_project)' do
|
describe '#check_access(user, current_project)' do
|
||||||
let_it_be(:group) { create(:group) }
|
|
||||||
# Making a project public to avoid false positives tests
|
|
||||||
let_it_be(:project) { create(:project, :public, group: group) }
|
|
||||||
let_it_be(:current_user) { create(:user) }
|
let_it_be(:current_user) { create(:user) }
|
||||||
let_it_be(:protected_ref) { create(association, project: project) }
|
|
||||||
|
|
||||||
let(:access_level) { ::Gitlab::Access::DEVELOPER }
|
let(:access_level) { ::Gitlab::Access::DEVELOPER }
|
||||||
let(:current_project) { project }
|
let(:current_project) { project }
|
||||||
let(:described_instance) do
|
|
||||||
described_class.new(
|
|
||||||
association => protected_ref,
|
|
||||||
access_level: access_level
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
before_all do
|
before_all do
|
||||||
project.add_developer(current_user)
|
project.add_developer(current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject do
|
subject(:check_access) do
|
||||||
described_instance.check_access(current_user, current_project)
|
described_class
|
||||||
|
.new(protected_ref_name => protected_ref, access_level: access_level)
|
||||||
|
.check_access(current_user, current_project)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when current_user is nil' do
|
context 'when current_user is nil' do
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.shared_examples 'protected ref deploy_key access' do
|
RSpec.shared_examples 'protected ref deploy_key access' do
|
||||||
let_it_be(:described_instance) { described_class.model_name.singular }
|
include_context 'for protected ref access'
|
||||||
let_it_be(:protected_ref_name) { described_class.module_parent.model_name.singular }
|
|
||||||
let_it_be(:project) { create(:project, :in_group) }
|
|
||||||
let_it_be(:protected_ref) { create(protected_ref_name, project: project) } # rubocop:disable Rails/SaveBang -- False positive because factory name is dynamic
|
|
||||||
|
|
||||||
describe 'associations' do
|
describe 'associations' do
|
||||||
it { is_expected.to belong_to(:deploy_key) }
|
it { is_expected.to belong_to(:deploy_key) }
|
||||||
@ -18,7 +15,7 @@ RSpec.shared_examples 'protected ref deploy_key access' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'is valid' do
|
it 'is valid' do
|
||||||
level = build(described_instance, protected_ref_name => protected_ref, deploy_key: deploy_key)
|
level = build(described_factory, protected_ref_name => protected_ref, deploy_key: deploy_key)
|
||||||
|
|
||||||
expect(level).to be_valid
|
expect(level).to be_valid
|
||||||
end
|
end
|
||||||
@ -26,7 +23,7 @@ RSpec.shared_examples 'protected ref deploy_key access' do
|
|||||||
|
|
||||||
context 'when deploy_key_id is invalid' do
|
context 'when deploy_key_id is invalid' do
|
||||||
subject(:access_level) do
|
subject(:access_level) do
|
||||||
build(described_instance, protected_ref_name => protected_ref, deploy_key_id: 0)
|
build(described_factory, protected_ref_name => protected_ref, deploy_key_id: 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'is not valid', :aggregate_failures do
|
it 'is not valid', :aggregate_failures do
|
||||||
@ -39,11 +36,11 @@ RSpec.shared_examples 'protected ref deploy_key access' do
|
|||||||
let(:deploy_key) { create(:deploy_keys_project, :write_access, project: project).deploy_key }
|
let(:deploy_key) { create(:deploy_keys_project, :write_access, project: project).deploy_key }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
create(described_instance, protected_ref_name => protected_ref, deploy_key: deploy_key)
|
create(described_factory, protected_ref_name => protected_ref, deploy_key: deploy_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject(:access_level) do
|
subject(:access_level) do
|
||||||
build(described_instance, protected_ref_name => protected_ref, deploy_key: deploy_key)
|
build(described_factory, protected_ref_name => protected_ref, deploy_key: deploy_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'is not valid', :aggregate_failures do
|
it 'is not valid', :aggregate_failures do
|
||||||
@ -54,7 +51,7 @@ RSpec.shared_examples 'protected ref deploy_key access' do
|
|||||||
|
|
||||||
context 'when deploy key is not enabled for the project' do
|
context 'when deploy key is not enabled for the project' do
|
||||||
subject(:access_level) do
|
subject(:access_level) do
|
||||||
build(described_instance, protected_ref_name => protected_ref, deploy_key: create(:deploy_key))
|
build(described_factory, protected_ref_name => protected_ref, deploy_key: create(:deploy_key))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'is not valid', :aggregate_failures do
|
it 'is not valid', :aggregate_failures do
|
||||||
@ -66,7 +63,7 @@ RSpec.shared_examples 'protected ref deploy_key access' do
|
|||||||
context 'when deploy key is not active for the project' do
|
context 'when deploy key is not active for the project' do
|
||||||
subject(:access_level) do
|
subject(:access_level) do
|
||||||
deploy_key = create(:deploy_keys_project, :readonly_access, project: project).deploy_key
|
deploy_key = create(:deploy_keys_project, :readonly_access, project: project).deploy_key
|
||||||
build(described_instance, protected_ref_name => protected_ref, deploy_key: deploy_key)
|
build(described_factory, protected_ref_name => protected_ref, deploy_key: deploy_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'is not valid', :aggregate_failures do
|
it 'is not valid', :aggregate_failures do
|
||||||
@ -88,7 +85,7 @@ RSpec.shared_examples 'protected ref deploy_key access' do
|
|||||||
|
|
||||||
context "when this #{described_class.model_name.singular} is tied to a deploy key" do
|
context "when this #{described_class.model_name.singular} is tied to a deploy key" do
|
||||||
let!(:access_level) do
|
let!(:access_level) do
|
||||||
create(described_instance, protected_ref_name => protected_ref, deploy_key: deploy_key)
|
create(described_factory, protected_ref_name => protected_ref, deploy_key: deploy_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'and user is not a project member' do
|
context 'and user is not a project member' do
|
||||||
@ -161,13 +158,13 @@ RSpec.shared_examples 'protected ref deploy_key access' do
|
|||||||
subject { access_level.type }
|
subject { access_level.type }
|
||||||
|
|
||||||
context 'when deploy_key is present and deploy_key_id is nil' do
|
context 'when deploy_key is present and deploy_key_id is nil' do
|
||||||
let(:access_level) { build(described_instance, deploy_key: build(:deploy_key)) }
|
let(:access_level) { build(described_factory, deploy_key: build(:deploy_key)) }
|
||||||
|
|
||||||
it { is_expected.to eq(:deploy_key) }
|
it { is_expected.to eq(:deploy_key) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when deploy_key_id is present and deploy_key is nil' do
|
context 'when deploy_key_id is present and deploy_key is nil' do
|
||||||
let(:access_level) { build(described_instance, deploy_key_id: 0) }
|
let(:access_level) { build(described_factory, deploy_key_id: 0) }
|
||||||
|
|
||||||
it { is_expected.to eq(:deploy_key) }
|
it { is_expected.to eq(:deploy_key) }
|
||||||
end
|
end
|
||||||
@ -178,13 +175,13 @@ RSpec.shared_examples 'protected ref deploy_key access' do
|
|||||||
|
|
||||||
context 'when deploy_key is present' do
|
context 'when deploy_key is present' do
|
||||||
let(:deploy_key) { build(:deploy_key) }
|
let(:deploy_key) { build(:deploy_key) }
|
||||||
let(:access_level) { build(described_instance, deploy_key: deploy_key) }
|
let(:access_level) { build(described_factory, deploy_key: deploy_key) }
|
||||||
|
|
||||||
it { is_expected.to eq(deploy_key.title) }
|
it { is_expected.to eq(deploy_key.title) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when deploy_key_id is present and deploy_key is nil' do
|
context 'when deploy_key_id is present and deploy_key is nil' do
|
||||||
let(:access_level) { build(described_instance, deploy_key_id: 0) }
|
let(:access_level) { build(described_factory, deploy_key_id: 0) }
|
||||||
|
|
||||||
it { is_expected.to eq('Deploy key') }
|
it { is_expected.to eq('Deploy key') }
|
||||||
end
|
end
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.shared_examples 'protected tag access' do
|
RSpec.shared_examples 'protected tag access' do
|
||||||
include_examples 'protected ref access', :protected_tag
|
include_examples 'protected ref access'
|
||||||
|
|
||||||
let_it_be(:protected_tag) { create(:protected_tag) }
|
|
||||||
|
|
||||||
it { is_expected.to belong_to(:protected_tag) }
|
it { is_expected.to belong_to(:protected_tag) }
|
||||||
|
|
||||||
describe '#project' do
|
describe '#project' do
|
||||||
|
let_it_be(:protected_tag) { create(:protected_tag) }
|
||||||
|
|
||||||
it 'delegates project to protected_tag association' do
|
it 'delegates project to protected_tag association' do
|
||||||
allow(protected_tag).to receive(:project)
|
allow(protected_tag).to receive(:project)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user