debian-mirror-gitlab/spec/models/container_registry/event_spec.rb
2023-04-23 21:23:45 +05:30

239 lines
7.5 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ContainerRegistry::Event do
using RSpec::Parameterized::TableSyntax
let_it_be(:group) { create(:group, name: 'group') }
let_it_be(:project) { create(:project, name: 'test', namespace: group) }
describe '#supported?' do
let(:raw_event) { { 'action' => action } }
subject { described_class.new(raw_event).supported? }
where(:action, :supported) do
'delete' | true
'push' | true
'mount' | false
'pull' | false
end
with_them do
it { is_expected.to eq supported }
end
end
describe '#handle!' do
let(:action) { 'push' }
let(:repository) { project.full_path }
let(:target) do
{
'mediaType' => ContainerRegistry::Client::DOCKER_DISTRIBUTION_MANIFEST_V2_TYPE,
'tag' => 'latest',
'repository' => repository
}
end
let(:raw_event) { { 'action' => action, 'target' => target } }
subject(:handle!) { described_class.new(raw_event).handle! }
shared_examples 'event with project statistics update' do
it 'enqueues a project statistics update' do
expect(ProjectCacheWorker).to receive(:perform_async).with(project.id, [], [:container_registry_size])
handle!
end
it 'clears the cache for the namespace container repositories size' do
expect(Rails.cache).to receive(:delete).with(group.container_repositories_size_cache_key)
handle!
end
end
shared_examples 'event without project statistics update' do
it 'does not queue a project statistics update' do
expect(ProjectCacheWorker).not_to receive(:perform_async)
handle!
end
end
it_behaves_like 'event with project statistics update'
context 'with no target tag' do
let(:target) { super().without('tag') }
it_behaves_like 'event without project statistics update'
context 'with a target digest' do
let(:target) { super().merge('digest' => 'abc123') }
it_behaves_like 'event without project statistics update'
end
context 'with a delete action' do
let(:action) { 'delete' }
context 'without a target digest' do
it_behaves_like 'event without project statistics update'
end
context 'with a target digest' do
let(:target) { super().merge('digest' => 'abc123') }
it_behaves_like 'event with project statistics update'
end
end
end
context 'with an unsupported action' do
let(:action) { 'pull' }
it_behaves_like 'event without project statistics update'
end
context 'with an invalid project repository path' do
let(:repository) { 'does/not/exist' }
it_behaves_like 'event without project statistics update'
end
context 'with no project repository path' do
let(:repository) { nil }
it_behaves_like 'event without project statistics update'
end
end
describe '#track!' do
let_it_be(:container_repository) { create(:container_repository, name: 'container', project: project) }
let(:raw_event) { { 'action' => action, 'target' => target } }
subject { described_class.new(raw_event).track! }
shared_examples 'tracking event is sent to HLLRedisCounter with event and originator ID' do |originator_type|
it 'fetches the event originator based on username' do
count.times do
expect(User).to receive(:find_by_username).with(originator.username)
end
subject
end
it 'sends a tracking event to HLLRedisCounter' do
expect(::Gitlab::UsageDataCounters::HLLRedisCounter)
.to receive(:track_event).with("i_container_registry_#{event}_#{originator_type}", values: originator.id)
.exactly(count).time
subject
end
end
context 'with a respository target' do
let(:target) do
{
'mediaType' => ContainerRegistry::Client::DOCKER_DISTRIBUTION_MANIFEST_V2_TYPE,
'repository' => repository_path
}
end
where(:repository_path, :action, :tracking_action) do
'group/test/container' | 'push' | 'push_repository'
'group/test/container' | 'delete' | 'delete_repository'
'foo/bar' | 'push' | 'create_repository'
'foo/bar' | 'delete' | 'delete_repository'
end
with_them do
it 'creates a tracking event' do
expect(::Gitlab::Tracking).to receive(:event).with('container_registry:notification', tracking_action)
subject
end
end
end
context 'with a tag target' do
let(:target) do
{
'mediaType' => ContainerRegistry::Client::DOCKER_DISTRIBUTION_MANIFEST_V2_TYPE,
'repository' => repository_path,
'tag' => 'latest'
}
end
where(:repository_path, :action, :tracking_action) do
'group/test/container' | 'push' | 'push_tag'
'group/test/container' | 'delete' | 'delete_tag'
'foo/bar' | 'push' | 'push_tag'
'foo/bar' | 'delete' | 'delete_tag'
end
with_them do
it 'creates a tracking event' do
expect(::Gitlab::Tracking).to receive(:event).with('container_registry:notification', tracking_action)
subject
end
end
end
context 'with a deploy token as the actor' do
let!(:originator) { create(:deploy_token, username: 'username', id: 3) }
let(:raw_event) do
{
'action' => 'push',
'target' => { 'tag' => 'latest' },
'actor' => { 'user_type' => 'deploy_token', 'name' => originator.username }
}
end
it 'does not send a tracking event to HLLRedisCounter' do
expect(::Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
subject
end
end
context 'with a user as the actor' do
let_it_be(:originator) { create(:user, username: 'username') }
let(:raw_event) do
{
'action' => action,
'target' => target,
'actor' => { 'user_type' => user_type, 'name' => originator.username }
}
end
where(:target, :action, :event, :user_type, :count) do
{ 'tag' => 'latest' } | 'push' | 'push_tag' | 'personal_access_token' | 1
{ 'tag' => 'latest' } | 'delete' | 'delete_tag' | 'personal_access_token' | 1
{ 'repository' => 'foo/bar' } | 'push' | 'create_repository' | 'build' | 1
{ 'repository' => 'foo/bar' } | 'delete' | 'delete_repository' | 'gitlab_or_ldap' | 1
{ 'repository' => 'foo/bar' } | 'delete' | 'delete_repository' | 'not_a_user' | 0
{ 'tag' => 'latest' } | 'copy' | '' | nil | 0
{ 'repository' => 'foo/bar' } | 'copy' | '' | '' | 0
end
with_them do
it_behaves_like 'tracking event is sent to HLLRedisCounter with event and originator ID', :user
end
end
context 'without an actor name' do
let(:raw_event) { { 'action' => 'push', 'target' => {}, 'actor' => { 'user_type' => 'personal_access_token' } } }
it 'does not send a tracking event to HLLRedisCounter' do
expect(User).not_to receive(:find_by_username)
expect(::Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
subject
end
end
end
end