summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2016-12-06 14:49:37 +0100
committerKamil Trzcinski <ayufan@ayufan.eu>2016-12-06 16:04:30 +0100
commit953a10947bea8ff75290cd50fae4ae1f7636a71d (patch)
tree060ae96378341519786aa236050c110a246047ae
parent401c155e16e4966be538fd14f23e268cd3383aa7 (diff)
downloadgitlab-ce-953a10947bea8ff75290cd50fae4ae1f7636a71d.tar.gz
Added Ci::Stage specs
-rw-r--r--app/models/ci/pipeline.rb4
-rw-r--r--lib/gitlab/data_builder/pipeline.rb2
-rw-r--r--spec/factories/ci/stages.rb13
-rw-r--r--spec/lib/gitlab/ci/status/pipeline/factory_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/stage/common_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/stage/factory_spec.rb10
-rw-r--r--spec/models/ci/pipeline_spec.rb4
-rw-r--r--spec/models/ci/stage_spec.rb133
8 files changed, 165 insertions, 9 deletions
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index aa23b5cf97c..d14825c082a 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -104,6 +104,10 @@ module Ci
statuses.select(:stage).distinct.count
end
+ def stages_name
+ statuses.order(:stage_idx).distinct.pluck(:stage)
+ end
+
def stages
status_sql = statuses.latest.where('stage=sg.stage').status_sql
diff --git a/lib/gitlab/data_builder/pipeline.rb b/lib/gitlab/data_builder/pipeline.rb
index e0284d55da8..e50e54b6e99 100644
--- a/lib/gitlab/data_builder/pipeline.rb
+++ b/lib/gitlab/data_builder/pipeline.rb
@@ -22,7 +22,7 @@ module Gitlab
sha: pipeline.sha,
before_sha: pipeline.before_sha,
status: pipeline.status,
- stages: pipeline.stages.map(&:name),
+ stages: pipeline.stages_name,
created_at: pipeline.created_at,
finished_at: pipeline.finished_at,
duration: pipeline.duration
diff --git a/spec/factories/ci/stages.rb b/spec/factories/ci/stages.rb
new file mode 100644
index 00000000000..ee3b17b8bf1
--- /dev/null
+++ b/spec/factories/ci/stages.rb
@@ -0,0 +1,13 @@
+FactoryGirl.define do
+ factory :ci_stage, class: Ci::Stage do
+ transient do
+ name 'test'
+ status nil
+ pipeline factory: :ci_empty_pipeline
+ end
+
+ initialize_with do
+ Ci::Stage.new(pipeline, name: name, status: status)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb
index d6243940f2e..939ad2edf04 100644
--- a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb
@@ -21,7 +21,7 @@ describe Gitlab::Ci::Status::Pipeline::Factory do
Gitlab::Ci::Status.const_get(core_status.capitalize))
end
- it 'extends core status with common pipeline methods' do
+ it 'extends core status with common stage methods' do
expect(status).to have_details
expect(status).not_to have_action
expect(status.details_path)
@@ -45,7 +45,7 @@ describe Gitlab::Ci::Status::Pipeline::Factory do
.to be_a Gitlab::Ci::Status::Pipeline::SuccessWithWarnings
end
- it 'extends core status with common pipeline methods' do
+ it 'extends core status with common stage methods' do
expect(status).to have_details
end
end
diff --git a/spec/lib/gitlab/ci/status/stage/common_spec.rb b/spec/lib/gitlab/ci/status/stage/common_spec.rb
index f15d6047878..f3259c6f23e 100644
--- a/spec/lib/gitlab/ci/status/stage/common_spec.rb
+++ b/spec/lib/gitlab/ci/status/stage/common_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Stage::Common do
- let(:pipeline) { create(:ci_pipeline) }
- let(:stage) { Ci::Stage.new(pipeline, name: 'test') }
+ let(:pipeline) { create(:ci_empty_pipeline) }
+ let(:stage) { build(:ci_stage, pipeline: pipeline, name: 'test') }
subject do
Class.new(Gitlab::Ci::Status::Core)
diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb
index 2d22bd1e2a0..17929665c83 100644
--- a/spec/lib/gitlab/ci/status/stage/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/stage/factory_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Stage::Factory do
- let(:pipeline) { create(:ci_pipeline) }
- let(:stage) { Ci::Stage.new(pipeline, name: 'test') }
+ let(:pipeline) { create(:ci_empty_pipeline) }
+ let(:stage) { build(:ci_stage, pipeline: pipeline, name: 'test') }
subject do
described_class.new(stage)
@@ -15,8 +15,10 @@ describe Gitlab::Ci::Status::Stage::Factory do
context 'when stage has a core status' do
HasStatus::AVAILABLE_STATUSES.each do |core_status|
context "when core status is #{core_status}" do
- let!(:build) do
+ before do
create(:ci_build, pipeline: pipeline, stage: 'test', status: core_status)
+ create(:commit_status, pipeline: pipeline, stage: 'test', status: core_status)
+ create(:ci_build, pipeline: pipeline, stage: 'build', status: :failed)
end
it "fabricates a core status #{core_status}" do
@@ -24,7 +26,7 @@ describe Gitlab::Ci::Status::Stage::Factory do
Gitlab::Ci::Status.const_get(core_status.capitalize))
end
- it 'extends core status with common pipeline methods' do
+ it 'extends core status with common stage methods' do
expect(status).to have_details
expect(status.details_path).to include "pipelines/#{pipeline.id}"
expect(status.details_path).to include "##{stage.name}"
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index cdc858c13b4..8158e71dd55 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -142,6 +142,10 @@ describe Ci::Pipeline, models: true do
expect(pipeline.stages_count).to eq(3)
end
+ it 'returns a valid names of stages' do
+ expect(pipeline.stages_name).to eq(['build', 'test', 'deploy'])
+ end
+
context 'stages with statuses' do
let(:statuses) do
subject.map do |stage|
diff --git a/spec/models/ci/stage_spec.rb b/spec/models/ci/stage_spec.rb
new file mode 100644
index 00000000000..f232761dba2
--- /dev/null
+++ b/spec/models/ci/stage_spec.rb
@@ -0,0 +1,133 @@
+require 'spec_helper'
+
+describe Ci::Stage, models: true do
+ let(:stage) { build(:ci_stage) }
+ let(:pipeline) { stage.pipeline }
+ let(:stage_name) { stage.name }
+
+ describe '#expectations' do
+ subject { stage }
+
+ it { is_expected.to include_module(StaticModel) }
+
+ it { is_expected.to respond_to(:pipeline) }
+ it { is_expected.to respond_to(:name) }
+
+ it { is_expected.to delegate_method(:project).to(:pipeline) }
+ end
+
+ describe '#statuses' do
+ let!(:stage_build) { create_job(:ci_build) }
+ let!(:commit_status) { create_job(:commit_status) }
+ let!(:other_build) { create_job(:ci_build, stage: 'other stage') }
+
+ subject { stage.statuses }
+
+ it "returns only matching statuses" do
+ is_expected.to contain_exactly(stage_build, commit_status)
+ end
+ end
+
+ describe '#builds' do
+ let!(:stage_build) { create_job(:ci_build) }
+ let!(:commit_status) { create_job(:commit_status) }
+
+ subject { stage.builds }
+
+ it "returns only builds" do
+ is_expected.to contain_exactly(stage_build)
+ end
+ end
+
+ describe '#status' do
+ subject { stage.status }
+
+ context 'if status is already defined' do
+ let(:stage) { build(:ci_stage, status: 'success') }
+
+ it "returns defined status" do
+ is_expected.to eq('success')
+ end
+ end
+
+ context 'if status has to be calculated' do
+ let!(:stage_build) { create_job(:ci_build, status: :failed) }
+
+ it "returns status of a build" do
+ is_expected.to eq('failed')
+ end
+
+ context 'and builds are retried' do
+ let!(:new_build) { create_job(:ci_build, status: :success) }
+
+ it "returns status of latest build" do
+ is_expected.to eq('success')
+ end
+ end
+ end
+ end
+
+ describe '#detailed_status' do
+ subject { stage.detailed_status }
+
+ context 'when build is created' do
+ let!(:stage_build) { create_job(:ci_build, status: :created) }
+
+ it 'returns detailed status for created stage' do
+ expect(subject.text).to eq 'created'
+ end
+ end
+
+ context 'when build is pending' do
+ let!(:stage_build) { create_job(:ci_build, status: :pending) }
+
+ it 'returns detailed status for pending stage' do
+ expect(subject.text).to eq 'pending'
+ end
+ end
+
+ context 'when build is running' do
+ let!(:stage_build) { create_job(:ci_build, status: :running) }
+
+ it 'returns detailed status for running stage' do
+ expect(subject.text).to eq 'running'
+ end
+ end
+
+ context 'when build is successful' do
+ let!(:stage_build) { create_job(:ci_build, status: :success) }
+
+ it 'returns detailed status for successful stage' do
+ expect(subject.text).to eq 'passed'
+ end
+ end
+
+ context 'when build is failed' do
+ let!(:stage_build) { create_job(:ci_build, status: :failed) }
+
+ it 'returns detailed status for failed stage' do
+ expect(subject.text).to eq 'failed'
+ end
+ end
+
+ context 'when build is canceled' do
+ let!(:stage_build) { create_job(:ci_build, status: :canceled) }
+
+ it 'returns detailed status for canceled stage' do
+ expect(subject.text).to eq 'canceled'
+ end
+ end
+
+ context 'when build is skipped' do
+ let!(:stage_build) { create_job(:ci_build, status: :skipped) }
+
+ it 'returns detailed status for skipped stage' do
+ expect(subject.text).to eq 'skipped'
+ end
+ end
+ end
+
+ def create_job(type, status: 'success', stage: stage_name)
+ create(type, pipeline: pipeline, stage: stage, status: status)
+ end
+end