Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/import_export/after_export_strategies/web_upload_strategy_spec.rb')
-rw-r--r--spec/lib/gitlab/import_export/after_export_strategies/web_upload_strategy_spec.rb168
1 files changed, 159 insertions, 9 deletions
diff --git a/spec/lib/gitlab/import_export/after_export_strategies/web_upload_strategy_spec.rb b/spec/lib/gitlab/import_export/after_export_strategies/web_upload_strategy_spec.rb
index 451fd6c6f46..42cf9c54798 100644
--- a/spec/lib/gitlab/import_export/after_export_strategies/web_upload_strategy_spec.rb
+++ b/spec/lib/gitlab/import_export/after_export_strategies/web_upload_strategy_spec.rb
@@ -9,12 +9,21 @@ RSpec.describe Gitlab::ImportExport::AfterExportStrategies::WebUploadStrategy do
allow_next_instance_of(ProjectExportWorker) do |job|
allow(job).to receive(:jid).and_return(SecureRandom.hex(8))
end
+
+ stub_feature_flags(import_export_web_upload_stream: false)
+ stub_uploads_object_storage(FileUploader, enabled: false)
end
let(:example_url) { 'http://www.example.com' }
let(:strategy) { subject.new(url: example_url, http_method: 'post') }
- let!(:project) { create(:project, :with_export) }
- let!(:user) { build(:user) }
+ let(:user) { build(:user) }
+ let(:project) { import_export_upload.project }
+ let(:import_export_upload) do
+ create(
+ :import_export_upload,
+ export_file: fixture_file_upload('spec/fixtures/gitlab/import_export/lightweight_project_export.tar.gz')
+ )
+ end
subject { described_class }
@@ -36,20 +45,42 @@ RSpec.describe Gitlab::ImportExport::AfterExportStrategies::WebUploadStrategy do
describe '#execute' do
context 'when upload succeeds' do
before do
- allow(strategy).to receive(:send_file)
- allow(strategy).to receive(:handle_response_error)
+ stub_full_request(example_url, method: :post).to_return(status: 200)
end
- it 'does not remove the exported project file after the upload' do
+ it 'does not remove the exported project file after the upload', :aggregate_failures do
expect(project).not_to receive(:remove_exports)
- strategy.execute(user, project)
+ expect { strategy.execute(user, project) }.not_to change(project, :export_status)
+
+ expect(project.export_status).to eq(:finished)
end
- it 'has finished export status' do
- strategy.execute(user, project)
+ it 'logs when upload starts and finishes' do
+ export_size = import_export_upload.export_file.size
+
+ expect_next_instance_of(Gitlab::Export::Logger) do |logger|
+ expect(logger).to receive(:info).ordered.with(
+ {
+ message: "Started uploading project",
+ project_id: project.id,
+ project_name: project.name,
+ export_size: export_size
+ }
+ )
+
+ expect(logger).to receive(:info).ordered.with(
+ {
+ message: "Finished uploading project",
+ project_id: project.id,
+ project_name: project.name,
+ export_size: export_size,
+ upload_duration: anything
+ }
+ )
+ end
- expect(project.export_status).to eq(:finished)
+ strategy.execute(user, project)
end
end
@@ -64,5 +95,124 @@ RSpec.describe Gitlab::ImportExport::AfterExportStrategies::WebUploadStrategy do
expect(errors.first).to eq "Error uploading the project. Code 404: Page not found"
end
end
+
+ context 'when object store is disabled' do
+ it 'reads file from disk and uploads to external url' do
+ stub_request(:post, example_url).to_return(status: 200)
+ expect(Gitlab::ImportExport::RemoteStreamUpload).not_to receive(:new)
+ expect(Gitlab::HttpIO).not_to receive(:new)
+
+ strategy.execute(user, project)
+
+ expect(a_request(:post, example_url)).to have_been_made
+ end
+ end
+
+ context 'when object store is enabled' do
+ before do
+ object_store_url = 'http://object-storage/project.tar.gz'
+ stub_uploads_object_storage(FileUploader)
+ stub_request(:get, object_store_url)
+ stub_request(:post, example_url)
+ allow(import_export_upload.export_file).to receive(:url).and_return(object_store_url)
+ allow(import_export_upload.export_file).to receive(:file_storage?).and_return(false)
+ end
+
+ it 'reads file using Gitlab::HttpIO and uploads to external url' do
+ expect_next_instance_of(Gitlab::HttpIO) do |http_io|
+ expect(http_io).to receive(:read).and_call_original
+ end
+ expect(Gitlab::ImportExport::RemoteStreamUpload).not_to receive(:new)
+
+ strategy.execute(user, project)
+
+ expect(a_request(:post, example_url)).to have_been_made
+ end
+ end
+
+ context 'when `import_export_web_upload_stream` feature is enabled' do
+ before do
+ stub_feature_flags(import_export_web_upload_stream: true)
+ end
+
+ context 'when remote object store is disabled' do
+ it 'reads file from disk and uploads to external url' do
+ stub_request(:post, example_url).to_return(status: 200)
+ expect(Gitlab::ImportExport::RemoteStreamUpload).not_to receive(:new)
+ expect(Gitlab::HttpIO).not_to receive(:new)
+
+ strategy.execute(user, project)
+
+ expect(a_request(:post, example_url)).to have_been_made
+ end
+ end
+
+ context 'when object store is enabled' do
+ let(:object_store_url) { 'http://object-storage/project.tar.gz' }
+
+ before do
+ stub_uploads_object_storage(FileUploader)
+
+ allow(import_export_upload.export_file).to receive(:url).and_return(object_store_url)
+ allow(import_export_upload.export_file).to receive(:file_storage?).and_return(false)
+ end
+
+ it 'uploads file as a remote stream' do
+ arguments = {
+ download_url: object_store_url,
+ upload_url: example_url,
+ options: {
+ upload_method: :post,
+ upload_content_type: 'application/gzip'
+ }
+ }
+
+ expect_next_instance_of(Gitlab::ImportExport::RemoteStreamUpload, arguments) do |remote_stream_upload|
+ expect(remote_stream_upload).to receive(:execute)
+ end
+ expect(Gitlab::HttpIO).not_to receive(:new)
+
+ strategy.execute(user, project)
+ end
+
+ context 'when upload as remote stream raises an exception' do
+ before do
+ allow_next_instance_of(Gitlab::ImportExport::RemoteStreamUpload) do |remote_stream_upload|
+ allow(remote_stream_upload).to receive(:execute).and_raise(
+ Gitlab::ImportExport::RemoteStreamUpload::StreamError.new('Exception error message', 'Response body')
+ )
+ end
+ end
+
+ it 'logs the exception and stores the error message' do
+ expect_next_instance_of(Gitlab::Export::Logger) do |logger|
+ expect(logger).to receive(:error).ordered.with(
+ {
+ project_id: project.id,
+ project_name: project.name,
+ message: 'Exception error message',
+ response_body: 'Response body'
+ }
+ )
+
+ expect(logger).to receive(:error).ordered.with(
+ {
+ project_id: project.id,
+ project_name: project.name,
+ message: 'After export strategy failed',
+ 'exception.class' => 'Gitlab::ImportExport::RemoteStreamUpload::StreamError',
+ 'exception.message' => 'Exception error message',
+ 'exception.backtrace' => anything
+ }
+ )
+ end
+
+ strategy.execute(user, project)
+
+ expect(project.import_export_shared.errors.first).to eq('Exception error message')
+ end
+ end
+ end
+ end
end
end