Commit 8415d486 authored by Arthur de Lapertosa Lisboa's avatar Arthur de Lapertosa Lisboa Committed by Fabio Pitino

Add Groups::SharedRunnersService, related tests and migrations

parent 8dd8e6ad
......@@ -18,6 +18,8 @@ class Group < Namespace
ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT = 10
UpdateSharedRunnersError = Class.new(StandardError)
has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source # rubocop:disable Cop/ActiveRecordDependent
alias_method :members, :group_members
has_many :users, through: :group_members
......@@ -89,6 +91,8 @@ class Group < Namespace
scope :with_users, -> { includes(:users) }
scope :by_id, ->(groups) { where(id: groups) }
class << self
def sort_by_attribute(method)
if method == 'storage_size_desc'
......@@ -504,6 +508,55 @@ class Group < Namespace
preloader.preload(self, shared_with_group_links: [shared_with_group: :route])
end
def shared_runners_allowed?
shared_runners_enabled? || allow_descendants_override_disabled_shared_runners?
end
def parent_allows_shared_runners?
return true unless has_parent?
parent.shared_runners_allowed?
end
def parent_enabled_shared_runners?
return true unless has_parent?
parent.shared_runners_enabled?
end
def enable_shared_runners!
raise UpdateSharedRunnersError, 'Shared Runners disabled for the parent group' unless parent_enabled_shared_runners?
update_column(:shared_runners_enabled, true)
end
def disable_shared_runners!
group_ids = self_and_descendants
return if group_ids.empty?
Group.by_id(group_ids).update_all(shared_runners_enabled: false)
all_projects.update_all(shared_runners_enabled: false)
end
def allow_descendants_override_disabled_shared_runners!
raise UpdateSharedRunnersError, 'Shared Runners enabled' if shared_runners_enabled?
raise UpdateSharedRunnersError, 'Group level shared Runners not allowed' unless parent_allows_shared_runners?
update_column(:allow_descendants_override_disabled_shared_runners, true)
end
def disallow_descendants_override_disabled_shared_runners!
raise UpdateSharedRunnersError, 'Shared Runners enabled' if shared_runners_enabled?
group_ids = self_and_descendants
return if group_ids.empty?
Group.by_id(group_ids).update_all(allow_descendants_override_disabled_shared_runners: false)
all_projects.update_all(shared_runners_enabled: false)
end
private
def update_two_factor_requirement
......
......@@ -211,7 +211,7 @@ class Namespace < ApplicationRecord
Gitlab.config.lfs.enabled
end
def shared_runners_enabled?
def any_project_with_shared_runners_enabled?
projects.with_shared_runners.any?
end
......
# frozen_string_literal: true
module Groups
class UpdateSharedRunnersService < Groups::BaseService
def execute
return error('Operation not allowed', 403) unless can?(current_user, :admin_group, group)
validate_params
enable_or_disable_shared_runners!
allow_or_disallow_descendants_override_disabled_shared_runners!
success
rescue Group::UpdateSharedRunnersError => error
error(error.message)
end
private
def validate_params
if Gitlab::Utils.to_boolean(params[:shared_runners_enabled]) && !params[:allow_descendants_override_disabled_shared_runners].nil?
raise Group::UpdateSharedRunnersError, 'Cannot set shared_runners_enabled to true and allow_descendants_override_disabled_shared_runners'
end
end
def enable_or_disable_shared_runners!
return if params[:shared_runners_enabled].nil?
if Gitlab::Utils.to_boolean(params[:shared_runners_enabled])
group.enable_shared_runners!
else
group.disable_shared_runners!
end
end
def allow_or_disallow_descendants_override_disabled_shared_runners!
return if params[:allow_descendants_override_disabled_shared_runners].nil?
# Needs to reset group because if both params are present could result in error
group.reset
if Gitlab::Utils.to_boolean(params[:allow_descendants_override_disabled_shared_runners])
group.allow_descendants_override_disabled_shared_runners!
else
group.disallow_descendants_override_disabled_shared_runners!
end
end
end
end
---
title: Add setting to enable and disable shared Runners for a group and its descendants
merge_request: 33411
author: Arthur de Lapertosa Lisboa
type: added
# frozen_string_literal: true
class AddSharedRunnersEnabledAndOverrideToNamespaces < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
with_lock_retries do
add_column :namespaces, :shared_runners_enabled, :boolean, default: true, null: false
add_column :namespaces, :allow_descendants_override_disabled_shared_runners, :boolean, default: false, null: false
end
end
def down
with_lock_retries do
remove_column :namespaces, :shared_runners_enabled, :boolean
remove_column :namespaces, :allow_descendants_override_disabled_shared_runners, :boolean
end
end
end
......@@ -13086,7 +13086,9 @@ CREATE TABLE public.namespaces (
default_branch_protection smallint,
unlock_membership_to_ldap boolean,
max_personal_access_token_lifetime integer,
push_rule_id bigint
push_rule_id bigint,
shared_runners_enabled boolean DEFAULT true NOT NULL,
allow_descendants_override_disabled_shared_runners boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE public.namespaces_id_seq
......@@ -23366,6 +23368,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200424043515
20200424050250
20200424101920
20200424102023
20200424135319
20200427064130
20200428134356
......
......@@ -212,7 +212,7 @@ module EE
def shared_runners_minutes_limit_enabled?
shared_runner_minutes_supported? &&
shared_runners_enabled? &&
any_project_with_shared_runners_enabled? &&
actual_shared_runners_minutes_limit.nonzero?
end
......@@ -238,7 +238,7 @@ module EE
extra_shared_runners_minutes.to_i >= extra_shared_runners_minutes_limit
end
def shared_runners_enabled?
def any_project_with_shared_runners_enabled?
all_projects.with_shared_runners.any?
end
......
- namespace = local_assigns.fetch(:namespace)
- minutes_quota = namespace.ci_minutes_quota
- if namespace.shared_runners_enabled?
- if namespace.any_project_with_shared_runners_enabled?
%li
%span.light Pipeline minutes quota:
%strong
......
......@@ -29,7 +29,7 @@
.col-sm-6.right
- if namespace.shared_runners_minutes_limit_enabled?
#{minutes_quota.monthly_percent_used}% used
- elsif !namespace.shared_runners_enabled?
- elsif !namespace.any_project_with_shared_runners_enabled?
0% used
- else
= s_('UsageQuota|Unlimited')
......@@ -47,7 +47,7 @@
= _('Minutes')
%tbody
- if !namespace.shared_runners_enabled?
- if !namespace.any_project_with_shared_runners_enabled?
%tr
%td{ colspan: 2 }
.nothing-here-block
......
......@@ -429,8 +429,8 @@ RSpec.describe Namespace do
end
end
describe '#shared_runners_enabled?' do
subject { namespace.shared_runners_enabled? }
describe '#any_project_with_shared_runners_enabled?' do
subject { namespace.any_project_with_shared_runners_enabled? }
context 'without projects' do
it { is_expected.to be_falsey }
......@@ -557,8 +557,8 @@ RSpec.describe Namespace do
end
end
describe '#shared_runners_enabled?' do
subject { namespace.shared_runners_enabled? }
describe '#any_project_with_shared_runners_enabled?' do
subject { namespace.any_project_with_shared_runners_enabled? }
context 'subgroup with shared runners enabled project' do
let(:subgroup) { create(:group, parent: namespace) }
......
......@@ -51,5 +51,13 @@ FactoryBot.define do
trait :owner_subgroup_creation_only do
subgroup_creation_level { ::Gitlab::Access::OWNER_SUBGROUP_ACCESS }
end
trait :shared_runners_disabled do
shared_runners_enabled { false }
end
trait :allow_descendants_override_disabled_shared_runners do
allow_descendants_override_disabled_shared_runners { true }
end
end
end
......@@ -1313,4 +1313,231 @@ RSpec.describe Group do
expect(groups).to contain_exactly(parent_group1, parent_group2, child_group1, child_group2, child_group3)
end
end
describe '#shared_runners_allowed?' do
using RSpec::Parameterized::TableSyntax
where(:shared_runners_enabled, :allow_descendants_override, :expected_shared_runners_allowed) do
true | false | true
true | true | true
false | false | false
false | true | true
end
with_them do
let!(:group) { create(:group, shared_runners_enabled: shared_runners_enabled, allow_descendants_override_disabled_shared_runners: allow_descendants_override) }
it 'returns the expected result' do
expect(group.shared_runners_allowed?).to eq(expected_shared_runners_allowed)
end
end
end
describe '#parent_allows_shared_runners?' do
context 'when parent group is present' do
using RSpec::Parameterized::TableSyntax
where(:shared_runners_enabled, :allow_descendants_override, :expected_shared_runners_allowed) do
true | false | true
true | true | true
false | false | false
false | true | true
end
with_them do
let!(:parent_group) { create(:group, shared_runners_enabled: shared_runners_enabled, allow_descendants_override_disabled_shared_runners: allow_descendants_override) }
let!(:group) { create(:group, parent: parent_group) }
it 'returns the expected result' do
expect(group.parent_allows_shared_runners?).to eq(expected_shared_runners_allowed)
end
end
end
context 'when parent group is missing' do
let!(:group) { create(:group) }
it 'returns true' do
expect(group.parent_allows_shared_runners?).to be_truthy
end
end
end
describe '#parent_enabled_shared_runners?' do
subject { group.parent_enabled_shared_runners? }
context 'when parent group is present' do
context 'When shared Runners are disabled' do
let!(:parent_group) { create(:group, :shared_runners_disabled) }
let!(:group) { create(:group, parent: parent_group) }
it { is_expected.to be_falsy }
end
context 'When shared Runners are enabled' do
let!(:parent_group) { create(:group) }
let!(:group) { create(:group, parent: parent_group) }
it { is_expected.to be_truthy }
end
end
context 'when parent group is missing' do
let!(:group) { create(:group) }
it { is_expected.to be_truthy }
end
end
describe '#enable_shared_runners!' do
subject { group.enable_shared_runners! }
context 'group that its ancestors have shared runners disabled' do
let_it_be(:parent) { create(:group, :shared_runners_disabled) }
let_it_be(:group) { create(:group, :shared_runners_disabled, parent: parent) }
let_it_be(:project) { create(:project, shared_runners_enabled: false, group: group) }
it 'raises error and does not enable shared Runners' do
expect { subject }
.to raise_error(described_class::UpdateSharedRunnersError, 'Shared Runners disabled for the parent group')
.and not_change { parent.reload.shared_runners_enabled }
.and not_change { group.reload.shared_runners_enabled }
.and not_change { project.reload.shared_runners_enabled }
end
end
context 'root group with shared runners disabled' do
let_it_be(:group) { create(:group, :shared_runners_disabled) }
let_it_be(:sub_group) { create(:group, :shared_runners_disabled, parent: group) }
let_it_be(:project) { create(:project, shared_runners_enabled: false, group: sub_group) }
it 'enables shared Runners only for itself' do
expect { subject }
.to change { group.reload.shared_runners_enabled }.from(false).to(true)
.and not_change { sub_group.reload.shared_runners_enabled }
.and not_change { project.reload.shared_runners_enabled }
end
end
end
describe '#disable_shared_runners!' do
let_it_be(:group) { create(:group) }
let_it_be(:sub_group) { create(:group, :shared_runners_disabled, :allow_descendants_override_disabled_shared_runners, parent: group) }
let_it_be(:sub_group_2) { create(:group, parent: group) }
let_it_be(:project) { create(:project, group: group, shared_runners_enabled: true) }
let_it_be(:project_2) { create(:project, group: sub_group_2, shared_runners_enabled: true) }
subject { group.disable_shared_runners! }
it 'disables shared Runners for all descendant groups and projects' do
expect { subject }
.to change { group.reload.shared_runners_enabled }.from(true).to(false)
.and not_change { group.reload.allow_descendants_override_disabled_shared_runners }
.and not_change { sub_group.reload.shared_runners_enabled }
.and not_change { sub_group.reload.allow_descendants_override_disabled_shared_runners }
.and change { sub_group_2.reload.shared_runners_enabled }.from(true).to(false)
.and not_change { sub_group_2.reload.allow_descendants_override_disabled_shared_runners }
.and change { project.reload.shared_runners_enabled }.from(true).to(false)
.and change { project_2.reload.shared_runners_enabled }.from(true).to(false)
end
end
describe '#allow_descendants_override_disabled_shared_runners!' do
subject { group.allow_descendants_override_disabled_shared_runners! }
context 'top level group' do
let_it_be(:group) { create(:group, :shared_runners_disabled) }
let_it_be(:sub_group) { create(:group, :shared_runners_disabled, parent: group) }
let_it_be(:project) { create(:project, shared_runners_enabled: false, group: sub_group) }
it 'enables allow descendants to override only for itself' do
expect { subject }
.to change { group.reload.allow_descendants_override_disabled_shared_runners }.from(false).to(true)
.and not_change { group.reload.shared_runners_enabled }
.and not_change { sub_group.reload.allow_descendants_override_disabled_shared_runners }
.and not_change { sub_group.reload.shared_runners_enabled }
.and not_change { project.reload.shared_runners_enabled }
end
end
context 'group that its ancestors have shared Runners disabled but allows to override' do
let_it_be(:parent) { create(:group, :shared_runners_disabled, :allow_descendants_override_disabled_shared_runners) }
let_it_be(:group) { create(:group, :shared_runners_disabled, parent: parent) }
let_it_be(:project) { create(:project, shared_runners_enabled: false, group: group) }
it 'enables allow descendants to override' do
expect { subject }
.to not_change { parent.reload.allow_descendants_override_disabled_shared_runners }
.and not_change { parent.reload.shared_runners_enabled }
.and change { group.reload.allow_descendants_override_disabled_shared_runners }.from(false).to(true)
.and not_change { group.reload.shared_runners_enabled }
.and not_change { project.reload.shared_runners_enabled }
end
end
context 'when parent does not allow' do
let_it_be(:parent) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false ) }
let_it_be(:group) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false, parent: parent) }
it 'raises error and does not allow descendants to override' do
expect { subject }
.to raise_error(described_class::UpdateSharedRunnersError, 'Group level shared Runners not allowed')
.and not_change { parent.reload.allow_descendants_override_disabled_shared_runners }
.and not_change { parent.reload.shared_runners_enabled }
.and not_change { group.reload.allow_descendants_override_disabled_shared_runners }
.and not_change { group.reload.shared_runners_enabled }
end
end
context 'top level group that has shared Runners enabled' do
let_it_be(:group) { create(:group, shared_runners_enabled: true) }
let_it_be(:sub_group) { create(:group, :shared_runners_disabled, parent: group) }
let_it_be(:project) { create(:project, shared_runners_enabled: false, group: sub_group) }
it 'raises error and does not change config' do
expect { subject }
.to raise_error(described_class::UpdateSharedRunnersError, 'Shared Runners enabled')
.and not_change { group.reload.allow_descendants_override_disabled_shared_runners }
.and not_change { group.reload.shared_runners_enabled }
.and not_change { sub_group.reload.allow_descendants_override_disabled_shared_runners }
.and not_change { sub_group.reload.shared_runners_enabled }
.and not_change { project.reload.shared_runners_enabled }
end
end
end
describe '#disallow_descendants_override_disabled_shared_runners!' do
subject { group.disallow_descendants_override_disabled_shared_runners! }
context 'top level group' do
let_it_be(:group) { create(:group, :shared_runners_disabled, :allow_descendants_override_disabled_shared_runners ) }
let_it_be(:sub_group) { create(:group, :shared_runners_disabled, :allow_descendants_override_disabled_shared_runners, parent: group) }
let_it_be(:project) { create(:project, shared_runners_enabled: true, group: sub_group) }
it 'disables allow project to override for descendants and disables project shared Runners' do
expect { subject }
.to not_change { group.reload.shared_runners_enabled }
.and change { group.reload.allow_descendants_override_disabled_shared_runners }.from(true).to(false)
.and not_change { sub_group.reload.shared_runners_enabled }
.and change { sub_group.reload.allow_descendants_override_disabled_shared_runners }.from(true).to(false)
.and change { project.reload.shared_runners_enabled }.from(true).to(false)
end
end
context 'top level group that has shared Runners enabled' do
let_it_be(:group) { create(:group, shared_runners_enabled: true) }
let_it_be(:sub_group) { create(:group, :shared_runners_disabled, parent: group) }
let_it_be(:project) { create(:project, shared_runners_enabled: false, group: sub_group) }
it 'results error and does not change config' do
expect { subject }
.to raise_error(described_class::UpdateSharedRunnersError, 'Shared Runners enabled')
.and not_change { group.reload.allow_descendants_override_disabled_shared_runners }
.and not_change { group.reload.shared_runners_enabled }
.and not_change { sub_group.reload.allow_descendants_override_disabled_shared_runners }
.and not_change { sub_group.reload.shared_runners_enabled }
.and not_change { project.reload.shared_runners_enabled }
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Groups::UpdateSharedRunnersService do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:params) { {} }
describe '#execute' do
subject { described_class.new(group, user, params).execute }
context 'when current_user is not the group owner' do
let_it_be(:group) { create(:group) }
let(:params) { { shared_runners_enabled: '0' } }
before do
group.add_maintainer(user)
end
it 'results error and does not call any method' do
expect(group).not_to receive(:enable_shared_runners!)
expect(group).not_to receive(:disable_shared_runners!)
expect(group).not_to receive(:allow_descendants_override_disabled_shared_runners!)
expect(group).not_to receive(:disallow_descendants_override_disabled_shared_runners!)
expect(subject[:status]).to eq(:error)
expect(subject[:message]).to eq('Operation not allowed')
expect(subject[:http_status]).to eq(403)
end
end
context 'when current_user is the group owner' do
before do
group.add_owner(user)
end
context 'enable shared Runners' do
where(:desired_params) do
['1', true]
end
with_them do
let(:params) { { shared_runners_enabled: desired_params } }
context 'group that its ancestors have shared runners disabled' do
let_it_be(:parent) { create(:group, :shared_runners_disabled) }
let_it_be(:group) { create(:group, :shared_runners_disabled, parent: parent) }
it 'results error' do
expect(subject[:status]).to eq(:error)
expect(subject[:message]).to eq('Shared Runners disabled for the parent group')
end
end
context 'root group with shared runners disabled' do
let_it_be(:group) { create(:group, :shared_runners_disabled) }
it 'receives correct method and succeeds' do
expect(group).to receive(:enable_shared_runners!)
expect(group).not_to receive(:disable_shared_runners!)
expect(group).not_to receive(:allow_descendants_override_disabled_shared_runners!)
expect(group).not_to receive(:disallow_descendants_override_disabled_shared_runners!)
expect(subject[:status]).to eq(:success)
end
end
end
end
context 'disable shared Runners' do
let_it_be(:group) { create(:group) }
where(:desired_params) do
['0', false]
end
with_them do
let(:params) { { shared_runners_enabled: desired_params } }
it 'receives correct method and succeeds' do
expect(group).to receive(:disable_shared_runners!)
expect(group).not_to receive(:enable_shared_runners!)
expect(group).not_to receive(:allow_descendants_override_disabled_shared_runners!)
expect(group).not_to receive(:disallow_descendants_override_disabled_shared_runners!)
expect(subject[:status]).to eq(:success)
end
end
end
context 'allow descendants to override' do
where(:desired_params) do
['1', true]
end
with_them do
let(:params) { { allow_descendants_override_disabled_shared_runners: desired_params } }
context 'top level group' do
let_it_be(:group) { create(:group, :shared_runners_disabled) }
it 'receives correct method and succeeds' do
expect(group).to receive(:allow_descendants_override_disabled_shared_runners!)
expect(group).not_to receive(:disallow_descendants_override_disabled_shared_runners!)
expect(group).not_to receive(:enable_shared_runners!)
expect(group).not_to receive(:disable_shared_runners!)
expect(subject[:status]).to eq(:success)
end
end
context 'when parent does not allow' do
let_it_be(:parent) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false ) }
let_it_be(:group) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false, parent: parent) }
it 'results error' do
expect(subject[:status]).to eq(:error)
expect(subject[:message]).to eq('Group level shared Runners not allowed')
end
end
end
end
context 'disallow descendants to override' do
where(:desired_params) do
['0', false]
end
with_them do
let(:params) { { allow_descendants_override_disabled_shared_runners: desired_params } }
context 'top level group' do
let_it_be(:group) { create(:group, :shared_runners_disabled, :allow_descendants_override_disabled_shared_runners ) }
it 'receives correct method and succeeds' do
expect(group).to receive(:disallow_descendants_override_disabled_shared_runners!)
expect(group).not_to receive(:allow_descendants_override_disabled_shared_runners!)
expect(group).not_to receive(:enable_shared_runners!)
expect(group).not_to receive(:disable_shared_runners!)
expect(subject[:status]).to eq(:success)
end
end
context 'top level group that has shared Runners enabled' do
let_it_be(:group) { create(:group, shared_runners_enabled: true) }
it 'results error' do
expect(subject[:status]).to eq(:error)
expect(subject[:message]).to eq('Shared Runners enabled')
end
end
end
end
context 'both params are present' do
context 'shared_runners_enabled: 1 and allow_descendants_override_disabled_shared_runners' do
let_it_be(:group) { create(:group, :shared_runners_disabled) }
let_it_be(:sub_group) { create(:group, :shared_runners_disabled, parent: group) }
let_it_be(:project) { create(:project, shared_runners_enabled: false, group: sub_group) }
where(:allow_descendants_override) do
['1', true, '0', false]
end
with_them do
let(:params) { { shared_runners_enabled: '1', allow_descendants_override_disabled_shared_runners: allow_descendants_override } }
it 'results in an error because shared Runners are enabled' do
expect { subject }
.to not_change { group.reload.shared_runners_enabled }
.and not_change { sub_group.reload.shared_runners_enabled }
.and not_change { project.reload.shared_runners_enabled }
.and not_change { group.reload.allow_descendants_override_disabled_shared_runners }
.and not_change { sub_group.reload.allow_descendants_override_disabled_shared_runners }
expect(subject[:status]).to eq(:error)
expect(subject[:message]).to eq('Cannot set shared_runners_enabled to true and allow_descendants_override_disabled_shared_runners')
end
end
end
context 'shared_runners_enabled: 0 and allow_descendants_override_disabled_shared_runners: 0' do
let_it_be(:group) { create(:group, :allow_descendants_override_disabled_shared_runners) }
let_it_be(:sub_group) { create(:group, :shared_runners_disabled, :allow_descendants_override_disabled_shared_runners, parent: group) }
let_it_be(:sub_group_2) { create(:group, parent: group) }
let_it_be(:project) { create(:project, group: group, shared_runners_enabled: true) }
let_it_be(:project_2) { create(:project, group: sub_group_2, shared_runners_enabled: true) }
let(:params) { { shared_runners_enabled: '0', allow_descendants_override_disabled_shared_runners: '0' } }
it 'disables shared Runners and disable allow_descendants_override_disabled_shared_runners' do
expect { subject }
.to change { group.reload.shared_runners_enabled }.from(true).to(false)
.and change { group.reload.allow_descendants_override_disabled_shared_runners }.from(true).to(false)
.and not_change { sub_group.reload.shared_runners_enabled }
.and change { sub_group.reload.allow_descendants_override_disabled_shared_runners }.from(true).to(false)
.and change { sub_group_2.reload.shared_runners_enabled }.from(true).to(false)
.and not_change { sub_group_2.reload.allow_descendants_override_disabled_shared_runners }
.and change { project.reload.shared_runners_enabled }.from(true).to(false)
.and change { project_2.reload.shared_runners_enabled }.from(true).to(false)
end
end
context 'shared_runners_enabled: 0 and allow_descendants_override_disabled_shared_runners: 1' do
let_it_be(:group) { create(:group) }
let_it_be(:sub_group) { create(:group, :shared_runners_disabled, parent: group) }
let_it_be(:sub_group_2) { create(:group, parent: group) }
let_it_be(:project) { create(:project, group: group, shared_runners_enabled: true) }
let_it_be(:project_2) { create(:project, group: sub_group_2, shared_runners_enabled: true) }
let(:params) { { shared_runners_enabled: '0', allow_descendants_override_disabled_shared_runners: '1' } }
it 'disables shared Runners and enable allow_descendants_override_disabled_shared_runners only for itself' do
expect { subject }
.to change { group.reload.shared_runners_enabled }.from(true).to(false)
.and change { group.reload.allow_descendants_override_disabled_shared_runners }.from(false).to(true)
.and not_change { sub_group.reload.shared_runners_enabled }
.and not_change { sub_group.reload.allow_descendants_override_disabled_shared_runners }
.and change { sub_group_2.reload.shared_runners_enabled }.from(true).to(false)
.and not_change { sub_group_2.reload.allow_descendants_override_disabled_shared_runners }
.and change { project.reload.shared_runners_enabled }.from(true).to(false)
.and change { project_2.reload.shared_runners_enabled }.from(true).to(false)
end
end
end
end
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