summaryrefslogtreecommitdiff
path: root/spec/lib
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2017-04-06 22:00:00 +0200
committerKamil Trzcinski <ayufan@ayufan.eu>2017-04-06 22:05:22 +0200
commit37a7b099d6eafc87209368a9fc7f608282b99e08 (patch)
treea2712e439cec8547d84bed2d57d339cb1cd5c502 /spec/lib
parent57c353fca7121a120142161b253004f33d815766 (diff)
parent73cb71e41c0ade92b9673a5d74c7dd78679fae91 (diff)
downloadgitlab-ce-37a7b099d6eafc87209368a9fc7f608282b99e08.tar.gz
Merge remote-tracking branch 'origin/master' into optimise-pipelinesoptimise-pipelines
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/banzai/filter/markdown_filter_spec.rb19
-rw-r--r--spec/lib/banzai/filter/sanitization_filter_spec.rb7
-rw-r--r--spec/lib/banzai/filter/syntax_highlight_filter_spec.rb6
-rw-r--r--spec/lib/ci/ansi2html_spec.rb110
-rw-r--r--spec/lib/container_registry/blob_spec.rb115
-rw-r--r--spec/lib/container_registry/path_spec.rb212
-rw-r--r--spec/lib/container_registry/registry_spec.rb2
-rw-r--r--spec/lib/container_registry/repository_spec.rb65
-rw-r--r--spec/lib/container_registry/tag_spec.rb86
-rw-r--r--spec/lib/gitlab/backend/shell_spec.rb9
-rw-r--r--spec/lib/gitlab/ci/cron_parser_spec.rb116
-rw-r--r--spec/lib/gitlab/ci/trace/stream_spec.rb201
-rw-r--r--spec/lib/gitlab/ci/trace_reader_spec.rb52
-rw-r--r--spec/lib/gitlab/ci/trace_spec.rb216
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb42
-rw-r--r--spec/lib/gitlab/etag_caching/middleware_spec.rb16
-rw-r--r--spec/lib/gitlab/git/attributes_spec.rb4
-rw-r--r--spec/lib/gitlab/git/blame_spec.rb2
-rw-r--r--spec/lib/gitlab/git/blob_spec.rb2
-rw-r--r--spec/lib/gitlab/git/branch_spec.rb2
-rw-r--r--spec/lib/gitlab/git/commit_spec.rb8
-rw-r--r--spec/lib/gitlab/git/compare_spec.rb2
-rw-r--r--spec/lib/gitlab/git/diff_spec.rb2
-rw-r--r--spec/lib/gitlab/git/encoding_helper_spec.rb2
-rw-r--r--spec/lib/gitlab/git/index_spec.rb2
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb111
-rw-r--r--spec/lib/gitlab/git/tag_spec.rb2
-rw-r--r--spec/lib/gitlab/git/tree_spec.rb2
-rw-r--r--spec/lib/gitlab/gitaly_client/notifications_spec.rb9
-rw-r--r--spec/lib/gitlab/gitaly_client/ref_spec.rb41
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml11
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml11
-rw-r--r--spec/lib/gitlab/o_auth/user_spec.rb9
-rw-r--r--spec/lib/gitlab/polling_interval_spec.rb4
-rw-r--r--spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_status_spec.rb13
-rw-r--r--spec/lib/gitlab/workhorse_spec.rb4
37 files changed, 1218 insertions, 301 deletions
diff --git a/spec/lib/banzai/filter/markdown_filter_spec.rb b/spec/lib/banzai/filter/markdown_filter_spec.rb
new file mode 100644
index 00000000000..897288b8ad5
--- /dev/null
+++ b/spec/lib/banzai/filter/markdown_filter_spec.rb
@@ -0,0 +1,19 @@
+require 'spec_helper'
+
+describe Banzai::Filter::MarkdownFilter, lib: true do
+ include FilterSpecHelper
+
+ context 'code block' do
+ it 'adds language to lang attribute when specified' do
+ result = filter("```html\nsome code\n```")
+
+ expect(result).to start_with("\n<pre><code lang=\"html\">")
+ end
+
+ it 'does not add language to lang attribute when not specified' do
+ result = filter("```\nsome code\n```")
+
+ expect(result).to start_with("\n<pre><code>")
+ end
+ end
+end
diff --git a/spec/lib/banzai/filter/sanitization_filter_spec.rb b/spec/lib/banzai/filter/sanitization_filter_spec.rb
index b4cd5f63a15..fdbc65b5e00 100644
--- a/spec/lib/banzai/filter/sanitization_filter_spec.rb
+++ b/spec/lib/banzai/filter/sanitization_filter_spec.rb
@@ -49,11 +49,12 @@ describe Banzai::Filter::SanitizationFilter, lib: true do
instance = described_class.new('Foo')
3.times { instance.whitelist }
- expect(instance.whitelist[:transformers].size).to eq 5
+ expect(instance.whitelist[:transformers].size).to eq 4
end
- it 'allows syntax highlighting' do
- exp = act = %q{<pre class="code highlight white c"><code><span class="k">def</span></code></pre>}
+ it 'sanitizes `class` attribute from all elements' do
+ act = %q{<pre class="code highlight white c"><code>&lt;span class="k"&gt;def&lt;/span&gt;</code></pre>}
+ exp = %q{<pre><code>&lt;span class="k"&gt;def&lt;/span&gt;</code></pre>}
expect(filter(act).to_html).to eq exp
end
diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
index 63fb1bb25c4..f61fc8ceb9e 100644
--- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
+++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
@@ -12,14 +12,14 @@ describe Banzai::Filter::SyntaxHighlightFilter, lib: true do
context "when a valid language is specified" do
it "highlights as that language" do
- result = filter('<pre><code class="ruby">def fun end</code></pre>')
+ result = filter('<pre><code lang="ruby">def fun end</code></pre>')
expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight ruby" lang="ruby" v-pre="true"><code><span id="LC1" class="line" lang="ruby"><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></span></code></pre>')
end
end
context "when an invalid language is specified" do
it "highlights as plaintext" do
- result = filter('<pre><code class="gnuplot">This is a test</code></pre>')
+ result = filter('<pre><code lang="gnuplot">This is a test</code></pre>')
expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre>')
end
end
@@ -30,7 +30,7 @@ describe Banzai::Filter::SyntaxHighlightFilter, lib: true do
end
it "highlights as plaintext" do
- result = filter('<pre><code class="ruby">This is a test</code></pre>')
+ result = filter('<pre><code lang="ruby">This is a test</code></pre>')
expect(result.to_html).to eq('<pre class="code highlight" lang="" v-pre="true"><code>This is a test</code></pre>')
end
end
diff --git a/spec/lib/ci/ansi2html_spec.rb b/spec/lib/ci/ansi2html_spec.rb
index 0762fd7e56a..a5dfb49478a 100644
--- a/spec/lib/ci/ansi2html_spec.rb
+++ b/spec/lib/ci/ansi2html_spec.rb
@@ -1,159 +1,160 @@
require 'spec_helper'
describe Ci::Ansi2html, lib: true do
- subject { Ci::Ansi2html }
+ subject { described_class }
it "prints non-ansi as-is" do
- expect(subject.convert("Hello")[:html]).to eq('Hello')
+ expect(convert_html("Hello")).to eq('Hello')
end
it "strips non-color-changing controll sequences" do
- expect(subject.convert("Hello \e[2Kworld")[:html]).to eq('Hello world')
+ expect(convert_html("Hello \e[2Kworld")).to eq('Hello world')
end
it "prints simply red" do
- expect(subject.convert("\e[31mHello\e[0m")[:html]).to eq('<span class="term-fg-red">Hello</span>')
+ expect(convert_html("\e[31mHello\e[0m")).to eq('<span class="term-fg-red">Hello</span>')
end
it "prints simply red without trailing reset" do
- expect(subject.convert("\e[31mHello")[:html]).to eq('<span class="term-fg-red">Hello</span>')
+ expect(convert_html("\e[31mHello")).to eq('<span class="term-fg-red">Hello</span>')
end
it "prints simply yellow" do
- expect(subject.convert("\e[33mHello\e[0m")[:html]).to eq('<span class="term-fg-yellow">Hello</span>')
+ expect(convert_html("\e[33mHello\e[0m")).to eq('<span class="term-fg-yellow">Hello</span>')
end
it "prints default on blue" do
- expect(subject.convert("\e[39;44mHello")[:html]).to eq('<span class="term-bg-blue">Hello</span>')
+ expect(convert_html("\e[39;44mHello")).to eq('<span class="term-bg-blue">Hello</span>')
end
it "prints red on blue" do
- expect(subject.convert("\e[31;44mHello")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello</span>')
+ expect(convert_html("\e[31;44mHello")).to eq('<span class="term-fg-red term-bg-blue">Hello</span>')
end
it "resets colors after red on blue" do
- expect(subject.convert("\e[31;44mHello\e[0m world")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello</span> world')
+ expect(convert_html("\e[31;44mHello\e[0m world")).to eq('<span class="term-fg-red term-bg-blue">Hello</span> world')
end
it "performs color change from red/blue to yellow/blue" do
- expect(subject.convert("\e[31;44mHello \e[33mworld")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-fg-yellow term-bg-blue">world</span>')
+ expect(convert_html("\e[31;44mHello \e[33mworld")).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-fg-yellow term-bg-blue">world</span>')
end
it "performs color change from red/blue to yellow/green" do
- expect(subject.convert("\e[31;44mHello \e[33;42mworld")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-fg-yellow term-bg-green">world</span>')
+ expect(convert_html("\e[31;44mHello \e[33;42mworld")).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-fg-yellow term-bg-green">world</span>')
end
it "performs color change from red/blue to reset to yellow/green" do
- expect(subject.convert("\e[31;44mHello\e[0m \e[33;42mworld")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello</span> <span class="term-fg-yellow term-bg-green">world</span>')
+ expect(convert_html("\e[31;44mHello\e[0m \e[33;42mworld")).to eq('<span class="term-fg-red term-bg-blue">Hello</span> <span class="term-fg-yellow term-bg-green">world</span>')
end
it "ignores unsupported codes" do
- expect(subject.convert("\e[51mHello\e[0m")[:html]).to eq('Hello')
+ expect(convert_html("\e[51mHello\e[0m")).to eq('Hello')
end
it "prints light red" do
- expect(subject.convert("\e[91mHello\e[0m")[:html]).to eq('<span class="term-fg-l-red">Hello</span>')
+ expect(convert_html("\e[91mHello\e[0m")).to eq('<span class="term-fg-l-red">Hello</span>')
end
it "prints default on light red" do
- expect(subject.convert("\e[101mHello\e[0m")[:html]).to eq('<span class="term-bg-l-red">Hello</span>')
+ expect(convert_html("\e[101mHello\e[0m")).to eq('<span class="term-bg-l-red">Hello</span>')
end
it "performs color change from red/blue to default/blue" do
- expect(subject.convert("\e[31;44mHello \e[39mworld")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-bg-blue">world</span>')
+ expect(convert_html("\e[31;44mHello \e[39mworld")).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-bg-blue">world</span>')
end
it "performs color change from light red/blue to default/blue" do
- expect(subject.convert("\e[91;44mHello \e[39mworld")[:html]).to eq('<span class="term-fg-l-red term-bg-blue">Hello </span><span class="term-bg-blue">world</span>')
+ expect(convert_html("\e[91;44mHello \e[39mworld")).to eq('<span class="term-fg-l-red term-bg-blue">Hello </span><span class="term-bg-blue">world</span>')
end
it "prints bold text" do
- expect(subject.convert("\e[1mHello")[:html]).to eq('<span class="term-bold">Hello</span>')
+ expect(convert_html("\e[1mHello")).to eq('<span class="term-bold">Hello</span>')
end
it "resets bold text" do
- expect(subject.convert("\e[1mHello\e[21m world")[:html]).to eq('<span class="term-bold">Hello</span> world')
- expect(subject.convert("\e[1mHello\e[22m world")[:html]).to eq('<span class="term-bold">Hello</span> world')
+ expect(convert_html("\e[1mHello\e[21m world")).to eq('<span class="term-bold">Hello</span> world')
+ expect(convert_html("\e[1mHello\e[22m world")).to eq('<span class="term-bold">Hello</span> world')
end
it "prints italic text" do
- expect(subject.convert("\e[3mHello")[:html]).to eq('<span class="term-italic">Hello</span>')
+ expect(convert_html("\e[3mHello")).to eq('<span class="term-italic">Hello</span>')
end
it "resets italic text" do
- expect(subject.convert("\e[3mHello\e[23m world")[:html]).to eq('<span class="term-italic">Hello</span> world')
+ expect(convert_html("\e[3mHello\e[23m world")).to eq('<span class="term-italic">Hello</span> world')
end
it "prints underlined text" do
- expect(subject.convert("\e[4mHello")[:html]).to eq('<span class="term-underline">Hello</span>')
+ expect(convert_html("\e[4mHello")).to eq('<span class="term-underline">Hello</span>')
end
it "resets underlined text" do
- expect(subject.convert("\e[4mHello\e[24m world")[:html]).to eq('<span class="term-underline">Hello</span> world')
+ expect(convert_html("\e[4mHello\e[24m world")).to eq('<span class="term-underline">Hello</span> world')
end
it "prints concealed text" do
- expect(subject.convert("\e[8mHello")[:html]).to eq('<span class="term-conceal">Hello</span>')
+ expect(convert_html("\e[8mHello")).to eq('<span class="term-conceal">Hello</span>')
end
it "resets concealed text" do
- expect(subject.convert("\e[8mHello\e[28m world")[:html]).to eq('<span class="term-conceal">Hello</span> world')
+ expect(convert_html("\e[8mHello\e[28m world")).to eq('<span class="term-conceal">Hello</span> world')
end
it "prints crossed-out text" do
- expect(subject.convert("\e[9mHello")[:html]).to eq('<span class="term-cross">Hello</span>')
+ expect(convert_html("\e[9mHello")).to eq('<span class="term-cross">Hello</span>')
end
it "resets crossed-out text" do
- expect(subject.convert("\e[9mHello\e[29m world")[:html]).to eq('<span class="term-cross">Hello</span> world')
+ expect(convert_html("\e[9mHello\e[29m world")).to eq('<span class="term-cross">Hello</span> world')
end
it "can print 256 xterm fg colors" do
- expect(subject.convert("\e[38;5;16mHello")[:html]).to eq('<span class="xterm-fg-16">Hello</span>')
+ expect(convert_html("\e[38;5;16mHello")).to eq('<span class="xterm-fg-16">Hello</span>')
end
it "can print 256 xterm fg colors on normal magenta background" do
- expect(subject.convert("\e[38;5;16;45mHello")[:html]).to eq('<span class="xterm-fg-16 term-bg-magenta">Hello</span>')
+ expect(convert_html("\e[38;5;16;45mHello")).to eq('<span class="xterm-fg-16 term-bg-magenta">Hello</span>')
end
it "can print 256 xterm bg colors" do
- expect(subject.convert("\e[48;5;240mHello")[:html]).to eq('<span class="xterm-bg-240">Hello</span>')
+ expect(convert_html("\e[48;5;240mHello")).to eq('<span class="xterm-bg-240">Hello</span>')
end
it "can print 256 xterm bg colors on normal magenta foreground" do
- expect(subject.convert("\e[48;5;16;35mHello")[:html]).to eq('<span class="term-fg-magenta xterm-bg-16">Hello</span>')
+ expect(convert_html("\e[48;5;16;35mHello")).to eq('<span class="term-fg-magenta xterm-bg-16">Hello</span>')
end
it "prints bold colored text vividly" do
- expect(subject.convert("\e[1;31mHello\e[0m")[:html]).to eq('<span class="term-fg-l-red term-bold">Hello</span>')
+ expect(convert_html("\e[1;31mHello\e[0m")).to eq('<span class="term-fg-l-red term-bold">Hello</span>')
end
it "prints bold light colored text correctly" do
- expect(subject.convert("\e[1;91mHello\e[0m")[:html]).to eq('<span class="term-fg-l-red term-bold">Hello</span>')
+ expect(convert_html("\e[1;91mHello\e[0m")).to eq('<span class="term-fg-l-red term-bold">Hello</span>')
end
it "prints &lt;" do
- expect(subject.convert("<")[:html]).to eq('&lt;')
+ expect(convert_html("<")).to eq('&lt;')
end
it "replaces newlines with line break tags" do
- expect(subject.convert("\n")[:html]).to eq('<br>')
+ expect(convert_html("\n")).to eq('<br>')
end
it "groups carriage returns with newlines" do
- expect(subject.convert("\r\n")[:html]).to eq('<br>')
+ expect(convert_html("\r\n")).to eq('<br>')
end
describe "incremental update" do
shared_examples 'stateable converter' do
- let(:pass1) { subject.convert(pre_text) }
- let(:pass2) { subject.convert(pre_text + text, pass1[:state]) }
+ let(:pass1_stream) { StringIO.new(pre_text) }
+ let(:pass2_stream) { StringIO.new(pre_text + text) }
+ let(:pass1) { subject.convert(pass1_stream) }
+ let(:pass2) { subject.convert(pass2_stream, pass1.state) }
it "to returns html to append" do
- expect(pass2[:append]).to be_truthy
- expect(pass2[:html]).to eq(html)
- expect(pass1[:text] + pass2[:text]).to eq(pre_text + text)
- expect(pass1[:html] + pass2[:html]).to eq(pre_html + html)
+ expect(pass2.append).to be_truthy
+ expect(pass2.html).to eq(html)
+ expect(pass1.html + pass2.html).to eq(pre_html + html)
end
end
@@ -193,4 +194,27 @@ describe Ci::Ansi2html, lib: true do
it_behaves_like 'stateable converter'
end
end
+
+ describe "truncates" do
+ let(:text) { "Hello World" }
+ let(:stream) { StringIO.new(text) }
+ let(:subject) { described_class.convert(stream) }
+
+ before do
+ stream.seek(3, IO::SEEK_SET)
+ end
+
+ it "returns truncated output" do
+ expect(subject.truncated).to be_truthy
+ end
+
+ it "does not append output" do
+ expect(subject.append).to be_falsey
+ end
+ end
+
+ def convert_html(data)
+ stream = StringIO.new(data)
+ subject.convert(stream).html
+ end
end
diff --git a/spec/lib/container_registry/blob_spec.rb b/spec/lib/container_registry/blob_spec.rb
index bbacdc67ebd..f06e5fd54a2 100644
--- a/spec/lib/container_registry/blob_spec.rb
+++ b/spec/lib/container_registry/blob_spec.rb
@@ -1,110 +1,121 @@
require 'spec_helper'
describe ContainerRegistry::Blob do
- let(:digest) { 'sha256:0123456789012345' }
+ let(:group) { create(:group, name: 'group') }
+ let(:project) { create(:empty_project, path: 'test', group: group) }
+
+ let(:repository) do
+ create(:container_repository, name: 'image',
+ tags: %w[latest rc1],
+ project: project)
+ end
+
let(:config) do
- {
- 'digest' => digest,
+ { 'digest' => 'sha256:0123456789012345',
'mediaType' => 'binary',
- 'size' => 1000
- }
+ 'size' => 1000 }
+ end
+
+ let(:blob) { described_class.new(repository, config) }
+
+ before do
+ stub_container_registry_config(enabled: true,
+ api_url: 'http://registry.gitlab',
+ host_port: 'registry.gitlab')
end
- let(:token) { 'authorization-token' }
-
- let(:registry) { ContainerRegistry::Registry.new('http://example.com', token: token) }
- let(:repository) { registry.repository('group/test') }
- let(:blob) { repository.blob(config) }
it { expect(blob).to respond_to(:repository) }
it { expect(blob).to delegate_method(:registry).to(:repository) }
it { expect(blob).to delegate_method(:client).to(:repository) }
- context '#path' do
- subject { blob.path }
-
- it { is_expected.to eq('example.com/group/test@sha256:0123456789012345') }
+ describe '#path' do
+ it 'returns a valid path to the blob' do
+ expect(blob.path).to eq('group/test/image@sha256:0123456789012345')
+ end
end
- context '#digest' do
- subject { blob.digest }
-
- it { is_expected.to eq(digest) }
+ describe '#digest' do
+ it 'return correct digest value' do
+ expect(blob.digest).to eq 'sha256:0123456789012345'
+ end
end
- context '#type' do
- subject { blob.type }
-
- it { is_expected.to eq('binary') }
+ describe '#type' do
+ it 'returns a correct type' do
+ expect(blob.type).to eq 'binary'
+ end
end
- context '#revision' do
- subject { blob.revision }
-
- it { is_expected.to eq('0123456789012345') }
+ describe '#revision' do
+ it 'returns a correct blob SHA' do
+ expect(blob.revision).to eq '0123456789012345'
+ end
end
- context '#short_revision' do
- subject { blob.short_revision }
-
- it { is_expected.to eq('012345678') }
+ describe '#short_revision' do
+ it 'return a short SHA' do
+ expect(blob.short_revision).to eq '012345678'
+ end
end
- context '#delete' do
+ describe '#delete' do
before do
- stub_request(:delete, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345').
- to_return(status: 200)
+ stub_request(:delete, 'http://registry.gitlab/v2/group/test/image/blobs/sha256:0123456789012345')
+ .to_return(status: 200)
end
- subject { blob.delete }
-
- it { is_expected.to be_truthy }
+ it 'returns true when blob has been successfuly deleted' do
+ expect(blob.delete).to be_truthy
+ end
end
- context '#data' do
- let(:data) { '{"key":"value"}' }
-
- subject { blob.data }
-
+ describe '#data' do
context 'when locally stored' do
before do
- stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345').
+ stub_request(:get, 'http://registry.gitlab/v2/group/test/image/blobs/sha256:0123456789012345').
to_return(
status: 200,
headers: { 'Content-Type' => 'application/json' },
- body: data)
+ body: '{"key":"value"}')
end
- it { is_expected.to eq(data) }
+ it 'returns a correct blob data' do
+ expect(blob.data).to eq '{"key":"value"}'
+ end
end
context 'when externally stored' do
+ let(:location) { 'http://external.com/blob/file' }
+
before do
- stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345').
- with(headers: { 'Authorization' => "bearer #{token}" }).
- to_return(
+ stub_request(:get, 'http://registry.gitlab/v2/group/test/image/blobs/sha256:0123456789012345')
+ .with(headers: { 'Authorization' => 'bearer token' })
+ .to_return(
status: 307,
headers: { 'Location' => location })
end
context 'for a valid address' do
- let(:location) { 'http://external.com/blob/file' }
-
before do
stub_request(:get, location).
with(headers: { 'Authorization' => nil }).
to_return(
status: 200,
headers: { 'Content-Type' => 'application/json' },
- body: data)
+ body: '{"key":"value"}')
end
- it { is_expected.to eq(data) }
+ it 'returns correct data' do
+ expect(blob.data).to eq '{"key":"value"}'
+ end
end
context 'for invalid file' do
let(:location) { 'file:///etc/passwd' }
- it { expect{ subject }.to raise_error(ArgumentError, 'invalid address') }
+ it 'raises an error' do
+ expect { blob.data }.to raise_error(ArgumentError, 'invalid address')
+ end
end
end
end
diff --git a/spec/lib/container_registry/path_spec.rb b/spec/lib/container_registry/path_spec.rb
new file mode 100644
index 00000000000..b9c4572c269
--- /dev/null
+++ b/spec/lib/container_registry/path_spec.rb
@@ -0,0 +1,212 @@
+require 'spec_helper'
+
+describe ContainerRegistry::Path do
+ subject { described_class.new(path) }
+
+ describe '#components' do
+ let(:path) { 'path/to/some/project' }
+
+ it 'splits components by a forward slash' do
+ expect(subject.components).to eq %w[path to some project]
+ end
+ end
+
+ describe '#nodes' do
+ context 'when repository path is valid' do
+ let(:path) { 'path/to/some/project' }
+
+ it 'return all project path like node in reverse order' do
+ expect(subject.nodes).to eq %w[path/to/some/project
+ path/to/some
+ path/to]
+ end
+ end
+
+ context 'when repository path is invalid' do
+ let(:path) { '' }
+
+ it 'rasises en error' do
+ expect { subject.nodes }
+ .to raise_error described_class::InvalidRegistryPathError
+ end
+ end
+ end
+
+ describe '#to_s' do
+ let(:path) { 'some/image' }
+
+ it 'return a string with a repository path' do
+ expect(subject.to_s).to eq path
+ end
+ end
+
+ describe '#valid?' do
+ context 'when path has less than two components' do
+ let(:path) { 'something/' }
+
+ it { is_expected.not_to be_valid }
+ end
+
+ context 'when path has more than allowed number of components' do
+ let(:path) { 'a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/r/s/t/u/w/y/z' }
+
+ it { is_expected.not_to be_valid }
+ end
+
+ context 'when path has invalid characters' do
+ let(:path) { 'some\path' }
+
+ it { is_expected.not_to be_valid }
+ end
+
+ context 'when path has two or more components' do
+ let(:path) { 'some/path' }
+
+ it { is_expected.to be_valid }
+ end
+
+ context 'when path is related to multi-level image' do
+ let(:path) { 'some/path/my/image' }
+
+ it { is_expected.to be_valid }
+ end
+ end
+
+ describe '#has_repository?' do
+ context 'when project exists' do
+ let(:project) { create(:empty_project) }
+ let(:path) { "#{project.full_path}/my/image" }
+
+ context 'when path already has matching repository' do
+ before do
+ create(:container_repository, project: project, name: 'my/image')
+ end
+
+ it { is_expected.to have_repository }
+ it { is_expected.to have_project }
+ end
+
+ context 'when path does not have matching repository' do
+ it { is_expected.not_to have_repository }
+ it { is_expected.to have_project }
+ end
+ end
+
+ context 'when project does not exist' do
+ let(:path) { 'some/project/my/image' }
+
+ it { is_expected.not_to have_repository }
+ it { is_expected.not_to have_project }
+ end
+ end
+
+ describe '#repository_project' do
+ let(:group) { create(:group, path: 'some_group') }
+
+ context 'when project for given path exists' do
+ let(:path) { 'some_group/some_project' }
+
+ before do
+ create(:empty_project, group: group, name: 'some_project')
+ create(:empty_project, name: 'some_project')
+ end
+
+ it 'returns a correct project' do
+ expect(subject.repository_project.group).to eq group
+ end
+ end
+
+ context 'when project for given path does not exist' do
+ let(:path) { 'not/matching' }
+
+ it 'returns nil' do
+ expect(subject.repository_project).to be_nil
+ end
+ end
+
+ context 'when matching multi-level path' do
+ let(:project) do
+ create(:empty_project, group: group, name: 'some_project')
+ end
+
+ context 'when using the zero-level path' do
+ let(:path) { project.full_path }
+
+ it 'supports zero-level path' do
+ expect(subject.repository_project).to eq project
+ end
+ end
+
+ context 'when using first-level path' do
+ let(:path) { "#{project.full_path}/repository" }
+
+ it 'supports first-level path' do
+ expect(subject.repository_project).to eq project
+ end
+ end
+
+ context 'when using second-level path' do
+ let(:path) { "#{project.full_path}/repository/name" }
+
+ it 'supports second-level path' do
+ expect(subject.repository_project).to eq project
+ end
+ end
+
+ context 'when using too deep nesting in the path' do
+ let(:path) { "#{project.full_path}/repository/name/invalid" }
+
+ it 'does not support three-levels of nesting' do
+ expect(subject.repository_project).to be_nil
+ end
+ end
+ end
+ end
+
+ describe '#repository_name' do
+ context 'when project does not exist' do
+ let(:path) { 'some/name' }
+
+ it 'returns nil' do
+ expect(subject.repository_name).to be_nil
+ end
+ end
+
+ context 'when project exists' do
+ let(:group) { create(:group, path: 'some_group') }
+
+ let(:project) do
+ create(:empty_project, group: group, name: 'some_project')
+ end
+
+ before do
+ allow(path).to receive(:repository_project)
+ .and_return(project)
+ end
+
+ context 'when project path equal repository path' do
+ let(:path) { 'some_group/some_project' }
+
+ it 'returns an empty string' do
+ expect(subject.repository_name).to eq ''
+ end
+ end
+
+ context 'when repository path has one additional level' do
+ let(:path) { 'some_group/some_project/repository' }
+
+ it 'returns a correct repository name' do
+ expect(subject.repository_name).to eq 'repository'
+ end
+ end
+
+ context 'when repository path has two additional levels' do
+ let(:path) { 'some_group/some_project/repository/image' }
+
+ it 'returns a correct repository name' do
+ expect(subject.repository_name).to eq 'repository/image'
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/container_registry/registry_spec.rb b/spec/lib/container_registry/registry_spec.rb
index 4f3f8b24fc4..4d6eea94bf0 100644
--- a/spec/lib/container_registry/registry_spec.rb
+++ b/spec/lib/container_registry/registry_spec.rb
@@ -10,7 +10,7 @@ describe ContainerRegistry::Registry do
it { is_expected.to respond_to(:uri) }
it { is_expected.to respond_to(:path) }
- it { expect(subject.repository('test')).not_to be_nil }
+ it { expect(subject).not_to be_nil }
context '#path' do
subject { registry.path }
diff --git a/spec/lib/container_registry/repository_spec.rb b/spec/lib/container_registry/repository_spec.rb
deleted file mode 100644
index c364e759108..00000000000
--- a/spec/lib/container_registry/repository_spec.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-require 'spec_helper'
-
-describe ContainerRegistry::Repository do
- let(:registry) { ContainerRegistry::Registry.new('http://example.com') }
- let(:repository) { registry.repository('group/test') }
-
- it { expect(repository).to respond_to(:registry) }
- it { expect(repository).to delegate_method(:client).to(:registry) }
- it { expect(repository.tag('test')).not_to be_nil }
-
- context '#path' do
- subject { repository.path }
-
- it { is_expected.to eq('example.com/group/test') }
- end
-
- context 'manifest processing' do
- before do
- stub_request(:get, 'http://example.com/v2/group/test/tags/list').
- with(headers: { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' }).
- to_return(
- status: 200,
- body: JSON.dump(tags: ['test']),
- headers: { 'Content-Type' => 'application/json' })
- end
-
- context '#manifest' do
- subject { repository.manifest }
-
- it { is_expected.not_to be_nil }
- end
-
- context '#valid?' do
- subject { repository.valid? }
-
- it { is_expected.to be_truthy }
- end
-
- context '#tags' do
- subject { repository.tags }
-
- it { is_expected.not_to be_empty }
- end
- end
-
- context '#delete_tags' do
- let(:tag) { ContainerRegistry::Tag.new(repository, 'tag') }
-
- before { expect(repository).to receive(:tags).twice.and_return([tag]) }
-
- subject { repository.delete_tags }
-
- context 'succeeds' do
- before { expect(tag).to receive(:delete).and_return(true) }
-
- it { is_expected.to be_truthy }
- end
-
- context 'any fails' do
- before { expect(tag).to receive(:delete).and_return(false) }
-
- it { is_expected.to be_falsey }
- end
- end
-end
diff --git a/spec/lib/container_registry/tag_spec.rb b/spec/lib/container_registry/tag_spec.rb
index c5e31ae82b6..bc1912d8e6c 100644
--- a/spec/lib/container_registry/tag_spec.rb
+++ b/spec/lib/container_registry/tag_spec.rb
@@ -1,25 +1,59 @@
require 'spec_helper'
describe ContainerRegistry::Tag do
- let(:registry) { ContainerRegistry::Registry.new('http://example.com') }
- let(:repository) { registry.repository('group/test') }
- let(:tag) { repository.tag('tag') }
- let(:headers) { { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' } }
+ let(:group) { create(:group, name: 'group') }
+ let(:project) { create(:project, path: 'test', group: group) }
+
+ let(:repository) do
+ create(:container_repository, name: '', project: project)
+ end
+
+ let(:headers) do
+ { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' }
+ end
+
+ let(:tag) { described_class.new(repository, 'tag') }
+
+ before do
+ stub_container_registry_config(enabled: true,
+ api_url: 'http://registry.gitlab',
+ host_port: 'registry.gitlab')
+ end
it { expect(tag).to respond_to(:repository) }
it { expect(tag).to delegate_method(:registry).to(:repository) }
it { expect(tag).to delegate_method(:client).to(:repository) }
- context '#path' do
- subject { tag.path }
+ describe '#path' do
+ context 'when tag belongs to zero-level repository' do
+ let(:repository) do
+ create(:container_repository, name: '',
+ tags: %w[rc1],
+ project: project)
+ end
+
+ it 'returns path to the image' do
+ expect(tag.path).to eq('group/test:tag')
+ end
+ end
+
+ context 'when tag belongs to first-level repository' do
+ let(:repository) do
+ create(:container_repository, name: 'my_image',
+ tags: %w[tag],
+ project: project)
+ end
- it { is_expected.to eq('example.com/group/test:tag') }
+ it 'returns path to the image' do
+ expect(tag.path).to eq('group/test/my_image:tag')
+ end
+ end
end
context 'manifest processing' do
context 'schema v1' do
before do
- stub_request(:get, 'http://example.com/v2/group/test/manifests/tag').
+ stub_request(:get, 'http://registry.gitlab/v2/group/test/manifests/tag').
with(headers: headers).
to_return(
status: 200,
@@ -56,7 +90,7 @@ describe ContainerRegistry::Tag do
context 'schema v2' do
before do
- stub_request(:get, 'http://example.com/v2/group/test/manifests/tag').
+ stub_request(:get, 'http://registry.gitlab/v2/group/test/manifests/tag').
with(headers: headers).
to_return(
status: 200,
@@ -93,7 +127,7 @@ describe ContainerRegistry::Tag do
context 'when locally stored' do
before do
- stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac').
+ stub_request(:get, 'http://registry.gitlab/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac').
with(headers: { 'Accept' => 'application/octet-stream' }).
to_return(
status: 200,
@@ -105,7 +139,7 @@ describe ContainerRegistry::Tag do
context 'when externally stored' do
before do
- stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac').
+ stub_request(:get, 'http://registry.gitlab/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac').
with(headers: { 'Accept' => 'application/octet-stream' }).
to_return(
status: 307,
@@ -123,29 +157,29 @@ describe ContainerRegistry::Tag do
end
end
- context 'manifest digest' do
+ context 'with stubbed digest' do
before do
- stub_request(:head, 'http://example.com/v2/group/test/manifests/tag').
- with(headers: headers).
- to_return(status: 200, headers: { 'Docker-Content-Digest' => 'sha256:digest' })
+ stub_request(:head, 'http://registry.gitlab/v2/group/test/manifests/tag')
+ .with(headers: headers)
+ .to_return(status: 200, headers: { 'Docker-Content-Digest' => 'sha256:digest' })
end
- context '#digest' do
- subject { tag.digest }
-
- it { is_expected.to eq('sha256:digest') }
+ describe '#digest' do
+ it 'returns a correct tag digest' do
+ expect(tag.digest).to eq 'sha256:digest'
+ end
end
- context '#delete' do
+ describe '#delete' do
before do
- stub_request(:delete, 'http://example.com/v2/group/test/manifests/sha256:digest').
- with(headers: headers).
- to_return(status: 200)
+ stub_request(:delete, 'http://registry.gitlab/v2/group/test/manifests/sha256:digest')
+ .with(headers: headers)
+ .to_return(status: 200)
end
- subject { tag.delete }
-
- it { is_expected.to be_truthy }
+ it 'correctly deletes the tag' do
+ expect(tag.delete).to be_truthy
+ end
end
end
end
diff --git a/spec/lib/gitlab/backend/shell_spec.rb b/spec/lib/gitlab/backend/shell_spec.rb
index 4b08a02ec73..6675d26734e 100644
--- a/spec/lib/gitlab/backend/shell_spec.rb
+++ b/spec/lib/gitlab/backend/shell_spec.rb
@@ -69,6 +69,15 @@ describe Gitlab::Shell, lib: true do
expect(io).to have_received(:puts).with("key-42\tssh-rsa foo")
end
+ it 'handles multiple spaces in the key' do
+ io = spy(:io)
+ adder = described_class.new(io)
+
+ adder.add_key('key-42', "ssh-rsa foo")
+
+ expect(io).to have_received(:puts).with("key-42\tssh-rsa foo")
+ end
+
it 'raises an exception if the key contains a tab' do
expect do
described_class.new(StringIO.new).add_key('key-42', "ssh-rsa\tfoobar")
diff --git a/spec/lib/gitlab/ci/cron_parser_spec.rb b/spec/lib/gitlab/ci/cron_parser_spec.rb
new file mode 100644
index 00000000000..0864bc7258d
--- /dev/null
+++ b/spec/lib/gitlab/ci/cron_parser_spec.rb
@@ -0,0 +1,116 @@
+require 'spec_helper'
+
+describe Gitlab::Ci::CronParser do
+ shared_examples_for "returns time in the future" do
+ it { is_expected.to be > Time.now }
+ end
+
+ describe '#next_time_from' do
+ subject { described_class.new(cron, cron_timezone).next_time_from(Time.now) }
+
+ context 'when cron and cron_timezone are valid' do
+ context 'when specific time' do
+ let(:cron) { '3 4 5 6 *' }
+ let(:cron_timezone) { 'UTC' }
+
+ it_behaves_like "returns time in the future"
+
+ it 'returns exact time' do
+ expect(subject.min).to eq(3)
+ expect(subject.hour).to eq(4)
+ expect(subject.day).to eq(5)
+ expect(subject.month).to eq(6)
+ end
+ end
+
+ context 'when specific day of week' do
+ let(:cron) { '* * * * 0' }
+ let(:cron_timezone) { 'UTC' }
+
+ it_behaves_like "returns time in the future"
+
+ it 'returns exact day of week' do
+ expect(subject.wday).to eq(0)
+ end
+ end
+
+ context 'when slash used' do
+ let(:cron) { '*/10 */6 */10 */10 *' }
+ let(:cron_timezone) { 'UTC' }
+
+ it_behaves_like "returns time in the future"
+
+ it 'returns specific time' do
+ expect(subject.min).to be_in([0, 10, 20, 30, 40, 50])
+ expect(subject.hour).to be_in([0, 6, 12, 18])
+ expect(subject.day).to be_in([1, 11, 21, 31])
+ expect(subject.month).to be_in([1, 11])
+ end
+ end
+
+ context 'when range used' do
+ let(:cron) { '0,20,40 * 1-5 * *' }
+ let(:cron_timezone) { 'UTC' }
+
+ it_behaves_like "returns time in the future"
+
+ it 'returns specific time' do
+ expect(subject.min).to be_in([0, 20, 40])
+ expect(subject.day).to be_in((1..5).to_a)
+ end
+ end
+
+ context 'when cron_timezone is US/Pacific' do
+ let(:cron) { '0 0 * * *' }
+ let(:cron_timezone) { 'US/Pacific' }
+
+ it_behaves_like "returns time in the future"
+
+ it 'converts time in server time zone' do
+ expect(subject.hour).to eq((Time.zone.now.in_time_zone(cron_timezone).utc_offset / 60 / 60).abs)
+ end
+ end
+ end
+
+ context 'when cron and cron_timezone are invalid' do
+ let(:cron) { 'invalid_cron' }
+ let(:cron_timezone) { 'invalid_cron_timezone' }
+
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
+ end
+
+ describe '#cron_valid?' do
+ subject { described_class.new(cron, Gitlab::Ci::CronParser::VALID_SYNTAX_SAMPLE_TIME_ZONE).cron_valid? }
+
+ context 'when cron is valid' do
+ let(:cron) { '* * * * *' }
+
+ it { is_expected.to eq(true) }
+ end
+
+ context 'when cron is invalid' do
+ let(:cron) { '*********' }
+
+ it { is_expected.to eq(false) }
+ end
+ end
+
+ describe '#cron_timezone_valid?' do
+ subject { described_class.new(Gitlab::Ci::CronParser::VALID_SYNTAX_SAMPLE_CRON, cron_timezone).cron_timezone_valid? }
+
+ context 'when cron is valid' do
+ let(:cron_timezone) { 'Europe/Istanbul' }
+
+ it { is_expected.to eq(true) }
+ end
+
+ context 'when cron is invalid' do
+ let(:cron_timezone) { 'Invalid-zone' }
+
+ it { is_expected.to eq(false) }
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/trace/stream_spec.rb b/spec/lib/gitlab/ci/trace/stream_spec.rb
new file mode 100644
index 00000000000..f1a1a71c528
--- /dev/null
+++ b/spec/lib/gitlab/ci/trace/stream_spec.rb
@@ -0,0 +1,201 @@
+require 'spec_helper'
+
+describe Gitlab::Ci::Trace::Stream do
+ describe 'delegates' do
+ subject { described_class.new { nil } }
+
+ it { is_expected.to delegate_method(:close).to(:stream) }
+ it { is_expected.to delegate_method(:tell).to(:stream) }
+ it { is_expected.to delegate_method(:seek).to(:stream) }
+ it { is_expected.to delegate_method(:size).to(:stream) }
+ it { is_expected.to delegate_method(:path).to(:stream) }
+ it { is_expected.to delegate_method(:truncate).to(:stream) }
+ it { is_expected.to delegate_method(:valid?).to(:stream).as(:present?) }
+ it { is_expected.to delegate_method(:file?).to(:path).as(:present?) }
+ end
+
+ describe '#limit' do
+ let(:stream) do
+ described_class.new do
+ StringIO.new("12345678")
+ end
+ end
+
+ it 'if size is larger we start from beggining' do
+ stream.limit(10)
+
+ expect(stream.tell).to eq(0)
+ end
+
+ it 'if size is smaller we start from the end' do
+ stream.limit(2)
+
+ expect(stream.tell).to eq(6)
+ end
+ end
+
+ describe '#append' do
+ let(:stream) do
+ described_class.new do
+ StringIO.new("12345678")
+ end
+ end
+
+ it "truncates and append content" do
+ stream.append("89", 4)
+ stream.seek(0)
+
+ expect(stream.size).to eq(6)
+ expect(stream.raw).to eq("123489")
+ end
+ end
+
+ describe '#set' do
+ let(:stream) do
+ described_class.new do
+ StringIO.new("12345678")
+ end
+ end
+
+ before do
+ stream.set("8901")
+ end
+
+ it "overwrite content" do
+ stream.seek(0)
+
+ expect(stream.size).to eq(4)
+ expect(stream.raw).to eq("8901")
+ end
+ end
+
+ describe '#raw' do
+ let(:path) { __FILE__ }
+ let(:lines) { File.readlines(path) }
+ let(:stream) do
+ described_class.new do
+ File.open(path)
+ end
+ end
+
+ it 'returns all contents if last_lines is not specified' do
+ result = stream.raw
+
+ expect(result).to eq(lines.join)
+ expect(result.encoding).to eq(Encoding.default_external)
+ end
+
+ context 'limit max lines' do
+ before do
+ # specifying BUFFER_SIZE forces to seek backwards
+ allow(described_class).to receive(:BUFFER_SIZE)
+ .and_return(2)
+ end
+
+ it 'returns last few lines' do
+ result = stream.raw(last_lines: 2)
+
+ expect(result).to eq(lines.last(2).join)
+ expect(result.encoding).to eq(Encoding.default_external)
+ end
+
+ it 'returns everything if trying to get too many lines' do
+ result = stream.raw(last_lines: lines.size * 2)
+
+ expect(result).to eq(lines.join)
+ expect(result.encoding).to eq(Encoding.default_external)
+ end
+ end
+ end
+
+ describe '#html_with_state' do
+ let(:stream) do
+ described_class.new do
+ StringIO.new("1234")
+ end
+ end
+
+ it 'returns html content with state' do
+ result = stream.html_with_state
+
+ expect(result.html).to eq("1234")
+ end
+
+ context 'follow-up state' do
+ let!(:last_result) { stream.html_with_state }
+
+ before do
+ stream.append("5678", 4)
+ stream.seek(0)
+ end
+
+ it "returns appended trace" do
+ result = stream.html_with_state(last_result.state)
+
+ expect(result.append).to be_truthy
+ expect(result.html).to eq("5678")
+ end
+ end
+ end
+
+ describe '#html' do
+ let(:stream) do
+ described_class.new do
+ StringIO.new("12\n34\n56")
+ end
+ end
+
+ it "returns html" do
+ expect(stream.html).to eq("12<br>34<br>56")
+ end
+
+ it "returns html for last line only" do
+ expect(stream.html(last_lines: 1)).to eq("56")
+ end
+ end
+
+ describe '#extract_coverage' do
+ let(:stream) do
+ described_class.new do
+ StringIO.new(data)
+ end
+ end
+
+ subject { stream.extract_coverage(regex) }
+
+ context 'valid content & regex' do
+ let(:data) { 'Coverage 1033 / 1051 LOC (98.29%) covered' }
+ let(:regex) { '\(\d+.\d+\%\) covered' }
+
+ it { is_expected.to eq(98.29) }
+ end
+
+ context 'valid content & bad regex' do
+ let(:data) { 'Coverage 1033 / 1051 LOC (98.29%) covered\n' }
+ let(:regex) { 'very covered' }
+
+ it { is_expected.to be_nil }
+ end
+
+ context 'no coverage content & regex' do
+ let(:data) { 'No coverage for today :sad:' }
+ let(:regex) { '\(\d+.\d+\%\) covered' }
+
+ it { is_expected.to be_nil }
+ end
+
+ context 'multiple results in content & regex' do
+ let(:data) { ' (98.39%) covered. (98.29%) covered' }
+ let(:regex) { '\(\d+.\d+\%\) covered' }
+
+ it { is_expected.to eq(98.29) }
+ end
+
+ context 'using a regex capture' do
+ let(:data) { 'TOTAL 9926 3489 65%' }
+ let(:regex) { 'TOTAL\s+\d+\s+\d+\s+(\d{1,3}\%)' }
+
+ it { is_expected.to eq(65) }
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/trace_reader_spec.rb b/spec/lib/gitlab/ci/trace_reader_spec.rb
deleted file mode 100644
index ff5551bf703..00000000000
--- a/spec/lib/gitlab/ci/trace_reader_spec.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-require 'spec_helper'
-
-describe Gitlab::Ci::TraceReader do
- let(:path) { __FILE__ }
- let(:lines) { File.readlines(path) }
- let(:bytesize) { lines.sum(&:bytesize) }
-
- it 'returns last few lines' do
- 10.times do
- subject = build_subject
- last_lines = random_lines
-
- expected = lines.last(last_lines).join
- result = subject.read(last_lines: last_lines)
-
- expect(result).to eq(expected)
- expect(result.encoding).to eq(Encoding.default_external)
- end
- end
-
- it 'returns everything if trying to get too many lines' do
- result = build_subject.read(last_lines: lines.size * 2)
-
- expect(result).to eq(lines.join)
- expect(result.encoding).to eq(Encoding.default_external)
- end
-
- it 'returns all contents if last_lines is not specified' do
- result = build_subject.read
-
- expect(result).to eq(lines.join)
- expect(result.encoding).to eq(Encoding.default_external)
- end
-
- it 'raises an error if not passing an integer for last_lines' do
- expect do
- build_subject.read(last_lines: lines)
- end.to raise_error(ArgumentError)
- end
-
- def random_lines
- Random.rand(lines.size) + 1
- end
-
- def random_buffer
- Random.rand(bytesize) + 1
- end
-
- def build_subject
- described_class.new(__FILE__, buffer_size: random_buffer)
- end
-end
diff --git a/spec/lib/gitlab/ci/trace_spec.rb b/spec/lib/gitlab/ci/trace_spec.rb
new file mode 100644
index 00000000000..69e8dc9220d
--- /dev/null
+++ b/spec/lib/gitlab/ci/trace_spec.rb
@@ -0,0 +1,216 @@
+require 'spec_helper'
+
+describe Gitlab::Ci::Trace do
+ let(:build) { create(:ci_build) }
+ let(:trace) { described_class.new(build) }
+
+ describe "associations" do
+ it { expect(trace).to respond_to(:job) }
+ it { expect(trace).to delegate_method(:old_trace).to(:job) }
+ end
+
+ describe '#html' do
+ before do
+ trace.set("12\n34")
+ end
+
+ it "returns formatted html" do
+ expect(trace.html).to eq("12<br>34")
+ end
+
+ it "returns last line of formatted html" do
+ expect(trace.html(last_lines: 1)).to eq("34")
+ end
+ end
+
+ describe '#raw' do
+ before do
+ trace.set("12\n34")
+ end
+
+ it "returns raw output" do
+ expect(trace.raw).to eq("12\n34")
+ end
+
+ it "returns last line of raw output" do
+ expect(trace.raw(last_lines: 1)).to eq("34")
+ end
+ end
+
+ describe '#extract_coverage' do
+ let(:regex) { '\(\d+.\d+\%\) covered' }
+
+ before do
+ trace.set('Coverage 1033 / 1051 LOC (98.29%) covered')
+ end
+
+ it "returns valid coverage" do
+ expect(trace.extract_coverage(regex)).to eq(98.29)
+ end
+ end
+
+ describe '#set' do
+ before do
+ trace.set("12")
+ end
+
+ it "returns trace" do
+ expect(trace.raw).to eq("12")
+ end
+
+ context 'overwrite trace' do
+ before do
+ trace.set("34")
+ end
+
+ it "returns new trace" do
+ expect(trace.raw).to eq("34")
+ end
+ end
+
+ context 'runners token' do
+ let(:token) { 'my_secret_token' }
+
+ before do
+ build.project.update(runners_token: token)
+ trace.set(token)
+ end
+
+ it "hides token" do
+ expect(trace.raw).not_to include(token)
+ end
+ end
+
+ context 'hides build token' do
+ let(:token) { 'my_secret_token' }
+
+ before do
+ build.update(token: token)
+ trace.set(token)
+ end
+
+ it "hides token" do
+ expect(trace.raw).not_to include(token)
+ end
+ end
+ end
+
+ describe '#append' do
+ before do
+ trace.set("1234")
+ end
+
+ it "returns correct trace" do
+ expect(trace.append("56", 4)).to eq(6)
+ expect(trace.raw).to eq("123456")
+ end
+
+ context 'tries to append trace at different offset' do
+ it "fails with append" do
+ expect(trace.append("56", 2)).to eq(-4)
+ expect(trace.raw).to eq("1234")
+ end
+ end
+
+ context 'runners token' do
+ let(:token) { 'my_secret_token' }
+
+ before do
+ build.project.update(runners_token: token)
+ trace.append(token, 0)
+ end
+
+ it "hides token" do
+ expect(trace.raw).not_to include(token)
+ end
+ end
+
+ context 'build token' do
+ let(:token) { 'my_secret_token' }
+
+ before do
+ build.update(token: token)
+ trace.append(token, 0)
+ end
+
+ it "hides token" do
+ expect(trace.raw).not_to include(token)
+ end
+ end
+ end
+
+ describe 'trace handling' do
+ context 'trace does not exist' do
+ it { expect(trace.exist?).to be(false) }
+ end
+
+ context 'new trace path is used' do
+ before do
+ trace.send(:ensure_directory)
+
+ File.open(trace.send(:default_path), "w") do |file|
+ file.write("data")
+ end
+ end
+
+ it "trace exist" do
+ expect(trace.exist?).to be(true)
+ end
+
+ it "can be erased" do
+ trace.erase!
+ expect(trace.exist?).to be(false)
+ end
+ end
+
+ context 'deprecated path' do
+ let(:path) { trace.send(:deprecated_path) }
+
+ context 'with valid ci_id' do
+ before do
+ build.project.update(ci_id: 1000)
+
+ FileUtils.mkdir_p(File.dirname(path))
+
+ File.open(path, "w") do |file|
+ file.write("data")
+ end
+ end
+
+ it "trace exist" do
+ expect(trace.exist?).to be(true)
+ end
+
+ it "can be erased" do
+ trace.erase!
+ expect(trace.exist?).to be(false)
+ end
+ end
+
+ context 'without valid ci_id' do
+ it "does not return deprecated path" do
+ expect(path).to be_nil
+ end
+ end
+ end
+
+ context 'stored in database' do
+ before do
+ build.send(:write_attribute, :trace, "data")
+ end
+
+ it "trace exist" do
+ expect(trace.exist?).to be(true)
+ end
+
+ it "can be erased" do
+ trace.erase!
+ expect(trace.exist?).to be(false)
+ end
+
+ it "returns database data" do
+ expect(trace.raw).to eq("data")
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index e007044868c..4ac79454647 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -58,6 +58,48 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
end
end
+ describe '#remove_concurrent_index' do
+ context 'outside a transaction' do
+ before do
+ allow(model).to receive(:transaction_open?).and_return(false)
+ end
+
+ context 'using PostgreSQL' do
+ before do
+ allow(Gitlab::Database).to receive(:postgresql?).and_return(true)
+ allow(model).to receive(:disable_statement_timeout)
+ end
+
+ it 'removes the index concurrently' do
+ expect(model).to receive(:remove_index).
+ with(:users, { algorithm: :concurrently, column: :foo })
+
+ model.remove_concurrent_index(:users, :foo)
+ end
+ end
+
+ context 'using MySQL' do
+ it 'removes an index' do
+ expect(Gitlab::Database).to receive(:postgresql?).and_return(false)
+
+ expect(model).to receive(:remove_index).
+ with(:users, { column: :foo })
+
+ model.remove_concurrent_index(:users, :foo)
+ end
+ end
+ end
+
+ context 'inside a transaction' do
+ it 'raises RuntimeError' do
+ expect(model).to receive(:transaction_open?).and_return(true)
+
+ expect { model.remove_concurrent_index(:users, :foo) }.
+ to raise_error(RuntimeError)
+ end
+ end
+ end
+
describe '#add_concurrent_foreign_key' do
context 'inside a transaction' do
it 'raises an error' do
diff --git a/spec/lib/gitlab/etag_caching/middleware_spec.rb b/spec/lib/gitlab/etag_caching/middleware_spec.rb
index 6ec4360adc2..c872d8232b0 100644
--- a/spec/lib/gitlab/etag_caching/middleware_spec.rb
+++ b/spec/lib/gitlab/etag_caching/middleware_spec.rb
@@ -47,9 +47,9 @@ describe Gitlab::EtagCaching::Middleware do
it 'tracks "etag_caching_key_not_found" event' do
expect(Gitlab::Metrics).to receive(:add_event)
- .with(:etag_caching_middleware_used)
+ .with(:etag_caching_middleware_used, endpoint: 'issue_notes')
expect(Gitlab::Metrics).to receive(:add_event)
- .with(:etag_caching_key_not_found)
+ .with(:etag_caching_key_not_found, endpoint: 'issue_notes')
middleware.call(build_env(path, if_none_match))
end
@@ -93,9 +93,9 @@ describe Gitlab::EtagCaching::Middleware do
it 'tracks "etag_caching_cache_hit" event' do
expect(Gitlab::Metrics).to receive(:add_event)
- .with(:etag_caching_middleware_used)
+ .with(:etag_caching_middleware_used, endpoint: 'issue_notes')
expect(Gitlab::Metrics).to receive(:add_event)
- .with(:etag_caching_cache_hit)
+ .with(:etag_caching_cache_hit, endpoint: 'issue_notes')
middleware.call(build_env(path, if_none_match))
end
@@ -132,9 +132,9 @@ describe Gitlab::EtagCaching::Middleware do
mock_app_response
expect(Gitlab::Metrics).to receive(:add_event)
- .with(:etag_caching_middleware_used)
+ .with(:etag_caching_middleware_used, endpoint: 'issue_notes')
expect(Gitlab::Metrics).to receive(:add_event)
- .with(:etag_caching_resource_changed)
+ .with(:etag_caching_resource_changed, endpoint: 'issue_notes')
middleware.call(build_env(path, if_none_match))
end
@@ -150,9 +150,9 @@ describe Gitlab::EtagCaching::Middleware do
it 'tracks "etag_caching_header_missing" event' do
expect(Gitlab::Metrics).to receive(:add_event)
- .with(:etag_caching_middleware_used)
+ .with(:etag_caching_middleware_used, endpoint: 'issue_notes')
expect(Gitlab::Metrics).to receive(:add_event)
- .with(:etag_caching_header_missing)
+ .with(:etag_caching_header_missing, endpoint: 'issue_notes')
middleware.call(build_env(path, if_none_match))
end
diff --git a/spec/lib/gitlab/git/attributes_spec.rb b/spec/lib/gitlab/git/attributes_spec.rb
index 9c011e34c11..1cfd8db09a5 100644
--- a/spec/lib/gitlab/git/attributes_spec.rb
+++ b/spec/lib/gitlab/git/attributes_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::Git::Attributes, seed_helper: true do
let(:path) do
- File.join(SEED_REPOSITORY_PATH, 'with-git-attributes.git')
+ File.join(SEED_STORAGE_PATH, 'with-git-attributes.git')
end
subject { described_class.new(path) }
@@ -141,7 +141,7 @@ describe Gitlab::Git::Attributes, seed_helper: true do
end
it 'does not yield when the attributes file has an unsupported encoding' do
- path = File.join(SEED_REPOSITORY_PATH, 'with-invalid-git-attributes.git')
+ path = File.join(SEED_STORAGE_PATH, 'with-invalid-git-attributes.git')
attrs = described_class.new(path)
expect { |b| attrs.each_line(&b) }.not_to yield_control
diff --git a/spec/lib/gitlab/git/blame_spec.rb b/spec/lib/gitlab/git/blame_spec.rb
index e169f5af6b6..8b041ac69b1 100644
--- a/spec/lib/gitlab/git/blame_spec.rb
+++ b/spec/lib/gitlab/git/blame_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
describe Gitlab::Git::Blame, seed_helper: true do
- let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:blame) do
Gitlab::Git::Blame.new(repository, SeedRepo::Commit::ID, "CONTRIBUTING.md")
end
diff --git a/spec/lib/gitlab/git/blob_spec.rb b/spec/lib/gitlab/git/blob_spec.rb
index b883526151e..3f494257545 100644
--- a/spec/lib/gitlab/git/blob_spec.rb
+++ b/spec/lib/gitlab/git/blob_spec.rb
@@ -3,7 +3,7 @@
require "spec_helper"
describe Gitlab::Git::Blob, seed_helper: true do
- let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
describe 'initialize' do
let(:blob) { Gitlab::Git::Blob.new(name: 'test') }
diff --git a/spec/lib/gitlab/git/branch_spec.rb b/spec/lib/gitlab/git/branch_spec.rb
index 78234b396c5..cdf1b8beee3 100644
--- a/spec/lib/gitlab/git/branch_spec.rb
+++ b/spec/lib/gitlab/git/branch_spec.rb
@@ -1,7 +1,7 @@
require "spec_helper"
describe Gitlab::Git::Branch, seed_helper: true do
- let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
subject { repository.branches }
diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb
index 5cf4631fbfc..3e44c577643 100644
--- a/spec/lib/gitlab/git/commit_spec.rb
+++ b/spec/lib/gitlab/git/commit_spec.rb
@@ -1,7 +1,7 @@
require "spec_helper"
describe Gitlab::Git::Commit, seed_helper: true do
- let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:commit) { Gitlab::Git::Commit.find(repository, SeedRepo::Commit::ID) }
let(:rugged_commit) do
repository.rugged.lookup(SeedRepo::Commit::ID)
@@ -9,7 +9,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
describe "Commit info" do
before do
- repo = Gitlab::Git::Repository.new(TEST_REPO_PATH).rugged
+ repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged
@committer = {
email: 'mike@smith.com',
@@ -59,7 +59,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
after do
# Erase the new commit so other tests get the original repo
- repo = Gitlab::Git::Repository.new(TEST_REPO_PATH).rugged
+ repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged
repo.references.update("refs/heads/master", SeedRepo::LastCommit::ID)
end
end
@@ -95,7 +95,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
end
context 'with broken repo' do
- let(:repository) { Gitlab::Git::Repository.new(TEST_BROKEN_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_BROKEN_REPO_PATH) }
it 'returns nil' do
expect(Gitlab::Git::Commit.find(repository, SeedRepo::Commit::ID)).to be_nil
diff --git a/spec/lib/gitlab/git/compare_spec.rb b/spec/lib/gitlab/git/compare_spec.rb
index e28debe1494..7c45071ec45 100644
--- a/spec/lib/gitlab/git/compare_spec.rb
+++ b/spec/lib/gitlab/git/compare_spec.rb
@@ -1,7 +1,7 @@
require "spec_helper"
describe Gitlab::Git::Compare, seed_helper: true do
- let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:compare) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, false) }
let(:compare_straight) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, true) }
diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb
index 992126ef153..7253a2edeff 100644
--- a/spec/lib/gitlab/git/diff_spec.rb
+++ b/spec/lib/gitlab/git/diff_spec.rb
@@ -1,7 +1,7 @@
require "spec_helper"
describe Gitlab::Git::Diff, seed_helper: true do
- let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
before do
@raw_diff_hash = {
diff --git a/spec/lib/gitlab/git/encoding_helper_spec.rb b/spec/lib/gitlab/git/encoding_helper_spec.rb
index 83311536893..27bcc241b82 100644
--- a/spec/lib/gitlab/git/encoding_helper_spec.rb
+++ b/spec/lib/gitlab/git/encoding_helper_spec.rb
@@ -2,7 +2,7 @@ require "spec_helper"
describe Gitlab::Git::EncodingHelper do
let(:ext_class) { Class.new { extend Gitlab::Git::EncodingHelper } }
- let(:binary_string) { File.join(SEED_REPOSITORY_PATH, 'gitlab_logo.png') }
+ let(:binary_string) { File.join(SEED_STORAGE_PATH, 'gitlab_logo.png') }
describe '#encode!' do
[
diff --git a/spec/lib/gitlab/git/index_spec.rb b/spec/lib/gitlab/git/index_spec.rb
index d0c7ca60ddc..07d71f6777d 100644
--- a/spec/lib/gitlab/git/index_spec.rb
+++ b/spec/lib/gitlab/git/index_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::Git::Index, seed_helper: true do
- let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:index) { described_class.new(repository) }
before do
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index d4b7684adfd..7e8bb796e03 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -3,7 +3,7 @@ require "spec_helper"
describe Gitlab::Git::Repository, seed_helper: true do
include Gitlab::Git::EncodingHelper
- let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
describe "Respond to" do
subject { repository }
@@ -14,6 +14,32 @@ describe Gitlab::Git::Repository, seed_helper: true do
it { is_expected.to respond_to(:tags) }
end
+ describe '#root_ref' do
+ context 'with gitaly disabled' do
+ before { allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(false) }
+
+ it 'calls #discover_default_branch' do
+ expect(repository).to receive(:discover_default_branch)
+ repository.root_ref
+ end
+ end
+
+ context 'with gitaly enabled' do
+ before { stub_gitaly }
+
+ it 'gets the branch name from GitalyClient' do
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name)
+ repository.root_ref
+ end
+
+ it 'wraps GRPC exceptions' do
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name).
+ and_raise(GRPC::Unknown)
+ expect { repository.root_ref }.to raise_error(Gitlab::Git::CommandError)
+ end
+ end
+ end
+
describe "#discover_default_branch" do
let(:master) { 'master' }
let(:feature) { 'feature' }
@@ -55,6 +81,21 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
it { is_expected.to include("master") }
it { is_expected.not_to include("branch-from-space") }
+
+ context 'with gitaly enabled' do
+ before { stub_gitaly }
+
+ it 'gets the branch names from GitalyClient' do
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names)
+ subject
+ end
+
+ it 'wraps GRPC exceptions' do
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names).
+ and_raise(GRPC::Unknown)
+ expect { subject }.to raise_error(Gitlab::Git::CommandError)
+ end
+ end
end
describe '#tag_names' do
@@ -71,6 +112,21 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
it { is_expected.to include("v1.0.0") }
it { is_expected.not_to include("v5.0.0") }
+
+ context 'with gitaly enabled' do
+ before { stub_gitaly }
+
+ it 'gets the tag names from GitalyClient' do
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names)
+ subject
+ end
+
+ it 'wraps GRPC exceptions' do
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names).
+ and_raise(GRPC::Unknown)
+ expect { subject }.to raise_error(Gitlab::Git::CommandError)
+ end
+ end
end
shared_examples 'archive check' do |extenstion|
@@ -221,7 +277,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
context '#submodules' do
- let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
context 'where repo has submodules' do
let(:submodules) { repository.submodules('master') }
@@ -290,9 +346,9 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
describe "#reset" do
- change_path = File.join(TEST_NORMAL_REPO_PATH, "CHANGELOG")
- untracked_path = File.join(TEST_NORMAL_REPO_PATH, "UNTRACKED")
- tracked_path = File.join(TEST_NORMAL_REPO_PATH, "files", "ruby", "popen.rb")
+ change_path = File.join(SEED_STORAGE_PATH, TEST_NORMAL_REPO_PATH, "CHANGELOG")
+ untracked_path = File.join(SEED_STORAGE_PATH, TEST_NORMAL_REPO_PATH, "UNTRACKED")
+ tracked_path = File.join(SEED_STORAGE_PATH, TEST_NORMAL_REPO_PATH, "files", "ruby", "popen.rb")
change_text = "New changelog text"
untracked_text = "This file is untracked"
@@ -311,7 +367,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
f.write(untracked_text)
end
- @normal_repo = Gitlab::Git::Repository.new(TEST_NORMAL_REPO_PATH)
+ @normal_repo = Gitlab::Git::Repository.new('default', TEST_NORMAL_REPO_PATH)
@normal_repo.reset("HEAD", :hard)
end
@@ -354,7 +410,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
context "-b" do
before(:all) do
- @normal_repo = Gitlab::Git::Repository.new(TEST_NORMAL_REPO_PATH)
+ @normal_repo = Gitlab::Git::Repository.new('default', TEST_NORMAL_REPO_PATH)
@normal_repo.checkout(new_branch, { b: true }, "origin/feature")
end
@@ -382,7 +438,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
context "without -b" do
context "and specifying a nonexistent branch" do
it "should not do anything" do
- normal_repo = Gitlab::Git::Repository.new(TEST_NORMAL_REPO_PATH)
+ normal_repo = Gitlab::Git::Repository.new('default', TEST_NORMAL_REPO_PATH)
expect { normal_repo.checkout(new_branch) }.to raise_error(Rugged::ReferenceError)
expect(normal_repo.rugged.branches[new_branch]).to be_nil
@@ -402,7 +458,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
context "and with a valid branch" do
before(:all) do
- @normal_repo = Gitlab::Git::Repository.new(TEST_NORMAL_REPO_PATH)
+ @normal_repo = Gitlab::Git::Repository.new('default', TEST_NORMAL_REPO_PATH)
@normal_repo.rugged.branches.create("feature", "origin/feature")
@normal_repo.checkout("feature")
end
@@ -414,13 +470,13 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
it "should update the working directory" do
- File.open(File.join(TEST_NORMAL_REPO_PATH, ".gitignore"), "r") do |f|
+ File.open(File.join(SEED_STORAGE_PATH, TEST_NORMAL_REPO_PATH, ".gitignore"), "r") do |f|
expect(f.read.each_line.to_a).not_to include(".DS_Store\n")
end
end
after(:all) do
- FileUtils.rm_rf(TEST_NORMAL_REPO_PATH)
+ FileUtils.rm_rf(SEED_STORAGE_PATH, TEST_NORMAL_REPO_PATH)
ensure_seeds
end
end
@@ -429,7 +485,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "#delete_branch" do
before(:all) do
- @repo = Gitlab::Git::Repository.new(TEST_MUTABLE_REPO_PATH)
+ @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo.delete_branch("feature")
end
@@ -449,7 +505,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "#create_branch" do
before(:all) do
- @repo = Gitlab::Git::Repository.new(TEST_MUTABLE_REPO_PATH)
+ @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
end
it "should create a new branch" do
@@ -496,7 +552,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "#remote_delete" do
before(:all) do
- @repo = Gitlab::Git::Repository.new(TEST_MUTABLE_REPO_PATH)
+ @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo.remote_delete("expendable")
end
@@ -512,7 +568,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "#remote_add" do
before(:all) do
- @repo = Gitlab::Git::Repository.new(TEST_MUTABLE_REPO_PATH)
+ @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo.remote_add("new_remote", SeedHelper::GITLAB_GIT_TEST_REPO_URL)
end
@@ -528,7 +584,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "#remote_update" do
before(:all) do
- @repo = Gitlab::Git::Repository.new(TEST_MUTABLE_REPO_PATH)
+ @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo.remote_update("expendable", url: TEST_NORMAL_REPO_PATH)
end
@@ -551,7 +607,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
before(:context) do
# Add new commits so that there's a renamed file in the commit history
- repo = Gitlab::Git::Repository.new(TEST_REPO_PATH).rugged
+ repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged
commit_with_old_name = new_commit_edit_old_file(repo)
rename_commit = new_commit_move_file(repo)
@@ -560,7 +616,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
after(:context) do
# Erase our commits so other tests get the original repo
- repo = Gitlab::Git::Repository.new(TEST_REPO_PATH).rugged
+ repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged
repo.references.update("refs/heads/master", SeedRepo::LastCommit::ID)
end
@@ -885,7 +941,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe '#autocrlf' do
before(:all) do
- @repo = Gitlab::Git::Repository.new(TEST_MUTABLE_REPO_PATH)
+ @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo.rugged.config['core.autocrlf'] = true
end
@@ -900,14 +956,14 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe '#autocrlf=' do
before(:all) do
- @repo = Gitlab::Git::Repository.new(TEST_MUTABLE_REPO_PATH)
+ @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo.rugged.config['core.autocrlf'] = false
end
it 'should set the autocrlf option to the provided option' do
@repo.autocrlf = :input
- File.open(File.join(TEST_MUTABLE_REPO_PATH, '.git', 'config')) do |config_file|
+ File.open(File.join(SEED_STORAGE_PATH, TEST_MUTABLE_REPO_PATH, '.git', 'config')) do |config_file|
expect(config_file.read).to match('autocrlf = input')
end
end
@@ -999,7 +1055,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
describe "#copy_gitattributes" do
- let(:attributes_path) { File.join(TEST_REPO_PATH, 'info/attributes') }
+ let(:attributes_path) { File.join(SEED_STORAGE_PATH, TEST_REPO_PATH, 'info/attributes') }
it "raises an error with invalid ref" do
expect { repository.copy_gitattributes("invalid") }.to raise_error(Gitlab::Git::Repository::InvalidRef)
@@ -1075,7 +1131,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
describe '#diffable' do
- info_dir_path = attributes_path = File.join(TEST_REPO_PATH, 'info')
+ info_dir_path = attributes_path = File.join(SEED_STORAGE_PATH, TEST_REPO_PATH, 'info')
attributes_path = File.join(info_dir_path, 'attributes')
before(:all) do
@@ -1143,7 +1199,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe '#local_branches' do
before(:all) do
- @repo = Gitlab::Git::Repository.new(TEST_MUTABLE_REPO_PATH)
+ @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
end
after(:all) do
@@ -1235,4 +1291,11 @@ describe Gitlab::Git::Repository, seed_helper: true do
sha = Rugged::Commit.create(repo, options)
repo.lookup(sha)
end
+
+ def stub_gitaly
+ allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(true)
+
+ stub = double(:stub)
+ allow(Gitaly::Ref::Stub).to receive(:new).and_return(stub)
+ end
end
diff --git a/spec/lib/gitlab/git/tag_spec.rb b/spec/lib/gitlab/git/tag_spec.rb
index ad469e94735..67a9c974298 100644
--- a/spec/lib/gitlab/git/tag_spec.rb
+++ b/spec/lib/gitlab/git/tag_spec.rb
@@ -1,7 +1,7 @@
require "spec_helper"
describe Gitlab::Git::Tag, seed_helper: true do
- let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
describe 'first tag' do
let(:tag) { repository.tags.first }
diff --git a/spec/lib/gitlab/git/tree_spec.rb b/spec/lib/gitlab/git/tree_spec.rb
index 82685712b5b..4b76a43e6b5 100644
--- a/spec/lib/gitlab/git/tree_spec.rb
+++ b/spec/lib/gitlab/git/tree_spec.rb
@@ -2,7 +2,7 @@ require "spec_helper"
describe Gitlab::Git::Tree, seed_helper: true do
context :repo do
- let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) }
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:tree) { Gitlab::Git::Tree.where(repository, SeedRepo::Commit::ID) }
it { expect(tree).to be_kind_of Array }
diff --git a/spec/lib/gitlab/gitaly_client/notifications_spec.rb b/spec/lib/gitlab/gitaly_client/notifications_spec.rb
index bb5d93994ad..39c2048fef8 100644
--- a/spec/lib/gitlab/gitaly_client/notifications_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/notifications_spec.rb
@@ -2,12 +2,15 @@ require 'spec_helper'
describe Gitlab::GitalyClient::Notifications do
describe '#post_receive' do
+ let(:project) { create(:empty_project) }
+ let(:repo_path) { project.repository.path_to_repo }
+ subject { described_class.new(project.repository_storage, project.full_path + '.git') }
+
it 'sends a post_receive message' do
- repo_path = create(:empty_project).repository.path_to_repo
expect_any_instance_of(Gitaly::Notifications::Stub).
- to receive(:post_receive).with(post_receive_request_with_repo_path(repo_path))
+ to receive(:post_receive).with(gitaly_request_with_repo_path(repo_path))
- described_class.new(repo_path).post_receive
+ subject.post_receive
end
end
end
diff --git a/spec/lib/gitlab/gitaly_client/ref_spec.rb b/spec/lib/gitlab/gitaly_client/ref_spec.rb
new file mode 100644
index 00000000000..79c9ca993e4
--- /dev/null
+++ b/spec/lib/gitlab/gitaly_client/ref_spec.rb
@@ -0,0 +1,41 @@
+require 'spec_helper'
+
+describe Gitlab::GitalyClient::Ref do
+ let(:project) { create(:empty_project) }
+ let(:repo_path) { project.repository.path_to_repo }
+ let(:client) { Gitlab::GitalyClient::Ref.new(project.repository_storage, project.full_path + '.git') }
+
+ before do
+ allow(Gitlab.config.gitaly).to receive(:enabled).and_return(true)
+ end
+
+ describe '#branch_names' do
+ it 'sends a find_all_branch_names message' do
+ expect_any_instance_of(Gitaly::Ref::Stub).
+ to receive(:find_all_branch_names).with(gitaly_request_with_repo_path(repo_path)).
+ and_return([])
+
+ client.branch_names
+ end
+ end
+
+ describe '#tag_names' do
+ it 'sends a find_all_tag_names message' do
+ expect_any_instance_of(Gitaly::Ref::Stub).
+ to receive(:find_all_tag_names).with(gitaly_request_with_repo_path(repo_path)).
+ and_return([])
+
+ client.tag_names
+ end
+ end
+
+ describe '#default_branch_name' do
+ it 'sends a find_default_branch_name message' do
+ expect_any_instance_of(Gitaly::Ref::Stub).
+ to receive(:find_default_branch_name).with(gitaly_request_with_repo_path(repo_path)).
+ and_return(double(name: 'foo'))
+
+ client.default_branch_name
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 5a7e5fd4360..549eac76ced 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -104,6 +104,9 @@ triggers:
- project
- trigger_requests
- owner
+- trigger_schedule
+trigger_schedule:
+- trigger
deploy_keys:
- user
- deploy_keys_projects
@@ -121,6 +124,9 @@ merge_access_levels:
- protected_branch
push_access_levels:
- protected_branch
+container_repositories:
+- project
+- name
project:
- taggings
- base_tags
@@ -161,6 +167,8 @@ project:
- external_wiki_service
- kubernetes_service
- mock_ci_service
+- mock_deployment_service
+- mock_monitoring_service
- forked_project_link
- forked_from_project
- forked_project_links
@@ -195,8 +203,10 @@ project:
- builds
- runner_projects
- runners
+- active_runners
- variables
- triggers
+- trigger_schedules
- environments
- deployments
- project_feature
@@ -205,6 +215,7 @@ project:
- project_authorizations
- route
- statistics
+- container_repositories
- uploads
award_emoji:
- awardable
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 1ad16a9b57d..0c43c5662e8 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -240,6 +240,17 @@ Ci::Trigger:
- updated_at
- owner_id
- description
+- ref
+Ci::TriggerSchedule:
+- id
+- project_id
+- trigger_id
+- deleted_at
+- created_at
+- updated_at
+- cron
+- cron_timezone
+- next_run_at
DeployKey:
- id
- user_id
diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb
index 6c84a4c8b73..8f09266c3b3 100644
--- a/spec/lib/gitlab/o_auth/user_spec.rb
+++ b/spec/lib/gitlab/o_auth/user_spec.rb
@@ -40,6 +40,15 @@ describe Gitlab::OAuth::User, lib: true do
let(:provider) { 'twitter' }
describe 'signup' do
+ it 'marks user as having password_automatically_set' do
+ stub_omniauth_config(allow_single_sign_on: ['twitter'], external_providers: ['twitter'])
+
+ oauth_user.save
+
+ expect(gl_user).to be_persisted
+ expect(gl_user).to be_password_automatically_set
+ end
+
shared_examples 'to verify compliance with allow_single_sign_on' do
context 'provider is marked as external' do
it 'marks user as external' do
diff --git a/spec/lib/gitlab/polling_interval_spec.rb b/spec/lib/gitlab/polling_interval_spec.rb
index 56c2847e26a..5ea8ecb1c30 100644
--- a/spec/lib/gitlab/polling_interval_spec.rb
+++ b/spec/lib/gitlab/polling_interval_spec.rb
@@ -15,7 +15,7 @@ describe Gitlab::PollingInterval, lib: true do
it 'sets value to -1' do
polling_interval.set_header(response, interval: 10_000)
- expect(headers['Poll-Interval']).to eq(-1)
+ expect(headers['Poll-Interval']).to eq('-1')
end
end
@@ -27,7 +27,7 @@ describe Gitlab::PollingInterval, lib: true do
it 'applies modifier to base interval' do
polling_interval.set_header(response, interval: 10_000)
- expect(headers['Poll-Interval']).to eq(3333)
+ expect(headers['Poll-Interval']).to eq('3333')
end
end
end
diff --git a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
index 287bf62d9bd..6307f8c16a3 100644
--- a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Gitlab::SidekiqStatus::ClientMiddleware do
describe '#call' do
it 'tracks the job in Redis' do
- expect(Gitlab::SidekiqStatus).to receive(:set).with('123')
+ expect(Gitlab::SidekiqStatus).to receive(:set).with('123', Gitlab::SidekiqStatus::DEFAULT_EXPIRATION)
described_class.new.
call('Foo', { 'jid' => '123' }, double(:queue), double(:pool)) { nil }
diff --git a/spec/lib/gitlab/sidekiq_status_spec.rb b/spec/lib/gitlab/sidekiq_status_spec.rb
index 56f06b61afb..496e50fbae4 100644
--- a/spec/lib/gitlab/sidekiq_status_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status_spec.rb
@@ -73,4 +73,17 @@ describe Gitlab::SidekiqStatus do
expect(key).to include('123')
end
end
+
+ describe 'completed', :redis do
+ it 'returns the completed job' do
+ expect(described_class.completed_jids(%w(123))).to eq(['123'])
+ end
+
+ it 'returns only the jobs completed' do
+ described_class.set('123')
+ described_class.set('456')
+
+ expect(described_class.completed_jids(%w(123 456 789))).to eq(['789'])
+ end
+ end
end
diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb
index 9fbcb1fee69..b703e9808a8 100644
--- a/spec/lib/gitlab/workhorse_spec.rb
+++ b/spec/lib/gitlab/workhorse_spec.rb
@@ -188,10 +188,8 @@ describe Gitlab::Workhorse, lib: true do
context 'when Gitaly is enabled' do
let(:gitaly_params) do
- address = Gitlab::GitalyClient.get_address('default')
{
- GitalySocketPath: URI(address).path,
- GitalyAddress: address,
+ GitalyAddress: Gitlab::GitalyClient.get_address('default'),
}
end