summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/git/hook_env_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/git/hook_env_spec.rb')
-rw-r--r--spec/lib/gitlab/git/hook_env_spec.rb119
1 files changed, 119 insertions, 0 deletions
diff --git a/spec/lib/gitlab/git/hook_env_spec.rb b/spec/lib/gitlab/git/hook_env_spec.rb
new file mode 100644
index 00000000000..e6aa5ad8c90
--- /dev/null
+++ b/spec/lib/gitlab/git/hook_env_spec.rb
@@ -0,0 +1,119 @@
+require 'spec_helper'
+
+describe Gitlab::Git::HookEnv do
+ let(:gl_repository) { 'project-123' }
+
+ describe ".set" do
+ context 'with RequestStore.store disabled' do
+ before do
+ allow(RequestStore).to receive(:active?).and_return(false)
+ end
+
+ it 'does not store anything' do
+ described_class.set(gl_repository, GIT_OBJECT_DIRECTORY_RELATIVE: 'foo')
+
+ expect(described_class.all(gl_repository)).to be_empty
+ end
+ end
+
+ context 'with RequestStore.store enabled' do
+ before do
+ allow(RequestStore).to receive(:active?).and_return(true)
+ end
+
+ it 'whitelist some `GIT_*` variables and stores them using RequestStore' do
+ described_class.set(
+ gl_repository,
+ GIT_OBJECT_DIRECTORY_RELATIVE: 'foo',
+ GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE: 'bar',
+ GIT_EXEC_PATH: 'baz',
+ PATH: '~/.bin:/bin')
+
+ git_env = described_class.all(gl_repository)
+
+ expect(git_env[:GIT_OBJECT_DIRECTORY_RELATIVE]).to eq('foo')
+ expect(git_env[:GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE]).to eq('bar')
+ expect(git_env[:GIT_EXEC_PATH]).to be_nil
+ expect(git_env[:PATH]).to be_nil
+ expect(git_env[:bar]).to be_nil
+ end
+ end
+ end
+
+ describe ".all" do
+ context 'with RequestStore.store enabled' do
+ before do
+ allow(RequestStore).to receive(:active?).and_return(true)
+ described_class.set(
+ gl_repository,
+ GIT_OBJECT_DIRECTORY_RELATIVE: 'foo',
+ GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE: ['bar'])
+ end
+
+ it 'returns an env hash' do
+ expect(described_class.all(gl_repository)).to eq({
+ 'GIT_OBJECT_DIRECTORY_RELATIVE' => 'foo',
+ 'GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE' => ['bar']
+ })
+ end
+ end
+ end
+
+ describe ".to_env_hash" do
+ context 'with RequestStore.store enabled' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:key) { 'GIT_OBJECT_DIRECTORY_RELATIVE' }
+ subject { described_class.to_env_hash(gl_repository) }
+
+ where(:input, :output) do
+ nil | nil
+ 'foo' | 'foo'
+ [] | ''
+ ['foo'] | 'foo'
+ %w[foo bar] | 'foo:bar'
+ end
+
+ with_them do
+ before do
+ allow(RequestStore).to receive(:active?).and_return(true)
+ described_class.set(gl_repository, key.to_sym => input)
+ end
+
+ it 'puts the right value in the hash' do
+ if output
+ expect(subject.fetch(key)).to eq(output)
+ else
+ expect(subject.has_key?(key)).to eq(false)
+ end
+ end
+ end
+ end
+ end
+
+ describe 'thread-safety' do
+ context 'with RequestStore.store enabled' do
+ before do
+ allow(RequestStore).to receive(:active?).and_return(true)
+ described_class.set(gl_repository, GIT_OBJECT_DIRECTORY_RELATIVE: 'foo')
+ end
+
+ it 'is thread-safe' do
+ another_thread = Thread.new do
+ described_class.set(gl_repository, GIT_OBJECT_DIRECTORY_RELATIVE: 'bar')
+
+ Thread.stop
+ described_class.all(gl_repository)[:GIT_OBJECT_DIRECTORY_RELATIVE]
+ end
+
+ # Ensure another_thread runs first
+ sleep 0.1 until another_thread.stop?
+
+ expect(described_class.all(gl_repository)[:GIT_OBJECT_DIRECTORY_RELATIVE]).to eq('foo')
+
+ another_thread.run
+ expect(another_thread.value).to eq('bar')
+ end
+ end
+ end
+end