From bbdc35717c1ba08630f5b2ae59a333a81941b181 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 20 Jul 2017 13:30:05 +0200 Subject: [PATCH] Implement method that updates a stage status --- app/models/ci/stage.rb | 47 ++++++++++++++++++++++++++++++++++++ spec/models/ci/stage_spec.rb | 22 +++++++++++++++-- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb index c163d047127..066903ddc5b 100644 --- a/app/models/ci/stage.rb +++ b/app/models/ci/stage.rb @@ -3,6 +3,7 @@ module Ci extend Ci::Model include Importable include HasStatus + include Gitlab::OptimisticLocking enumerate_status! @@ -15,5 +16,51 @@ module Ci validates :project, presence: true, unless: :importing? validates :pipeline, presence: true, unless: :importing? validates :name, presence: true, unless: :importing? + + state_machine :status, initial: :created do + event :enqueue do + transition created: :pending + transition [:success, :failed, :canceled, :skipped] => :running + end + + event :run do + transition any - [:running] => :running + end + + event :skip do + transition any - [:skipped] => :skipped + end + + event :drop do + transition any - [:failed] => :failed + end + + event :succeed do + transition any - [:success] => :success + end + + event :cancel do + transition any - [:canceled] => :canceled + end + + event :block do + transition any - [:manual] => :manual + end + end + + def update! + retry_optimistic_lock(self) do + case commit_statuses.latest.status + when 'pending' then enqueue + when 'running' then run + when 'success' then succeed + when 'failed' then drop + when 'canceled' then cancel + when 'manual' then block + when 'skipped' then skip + else skip + end + end + end end end diff --git a/spec/models/ci/stage_spec.rb b/spec/models/ci/stage_spec.rb index 49573175266..e829ccb048e 100644 --- a/spec/models/ci/stage_spec.rb +++ b/spec/models/ci/stage_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' describe Ci::Stage, :models do - describe 'associations' do - let(:stage) { create(:ci_stage_entity) } + let(:stage) { create(:ci_stage_entity) } + describe 'associations' do before do create(:ci_build, stage_id: stage.id) create(:commit_status, stage_id: stage.id) @@ -39,4 +39,22 @@ describe Ci::Stage, :models do end end end + + describe 'update!' do + context 'when stage objects needs to be updated' do + before do + create(:ci_build, :success, stage_id: stage.id) + create(:ci_build, :running, stage_id: stage.id) + end + + it 'updates stage status correctly' do + expect { stage.update! } + .to change { stage.reload.status } + .to 'running' + end + end + + context 'when stage object is locked' do + end + end end