From 4f7f3258c18dfc207b838401f5ed71a3197eb22d Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 1 Jun 2016 18:34:20 +0800 Subject: [PATCH] Implement the logic for locking runner --- app/models/ci/build.rb | 4 +-- app/models/ci/runner.rb | 18 +++++++++++++ spec/models/build_spec.rb | 55 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index b8ada6361ac..860ac16eefd 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -291,9 +291,7 @@ module Ci end def can_be_served?(runner) - return false unless has_tags? || runner.run_untagged? - - (tag_list - runner.tag_list).empty? + runner.can_serve?(self) end def has_tags? diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index adb65292208..d61a8c00634 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -91,6 +91,12 @@ module Ci !shared? end + def can_serve?(build) + not_locked_or_locked_to?(build.project) && + run_untagged_or_has_tags?(build) && + accepting_tags?(build.tag_list) + end + def only_for?(project) projects == [project] end @@ -111,5 +117,17 @@ module Ci 'can not be empty when runner is not allowed to pick untagged jobs') end end + + def not_locked_or_locked_to?(project) + !locked? || projects.exists?(id: project.id) + end + + def run_untagged_or_has_tags?(build) + run_untagged? || build.has_tags? + end + + def accepting_tags?(target_tags) + (target_tags - tag_list).empty? + end end end diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb index 7660ea2659c..8cd1ffae9ce 100644 --- a/spec/models/build_spec.rb +++ b/spec/models/build_spec.rb @@ -296,16 +296,67 @@ describe Ci::Build, models: true do it_behaves_like 'tagged build picker' end - context 'when runner can not pick untagged jobs' do + context 'when runner cannot pick untagged jobs' do before { runner.run_untagged = false } - it 'can not handle builds without tags' do + it 'cannot handle builds without tags' do expect(build.can_be_served?(runner)).to be_falsey end it_behaves_like 'tagged build picker' end end + + context 'when runner is locked' do + before { runner.locked = true } + + shared_examples 'locked build picker' do |serve_matching_tags| + context 'when runner cannot pick untagged jobs' do + before { runner.run_untagged = false } + + it 'cannot handle builds without tags' do + expect(build.can_be_served?(runner)).to be_falsey + end + end + + context 'when having runner tags' do + before { runner.tag_list = ['bb', 'cc'] } + + it "#{serve_matching_tags} handle it for matching tags" do + build.tag_list = ['bb'] + expected = if serve_matching_tags + be_truthy + else + be_falsey + end + expect(build.can_be_served?(runner)).to expected + end + + it 'cannot handle it for builds without matching tags' do + build.tag_list = ['aa'] + expect(build.can_be_served?(runner)).to be_falsey + end + end + end + + context 'when serving the same project' do + it 'can handle it' do + expect(build.can_be_served?(runner)).to be_truthy + end + + it_behaves_like 'locked build picker', true + end + + context 'serving a different project' do + before { runner.runner_projects.destroy_all } + + it 'cannot handle it' do + expect(build.can_be_served?(runner)).to be_falsey + end + + it_behaves_like 'locked build picker', false + end + end end describe '#has_tags?' do