Commit 051f385e authored by Kamil Trzciński's avatar Kamil Trzciński Committed by Dylan Griffith

Refactor validations and make runner factory by default to be instance-wide runner

parent 5c34c3fc
...@@ -56,12 +56,15 @@ module Ci ...@@ -56,12 +56,15 @@ module Ci
end end
validate :tag_constraints validate :tag_constraints
validate :no_projects, unless: :project_type?
validate :no_groups, unless: :group_type?
validate :only_one_group, if: :group_type?
validates :access_level, presence: true validates :access_level, presence: true
validates :runner_type, presence: true validates :runner_type, presence: true
validate :no_projects, unless: :project_type?
validate :no_groups, unless: :group_type?
validate :any_project, if: :project_type?
validate :exactly_one_group, if: :group_type?
validate :is_shared_is_valid
acts_as_taggable acts_as_taggable
after_destroy :cleanup_runner_queue after_destroy :cleanup_runner_queue
...@@ -117,8 +120,8 @@ module Ci ...@@ -117,8 +120,8 @@ module Ci
raise ArgumentError, 'Transitioning a group runner to a project runner is not supported' raise ArgumentError, 'Transitioning a group runner to a project runner is not supported'
end end
self.save self.projects << project
project.runner_projects.create(runner_id: self.id) self.save!
end end
def display_name def display_name
...@@ -257,19 +260,31 @@ module Ci ...@@ -257,19 +260,31 @@ module Ci
def no_projects def no_projects
if projects.any? if projects.any?
errors.add(:runner, 'cannot assign project to a non-project runner') errors.add(:runner, 'cannot have projects assigned')
end end
end end
def no_groups def no_groups
if groups.any? if groups.any?
errors.add(:runner, 'cannot assign group to a non-group runner') errors.add(:runner, 'cannot have groups assigned')
end
end
def any_project
unless projects.any?
errors.add(:runner, 'needs to be assigned to at least one project')
end
end
def exactly_one_group
unless groups.one?
errors.add(:runner, 'needs to be assigned to exactly one group')
end end
end end
def only_one_group def is_shared_is_valid
if groups.many? unless is_shared? == instance_type?
errors.add(:runner, 'can only be assigned to one group') errors.add(:is_shared, 'is not equal to instance_type?')
end end
end end
......
...@@ -3,7 +3,7 @@ require 'spec_helper' ...@@ -3,7 +3,7 @@ require 'spec_helper'
describe Groups::RunnersController do describe Groups::RunnersController do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:group) { create(:group) } let(:group) { create(:group) }
let(:runner) { create(:ci_runner, :group) } let(:runner) { create(:ci_runner, :group, groups: [group]) }
let(:params) do let(:params) do
{ {
...@@ -15,7 +15,6 @@ describe Groups::RunnersController do ...@@ -15,7 +15,6 @@ describe Groups::RunnersController do
before do before do
sign_in(user) sign_in(user)
group.add_master(user) group.add_master(user)
group.runners << runner
end end
describe '#update' do describe '#update' do
......
...@@ -3,7 +3,7 @@ require 'spec_helper' ...@@ -3,7 +3,7 @@ require 'spec_helper'
describe Projects::RunnersController do describe Projects::RunnersController do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project) } let(:project) { create(:project) }
let(:runner) { create(:ci_runner) } let(:runner) { create(:ci_runner, :project, projects: [project]) }
let(:params) do let(:params) do
{ {
...@@ -16,7 +16,6 @@ describe Projects::RunnersController do ...@@ -16,7 +16,6 @@ describe Projects::RunnersController do
before do before do
sign_in(user) sign_in(user)
project.add_master(user) project.add_master(user)
project.runners << runner
end end
describe '#update' do describe '#update' do
......
...@@ -19,12 +19,12 @@ describe Projects::Settings::CiCdController do ...@@ -19,12 +19,12 @@ describe Projects::Settings::CiCdController do
end end
context 'with group runners' do context 'with group runners' do
let(:group_runner) { create(:ci_runner, runner_type: :group_type) }
let(:parent_group) { create(:group) } let(:parent_group) { create(:group) }
let(:group) { create(:group, runners: [group_runner], parent: parent_group) } let(:group) { create(:group, parent: parent_group) }
let(:group_runner) { create(:ci_runner, :group, groups: [group]) }
let(:other_project) { create(:project, group: group) } let(:other_project) { create(:project, group: group) }
let!(:project_runner) { create(:ci_runner, projects: [other_project], runner_type: :project_type) } let!(:project_runner) { create(:ci_runner, :project, projects: [other_project]) }
let!(:shared_runner) { create(:ci_runner, :shared) } let!(:shared_runner) { create(:ci_runner, :instance) }
it 'sets assignable project runners only' do it 'sets assignable project runners only' do
group.add_master(user) group.add_master(user)
......
FactoryBot.define do FactoryBot.define do
factory :ci_runner_project, class: Ci::RunnerProject do factory :ci_runner_project, class: Ci::RunnerProject do
runner factory: :ci_runner runner factory: [:ci_runner, :project]
project project
end end
end end
...@@ -3,37 +3,27 @@ FactoryBot.define do ...@@ -3,37 +3,27 @@ FactoryBot.define do
sequence(:description) { |n| "My runner#{n}" } sequence(:description) { |n| "My runner#{n}" }
platform "darwin" platform "darwin"
is_shared false
active true active true
access_level :not_protected access_level :not_protected
runner_type :project_type
trait :online do
contacted_at Time.now
end
trait :shared do
is_shared true is_shared true
runner_type :instance_type runner_type :instance_type
end
trait :specific do trait :instance do
is_shared false is_shared true
runner_type :instance_type
end end
trait :group do trait :group do
is_shared false
runner_type :group_type runner_type :group_type
end end
trait :project do trait :project do
is_shared false
runner_type :project_type runner_type :project_type
end end
trait :instance do
is_shared true
runner_type :instance_type
end
trait :inactive do trait :inactive do
active false active false
end end
......
...@@ -76,7 +76,7 @@ describe "Admin Runners" do ...@@ -76,7 +76,7 @@ describe "Admin Runners" do
context 'shared runner' do context 'shared runner' do
it 'shows the label and does not show the project count' do it 'shows the label and does not show the project count' do
runner = create :ci_runner, :shared runner = create :ci_runner, :instance
visit admin_runners_path visit admin_runners_path
...@@ -90,7 +90,7 @@ describe "Admin Runners" do ...@@ -90,7 +90,7 @@ describe "Admin Runners" do
context 'specific runner' do context 'specific runner' do
it 'shows the label and the project count' do it 'shows the label and the project count' do
project = create :project project = create :project
runner = create :ci_runner, projects: [project] runner = create :ci_runner, :project, projects: [project]
visit admin_runners_path visit admin_runners_path
...@@ -149,8 +149,9 @@ describe "Admin Runners" do ...@@ -149,8 +149,9 @@ describe "Admin Runners" do
end end
context 'with specific runner' do context 'with specific runner' do
let(:runner) { create(:ci_runner, :project, projects: [@project1]) }
before do before do
@project1.runners << runner
visit admin_runner_path(runner) visit admin_runner_path(runner)
end end
...@@ -158,9 +159,9 @@ describe "Admin Runners" do ...@@ -158,9 +159,9 @@ describe "Admin Runners" do
end end
context 'with locked runner' do context 'with locked runner' do
let(:runner) { create(:ci_runner, :project, projects: [@project1], locked: true) }
before do before do
runner.update(locked: true)
@project1.runners << runner
visit admin_runner_path(runner) visit admin_runner_path(runner)
end end
...@@ -168,9 +169,10 @@ describe "Admin Runners" do ...@@ -168,9 +169,10 @@ describe "Admin Runners" do
end end
context 'with shared runner' do context 'with shared runner' do
let(:runner) { create(:ci_runner, :instance) }
before do before do
@project1.destroy @project1.destroy
runner.update(is_shared: true)
visit admin_runner_path(runner) visit admin_runner_path(runner)
end end
...@@ -179,8 +181,9 @@ describe "Admin Runners" do ...@@ -179,8 +181,9 @@ describe "Admin Runners" do
end end
describe 'disable/destroy' do describe 'disable/destroy' do
let(:runner) { create(:ci_runner, :project, projects: [@project1]) }
before do before do
@project1.runners << runner
visit admin_runner_path(runner) visit admin_runner_path(runner)
end end
......
...@@ -29,11 +29,7 @@ feature 'Runners' do ...@@ -29,11 +29,7 @@ feature 'Runners' do
end end
context 'when a project_type runner is activated on the project' do context 'when a project_type runner is activated on the project' do
given(:specific_runner) { create(:ci_runner, :project) } given(:specific_runner) { create(:ci_runner, :project, projects: [specific_runner]) }
background do
project.runners << specific_runner
end
scenario 'user sees the specific runner' do scenario 'user sees the specific runner' do
visit project_runners_path(project) visit project_runners_path(project)
...@@ -126,11 +122,10 @@ feature 'Runners' do ...@@ -126,11 +122,10 @@ feature 'Runners' do
context 'when a specific runner exists in another project' do context 'when a specific runner exists in another project' do
given(:another_project) { create(:project) } given(:another_project) { create(:project) }
given(:specific_runner) { create(:ci_runner, :project) } given(:specific_runner) { create(:ci_runner, :project, projects: [another_project]) }
background do background do
another_project.add_master(user) another_project.add_master(user)
another_project.runners << specific_runner
end end
scenario 'user enables and disables a specific runner' do scenario 'user enables and disables a specific runner' do
......
...@@ -2,7 +2,7 @@ require 'spec_helper' ...@@ -2,7 +2,7 @@ require 'spec_helper'
describe RunnerJobsFinder do describe RunnerJobsFinder do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:runner) { create(:ci_runner, :shared) } let(:runner) { create(:ci_runner, :instance) }
subject { described_class.new(runner, params).execute } subject { described_class.new(runner, params).execute }
......
...@@ -148,10 +148,9 @@ describe Ci::Build do ...@@ -148,10 +148,9 @@ describe Ci::Build do
end end
context 'when there are runners' do context 'when there are runners' do
let(:runner) { create(:ci_runner) } let(:runner) { create(:ci_runner, :project, projects: [build.project]) }
before do before do
build.project.runners << runner
runner.update_attributes(contacted_at: 1.second.ago) runner.update_attributes(contacted_at: 1.second.ago)
end end
...@@ -1388,12 +1387,7 @@ describe Ci::Build do ...@@ -1388,12 +1387,7 @@ describe Ci::Build do
it { is_expected.to be_truthy } it { is_expected.to be_truthy }
context "and there are specific runner" do context "and there are specific runner" do
let(:runner) { create(:ci_runner, contacted_at: 1.second.ago) } let!(:runner) { create(:ci_runner, :project, projects: [build.project], contacted_at: 1.second.ago) }
before do
build.project.runners << runner
runner.save
end
it { is_expected.to be_falsey } it { is_expected.to be_falsey }
end end
......
...@@ -1589,7 +1589,7 @@ describe Ci::Pipeline, :mailer do ...@@ -1589,7 +1589,7 @@ describe Ci::Pipeline, :mailer do
context 'when pipeline is not stuck' do context 'when pipeline is not stuck' do
before do before do
create(:ci_runner, :shared, :online) create(:ci_runner, :instance, :online)
end end
it 'is not stuck' do it 'is not stuck' do
......
This diff is collapsed.
...@@ -1177,8 +1177,8 @@ describe Project do ...@@ -1177,8 +1177,8 @@ describe Project do
describe '#any_runners?' do describe '#any_runners?' do
context 'shared runners' do context 'shared runners' do
let(:project) { create(:project, shared_runners_enabled: shared_runners_enabled) } let(:project) { create(:project, shared_runners_enabled: shared_runners_enabled) }
let(:specific_runner) { create(:ci_runner) } let(:specific_runner) { create(:ci_runner, :project, projects: [project]) }
let(:shared_runner) { create(:ci_runner, :shared) } let(:shared_runner) { create(:ci_runner, :instance) }
context 'for shared runners disabled' do context 'for shared runners disabled' do
let(:shared_runners_enabled) { false } let(:shared_runners_enabled) { false }
...@@ -1188,7 +1188,7 @@ describe Project do ...@@ -1188,7 +1188,7 @@ describe Project do
end end
it 'has a specific runner' do it 'has a specific runner' do
project.runners << specific_runner specific_runner
expect(project.any_runners?).to be_truthy expect(project.any_runners?).to be_truthy
end end
...@@ -1200,13 +1200,13 @@ describe Project do ...@@ -1200,13 +1200,13 @@ describe Project do
end end
it 'checks the presence of specific runner' do it 'checks the presence of specific runner' do
project.runners << specific_runner specific_runner
expect(project.any_runners? { |runner| runner == specific_runner }).to be_truthy expect(project.any_runners? { |runner| runner == specific_runner }).to be_truthy
end end
it 'returns false if match cannot be found' do it 'returns false if match cannot be found' do
project.runners << specific_runner specific_runner
expect(project.any_runners? { false }).to be_falsey expect(project.any_runners? { false }).to be_falsey
end end
......
...@@ -1858,8 +1858,7 @@ describe User do ...@@ -1858,8 +1858,7 @@ describe User do
describe '#ci_owned_runners' do describe '#ci_owned_runners' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:runner_1) { create(:ci_runner) } let(:runner) { create(:ci_runner, :project, projects: [project]) }
let(:runner_2) { create(:ci_runner) }
context 'without any projects nor groups' do context 'without any projects nor groups' do
let!(:project) { create(:project, runners: [runner_1]) } let!(:project) { create(:project, runners: [runner_1]) }
......
...@@ -262,16 +262,12 @@ describe API::Runner, :clean_gitlab_redis_shared_state do ...@@ -262,16 +262,12 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
describe '/api/v4/jobs' do describe '/api/v4/jobs' do
let(:project) { create(:project, shared_runners_enabled: false) } let(:project) { create(:project, shared_runners_enabled: false) }
let(:pipeline) { create(:ci_pipeline_without_jobs, project: project, ref: 'master') } let(:pipeline) { create(:ci_pipeline_without_jobs, project: project, ref: 'master') }
let(:runner) { create(:ci_runner) } let(:runner) { create(:ci_runner, :project, projects: [project]) }
let(:job) do let(:job) do
create(:ci_build, :artifacts, :extended_options, create(:ci_build, :artifacts, :extended_options,
pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0, commands: "ls\ndate") pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0, commands: "ls\ndate")
end end
before do
project.runners << runner
end
describe 'POST /api/v4/jobs/request' do describe 'POST /api/v4/jobs/request' do
let!(:last_update) {} let!(:last_update) {}
let!(:new_update) { } let!(:new_update) { }
...@@ -379,7 +375,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do ...@@ -379,7 +375,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
end end
context 'when shared runner requests job for project without shared_runners_enabled' do context 'when shared runner requests job for project without shared_runners_enabled' do
let(:runner) { create(:ci_runner, :shared) } let(:runner) { create(:ci_runner, :instance) }
it_behaves_like 'no jobs available' it_behaves_like 'no jobs available'
end end
......
...@@ -11,7 +11,7 @@ describe API::Runners do ...@@ -11,7 +11,7 @@ describe API::Runners do
let(:group) { create(:group).tap { |group| group.add_owner(user) } } let(:group) { create(:group).tap { |group| group.add_owner(user) } }
let(:group2) { create(:group).tap { |group| group.add_owner(user) } } let(:group2) { create(:group).tap { |group| group.add_owner(user) } }
let!(:shared_runner) { create(:ci_runner, :shared, description: 'Shared runner') } let!(:shared_runner) { create(:ci_runner, :instance, description: 'Shared runner') }
let!(:unused_project_runner) { create(:ci_runner) } let!(:unused_project_runner) { create(:ci_runner) }
let!(:project_runner) do let!(:project_runner) do
......
require 'spec_helper' require 'spec_helper'
describe RunnerEntity do describe RunnerEntity do
let(:runner) { create(:ci_runner, :specific) } let(:project) { create(:project) }
let(:runner) { create(:ci_runner, :project, projects: [project]) }
let(:entity) { described_class.new(runner, request: request, current_user: user) } let(:entity) { described_class.new(runner, request: request, current_user: user) }
let(:request) { double('request') } let(:request) { double('request') }
let(:project) { create(:project) }
let(:user) { create(:admin) } let(:user) { create(:admin) }
before do before do
......
...@@ -292,7 +292,7 @@ module Ci ...@@ -292,7 +292,7 @@ module Ci
end end
context 'when access_level of runner is not_protected' do context 'when access_level of runner is not_protected' do
let!(:specific_runner) { create(:ci_runner, :specific) } let!(:specific_runner) { create(:ci_runner, :project, projects: [project]) }
context 'when a job is protected' do context 'when a job is protected' do
let!(:pending_job) { create(:ci_build, :protected, pipeline: pipeline) } let!(:pending_job) { create(:ci_build, :protected, pipeline: pipeline) }
......
...@@ -6,13 +6,9 @@ describe Ci::UpdateBuildQueueService do ...@@ -6,13 +6,9 @@ describe Ci::UpdateBuildQueueService do
let(:pipeline) { create(:ci_pipeline, project: project) } let(:pipeline) { create(:ci_pipeline, project: project) }
context 'when updating specific runners' do context 'when updating specific runners' do
let(:runner) { create(:ci_runner, :project) } let(:runner) { create(:ci_runner, :project, projects: [project]) }
context 'when there is a runner that can pick build' do context 'when there is a runner that can pick build' do
before do
build.project.runners << runner
end
it 'ticks runner queue value' do it 'ticks runner queue value' do
expect { subject.execute(build) }.to change { runner.ensure_runner_queue_value } expect { subject.execute(build) }.to change { runner.ensure_runner_queue_value }
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment