Commit e1d3a980 authored by Francisco Javier López's avatar Francisco Javier López Committed by Douglas Barbosa Alexandre

Enable linear version `ci_owned_runners`

parent 113dc497
...@@ -1614,14 +1614,8 @@ class User < ApplicationRecord ...@@ -1614,14 +1614,8 @@ class User < ApplicationRecord
.joins(:runner) .joins(:runner)
.select('ci_runners.*') .select('ci_runners.*')
base_and_descendants = if Feature.enabled?(:linear_user_ci_owned_runners, self, default_enabled: :yaml)
owned_groups.self_and_descendant_ids
else
Gitlab::ObjectHierarchy.new(owned_groups).base_and_descendants.select(:id)
end
group_runners = Ci::RunnerNamespace group_runners = Ci::RunnerNamespace
.where(namespace_id: base_and_descendants) .where(namespace_id: owned_groups.self_and_descendant_ids)
.joins(:runner) .joins(:runner)
.select('ci_runners.*') .select('ci_runners.*')
......
---
name: linear_user_ci_owned_runners
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68848
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339435
milestone: '14.6'
type: development
group: group::access
default_enabled: false
...@@ -3723,321 +3723,309 @@ RSpec.describe User do ...@@ -3723,321 +3723,309 @@ RSpec.describe User do
end end
describe '#ci_owned_runners' do describe '#ci_owned_runners' do
shared_examples 'ci_owned_runners examples' do let(:user) { create(:user) }
let(:user) { create(:user) }
shared_examples :nested_groups_owner do shared_examples :nested_groups_owner do
context 'when the user is the owner of a multi-level group' do context 'when the user is the owner of a multi-level group' do
before do before do
set_permissions_for_users set_permissions_for_users
end end
it 'loads all the runners in the tree of groups' do it 'loads all the runners in the tree of groups' do
expect(user.ci_owned_runners).to contain_exactly(runner, group_runner) expect(user.ci_owned_runners).to contain_exactly(runner, group_runner)
end end
it 'returns true for owns_runner?' do it 'returns true for owns_runner?' do
expect(user.owns_runner?(runner)).to eq(true) expect(user.owns_runner?(runner)).to eq(true)
expect(user.owns_runner?(group_runner)).to eq(true) expect(user.owns_runner?(group_runner)).to eq(true)
end
end end
end end
end
shared_examples :group_owner do shared_examples :group_owner do
context 'when the user is the owner of a one level group' do context 'when the user is the owner of a one level group' do
before do before do
group.add_owner(user) group.add_owner(user)
end end
it 'loads the runners in the group' do it 'loads the runners in the group' do
expect(user.ci_owned_runners).to contain_exactly(group_runner) expect(user.ci_owned_runners).to contain_exactly(group_runner)
end end
it 'returns true for owns_runner?' do it 'returns true for owns_runner?' do
expect(user.owns_runner?(group_runner)).to eq(true) expect(user.owns_runner?(group_runner)).to eq(true)
end
end end
end end
end
shared_examples :project_owner do shared_examples :project_owner do
context 'when the user is the owner of a project' do context 'when the user is the owner of a project' do
it 'loads the runner belonging to the project' do it 'loads the runner belonging to the project' do
expect(user.ci_owned_runners).to contain_exactly(runner) expect(user.ci_owned_runners).to contain_exactly(runner)
end end
it 'returns true for owns_runner?' do it 'returns true for owns_runner?' do
expect(user.owns_runner?(runner)).to eq(true) expect(user.owns_runner?(runner)).to eq(true)
end
end end
end end
end
shared_examples :project_member do shared_examples :project_member do
context 'when the user is a maintainer' do context 'when the user is a maintainer' do
before do before do
add_user(:maintainer) add_user(:maintainer)
end
it 'loads the runners of the project' do
expect(user.ci_owned_runners).to contain_exactly(project_runner)
end
it 'returns true for owns_runner?' do
expect(user.owns_runner?(project_runner)).to eq(true)
end
end end
context 'when the user is a developer' do it 'loads the runners of the project' do
before do expect(user.ci_owned_runners).to contain_exactly(project_runner)
add_user(:developer) end
end
it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty
end
it 'returns false for owns_runner?' do it 'returns true for owns_runner?' do
expect(user.owns_runner?(project_runner)).to eq(false) expect(user.owns_runner?(project_runner)).to eq(true)
end
end end
end
context 'when the user is a reporter' do context 'when the user is a developer' do
before do before do
add_user(:reporter) add_user(:developer)
end end
it 'does not load any runner' do it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty expect(user.ci_owned_runners).to be_empty
end end
it 'returns false for owns_runner?' do it 'returns false for owns_runner?' do
expect(user.owns_runner?(project_runner)).to eq(false) expect(user.owns_runner?(project_runner)).to eq(false)
end
end end
end
context 'when the user is a guest' do context 'when the user is a reporter' do
before do before do
add_user(:guest) add_user(:reporter)
end end
it 'does not load any runner' do it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty expect(user.ci_owned_runners).to be_empty
end end
it 'returns false for owns_runner?' do it 'returns false for owns_runner?' do
expect(user.owns_runner?(project_runner)).to eq(false) expect(user.owns_runner?(project_runner)).to eq(false)
end
end end
end end
shared_examples :group_member do context 'when the user is a guest' do
context 'when the user is a maintainer' do before do
before do add_user(:guest)
add_user(:maintainer) end
end
it 'does not load the runners of the group' do it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty expect(user.ci_owned_runners).to be_empty
end end
it 'returns false for owns_runner?' do it 'returns false for owns_runner?' do
expect(user.owns_runner?(runner)).to eq(false) expect(user.owns_runner?(project_runner)).to eq(false)
end
end end
end
end
context 'when the user is a developer' do shared_examples :group_member do
before do context 'when the user is a maintainer' do
add_user(:developer) before do
end add_user(:maintainer)
end
it 'does not load any runner' do it 'does not load the runners of the group' do
expect(user.ci_owned_runners).to be_empty expect(user.ci_owned_runners).to be_empty
end end
it 'returns false for owns_runner?' do it 'returns false for owns_runner?' do
expect(user.owns_runner?(runner)).to eq(false) expect(user.owns_runner?(runner)).to eq(false)
end
end end
end
context 'when the user is a reporter' do context 'when the user is a developer' do
before do before do
add_user(:reporter) add_user(:developer)
end end
it 'does not load any runner' do it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty expect(user.ci_owned_runners).to be_empty
end end
it 'returns false for owns_runner?' do it 'returns false for owns_runner?' do
expect(user.owns_runner?(runner)).to eq(false) expect(user.owns_runner?(runner)).to eq(false)
end
end end
end
context 'when the user is a guest' do context 'when the user is a reporter' do
before do before do
add_user(:guest) add_user(:reporter)
end end
it 'does not load any runner' do it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty expect(user.ci_owned_runners).to be_empty
end end
it 'returns false for owns_runner?' do it 'returns false for owns_runner?' do
expect(user.owns_runner?(runner)).to eq(false) expect(user.owns_runner?(runner)).to eq(false)
end
end end
end end
context 'without any projects nor groups' do context 'when the user is a guest' do
before do
add_user(:guest)
end
it 'does not load any runner' do it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty expect(user.ci_owned_runners).to be_empty
end end
it 'returns false for owns_runner?' do it 'returns false for owns_runner?' do
expect(user.owns_runner?(create(:ci_runner))).to eq(false) expect(user.owns_runner?(runner)).to eq(false)
end end
end end
end
context 'with runner in a personal project' do context 'without any projects nor groups' do
let!(:namespace) { create(:user_namespace, owner: user) } it 'does not load any runner' do
let!(:project) { create(:project, namespace: namespace) } expect(user.ci_owned_runners).to be_empty
let!(:runner) { create(:ci_runner, :project, projects: [project]) }
it_behaves_like :project_owner
end end
context 'with group runner in a non owned group' do it 'returns false for owns_runner?' do
let!(:group) { create(:group) } expect(user.owns_runner?(create(:ci_runner))).to eq(false)
let!(:runner) { create(:ci_runner, :group, groups: [group]) } end
end
def add_user(access) context 'with runner in a personal project' do
group.add_user(user, access) let!(:namespace) { create(:user_namespace, owner: user) }
end let!(:project) { create(:project, namespace: namespace) }
let!(:runner) { create(:ci_runner, :project, projects: [project]) }
it_behaves_like :group_member it_behaves_like :project_owner
end end
context 'with group runner in an owned group' do context 'with group runner in a non owned group' do
let!(:group) { create(:group) } let!(:group) { create(:group) }
let!(:group_runner) { create(:ci_runner, :group, groups: [group]) } let!(:runner) { create(:ci_runner, :group, groups: [group]) }
it_behaves_like :group_owner def add_user(access)
group.add_user(user, access)
end end
context 'with group runner in an owned group and group runner in a different owner subgroup' do it_behaves_like :group_member
let!(:group) { create(:group) } end
let!(:runner) { create(:ci_runner, :group, groups: [group]) }
let!(:subgroup) { create(:group, parent: group) }
let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) }
let!(:another_user) { create(:user) }
def set_permissions_for_users
group.add_owner(user)
subgroup.add_owner(another_user)
end
it_behaves_like :nested_groups_owner context 'with group runner in an owned group' do
end let!(:group) { create(:group) }
let!(:group_runner) { create(:ci_runner, :group, groups: [group]) }
context 'with personal project runner in an an owned group and a group runner in that same group' do it_behaves_like :group_owner
let!(:group) { create(:group) } end
let!(:group_runner) { create(:ci_runner, :group, groups: [group]) }
let!(:project) { create(:project, group: group) }
let!(:runner) { create(:ci_runner, :project, projects: [project]) }
def set_permissions_for_users context 'with group runner in an owned group and group runner in a different owner subgroup' do
group.add_owner(user) let!(:group) { create(:group) }
end let!(:runner) { create(:ci_runner, :group, groups: [group]) }
let!(:subgroup) { create(:group, parent: group) }
let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) }
let!(:another_user) { create(:user) }
it_behaves_like :nested_groups_owner def set_permissions_for_users
group.add_owner(user)
subgroup.add_owner(another_user)
end end
context 'with personal project runner in an owned group and a group runner in a subgroup' do it_behaves_like :nested_groups_owner
let!(:group) { create(:group) } end
let!(:subgroup) { create(:group, parent: group) }
let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) }
let!(:project) { create(:project, group: group) }
let!(:runner) { create(:ci_runner, :project, projects: [project]) }
def set_permissions_for_users context 'with personal project runner in an an owned group and a group runner in that same group' do
group.add_owner(user) let!(:group) { create(:group) }
end let!(:group_runner) { create(:ci_runner, :group, groups: [group]) }
let!(:project) { create(:project, group: group) }
let!(:runner) { create(:ci_runner, :project, projects: [project]) }
it_behaves_like :nested_groups_owner def set_permissions_for_users
group.add_owner(user)
end end
context 'with personal project runner in an owned group in an owned namespace and a group runner in that group' do it_behaves_like :nested_groups_owner
let!(:namespace) { create(:user_namespace, owner: user) } end
let!(:group) { create(:group) }
let!(:group_runner) { create(:ci_runner, :group, groups: [group]) }
let!(:project) { create(:project, namespace: namespace, group: group) }
let!(:runner) { create(:ci_runner, :project, projects: [project]) }
def set_permissions_for_users context 'with personal project runner in an owned group and a group runner in a subgroup' do
group.add_owner(user) let!(:group) { create(:group) }
end let!(:subgroup) { create(:group, parent: group) }
let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) }
let!(:project) { create(:project, group: group) }
let!(:runner) { create(:ci_runner, :project, projects: [project]) }
it_behaves_like :nested_groups_owner def set_permissions_for_users
group.add_owner(user)
end end
context 'with personal project runner in an owned namespace, an owned group, a subgroup and a group runner in that subgroup' do it_behaves_like :nested_groups_owner
let!(:namespace) { create(:user_namespace, owner: user) } end
let!(:group) { create(:group) }
let!(:subgroup) { create(:group, parent: group) }
let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) }
let!(:project) { create(:project, namespace: namespace, group: group) }
let!(:runner) { create(:ci_runner, :project, projects: [project]) }
def set_permissions_for_users context 'with personal project runner in an owned group in an owned namespace and a group runner in that group' do
group.add_owner(user) let!(:namespace) { create(:user_namespace, owner: user) }
end let!(:group) { create(:group) }
let!(:group_runner) { create(:ci_runner, :group, groups: [group]) }
let!(:project) { create(:project, namespace: namespace, group: group) }
let!(:runner) { create(:ci_runner, :project, projects: [project]) }
it_behaves_like :nested_groups_owner def set_permissions_for_users
group.add_owner(user)
end end
context 'with a project runner that belong to projects that belong to a not owned group' do it_behaves_like :nested_groups_owner
let!(:group) { create(:group) } end
let!(:project) { create(:project, group: group) }
let!(:project_runner) { create(:ci_runner, :project, projects: [project]) }
def add_user(access) context 'with personal project runner in an owned namespace, an owned group, a subgroup and a group runner in that subgroup' do
project.add_user(user, access) let!(:namespace) { create(:user_namespace, owner: user) }
end let!(:group) { create(:group) }
let!(:subgroup) { create(:group, parent: group) }
let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) }
let!(:project) { create(:project, namespace: namespace, group: group) }
let!(:runner) { create(:ci_runner, :project, projects: [project]) }
it_behaves_like :project_member def set_permissions_for_users
group.add_owner(user)
end end
context 'with project runners that belong to projects that do not belong to any group' do it_behaves_like :nested_groups_owner
let!(:project) { create(:project) } end
let!(:runner) { create(:ci_runner, :project, projects: [project]) }
it 'does not load any runner' do context 'with a project runner that belong to projects that belong to a not owned group' do
expect(user.ci_owned_runners).to be_empty let!(:group) { create(:group) }
end let!(:project) { create(:project, group: group) }
let!(:project_runner) { create(:ci_runner, :project, projects: [project]) }
def add_user(access)
project.add_user(user, access)
end end
context 'with a group runner that belongs to a subgroup of a group owned by another user' do it_behaves_like :project_member
let!(:group) { create(:group) } end
let!(:subgroup) { create(:group, parent: group) }
let!(:runner) { create(:ci_runner, :group, groups: [subgroup]) }
let!(:another_user) { create(:user) }
def add_user(access) context 'with project runners that belong to projects that do not belong to any group' do
subgroup.add_user(user, access) let!(:project) { create(:project) }
group.add_user(another_user, :owner) let!(:runner) { create(:ci_runner, :project, projects: [project]) }
end
it_behaves_like :group_member it 'does not load any runner' do
expect(user.ci_owned_runners).to be_empty
end end
end end
it_behaves_like 'ci_owned_runners examples' context 'with a group runner that belongs to a subgroup of a group owned by another user' do
let!(:group) { create(:group) }
let!(:subgroup) { create(:group, parent: group) }
let!(:runner) { create(:ci_runner, :group, groups: [subgroup]) }
let!(:another_user) { create(:user) }
context 'when feature flag :linear_user_ci_owned_runners is disabled' do def add_user(access)
before do subgroup.add_user(user, access)
stub_feature_flags(linear_user_ci_owned_runners: false) group.add_user(another_user, :owner)
end end
it_behaves_like 'ci_owned_runners examples' it_behaves_like :group_member
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