Skip to content
Snippets Groups Projects
Commit 2c89e169 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent bd497e35
No related branches found
No related tags found
No related merge requests found
Showing
with 357 additions and 90 deletions
Loading
Loading
@@ -3,8 +3,8 @@
require 'spec_helper'
 
describe ListUserPreference do
set(:user) { create(:user) }
set(:list) { create(:list) }
let_it_be(:user) { create(:user) }
let_it_be(:list) { create(:list) }
 
before do
list.update_preferences_for(user, { collapsed: true })
Loading
Loading
Loading
Loading
@@ -352,9 +352,9 @@ describe PagesDomain do
end
 
context 'configuration updates when attributes change' do
set(:project1) { create(:project) }
set(:project2) { create(:project) }
set(:domain) { create(:pages_domain) }
let_it_be(:project1) { create(:project) }
let_it_be(:project2) { create(:project) }
let_it_be(:domain) { create(:pages_domain) }
 
where(:attribute, :old_value, :new_value, :update_expected) do
now = Time.now
Loading
Loading
@@ -402,8 +402,8 @@ describe PagesDomain do
end
 
context 'TLS configuration' do
set(:domain_without_tls) { create(:pages_domain, :without_certificate, :without_key) }
set(:domain) { create(:pages_domain) }
let_it_be(:domain_without_tls) { create(:pages_domain, :without_certificate, :without_key) }
let_it_be(:domain) { create(:pages_domain) }
 
let(:cert1) { domain.certificate }
let(:cert2) { cert1 + ' ' }
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe AlertsService do
let_it_be(:project) { create(:project) }
let(:service_params) { { project: project, active: active } }
let(:active) { true }
let(:service) { described_class.new(service_params) }
shared_context 'when active' do
let(:active) { true }
end
shared_context 'when inactive' do
let(:active) { false }
end
shared_context 'when persisted' do
before do
service.save!
service.reload
end
end
describe '#url' do
include Gitlab::Routing
subject { service.url }
it { is_expected.to eq(project_alerts_notify_url(project, format: :json)) }
end
describe '#json_fields' do
subject { service.json_fields }
it { is_expected.to eq(%w(active token)) }
end
describe '#as_json' do
subject { service.as_json(only: service.json_fields) }
it { is_expected.to eq('active' => true, 'token' => nil) }
end
describe '#token' do
shared_context 'reset token' do
before do
service.token = ''
service.valid?
end
end
shared_context 'assign token' do |token|
before do
service.token = token
service.valid?
end
end
shared_examples 'valid token' do
it { is_expected.to match(/\A\h{32}\z/) }
end
shared_examples 'no token' do
it { is_expected.to be_blank }
end
subject { service.token }
context 'when active' do
include_context 'when active'
context 'when resetting' do
let!(:previous_token) { service.token }
include_context 'reset token'
it_behaves_like 'valid token'
it { is_expected.not_to eq(previous_token) }
end
context 'when assigning' do
include_context 'assign token', 'random token'
it_behaves_like 'valid token'
end
end
context 'when inactive' do
include_context 'when inactive'
context 'when resetting' do
let!(:previous_token) { service.token }
include_context 'reset token'
it_behaves_like 'no token'
end
end
context 'when persisted' do
include_context 'when persisted'
it_behaves_like 'valid token'
end
end
end
Loading
Loading
@@ -37,9 +37,9 @@ describe MicrosoftTeamsService do
end
 
describe "#execute" do
let(:user) { create(:user) }
let(:user) { create(:user) }
 
set(:project) { create(:project, :repository, :wiki_repo) }
let_it_be(:project) { create(:project, :repository, :wiki_repo) }
 
before do
allow(chat_service).to receive_messages(
Loading
Loading
Loading
Loading
@@ -169,7 +169,7 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
end
 
context 'cluster belongs to projects group' do
set(:group) { create(:group) }
let_it_be(:group) { create(:group) }
let(:project) { create(:prometheus_project, group: group) }
let(:cluster) { create(:cluster_for_group, :with_installed_helm, groups: [group]) }
 
Loading
Loading
Loading
Loading
@@ -3901,7 +3901,7 @@ describe Project do
end
 
context 'legacy storage' do
set(:project) { create(:project, :repository, :legacy_storage) }
let_it_be(:project) { create(:project, :repository, :legacy_storage) }
let(:gitlab_shell) { Gitlab::Shell.new }
let(:project_storage) { project.send(:storage) }
 
Loading
Loading
@@ -4000,7 +4000,7 @@ describe Project do
end
 
context 'hashed storage' do
set(:project) { create(:project, :repository, skip_disk_validation: true) }
let_it_be(:project) { create(:project, :repository, skip_disk_validation: true) }
let(:gitlab_shell) { Gitlab::Shell.new }
let(:hash) { Digest::SHA2.hexdigest(project.id.to_s) }
let(:hashed_prefix) { File.join('@hashed', hash[0..1], hash[2..3]) }
Loading
Loading
@@ -4090,7 +4090,7 @@ describe Project do
end
 
describe '#has_ci?' do
set(:project) { create(:project) }
let_it_be(:project, reload: true) { create(:project) }
let(:repository) { double }
 
before do
Loading
Loading
@@ -4134,7 +4134,7 @@ describe Project do
Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(0)
end
 
set(:project) { create(:project) }
let_it_be(:project, reload: true) { create(:project) }
 
subject { project.auto_devops_enabled? }
 
Loading
Loading
@@ -4269,7 +4269,7 @@ describe Project do
end
 
describe '#has_auto_devops_implicitly_enabled?' do
set(:project) { create(:project) }
let_it_be(:project, reload: true) { create(:project) }
 
context 'when disabled in settings' do
before do
Loading
Loading
@@ -4330,7 +4330,7 @@ describe Project do
end
 
describe '#has_auto_devops_implicitly_disabled?' do
set(:project) { create(:project) }
let_it_be(:project, reload: true) { create(:project) }
 
before do
allow(Feature).to receive(:enabled?).and_call_original
Loading
Loading
@@ -4408,7 +4408,7 @@ describe Project do
end
 
describe '#api_variables' do
set(:project) { create(:project) }
let_it_be(:project) { create(:project) }
 
it 'exposes API v4 URL' do
expect(project.api_variables.first[:key]).to eq 'CI_API_V4_URL'
Loading
Loading
@@ -4605,7 +4605,7 @@ describe Project do
end
 
describe '#write_repository_config' do
set(:project) { create(:project, :repository) }
let_it_be(:project) { create(:project, :repository) }
 
it 'writes full path in .git/config when key is missing' do
project.write_repository_config
Loading
Loading
@@ -4696,7 +4696,7 @@ describe Project do
end
 
describe '#has_active_hooks?' do
set(:project) { create(:project) }
let_it_be(:project) { create(:project) }
 
it { expect(project.has_active_hooks?).to be_falsey }
 
Loading
Loading
@@ -4723,7 +4723,7 @@ describe Project do
end
 
describe '#has_active_services?' do
set(:project) { create(:project) }
let_it_be(:project) { create(:project) }
 
it { expect(project.has_active_services?).to be_falsey }
 
Loading
Loading
@@ -5009,8 +5009,8 @@ describe Project do
describe '#members_among' do
let(:users) { create_list(:user, 3) }
 
set(:group) { create(:group) }
set(:project) { create(:project, namespace: group) }
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, namespace: group) }
 
before do
project.add_guest(users.first)
Loading
Loading
@@ -5584,6 +5584,14 @@ describe Project do
end
end
 
describe '#alerts_service_activated?' do
let!(:project) { create(:project) }
subject { project.alerts_service_activated? }
it { is_expected.to be_falsey }
end
def rugged_config
rugged_repo(project.repository).config
end
Loading
Loading
Loading
Loading
@@ -3,7 +3,7 @@
require 'spec_helper'
 
describe Releases::Source do
set(:project) { create(:project, :repository, name: 'finance-cal') }
let_it_be(:project) { create(:project, :repository, name: 'finance-cal') }
let(:tag_name) { 'v1.0' }
 
describe '.all' do
Loading
Loading
Loading
Loading
@@ -60,7 +60,8 @@ describe API::LsifData do
'end_char' => 18,
'end_line' => 8,
'start_char' => 13,
'start_line' => 8
'start_line' => 8,
'definition_url' => project_blob_path(project, "#{commit.id}/morestrings/reverse.go", anchor: 'L5')
})
end
 
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe Projects::Alerting::NotifyService do
let_it_be(:project, reload: true) { create(:project) }
shared_examples 'does not process incident issues' do |http_status:|
it 'does not process issues' do
expect(IncidentManagement::ProcessAlertWorker)
.not_to receive(:perform_async)
expect(subject.status).to eq(:error)
expect(subject.http_status).to eq(http_status)
end
end
describe '#execute' do
let(:token) { 'invalid-token' }
let(:starts_at) { Time.now.change(usec: 0) }
let(:service) { described_class.new(project, nil, payload) }
let(:payload_raw) do
{
'title' => 'alert title',
'start_time' => starts_at.rfc3339
}
end
let(:payload) { ActionController::Parameters.new(payload_raw).permit! }
subject { service.execute(token) }
it_behaves_like 'does not process incident issues', http_status: 403
end
end
Loading
Loading
@@ -41,7 +41,7 @@ describe Projects::ContainerRepository::CleanupTagsService do
let(:params) { {} }
 
it 'does not remove anything' do
expect_any_instance_of(ContainerRegistry::Client).not_to receive(:delete_repository_tag)
expect_any_instance_of(ContainerRegistry::Client).not_to receive(:delete_repository_tag_by_digest)
 
is_expected.to include(status: :success, deleted: [])
end
Loading
Loading
@@ -156,7 +156,7 @@ describe Projects::ContainerRepository::CleanupTagsService do
 
def expect_delete(digest)
expect_any_instance_of(ContainerRegistry::Client)
.to receive(:delete_repository_tag)
.to receive(:delete_repository_tag_by_digest)
.with(repository.path, digest) { true }
end
end
Loading
Loading
@@ -18,10 +18,6 @@ describe Projects::ContainerRepository::DeleteTagsService do
stub_container_registry_tags(
repository: repository.path,
tags: %w(latest A Ba Bb C D E))
stub_tag_digest('latest', 'sha256:configA')
stub_tag_digest('A', 'sha256:configA')
stub_tag_digest('Ba', 'sha256:configB')
end
 
describe '#execute' do
Loading
Loading
@@ -38,82 +34,178 @@ describe Projects::ContainerRepository::DeleteTagsService do
project.add_developer(user)
end
 
context 'when no params are specified' do
let(:params) { {} }
context 'when the registry supports fast delete' do
context 'and the feature is enabled' do
let_it_be(:project) { create(:project, :private) }
let_it_be(:repository) { create(:container_repository, :root, project: project) }
 
it 'does not remove anything' do
expect_any_instance_of(ContainerRegistry::Client).not_to receive(:delete_repository_tag)
before do
allow(repository.client).to receive(:supports_tag_delete?).and_return(true)
end
 
is_expected.to include(status: :error)
end
end
context 'with tags to delete' do
let_it_be(:tags) { %w[A Ba] }
 
context 'with empty tags' do
let(:tags) { [] }
it 'deletes the tags by name' do
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/A")
.to_return(status: 200, body: "")
 
it 'does not remove anything' do
expect_any_instance_of(ContainerRegistry::Client).not_to receive(:delete_repository_tag)
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/Ba")
.to_return(status: 200, body: "")
 
is_expected.to include(status: :error)
end
end
expect_delete_tag_by_name('A')
expect_delete_tag_by_name('Ba')
is_expected.to include(status: :success)
end
it 'succeeds when tag delete returns 404' do
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/A")
.to_return(status: 200, body: "")
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/Ba")
.to_return(status: 404, body: "")
is_expected.to include(status: :success)
end
context 'with failures' do
context 'when the delete request fails' do
before do
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/A")
.to_return(status: 500, body: "")
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/Ba")
.to_return(status: 500, body: "")
end
 
context 'with tags to delete' do
let(:tags) { %w[A Ba] }
it { is_expected.to include(status: :error) }
end
end
end
context 'when no params are specified' do
let_it_be(:params) { {} }
it 'does not remove anything' do
expect_any_instance_of(ContainerRegistry::Client).not_to receive(:delete_repository_tag_by_name)
is_expected.to include(status: :error)
end
end
 
it 'deletes the tags using a dummy image' do
stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
context 'with empty tags' do
let_it_be(:tags) { [] }
 
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/A")
.to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
it 'does not remove anything' do
expect_any_instance_of(ContainerRegistry::Client).not_to receive(:delete_repository_tag_by_name)
 
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/Ba")
.to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
is_expected.to include(status: :error)
end
end
end
context 'and the feature is disabled' do
before do
stub_feature_flags(container_registry_fast_tag_delete: false)
end
 
expect_delete_tag('sha256:dummy')
it 'fallbacks to slow delete' do
expect(service).not_to receive(:fast_delete)
expect(service).to receive(:slow_delete).with(repository, tags)
 
is_expected.to include(status: :success)
subject
end
end
end
context 'when the registry does not support fast delete' do
let_it_be(:project) { create(:project, :private) }
let_it_be(:repository) { create(:container_repository, :root, project: project) }
 
it 'succedes when tag delete returns 404' do
stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
before do
stub_tag_digest('latest', 'sha256:configA')
stub_tag_digest('A', 'sha256:configA')
stub_tag_digest('Ba', 'sha256:configB')
 
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/A")
.to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
allow(repository.client).to receive(:supports_tag_delete?).and_return(false)
end
 
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/Ba")
.to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
context 'when no params are specified' do
let_it_be(:params) { {} }
 
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/manifests/sha256:dummy")
.to_return(status: 404, body: "", headers: {})
it 'does not remove anything' do
expect_any_instance_of(ContainerRegistry::Client).not_to receive(:delete_repository_tag_by_digest)
 
is_expected.to include(status: :success)
is_expected.to include(status: :error)
end
end
 
context 'with failures' do
context 'when the dummy manifest generation fails' do
before do
stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3', success: false)
end
context 'with empty tags' do
let_it_be(:tags) { [] }
it 'does not remove anything' do
expect_any_instance_of(ContainerRegistry::Client).not_to receive(:delete_repository_tag_by_digest)
is_expected.to include(status: :error)
end
end
context 'with tags to delete' do
let_it_be(:tags) { %w[A Ba] }
 
it { is_expected.to include(status: :error) }
it 'deletes the tags using a dummy image' do
stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/A")
.to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/Ba")
.to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
expect_delete_tag_by_digest('sha256:dummy')
is_expected.to include(status: :success)
end
 
context 'when updating the tags fails' do
before do
stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
it 'succeeds when tag delete returns 404' do
stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
 
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/A")
.to_return(status: 500, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/A")
.to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
 
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/Ba")
.to_return(status: 500, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/Ba")
.to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/manifests/sha256:dummy")
.to_return(status: 404, body: "", headers: {})
is_expected.to include(status: :success)
end
 
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/manifests/sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3")
.to_return(status: 200, body: "", headers: {})
context 'with failures' do
context 'when the dummy manifest generation fails' do
before do
stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3', success: false)
end
it { is_expected.to include(status: :error) }
end
 
it { is_expected.to include(status: :error) }
context 'when updating the tags fails' do
before do
stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/A")
.to_return(status: 500, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/Ba")
.to_return(status: 500, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/manifests/sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3")
.to_return(status: 200, body: "", headers: {})
end
it { is_expected.to include(status: :error) }
end
end
end
end
Loading
Loading
@@ -141,9 +233,21 @@ describe Projects::ContainerRepository::DeleteTagsService do
.with(repository.path, content, digest) { double(success?: success ) }
end
 
def expect_delete_tag(digest)
def expect_delete_tag_by_digest(digest)
expect_any_instance_of(ContainerRegistry::Client)
.to receive(:delete_repository_tag)
.to receive(:delete_repository_tag_by_digest)
.with(repository.path, digest) { true }
expect_any_instance_of(ContainerRegistry::Client)
.not_to receive(:delete_repository_tag_by_name)
end
def expect_delete_tag_by_name(name)
expect_any_instance_of(ContainerRegistry::Client)
.to receive(:delete_repository_tag_by_name)
.with(repository.path, name) { true }
expect_any_instance_of(ContainerRegistry::Client)
.not_to receive(:delete_repository_tag_by_digest)
end
end
Loading
Loading
@@ -23,43 +23,51 @@ describe Projects::LsifDataService do
end
 
context 'for main.go' do
let(:path_prefix) { "/#{project.full_path}/-/blob/#{commit_id}" }
it 'returns lsif ranges for the file' do
expect(service.execute).to eq([
{
end_char: 9,
end_line: 6,
start_char: 5,
start_line: 6
start_line: 6,
definition_url: "#{path_prefix}/main.go#L7"
},
{
end_char: 36,
end_line: 3,
start_char: 1,
start_line: 3
start_line: 3,
definition_url: "#{path_prefix}/main.go#L4"
},
{
end_char: 12,
end_line: 7,
start_char: 1,
start_line: 7
start_line: 7,
definition_url: "#{path_prefix}/main.go#L4"
},
{
end_char: 20,
end_line: 7,
start_char: 13,
start_line: 7
start_line: 7,
definition_url: "#{path_prefix}/morestrings/reverse.go#L11"
},
{
end_char: 12,
end_line: 8,
start_char: 1,
start_line: 8
start_line: 8,
definition_url: "#{path_prefix}/main.go#L4"
},
{
end_char: 18,
end_line: 8,
start_char: 13,
start_line: 8
start_line: 8,
definition_url: "#{path_prefix}/morestrings/reverse.go#L5"
}
])
end
Loading
Loading
@@ -73,7 +81,8 @@ describe Projects::LsifDataService do
end_char: 2,
end_line: 11,
start_char: 1,
start_line: 11
start_line: 11,
definition_url: "/#{project.full_path}/-/blob/#{commit_id}/morestrings/reverse.go#L12"
})
end
end
Loading
Loading
@@ -87,7 +96,7 @@ describe Projects::LsifDataService do
end
end
 
describe '#doc_id_from' do
describe '#doc_id' do
context 'when the passed path matches multiple files' do
let(:path) { 'check/main.go' }
let(:docs) do
Loading
Loading
@@ -100,7 +109,9 @@ describe Projects::LsifDataService do
end
 
it 'fetches the document with the shortest absolute path' do
expect(service.__send__(:doc_id_from, docs)).to eq(3)
service.instance_variable_set(:@docs, docs)
expect(service.__send__(:doc_id)).to eq(3)
end
end
end
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment