summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/ci/builds.rb7
-rw-r--r--spec/factories/ci/job_artifacts.rb14
-rw-r--r--spec/fixtures/junit.xml.gzbin0 -> 568 bytes
-rw-r--r--spec/lib/gitlab/ci/config/entry/artifacts_spec.rb17
-rw-r--r--spec/lib/gitlab/ci/config/entry/commands_spec.rb3
-rw-r--r--spec/lib/gitlab/ci/config/entry/reports_spec.rb53
-rw-r--r--spec/models/ci/build_spec.rb44
-rw-r--r--spec/models/ci/job_artifact_spec.rb50
-rw-r--r--spec/presenters/ci/build_runner_presenter_spec.rb86
-rw-r--r--spec/requests/api/jobs_spec.rb4
-rw-r--r--spec/requests/api/runner_spec.rb54
-rw-r--r--spec/services/ci/retry_build_service_spec.rb4
-rw-r--r--spec/services/projects/update_pages_service_spec.rb2
13 files changed, 330 insertions, 8 deletions
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index 83cb4750741..8bd1f1ae4e0 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -187,6 +187,13 @@ FactoryBot.define do
end
end
+ trait :test_reports do
+ after(:create) do |build|
+ create(:ci_job_artifact, :junit, job: build)
+ build.reload
+ end
+ end
+
trait :expired do
artifacts_expire_at 1.minute.ago
end
diff --git a/spec/factories/ci/job_artifacts.rb b/spec/factories/ci/job_artifacts.rb
index 3d3287d8168..a6a87782fe7 100644
--- a/spec/factories/ci/job_artifacts.rb
+++ b/spec/factories/ci/job_artifacts.rb
@@ -4,6 +4,7 @@ FactoryBot.define do
factory :ci_job_artifact, class: Ci::JobArtifact do
job factory: :ci_build
file_type :archive
+ file_format :zip
trait :remote_store do
file_store JobArtifactUploader::Store::REMOTE
@@ -15,6 +16,7 @@ FactoryBot.define do
trait :archive do
file_type :archive
+ file_format :zip
after(:build) do |artifact, _|
artifact.file = fixture_file_upload(
@@ -24,6 +26,7 @@ FactoryBot.define do
trait :metadata do
file_type :metadata
+ file_format :gzip
after(:build) do |artifact, _|
artifact.file = fixture_file_upload(
@@ -33,6 +36,7 @@ FactoryBot.define do
trait :trace do
file_type :trace
+ file_format :raw
after(:build) do |artifact, evaluator|
artifact.file = fixture_file_upload(
@@ -40,6 +44,16 @@ FactoryBot.define do
end
end
+ trait :junit do
+ file_type :junit
+ file_format :gzip
+
+ after(:build) do |artifact, evaluator|
+ artifact.file = fixture_file_upload(
+ Rails.root.join('spec/fixtures/junit.xml.gz'), 'application/x-gzip')
+ end
+ end
+
trait :correct_checksum do
after(:build) do |artifact, evaluator|
artifact.file_sha256 = Digest::SHA256.file(artifact.file.path).hexdigest
diff --git a/spec/fixtures/junit.xml.gz b/spec/fixtures/junit.xml.gz
new file mode 100644
index 00000000000..88b7de6fa61
--- /dev/null
+++ b/spec/fixtures/junit.xml.gz
Binary files differ
diff --git a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb
index 5c31423fdee..d48aac15f28 100644
--- a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb
@@ -18,6 +18,14 @@ describe Gitlab::Ci::Config::Entry::Artifacts do
expect(entry).to be_valid
end
end
+
+ context "when value includes 'reports' keyword" do
+ let(:config) { { paths: %w[public/], reports: { junit: 'junit.xml' } } }
+
+ it 'returns general artifact and report-type artifacts configuration' do
+ expect(entry.value).to eq config
+ end
+ end
end
context 'when entry value is not correct' do
@@ -39,6 +47,15 @@ describe Gitlab::Ci::Config::Entry::Artifacts do
.to include 'artifacts config contains unknown keys: test'
end
end
+
+ context "when 'reports' keyword is not hash" do
+ let(:config) { { paths: %w[public/], reports: 'junit.xml' } }
+
+ it 'reports error' do
+ expect(entry.errors)
+ .to include 'artifacts reports should be a hash'
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/commands_spec.rb b/spec/lib/gitlab/ci/config/entry/commands_spec.rb
index afa4a089418..8934aeb83db 100644
--- a/spec/lib/gitlab/ci/config/entry/commands_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/commands_spec.rb
@@ -41,8 +41,7 @@ describe Gitlab::Ci::Config::Entry::Commands do
describe '#errors' do
it 'saves errors' do
expect(entry.errors)
- .to include 'commands config should be a ' \
- 'string or an array of strings'
+ .to include 'commands config should be an array of strings or a string'
end
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/reports_spec.rb b/spec/lib/gitlab/ci/config/entry/reports_spec.rb
new file mode 100644
index 00000000000..b3a3a6bee1d
--- /dev/null
+++ b/spec/lib/gitlab/ci/config/entry/reports_spec.rb
@@ -0,0 +1,53 @@
+require 'spec_helper'
+
+describe Gitlab::Ci::Config::Entry::Reports do
+ let(:entry) { described_class.new(config) }
+
+ describe 'validation' do
+ context 'when entry config value is correct' do
+ let(:config) { { junit: %w[junit.xml] } }
+
+ describe '#value' do
+ it 'returns artifacs configuration' do
+ expect(entry.value).to eq config
+ end
+ end
+
+ describe '#valid?' do
+ it 'is valid' do
+ expect(entry).to be_valid
+ end
+ end
+
+ context 'when value is not array' do
+ let(:config) { { junit: 'junit.xml' } }
+
+ it 'converts to array' do
+ expect(entry.value).to eq({ junit: ['junit.xml'] } )
+ end
+ end
+ end
+
+ context 'when entry value is not correct' do
+ describe '#errors' do
+ context 'when value of attribute is invalid' do
+ let(:config) { { junit: 10 } }
+
+ it 'reports error' do
+ expect(entry.errors)
+ .to include 'reports junit should be an array of strings or a string'
+ end
+ end
+
+ context 'when there is an unknown key present' do
+ let(:config) { { codeclimate: 'codeclimate.json' } }
+
+ it 'reports error' do
+ expect(entry.errors)
+ .to include 'reports config contains unknown keys: codeclimate'
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 67199eb6d26..e4fa04baae6 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -514,6 +514,44 @@ describe Ci::Build do
end
end
+ describe '#has_test_reports?' do
+ subject { build.has_test_reports? }
+
+ context 'when build has a test report' do
+ let(:build) { create(:ci_build, :test_reports) }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when build does not have test reports' do
+ let(:build) { create(:ci_build, :artifacts) }
+
+ it { is_expected.to be_falsy }
+ end
+ end
+
+ describe '#erase_test_reports!' do
+ subject { build.erase_test_reports! }
+
+ context 'when build has a test report' do
+ let!(:build) { create(:ci_build, :test_reports) }
+
+ it 'removes a test report' do
+ subject
+
+ expect(build.has_test_reports?).to be_falsy
+ end
+ end
+
+ context 'when build does not have test reports' do
+ let!(:build) { create(:ci_build, :artifacts) }
+
+ it 'does not erase anything' do
+ expect { subject }.not_to change { Ci::JobArtifact.count }
+ end
+ end
+ end
+
describe '#has_old_trace?' do
subject { build.has_old_trace? }
@@ -776,6 +814,10 @@ describe Ci::Build do
expect(build.artifacts_metadata.exists?).to be_falsy
end
+ it 'removes test reports' do
+ expect(build.job_artifacts.test_reports.count).to eq(0)
+ end
+
it 'erases build trace in trace file' do
expect(build).not_to have_trace
end
@@ -807,7 +849,7 @@ describe Ci::Build do
context 'build is erasable' do
context 'new artifacts' do
- let!(:build) { create(:ci_build, :trace_artifact, :success, :artifacts) }
+ let!(:build) { create(:ci_build, :test_reports, :trace_artifact, :success, :artifacts) }
describe '#erase' do
before do
diff --git a/spec/models/ci/job_artifact_spec.rb b/spec/models/ci/job_artifact_spec.rb
index 0fd7612c011..4f34c2e81f8 100644
--- a/spec/models/ci/job_artifact_spec.rb
+++ b/spec/models/ci/job_artifact_spec.rb
@@ -15,6 +15,22 @@ describe Ci::JobArtifact do
it { is_expected.to delegate_method(:open).to(:file) }
it { is_expected.to delegate_method(:exists?).to(:file) }
+ describe '.test_reports' do
+ subject { described_class.test_reports }
+
+ context 'when there is a test report' do
+ let!(:artifact) { create(:ci_job_artifact, :junit) }
+
+ it { is_expected.to eq([artifact]) }
+ end
+
+ context 'when there are no test reports' do
+ let!(:artifact) { create(:ci_job_artifact, :archive) }
+
+ it { is_expected.to be_empty }
+ end
+ end
+
describe 'callbacks' do
subject { create(:ci_job_artifact, :archive) }
@@ -87,6 +103,40 @@ describe Ci::JobArtifact do
end
end
+ describe 'validates file format' do
+ subject { artifact }
+
+ context 'when archive type with zip format' do
+ let(:artifact) { build(:ci_job_artifact, :archive, file_format: :zip) }
+
+ it { is_expected.to be_valid }
+ end
+
+ context 'when archive type with gzip format' do
+ let(:artifact) { build(:ci_job_artifact, :archive, file_format: :gzip) }
+
+ it { is_expected.not_to be_valid }
+ end
+
+ context 'when archive type without format specification' do
+ let(:artifact) { build(:ci_job_artifact, :archive, file_format: nil) }
+
+ it { is_expected.not_to be_valid }
+ end
+
+ context 'when junit type with zip format' do
+ let(:artifact) { build(:ci_job_artifact, :junit, file_format: :zip) }
+
+ it { is_expected.not_to be_valid }
+ end
+
+ context 'when junit type with gzip format' do
+ let(:artifact) { build(:ci_job_artifact, :junit, file_format: :gzip) }
+
+ it { is_expected.to be_valid }
+ end
+ end
+
describe '#file' do
subject { artifact.file }
diff --git a/spec/presenters/ci/build_runner_presenter_spec.rb b/spec/presenters/ci/build_runner_presenter_spec.rb
new file mode 100644
index 00000000000..e7019b990dd
--- /dev/null
+++ b/spec/presenters/ci/build_runner_presenter_spec.rb
@@ -0,0 +1,86 @@
+require 'spec_helper'
+
+describe Ci::BuildRunnerPresenter do
+ let(:presenter) { described_class.new(build) }
+ let(:archive) { { paths: ['sample.txt'] } }
+ let(:junit) { { junit: ['junit.xml'] } }
+
+ let(:archive_expectation) do
+ {
+ artifact_type: :archive,
+ artifact_format: :zip,
+ paths: archive[:paths],
+ untracked: archive[:untracked]
+ }
+ end
+
+ let(:junit_expectation) do
+ {
+ name: 'junit.xml',
+ artifact_type: :junit,
+ artifact_format: :gzip,
+ paths: ['junit.xml'],
+ when: 'always'
+ }
+ end
+
+ describe '#artifacts' do
+ context "when option contains archive-type artifacts" do
+ let(:build) { create(:ci_build, options: { artifacts: archive } ) }
+
+ it 'presents correct hash' do
+ expect(presenter.artifacts.first).to include(archive_expectation)
+ end
+
+ context "when untracked is specified" do
+ let(:archive) { { untracked: true } }
+
+ it 'presents correct hash' do
+ expect(presenter.artifacts.first).to include(archive_expectation)
+ end
+ end
+
+ context "when untracked and paths are missing" do
+ let(:archive) { { when: 'always' } }
+
+ it 'does not present hash' do
+ expect(presenter.artifacts).to be_empty
+ end
+ end
+ end
+
+ context "when option has 'junit' keyword" do
+ let(:build) { create(:ci_build, options: { artifacts: { reports: junit } } ) }
+
+ it 'presents correct hash' do
+ expect(presenter.artifacts.first).to include(junit_expectation)
+ end
+ end
+
+ context "when option has both archive and reports specification" do
+ let(:build) { create(:ci_build, options: { script: 'echo', artifacts: { **archive, reports: junit } } ) }
+
+ it 'presents correct hash' do
+ expect(presenter.artifacts.first).to include(archive_expectation)
+ expect(presenter.artifacts.second).to include(junit_expectation)
+ end
+
+ context "when archive specifies 'expire_in' keyword" do
+ let(:archive) { { paths: ['sample.txt'], expire_in: '3 mins 4 sec' } }
+
+ it 'inherits expire_in from archive' do
+ expect(presenter.artifacts.first).to include({ **archive_expectation, expire_in: '3 mins 4 sec' })
+ expect(presenter.artifacts.second).to include({ **junit_expectation, expire_in: '3 mins 4 sec' })
+ end
+ end
+ end
+
+ context "when option has no artifact keywords" do
+ let(:build) { create(:ci_build, :no_options) }
+
+ it 'does not present hash' do
+ expect(presenter.artifacts).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb
index 8412d0383f7..5814d834572 100644
--- a/spec/requests/api/jobs_spec.rb
+++ b/spec/requests/api/jobs_spec.rb
@@ -655,13 +655,15 @@ describe API::Jobs do
end
context 'job is erasable' do
- let(:job) { create(:ci_build, :trace_artifact, :artifacts, :success, project: project, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :trace_artifact, :artifacts, :test_reports, :success, project: project, pipeline: pipeline) }
it 'erases job content' do
expect(response).to have_gitlab_http_status(201)
+ expect(job.job_artifacts.count).to eq(0)
expect(job.trace.exist?).to be_falsy
expect(job.artifacts_file.exists?).to be_falsy
expect(job.artifacts_metadata.exists?).to be_falsy
+ expect(job.has_test_reports?).to be_falsy
end
it 'updates job' do
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index d57993ab454..0f41e46cdd5 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -424,7 +424,9 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
'untracked' => false,
'paths' => %w(out/),
'when' => 'always',
- 'expire_in' => '7d' }]
+ 'expire_in' => '7d',
+ "artifact_type" => "archive",
+ "artifact_format" => "zip" }]
end
let(:expected_cache) do
@@ -1420,6 +1422,56 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
end
end
end
+
+ context 'when artifact_type is archive' do
+ context 'when artifact_format is zip' do
+ let(:params) { { artifact_type: :archive, artifact_format: :zip } }
+
+ it 'stores junit test report' do
+ upload_artifacts(file_upload, headers_with_token, params)
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(job.reload.job_artifacts_archive).not_to be_nil
+ end
+ end
+
+ context 'when artifact_format is gzip' do
+ let(:params) { { artifact_type: :archive, artifact_format: :gzip } }
+
+ it 'returns an error' do
+ upload_artifacts(file_upload, headers_with_token, params)
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(job.reload.job_artifacts_archive).to be_nil
+ end
+ end
+ end
+
+ context 'when artifact_type is junit' do
+ context 'when artifact_format is gzip' do
+ let(:file_upload) { fixture_file_upload('spec/fixtures/junit.xml.gz') }
+ let(:params) { { artifact_type: :junit, artifact_format: :gzip } }
+
+ it 'stores junit test report' do
+ upload_artifacts(file_upload, headers_with_token, params)
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(job.reload.job_artifacts_junit).not_to be_nil
+ end
+ end
+
+ context 'when artifact_format is raw' do
+ let(:file_upload) { fixture_file_upload('spec/fixtures/junit.xml.gz') }
+ let(:params) { { artifact_type: :junit, artifact_format: :raw } }
+
+ it 'returns an error' do
+ upload_artifacts(file_upload, headers_with_token, params)
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(job.reload.job_artifacts_junit).to be_nil
+ end
+ end
+ end
end
context 'when artifacts are being stored outside of tmp path' do
diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb
index ecf5d849d3f..18d52082399 100644
--- a/spec/services/ci/retry_build_service_spec.rb
+++ b/spec/services/ci/retry_build_service_spec.rb
@@ -24,7 +24,7 @@ describe Ci::RetryBuildService do
artifacts_file artifacts_metadata artifacts_size created_at
updated_at started_at finished_at queued_at erased_by
erased_at auto_canceled_by job_artifacts job_artifacts_archive
- job_artifacts_metadata job_artifacts_trace].freeze
+ job_artifacts_metadata job_artifacts_trace job_artifacts_junit].freeze
IGNORE_ACCESSORS =
%i[type lock_version target_url base_tags trace_sections
@@ -38,7 +38,7 @@ describe Ci::RetryBuildService do
let(:another_pipeline) { create(:ci_empty_pipeline, project: project) }
let(:build) do
- create(:ci_build, :failed, :artifacts, :expired, :erased,
+ create(:ci_build, :failed, :artifacts, :test_reports, :expired, :erased,
:queued, :coverage, :tags, :allowed_to_fail, :on_tag,
:triggered, :trace_artifact, :teardown_environment,
description: 'my-job', stage: 'test', stage_id: stage.id,
diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb
index a4c103e6f30..36b619ba9be 100644
--- a/spec/services/projects/update_pages_service_spec.rb
+++ b/spec/services/projects/update_pages_service_spec.rb
@@ -79,7 +79,7 @@ describe Projects::UpdatePagesService do
context "for a valid job" do
before do
create(:ci_job_artifact, file: file, job: build)
- create(:ci_job_artifact, file_type: :metadata, file: metadata, job: build)
+ create(:ci_job_artifact, file_type: :metadata, file_format: :gzip, file: metadata, job: build)
build.reload
end