2022-04-04 11:22:00 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'spec_helper'
|
|
|
|
|
2022-07-16 23:28:13 +05:30
|
|
|
RSpec.describe API::Internal::ContainerRegistry::Migration, :aggregate_failures do
|
2022-04-04 11:22:00 +05:30
|
|
|
let_it_be_with_reload(:repository) { create(:container_repository) }
|
|
|
|
|
|
|
|
let(:secret_token) { 'secret_token' }
|
|
|
|
let(:sent_token) { secret_token }
|
|
|
|
let(:repository_path) { repository.path }
|
|
|
|
let(:status) { 'pre_import_complete' }
|
|
|
|
let(:params) { { path: repository.path, status: status } }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(Gitlab.config.registry).to receive(:notification_secret) { secret_token }
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'PUT /internal/registry/repositories/:path/migration/status' do
|
|
|
|
subject do
|
|
|
|
put api("/internal/registry/repositories/#{repository_path}/migration/status"),
|
|
|
|
params: params,
|
|
|
|
headers: { 'Authorization' => sent_token }
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples 'returning an error' do |with_message: nil, returning_status: :bad_request|
|
|
|
|
it "returns bad request response" do
|
|
|
|
expect { subject }
|
|
|
|
.not_to change { repository.reload.migration_state }
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(returning_status)
|
|
|
|
expect(response.body).to include(with_message) if with_message
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with a valid sent token' do
|
|
|
|
shared_examples 'updating the repository migration status' do |from:, to:|
|
|
|
|
it "updates the migration status from #{from} to #{to}" do
|
|
|
|
expect { subject }
|
|
|
|
.to change { repository.reload.migration_state }.from(from).to(to)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with status pre_import_complete' do
|
|
|
|
let(:status) { 'pre_import_complete' }
|
|
|
|
|
|
|
|
it_behaves_like 'returning an error', with_message: 'Wrong migration state (default)'
|
|
|
|
|
|
|
|
context 'with repository in pre_importing migration state' do
|
|
|
|
let(:repository) { create(:container_repository, :pre_importing) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow_next_found_instance_of(ContainerRepository) do |found_repository|
|
|
|
|
allow(found_repository).to receive(:migration_import).and_return(:ok)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'updating the repository migration status', from: 'pre_importing', to: 'importing'
|
|
|
|
|
|
|
|
context 'with a failing transition' do
|
|
|
|
before do
|
|
|
|
allow_next_found_instance_of(ContainerRepository) do |found_repository|
|
|
|
|
allow(found_repository).to receive(:finish_pre_import_and_start_import).and_return(false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'returning an error', with_message: "Couldn't transition from pre_importing to importing"
|
|
|
|
end
|
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
context 'with repository in importing migration state' do
|
|
|
|
let(:repository) { create(:container_repository, :importing) }
|
|
|
|
|
|
|
|
it 'returns ok and does not update the migration state' do
|
|
|
|
expect { subject }
|
|
|
|
.not_to change { repository.reload.migration_state }
|
2022-04-04 11:22:00 +05:30
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
|
|
|
end
|
|
|
|
end
|
2022-04-04 11:22:00 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with status import_complete' do
|
|
|
|
let(:status) { 'import_complete' }
|
|
|
|
|
|
|
|
it_behaves_like 'returning an error', with_message: 'Wrong migration state (default)'
|
|
|
|
|
|
|
|
context 'with repository in importing migration state' do
|
|
|
|
let(:repository) { create(:container_repository, :importing) }
|
|
|
|
let(:transition_result) { true }
|
|
|
|
|
|
|
|
it_behaves_like 'updating the repository migration status', from: 'importing', to: 'import_done'
|
|
|
|
|
|
|
|
context 'with a failing transition' do
|
|
|
|
before do
|
|
|
|
allow_next_found_instance_of(ContainerRepository) do |found_repository|
|
|
|
|
allow(found_repository).to receive(:finish_import).and_return(false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'returning an error', with_message: "Couldn't transition from importing to import_done"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with repository in pre_importing migration state' do
|
|
|
|
let(:repository) { create(:container_repository, :pre_importing) }
|
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
it_behaves_like 'updating the repository migration status', from: 'pre_importing', to: 'import_done'
|
2022-04-04 11:22:00 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
%w[pre_import_failed import_failed].each do |status|
|
|
|
|
context 'with status pre_import_failed' do
|
|
|
|
let(:status) { 'pre_import_failed' }
|
|
|
|
|
|
|
|
it_behaves_like 'returning an error', with_message: 'Wrong migration state (default)'
|
|
|
|
|
|
|
|
context 'with repository in importing migration state' do
|
|
|
|
let(:repository) { create(:container_repository, :importing) }
|
|
|
|
|
|
|
|
it_behaves_like 'updating the repository migration status', from: 'importing', to: 'import_aborted'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with repository in pre_importing migration state' do
|
|
|
|
let(:repository) { create(:container_repository, :pre_importing) }
|
|
|
|
|
|
|
|
it_behaves_like 'updating the repository migration status', from: 'pre_importing', to: 'import_aborted'
|
|
|
|
end
|
2022-07-16 23:28:13 +05:30
|
|
|
|
|
|
|
context 'with repository in unabortable migration state' do
|
|
|
|
let(:repository) { create(:container_repository, :import_skipped) }
|
|
|
|
|
|
|
|
it_behaves_like 'returning an error', with_message: 'Wrong migration state (import_skipped)'
|
|
|
|
end
|
2022-04-04 11:22:00 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with a non existing path' do
|
|
|
|
let(:repository_path) { 'this/does/not/exist' }
|
|
|
|
|
|
|
|
it_behaves_like 'returning an error', returning_status: :not_found
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with invalid status' do
|
|
|
|
let(:params) { super().merge(status: nil).compact }
|
|
|
|
|
|
|
|
it_behaves_like 'returning an error', returning_status: :bad_request
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with invalid path' do
|
|
|
|
let(:repository_path) { nil }
|
|
|
|
|
|
|
|
it_behaves_like 'returning an error', returning_status: :not_found
|
|
|
|
end
|
2022-07-16 23:28:13 +05:30
|
|
|
|
|
|
|
context 'query read location' do
|
|
|
|
it 'reads from the primary' do
|
|
|
|
expect(ContainerRepository).to receive(:find_by_path!).and_wrap_original do |m, *args|
|
|
|
|
expect(::Gitlab::Database::LoadBalancing::Session.current.use_primary?).to eq(true)
|
|
|
|
m.call(*args)
|
|
|
|
end
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
end
|
2022-04-04 11:22:00 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
context 'with an invalid sent token' do
|
|
|
|
let(:sent_token) { 'not_valid' }
|
|
|
|
|
|
|
|
it_behaves_like 'returning an error', returning_status: :unauthorized
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|