diff options
author | Grant Young <gyoung@gitlab.com> | 2019-07-01 09:01:44 +0300 |
---|---|---|
committer | Mark Lapierre <mlapierre@gitlab.com> | 2019-07-01 09:01:44 +0300 |
commit | eecd85d4618d747a407634e9fbf682b797ad2198 (patch) | |
tree | 4cb52c1ab6615ac0cbe5b6b72dfe249589e515d8 /qa | |
parent | 58f3a5615490aa30a5adda83ebb8ab66de891859 (diff) |
First pass at new automated QA API test for #52703
Checks that archives of two different user projects with the same name aren't the same via checksum. I.E. a user can't download the archive of another's project by mistake.
To enable the test some enhancements were made. Namely updating the client module to handle more than one API instance and the creation a custom rest call method that downloads to tmp.
Diffstat (limited to 'qa')
-rw-r--r-- | qa/qa/resource/api_fabricator.rb | 7 | ||||
-rw-r--r-- | qa/qa/resource/merge_request_from_fork.rb | 2 | ||||
-rw-r--r-- | qa/qa/resource/project.rb | 28 | ||||
-rw-r--r-- | qa/qa/resource/user.rb | 2 | ||||
-rw-r--r-- | qa/qa/runtime/api/client.rb | 19 | ||||
-rw-r--r-- | qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb | 75 | ||||
-rw-r--r-- | qa/qa/support/api.rb | 5 | ||||
-rw-r--r-- | qa/spec/runtime/api/client_spec.rb | 36 |
8 files changed, 151 insertions, 23 deletions
diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb index de04467ff5b..d1d75b6179e 100644 --- a/qa/qa/resource/api_fabricator.rb +++ b/qa/qa/resource/api_fabricator.rb @@ -13,6 +13,8 @@ module QA ResourceURLMissingError = Class.new(RuntimeError) attr_reader :api_resource, :api_response + attr_writer :api_client + attr_accessor :user def api_support? respond_to?(:api_get_path) && @@ -29,9 +31,12 @@ module QA end def eager_load_api_client! + return unless api_client.nil? + api_client.tap do |client| # Eager-load the API client so that the personal token creation isn't # taken in account in the actual resource creation timing. + client.user = user client.personal_access_token end end @@ -76,7 +81,7 @@ module QA def api_client @api_client ||= begin - Runtime::API::Client.new(:gitlab, is_new_session: !current_url.start_with?('http')) + Runtime::API::Client.new(:gitlab, is_new_session: !current_url.start_with?('http'), user: user) end end diff --git a/qa/qa/resource/merge_request_from_fork.rb b/qa/qa/resource/merge_request_from_fork.rb index 5d20a6e9c75..6c9a096289b 100644 --- a/qa/qa/resource/merge_request_from_fork.rb +++ b/qa/qa/resource/merge_request_from_fork.rb @@ -21,7 +21,7 @@ module QA def fabricate! populate(:push) - fork.visit! + fork.project.visit! Page::Project::Show.perform(&:new_merge_request) Page::MergeRequest::New.perform(&:create_merge_request) diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb index e8ea947581a..c0a6004fe27 100644 --- a/qa/qa/resource/project.rb +++ b/qa/qa/resource/project.rb @@ -11,7 +11,9 @@ module QA attribute :id attribute :name + attribute :add_name_uuid attribute :description + attribute :standalone attribute :group do Group.fabricate! @@ -38,18 +40,21 @@ module QA end def initialize + @add_name_uuid = true + @standalone = false @description = 'My awesome project' @initialize_with_readme = false end def name=(raw_name) - @name = "#{raw_name}-#{SecureRandom.hex(8)}" + @name = @add_name_uuid ? "#{raw_name}-#{SecureRandom.hex(8)}" : raw_name end def fabricate! - group.visit! - - Page::Group::Show.perform(&:go_to_new_project) + unless @standalone + group.visit! + Page::Group::Show.perform(&:go_to_new_project) + end Page::Project::New.perform do |page| page.choose_test_namespace @@ -71,19 +76,28 @@ module QA "/projects/#{CGI.escape(path_with_namespace)}" end + def api_get_archive_path(type = 'tar.gz') + "#{api_get_path}/repository/archive.#{type}" + end + def api_post_path '/projects' end def api_post_body - { - namespace_id: group.id, - path: name, + post_body = { name: name, description: description, visibility: 'public', initialize_with_readme: @initialize_with_readme } + + unless @standalone + post_body[:namespace_id] = group.id + post_body[:path] = name + end + + post_body end private diff --git a/qa/qa/resource/user.rb b/qa/qa/resource/user.rb index 6c5e91b6488..eec46f46d99 100644 --- a/qa/qa/resource/user.rb +++ b/qa/qa/resource/user.rb @@ -88,7 +88,7 @@ module QA }.merge(ldap_post_body) end - def self.fabricate_or_use(username, password) + def self.fabricate_or_use(username = nil, password = nil) if Runtime::Env.signup_disabled? self.new.tap do |user| user.username = username diff --git a/qa/qa/runtime/api/client.rb b/qa/qa/runtime/api/client.rb index 40a3bc85195..663be27a849 100644 --- a/qa/qa/runtime/api/client.rb +++ b/qa/qa/runtime/api/client.rb @@ -6,31 +6,34 @@ module QA module Runtime module API class Client - attr_reader :address + attr_reader :address, :user - def initialize(address = :gitlab, personal_access_token: nil, is_new_session: true) + def initialize(address = :gitlab, personal_access_token: nil, is_new_session: true, user: nil) @address = address @personal_access_token = personal_access_token @is_new_session = is_new_session + @user = user end def personal_access_token @personal_access_token ||= begin # you can set the environment variable GITLAB_QA_ACCESS_TOKEN # to use a specific access token rather than create one from the UI - Runtime::Env.personal_access_token ||= create_personal_access_token + # unless a specific user has been passed + @user.nil? ? Runtime::Env.personal_access_token ||= create_personal_access_token : create_personal_access_token end end private def create_personal_access_token - Runtime::Browser.visit(@address, Page::Main::Login) if @is_new_session - do_create_personal_access_token - end + Page::Main::Menu.perform(&:sign_out) if @is_new_session && Page::Main::Menu.perform { |p| p.has_personal_area?(wait: 0) } + + unless Page::Main::Menu.perform { |p| p.has_personal_area?(wait: 0) } + Runtime::Browser.visit(@address, Page::Main::Login) + Page::Main::Login.perform { |login| login.sign_in_using_credentials(@user) } + end - def do_create_personal_access_token - Page::Main::Login.perform(&:sign_in_using_credentials) Resource::PersonalAccessToken.fabricate!.access_token end end diff --git a/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb b/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb new file mode 100644 index 00000000000..3fe04e8b835 --- /dev/null +++ b/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require 'securerandom' +require 'digest' + +module QA + context 'Create' do + describe 'Compare archives of different user projects with the same name and check they\'re different' do + include Support::Api + + before(:all) do + @project_name = "project-archive-download-#{SecureRandom.hex(8)}" + @archive_types = %w(tar.gz tar.bz2 tar zip) + @users = { + user1: { username: Runtime::Env.gitlab_qa_username_1, password: Runtime::Env.gitlab_qa_password_1 }, + user2: { username: Runtime::Env.gitlab_qa_username_2, password: Runtime::Env.gitlab_qa_password_2 } + } + + @users.each do |_, user_info| + user_info[:user] = Resource::User.fabricate_or_use(user_info[:username], user_info[:password]) + user_info[:api_client] = Runtime::API::Client.new(:gitlab, user: user_info[:user]) + user_info[:api_client].personal_access_token + user_info[:project] = create_project(user_info[:user], user_info[:api_client], @project_name) + Page::Main::Menu.perform(&:sign_out) + end + end + + it 'download archives of each user project then check they are different' do + archive_checksums = {} + + @users.each do |user_key, user_info| + archive_checksums[user_key] = {} + + @archive_types.each do |type| + archive_path = download_project_archive_via_api(user_info[:api_client], user_info[:project], type).path + archive_checksums[user_key][type] = Digest::MD5.hexdigest(File.read(archive_path)) + end + end + + QA::Runtime::Logger.debug("Archive checksums are #{archive_checksums}") + + expect(archive_checksums[:user1]).not_to include(archive_checksums[:user2]) + end + + def create_project(user, api_client, project_name) + project = Resource::Project.fabricate! do |project| + project.standalone = true + project.add_name_uuid = false + project.name = project_name + project.path_with_namespace = "#{user.name}/#{project_name}" + project.user = user + project.api_client = api_client + end + + Resource::Repository::ProjectPush.fabricate! do |push| + push.project = project + push.file_name = 'README.md' + push.file_content = '# This is a test project' + push.commit_message = 'Add README.md' + push.user = user + end + + project + end + + def download_project_archive_via_api(api_client, project, type = 'tar.gz') + get_project_archive_zip = Runtime::API::Request.new(api_client, project.api_get_archive_path(type)) + project_archive_download = get(get_project_archive_zip.url, raw_response: true) + expect(project_archive_download.code).to eq(200) + + project_archive_download.file + end + end + end +end diff --git a/qa/qa/support/api.rb b/qa/qa/support/api.rb index a5c86425465..203064b2665 100644 --- a/qa/qa/support/api.rb +++ b/qa/qa/support/api.rb @@ -16,11 +16,12 @@ module QA e.response end - def get(url) + def get(url, raw_response: false) RestClient::Request.execute( method: :get, url: url, - verify_ssl: false) + verify_ssl: false, + raw_response: raw_response) rescue RestClient::ExceptionWithResponse => e e.response end diff --git a/qa/spec/runtime/api/client_spec.rb b/qa/spec/runtime/api/client_spec.rb index cf19b52700b..6f7020d6595 100644 --- a/qa/spec/runtime/api/client_spec.rb +++ b/qa/spec/runtime/api/client_spec.rb @@ -16,26 +16,56 @@ describe QA::Runtime::API::Client do end describe '#personal_access_token' do - context 'when QA::Runtime::Env.personal_access_token is present' do + context 'when user is nil and QA::Runtime::Env.personal_access_token is present' do before do allow(QA::Runtime::Env).to receive(:personal_access_token).and_return('a_token') end it 'returns specified token from env' do - expect(described_class.new.personal_access_token).to eq 'a_token' + expect(subject.personal_access_token).to eq 'a_token' end end - context 'when QA::Runtime::Env.personal_access_token is nil' do + context 'when user is present and QA::Runtime::Env.personal_access_token is nil' do before do allow(QA::Runtime::Env).to receive(:personal_access_token).and_return(nil) end it 'returns a created token' do + subject { described_class.new(user: { username: 'foo' }) } + expect(subject).to receive(:create_personal_access_token).and_return('created_token') expect(subject.personal_access_token).to eq 'created_token' end end + + context 'when user is nil and QA::Runtime::Env.personal_access_token is nil' do + before do + allow(QA::Runtime::Env).to receive(:personal_access_token).and_return(nil) + end + + it 'returns a created token' do + client = described_class.new + + expect(client).to receive(:create_personal_access_token).and_return('created_token') + + expect(client.personal_access_token).to eq 'created_token' + end + end + + context 'when user is present and QA::Runtime::Env.personal_access_token is present' do + before do + allow(QA::Runtime::Env).to receive(:personal_access_token).and_return('a_token') + end + + it 'returns a created token' do + client = described_class.new(user: { username: 'foo' }) + + expect(client).to receive(:create_personal_access_token).and_return('created_token') + + expect(client.personal_access_token).to eq 'created_token' + end + end end end |