224 lines
6.8 KiB
Ruby
224 lines
6.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
require 'json'
|
|
require 'tempfile'
|
|
|
|
RSpec.describe Gitlab::Git::RuggedImpl::UseRugged do
|
|
let(:project) { create(:project, :repository) }
|
|
let(:repository) { project.repository }
|
|
let(:feature_flag_name) { wrapper.rugged_feature_keys.first }
|
|
let(:temp_gitaly_metadata_file) { create_temporary_gitaly_metadata_file }
|
|
|
|
before(:all) do
|
|
create_gitaly_metadata_file
|
|
end
|
|
|
|
subject(:wrapper) do
|
|
klazz = Class.new do
|
|
include Gitlab::Git::RuggedImpl::UseRugged
|
|
|
|
def rugged_test(ref, test_number)
|
|
end
|
|
end
|
|
|
|
klazz.new
|
|
end
|
|
|
|
before do
|
|
allow(Gitlab::GitalyClient).to receive(:can_use_disk?).and_call_original
|
|
Gitlab::GitalyClient.instance_variable_set(:@can_use_disk, {})
|
|
end
|
|
|
|
describe '#execute_rugged_call', :request_store do
|
|
let(:args) { ['refs/heads/master', 1] }
|
|
|
|
before do
|
|
allow(Gitlab::PerformanceBar).to receive(:enabled_for_request?).and_return(true)
|
|
end
|
|
|
|
it 'instruments Rugged call' do
|
|
expect(subject).to receive(:rugged_test).with(args)
|
|
|
|
subject.execute_rugged_call(:rugged_test, args)
|
|
|
|
expect(Gitlab::RuggedInstrumentation.query_count).to eq(1)
|
|
expect(Gitlab::RuggedInstrumentation.list_call_details.count).to eq(1)
|
|
end
|
|
end
|
|
|
|
context 'when feature flag is not persisted', stub_feature_flags: false do
|
|
context 'when running puma with multiple threads' do
|
|
before do
|
|
allow(subject).to receive(:running_puma_with_multiple_threads?).and_return(true)
|
|
end
|
|
|
|
it 'returns false' do
|
|
expect(subject.use_rugged?(repository, feature_flag_name)).to be false
|
|
end
|
|
end
|
|
|
|
context 'when skip_rugged_auto_detect feature flag is enabled' do
|
|
context 'when not running puma with multiple threads' do
|
|
before do
|
|
allow(subject).to receive(:running_puma_with_multiple_threads?).and_return(false)
|
|
stub_feature_flags(feature_flag_name => nil)
|
|
stub_feature_flags(skip_rugged_auto_detect: true)
|
|
end
|
|
|
|
it 'returns false' do
|
|
expect(subject.use_rugged?(repository, feature_flag_name)).to be false
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when skip_rugged_auto_detect feature flag is disabled' do
|
|
before do
|
|
stub_feature_flags(skip_rugged_auto_detect: false)
|
|
end
|
|
|
|
context 'when not running puma with multiple threads' do
|
|
before do
|
|
allow(subject).to receive(:running_puma_with_multiple_threads?).and_return(false)
|
|
end
|
|
|
|
it 'returns true when gitaly matches disk' do
|
|
expect(subject.use_rugged?(repository, feature_flag_name)).to be true
|
|
end
|
|
|
|
it 'returns false when disk access fails' do
|
|
allow(Gitlab::GitalyClient).to receive(:storage_metadata_file_path).and_return("/fake/path/doesnt/exist")
|
|
|
|
expect(subject.use_rugged?(repository, feature_flag_name)).to be false
|
|
end
|
|
|
|
it "returns false when gitaly doesn't match disk" do
|
|
allow(Gitlab::GitalyClient).to receive(:storage_metadata_file_path).and_return(temp_gitaly_metadata_file)
|
|
|
|
expect(subject.use_rugged?(repository, feature_flag_name)).to be_falsey
|
|
|
|
File.delete(temp_gitaly_metadata_file)
|
|
end
|
|
|
|
it "doesn't lead to a second rpc call because gitaly client should use the cached value" do
|
|
expect(subject.use_rugged?(repository, feature_flag_name)).to be true
|
|
|
|
expect(Gitlab::GitalyClient).not_to receive(:filesystem_id)
|
|
|
|
subject.use_rugged?(repository, feature_flag_name)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when feature flag is persisted' do
|
|
it 'returns false when the feature flag is off' do
|
|
Feature.disable(feature_flag_name)
|
|
|
|
expect(subject.use_rugged?(repository, feature_flag_name)).to be_falsey
|
|
end
|
|
|
|
it "returns true when feature flag is on" do
|
|
Feature.enable(feature_flag_name)
|
|
|
|
allow(Gitlab::GitalyClient).to receive(:can_use_disk?).and_return(false)
|
|
|
|
expect(subject.use_rugged?(repository, feature_flag_name)).to be true
|
|
end
|
|
end
|
|
|
|
describe '#running_puma_with_multiple_threads?' do
|
|
context 'when using Puma' do
|
|
before do
|
|
stub_const('::Puma', double('puma constant'))
|
|
allow(Gitlab::Runtime).to receive(:puma?).and_return(true)
|
|
end
|
|
|
|
it "returns false when Puma doesn't support the cli_config method" do
|
|
allow(::Puma).to receive(:respond_to?).with(:cli_config).and_return(false)
|
|
|
|
expect(subject.running_puma_with_multiple_threads?).to be_falsey
|
|
end
|
|
|
|
it 'returns false for single thread Puma' do
|
|
allow(::Puma).to receive_message_chain(:cli_config, :options).and_return(max_threads: 1)
|
|
|
|
expect(subject.running_puma_with_multiple_threads?).to be false
|
|
end
|
|
|
|
it 'returns true for multi-threaded Puma' do
|
|
allow(::Puma).to receive_message_chain(:cli_config, :options).and_return(max_threads: 2)
|
|
|
|
expect(subject.running_puma_with_multiple_threads?).to be true
|
|
end
|
|
end
|
|
|
|
context 'when not using Puma' do
|
|
before do
|
|
allow(Gitlab::Runtime).to receive(:puma?).and_return(false)
|
|
end
|
|
|
|
it 'returns false' do
|
|
expect(subject.running_puma_with_multiple_threads?).to be false
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#rugged_enabled_through_feature_flag?' do
|
|
subject { wrapper.send(:rugged_enabled_through_feature_flag?) }
|
|
|
|
before do
|
|
allow(Feature).to receive(:enabled?).with(:feature_key_1).and_return(true)
|
|
allow(Feature).to receive(:enabled?).with(:feature_key_2).and_return(true)
|
|
allow(Feature).to receive(:enabled?).with(:feature_key_3).and_return(false)
|
|
allow(Feature).to receive(:enabled?).with(:feature_key_4).and_return(false)
|
|
|
|
stub_const('Gitlab::Git::RuggedImpl::Repository::FEATURE_FLAGS', feature_keys)
|
|
end
|
|
|
|
context 'no feature keys given' do
|
|
let(:feature_keys) { [] }
|
|
|
|
it { is_expected.to be_falsey }
|
|
end
|
|
|
|
context 'all features are enabled' do
|
|
let(:feature_keys) { [:feature_key_1, :feature_key_2] }
|
|
|
|
it { is_expected.to be_truthy }
|
|
end
|
|
|
|
context 'all features are not enabled' do
|
|
let(:feature_keys) { [:feature_key_3, :feature_key_4] }
|
|
|
|
it { is_expected.to be_falsey }
|
|
end
|
|
|
|
context 'some feature is enabled' do
|
|
let(:feature_keys) { [:feature_key_4, :feature_key_2] }
|
|
|
|
it { is_expected.to be_truthy }
|
|
end
|
|
end
|
|
|
|
def create_temporary_gitaly_metadata_file
|
|
tmp = Tempfile.new('.gitaly-metadata')
|
|
gitaly_metadata = {
|
|
"gitaly_filesystem_id" => "some-value"
|
|
}
|
|
tmp.write(gitaly_metadata.to_json)
|
|
tmp.flush
|
|
tmp.close
|
|
tmp.path
|
|
end
|
|
|
|
def create_gitaly_metadata_file
|
|
File.open(File.join(SEED_STORAGE_PATH, '.gitaly-metadata'), 'w+') do |f|
|
|
gitaly_metadata = {
|
|
"gitaly_filesystem_id" => SecureRandom.uuid
|
|
}
|
|
f.write(gitaly_metadata.to_json)
|
|
end
|
|
end
|
|
end
|