diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-06-25 15:07:44 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-06-25 15:07:44 +0300 |
commit | 5005c6e61f4d04cb6ad155b3910461cc77927dc3 (patch) | |
tree | 5e37c632ca5886d9071521303720066719351c7e /spec | |
parent | 6121eccf2bb21ac30a5c6c5b386e1bd3ddb17c91 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r-- | spec/controllers/import/bulk_imports_controller_spec.rb | 2 | ||||
-rw-r--r-- | spec/factories/packages/helm/file_metadatum.rb | 2 | ||||
-rw-r--r-- | spec/factories/packages/package_file.rb | 1 | ||||
-rw-r--r-- | spec/features/groups/import_export/connect_instance_spec.rb | 9 | ||||
-rw-r--r-- | spec/lib/api/entities/package_spec.rb | 35 | ||||
-rw-r--r-- | spec/lib/bulk_imports/clients/graphql_spec.rb | 41 | ||||
-rw-r--r-- | spec/lib/bulk_imports/clients/http_spec.rb | 24 | ||||
-rw-r--r-- | spec/requests/api/helm_packages_spec.rb | 13 | ||||
-rw-r--r-- | spec/requests/api/project_packages_spec.rb | 17 | ||||
-rw-r--r-- | spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb | 117 | ||||
-rw-r--r-- | spec/workers/bulk_imports/export_request_worker_spec.rb | 5 |
11 files changed, 253 insertions, 13 deletions
diff --git a/spec/controllers/import/bulk_imports_controller_spec.rb b/spec/controllers/import/bulk_imports_controller_spec.rb index 8f74d210667..4385342e1c6 100644 --- a/spec/controllers/import/bulk_imports_controller_spec.rb +++ b/spec/controllers/import/bulk_imports_controller_spec.rb @@ -149,7 +149,7 @@ RSpec.describe Import::BulkImportsController do context 'when connection error occurs' do before do allow(controller).to receive(:client).and_return(client) - allow(client).to receive(:get).and_raise(BulkImports::Clients::HTTP::ConnectionError) + allow(client).to receive(:get).and_raise(BulkImports::Error) end it 'returns 422' do diff --git a/spec/factories/packages/helm/file_metadatum.rb b/spec/factories/packages/helm/file_metadatum.rb index e809f592546..cbc7e114ef6 100644 --- a/spec/factories/packages/helm/file_metadatum.rb +++ b/spec/factories/packages/helm/file_metadatum.rb @@ -3,7 +3,7 @@ FactoryBot.define do factory :helm_file_metadatum, class: 'Packages::Helm::FileMetadatum' do package_file { association(:helm_package_file, without_loaded_metadatum: true) } - channel { 'stable' } + sequence(:channel) { |n| "#{FFaker::Lorem.word}-#{n}" } metadata { { 'name': package_file.package.name, 'version': package_file.package.version, 'apiVersion': 'v2' } } end end diff --git a/spec/factories/packages/package_file.rb b/spec/factories/packages/package_file.rb index 9b60f769505..ac121da432c 100644 --- a/spec/factories/packages/package_file.rb +++ b/spec/factories/packages/package_file.rb @@ -205,6 +205,7 @@ FactoryBot.define do package { association(:helm_package, without_package_files: true) } file_name { "#{package.name}-#{package.version}.tgz" } file_fixture { "spec/fixtures/packages/helm/rook-ceph-v1.5.8.tgz" } + file_sha256 { 'fd2b2fa0329e80a2a602c2bb3b40608bcd6ee5cf96cf46fd0d2800a4c129c9db' } transient do without_loaded_metadatum { false } diff --git a/spec/features/groups/import_export/connect_instance_spec.rb b/spec/features/groups/import_export/connect_instance_spec.rb index 563c8f429f8..4ed2137f7ae 100644 --- a/spec/features/groups/import_export/connect_instance_spec.rb +++ b/spec/features/groups/import_export/connect_instance_spec.rb @@ -24,6 +24,7 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do pat = 'demo-pat' stub_path = 'stub-group' total = 37 + stub_request(:get, "%{url}/api/v4/groups?page=1&per_page=20&top_level_only=true&min_access_level=50&search=" % { url: source_url }).to_return( body: [{ id: 2595438, @@ -32,7 +33,7 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do path: stub_path, full_name: 'Stub', full_path: stub_path - }].to_json, + }].to_json, headers: { 'Content-Type' => 'application/json', 'X-Next-Page' => 2, @@ -43,6 +44,10 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do } ) + allow_next_instance_of(BulkImports::Clients::HTTP) do |client| + allow(client).to receive(:validate_instance_version!).and_return(true) + end + expect(page).to have_content 'Import groups from another instance of GitLab' expect(page).to have_content 'Not all related objects are migrated' @@ -53,6 +58,8 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do expect(page).to have_content 'Showing 1-1 of %{total} groups from %{url}' % { url: source_url, total: total } expect(page).to have_content stub_path + + wait_for_all_requests end end diff --git a/spec/lib/api/entities/package_spec.rb b/spec/lib/api/entities/package_spec.rb new file mode 100644 index 00000000000..d63ea7833ac --- /dev/null +++ b/spec/lib/api/entities/package_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe API::Entities::Package do + let(:package) { create(:generic_package) } + + subject { described_class.new(package).as_json(namespace: package.project.namespace) } + + it 'exposes correct attributes' do + expect(subject).to include( + :id, + :name, + :version, + :package_type, + :status, + :_links, + :created_at, + :tags, + :versions + ) + end + + it 'exposes correct web_path in _links' do + expect(subject[:_links][:web_path]).to match('/packages/') + end + + context 'with a terraform_module' do + let(:package) { create(:terraform_module_package) } + + it 'exposes correct web_path in _links' do + expect(subject[:_links][:web_path]).to match('/infrastructure_registry/') + end + end +end diff --git a/spec/lib/bulk_imports/clients/graphql_spec.rb b/spec/lib/bulk_imports/clients/graphql_spec.rb new file mode 100644 index 00000000000..2f212458c4a --- /dev/null +++ b/spec/lib/bulk_imports/clients/graphql_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BulkImports::Clients::Graphql do + let_it_be(:config) { create(:bulk_import_configuration) } + + subject { described_class.new(url: config.url, token: config.access_token) } + + describe '#execute' do + let(:query) { '{ metadata { version } }' } + let(:graphql_client_double) { double } + let(:response_double) { double } + + before do + stub_const('BulkImports::MINIMUM_COMPATIBLE_MAJOR_VERSION', version) + allow(graphql_client_double).to receive(:execute) + allow(subject).to receive(:client).and_return(graphql_client_double) + allow(graphql_client_double).to receive(:execute).with(query).and_return(response_double) + allow(response_double).to receive_message_chain(:data, :metadata, :version).and_return(version) + end + + context 'when source instance is compatible' do + let(:version) { '14.0.0' } + + it 'marks source instance as compatible' do + subject.execute('test') + + expect(subject.instance_variable_get(:@compatible_instance_version)).to eq(true) + end + end + + context 'when source instance is incompatible' do + let(:version) { '13.0.0' } + + it 'raises an error' do + expect { subject.execute('test') }.to raise_error(::BulkImports::Error, "Unsupported GitLab Version. Minimum Supported Gitlab Version #{BulkImport::MINIMUM_GITLAB_MAJOR_VERSION}.") + end + end + end +end diff --git a/spec/lib/bulk_imports/clients/http_spec.rb b/spec/lib/bulk_imports/clients/http_spec.rb index ac42f12a3d4..d3a289da467 100644 --- a/spec/lib/bulk_imports/clients/http_spec.rb +++ b/spec/lib/bulk_imports/clients/http_spec.rb @@ -8,7 +8,15 @@ RSpec.describe BulkImports::Clients::HTTP do let(:uri) { 'http://gitlab.example' } let(:token) { 'token' } let(:resource) { 'resource' } + let(:version) { "#{BulkImport::MINIMUM_GITLAB_MAJOR_VERSION}.0.0" } let(:response_double) { double(code: 200, success?: true, parsed_response: {}) } + let(:version_response) { double(code: 200, success?: true, parsed_response: { 'version' => version }) } + + before do + allow(Gitlab::HTTP).to receive(:get) + .with('http://gitlab.example:80/api/v4/version', anything) + .and_return(version_response) + end subject { described_class.new(uri: uri, token: token) } @@ -21,20 +29,20 @@ RSpec.describe BulkImports::Clients::HTTP do context 'error handling' do context 'when error occurred' do - it 'raises ConnectionError' do + it 'raises BulkImports::Error' do allow(Gitlab::HTTP).to receive(method).and_raise(Errno::ECONNREFUSED) - expect { subject.public_send(method, resource) }.to raise_exception(described_class::ConnectionError) + expect { subject.public_send(method, resource) }.to raise_exception(BulkImports::Error) end end context 'when response is not success' do - it 'raises ConnectionError' do + it 'raises BulkImports::Error' do response_double = double(code: 503, success?: false) allow(Gitlab::HTTP).to receive(method).and_return(response_double) - expect { subject.public_send(method, resource) }.to raise_exception(described_class::ConnectionError) + expect { subject.public_send(method, resource) }.to raise_exception(BulkImports::Error) end end end @@ -167,4 +175,12 @@ RSpec.describe BulkImports::Clients::HTTP do subject.stream(resource) end end + + context 'when source instance is incompatible' do + let(:version) { '13.0.0' } + + it 'raises an error' do + expect { subject.get(resource) }.to raise_error(::BulkImports::Error, "Unsupported GitLab Version. Minimum Supported Gitlab Version #{BulkImport::MINIMUM_GITLAB_MAJOR_VERSION}.") + end + end end diff --git a/spec/requests/api/helm_packages_spec.rb b/spec/requests/api/helm_packages_spec.rb index 5871c0a5d5b..08edacb329f 100644 --- a/spec/requests/api/helm_packages_spec.rb +++ b/spec/requests/api/helm_packages_spec.rb @@ -9,13 +9,16 @@ RSpec.describe API::HelmPackages do let_it_be_with_reload(:project) { create(:project, :public) } let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) } let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) } + let_it_be(:package) { create(:helm_package, project: project) } - describe 'GET /api/v4/projects/:id/packages/helm/:channel/charts/:file_name.tgz' do - let_it_be(:package) { create(:helm_package, project: project) } - - let(:channel) { package.package_files.first.helm_channel } + describe 'GET /api/v4/projects/:id/packages/helm/:channel/index.yaml' do + it_behaves_like 'handling helm chart index requests' do + let(:url) { "/projects/#{project.id}/packages/helm/#{package.package_files.first.helm_channel}/index.yaml" } + end + end - let(:url) { "/projects/#{project.id}/packages/helm/#{channel}/charts/#{package.name}-#{package.version}.tgz" } + describe 'GET /api/v4/projects/:id/packages/helm/:channel/charts/:file_name.tgz' do + let(:url) { "/projects/#{project.id}/packages/helm/#{package.package_files.first.helm_channel}/charts/#{package.name}-#{package.version}.tgz" } subject { get api(url) } diff --git a/spec/requests/api/project_packages_spec.rb b/spec/requests/api/project_packages_spec.rb index 5886f293f41..9b7538547f6 100644 --- a/spec/requests/api/project_packages_spec.rb +++ b/spec/requests/api/project_packages_spec.rb @@ -3,8 +3,9 @@ require 'spec_helper' RSpec.describe API::ProjectPackages do - let(:user) { create(:user) } let_it_be(:project) { create(:project, :public) } + + let(:user) { create(:user) } let!(:package1) { create(:npm_package, project: project, version: '3.1.0', name: "@#{project.root_namespace.path}/foo1") } let(:package_url) { "/projects/#{project.id}/packages/#{package1.id}" } let!(:package2) { create(:nuget_package, project: project, version: '2.0.4') } @@ -71,6 +72,20 @@ RSpec.describe API::ProjectPackages do expect(json_response).to include(a_hash_including('_links' => a_hash_including('web_path' => include('infrastructure_registry')))) end end + + context 'in nested group' do + let_it_be(:nested_project) { create(:project, :public, :in_subgroup) } + let_it_be(:nested_terraform_module_package) { create(:terraform_module_package, project: nested_project) } + + let(:params) { { package_type: :terraform_module } } + let(:url) { "/projects/#{nested_project.id}/packages" } + + it 'returns the nested terraform module package with the correct web_path' do + subject + + expect(json_response).to include(a_hash_including('_links' => a_hash_including('web_path' => include(nested_project.namespace.full_path)))) + end + end end context 'project is private' do diff --git a/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb index 585c4fb8a4e..8a173ff99da 100644 --- a/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb @@ -18,6 +18,37 @@ RSpec.shared_examples 'rejects helm packages access' do |user_type, status, add_ end end +RSpec.shared_examples 'process helm service index request' do |user_type, status, add_member = true| + context "for user type #{user_type}" do + before do + project.send("add_#{user_type}", user) if add_member && user_type != :anonymous + end + + it_behaves_like 'returning response status', status + + it 'returns a valid YAML response', :aggregate_failures do + subject + + expect(response.media_type).to eq('text/yaml') + expect(response.body).to start_with("---\napiVersion: v1\nentries:\n") + + yaml_response = YAML.safe_load(response.body) + + expect(yaml_response.keys).to contain_exactly('apiVersion', 'entries', 'generated', 'serverInfo') + expect(yaml_response['entries']).to be_a(Hash) + expect(yaml_response['entries'].keys).to contain_exactly(package.name) + expect(yaml_response['serverInfo']).to eq({ 'contextPath' => "http://localhost/api/v4/projects/#{project.id}/packages/helm" }) + + package_entry = yaml_response['entries'][package.name] + + expect(package_entry.length).to eq(1) + expect(package_entry.first.keys).to contain_exactly('name', 'version', 'apiVersion', 'created', 'digest', 'urls') + expect(package_entry.first['digest']).to eq('fd2b2fa0329e80a2a602c2bb3b40608bcd6ee5cf96cf46fd0d2800a4c129c9db') + expect(package_entry.first['urls']).to eq(["charts/#{package.name}-#{package.version}.tgz"]) + end + end +end + RSpec.shared_examples 'process helm download content request' do |user_type, status, add_member = true| context "for user type #{user_type}" do before do @@ -51,3 +82,89 @@ RSpec.shared_examples 'rejects helm access with unknown project id' do end end end + +RSpec.shared_examples 'handling helm chart index requests' do |anonymous_requests_example_name: 'process helm service index request', anonymous_requests_status: :success| + context 'with valid project' do + using RSpec::Parameterized::TableSyntax + + context 'personal token' do + where(:visibility, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do + :public | :developer | true | true | 'process helm service index request' | :success + :public | :guest | true | true | 'process helm service index request' | :success + :public | :developer | true | false | 'rejects helm packages access' | :unauthorized + :public | :guest | true | false | 'rejects helm packages access' | :unauthorized + :public | :developer | false | true | 'process helm service index request' | :success + :public | :guest | false | true | 'process helm service index request' | :success + :public | :developer | false | false | 'rejects helm packages access' | :unauthorized + :public | :guest | false | false | 'rejects helm packages access' | :unauthorized + :public | :anonymous | false | true | anonymous_requests_example_name | anonymous_requests_status + :private | :developer | true | true | 'process helm service index request' | :success + :private | :guest | true | true | 'rejects helm packages access' | :forbidden + :private | :developer | true | false | 'rejects helm packages access' | :unauthorized + :private | :guest | true | false | 'rejects helm packages access' | :unauthorized + :private | :developer | false | true | 'rejects helm packages access' | :not_found + :private | :guest | false | true | 'rejects helm packages access' | :not_found + :private | :developer | false | false | 'rejects helm packages access' | :unauthorized + :private | :guest | false | false | 'rejects helm packages access' | :unauthorized + :private | :anonymous | false | true | 'rejects helm packages access' | :unauthorized + end + + with_them do + let(:token) { user_token ? personal_access_token.token : 'wrong' } + let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) } + + subject { get api(url), headers: headers } + + before do + project.update!(visibility: visibility.to_s) + end + + it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] + end + end + + context 'with job token' do + where(:visibility, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do + :public | :developer | true | true | 'process helm service index request' | :success + :public | :guest | true | true | 'process helm service index request' | :success + :public | :developer | true | false | 'rejects helm packages access' | :unauthorized + :public | :guest | true | false | 'rejects helm packages access' | :unauthorized + :public | :developer | false | true | 'process helm service index request' | :success + :public | :guest | false | true | 'process helm service index request' | :success + :public | :developer | false | false | 'rejects helm packages access' | :unauthorized + :public | :guest | false | false | 'rejects helm packages access' | :unauthorized + :public | :anonymous | false | true | anonymous_requests_example_name | anonymous_requests_status + :private | :developer | true | true | 'process helm service index request' | :success + :private | :guest | true | true | 'rejects helm packages access' | :forbidden + :private | :developer | true | false | 'rejects helm packages access' | :unauthorized + :private | :guest | true | false | 'rejects helm packages access' | :unauthorized + :private | :developer | false | true | 'rejects helm packages access' | :not_found + :private | :guest | false | true | 'rejects helm packages access' | :not_found + :private | :developer | false | false | 'rejects helm packages access' | :unauthorized + :private | :guest | false | false | 'rejects helm packages access' | :unauthorized + :private | :anonymous | false | true | 'rejects helm packages access' | :unauthorized + end + + with_them do + let_it_be(:ci_build) { create(:ci_build, project: project, user: user, status: :running) } + + let(:job) { user_token ? ci_build : double(token: 'wrong') } + let(:headers) { user_role == :anonymous ? {} : job_basic_auth_header(job) } + + subject { get api(url), headers: headers } + + before do + project.update!(visibility: visibility.to_s) + end + + it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] + end + end + end + + it_behaves_like 'deploy token for package GET requests' + + it_behaves_like 'rejects helm access with unknown project id' do + subject { get api(url) } + end +end diff --git a/spec/workers/bulk_imports/export_request_worker_spec.rb b/spec/workers/bulk_imports/export_request_worker_spec.rb index 8d528011752..9eabf7b8f0f 100644 --- a/spec/workers/bulk_imports/export_request_worker_spec.rb +++ b/spec/workers/bulk_imports/export_request_worker_spec.rb @@ -6,12 +6,17 @@ RSpec.describe BulkImports::ExportRequestWorker do let_it_be(:bulk_import) { create(:bulk_import) } let_it_be(:config) { create(:bulk_import_configuration, bulk_import: bulk_import) } let_it_be(:entity) { create(:bulk_import_entity, source_full_path: 'foo/bar', bulk_import: bulk_import) } + let_it_be(:version_url) { 'https://gitlab.example:443/api/v4/version' } let(:response_double) { double(code: 200, success?: true, parsed_response: {}) } let(:job_args) { [entity.id] } describe '#perform' do before do + allow(Gitlab::HTTP) + .to receive(:get) + .with(version_url, anything) + .and_return(double(code: 200, success?: true, parsed_response: { 'version' => Gitlab::VERSION })) allow(Gitlab::HTTP).to receive(:post).and_return(response_double) end |