Commit 2f4fbca2 authored by Mark Lapierre's avatar Mark Lapierre

Merge branch 'grantyoung-52703-project-archive-compare-qa' into 'master'

[CE] Add e2e test comparing archives of identically named user projects

Closes #52703

See merge request gitlab-org/gitlab-ce!29937
parents 58f3a561 eecd85d4
...@@ -13,6 +13,8 @@ module QA ...@@ -13,6 +13,8 @@ module QA
ResourceURLMissingError = Class.new(RuntimeError) ResourceURLMissingError = Class.new(RuntimeError)
attr_reader :api_resource, :api_response attr_reader :api_resource, :api_response
attr_writer :api_client
attr_accessor :user
def api_support? def api_support?
respond_to?(:api_get_path) && respond_to?(:api_get_path) &&
...@@ -29,9 +31,12 @@ module QA ...@@ -29,9 +31,12 @@ module QA
end end
def eager_load_api_client! def eager_load_api_client!
return unless api_client.nil?
api_client.tap do |client| api_client.tap do |client|
# Eager-load the API client so that the personal token creation isn't # Eager-load the API client so that the personal token creation isn't
# taken in account in the actual resource creation timing. # taken in account in the actual resource creation timing.
client.user = user
client.personal_access_token client.personal_access_token
end end
end end
...@@ -76,7 +81,7 @@ module QA ...@@ -76,7 +81,7 @@ module QA
def api_client def api_client
@api_client ||= begin @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
end end
......
...@@ -21,7 +21,7 @@ module QA ...@@ -21,7 +21,7 @@ module QA
def fabricate! def fabricate!
populate(:push) populate(:push)
fork.visit! fork.project.visit!
Page::Project::Show.perform(&:new_merge_request) Page::Project::Show.perform(&:new_merge_request)
Page::MergeRequest::New.perform(&:create_merge_request) Page::MergeRequest::New.perform(&:create_merge_request)
......
...@@ -11,7 +11,9 @@ module QA ...@@ -11,7 +11,9 @@ module QA
attribute :id attribute :id
attribute :name attribute :name
attribute :add_name_uuid
attribute :description attribute :description
attribute :standalone
attribute :group do attribute :group do
Group.fabricate! Group.fabricate!
...@@ -38,18 +40,21 @@ module QA ...@@ -38,18 +40,21 @@ module QA
end end
def initialize def initialize
@add_name_uuid = true
@standalone = false
@description = 'My awesome project' @description = 'My awesome project'
@initialize_with_readme = false @initialize_with_readme = false
end end
def name=(raw_name) def name=(raw_name)
@name = "#{raw_name}-#{SecureRandom.hex(8)}" @name = @add_name_uuid ? "#{raw_name}-#{SecureRandom.hex(8)}" : raw_name
end end
def fabricate! def fabricate!
group.visit! unless @standalone
group.visit!
Page::Group::Show.perform(&:go_to_new_project) Page::Group::Show.perform(&:go_to_new_project)
end
Page::Project::New.perform do |page| Page::Project::New.perform do |page|
page.choose_test_namespace page.choose_test_namespace
...@@ -71,19 +76,28 @@ module QA ...@@ -71,19 +76,28 @@ module QA
"/projects/#{CGI.escape(path_with_namespace)}" "/projects/#{CGI.escape(path_with_namespace)}"
end end
def api_get_archive_path(type = 'tar.gz')
"#{api_get_path}/repository/archive.#{type}"
end
def api_post_path def api_post_path
'/projects' '/projects'
end end
def api_post_body def api_post_body
{ post_body = {
namespace_id: group.id,
path: name,
name: name, name: name,
description: description, description: description,
visibility: 'public', visibility: 'public',
initialize_with_readme: @initialize_with_readme initialize_with_readme: @initialize_with_readme
} }
unless @standalone
post_body[:namespace_id] = group.id
post_body[:path] = name
end
post_body
end end
private private
......
...@@ -88,7 +88,7 @@ module QA ...@@ -88,7 +88,7 @@ module QA
}.merge(ldap_post_body) }.merge(ldap_post_body)
end end
def self.fabricate_or_use(username, password) def self.fabricate_or_use(username = nil, password = nil)
if Runtime::Env.signup_disabled? if Runtime::Env.signup_disabled?
self.new.tap do |user| self.new.tap do |user|
user.username = username user.username = username
......
...@@ -6,31 +6,34 @@ module QA ...@@ -6,31 +6,34 @@ module QA
module Runtime module Runtime
module API module API
class Client 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 @address = address
@personal_access_token = personal_access_token @personal_access_token = personal_access_token
@is_new_session = is_new_session @is_new_session = is_new_session
@user = user
end end
def personal_access_token def personal_access_token
@personal_access_token ||= begin @personal_access_token ||= begin
# you can set the environment variable GITLAB_QA_ACCESS_TOKEN # you can set the environment variable GITLAB_QA_ACCESS_TOKEN
# to use a specific access token rather than create one from the UI # 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
end end
private private
def create_personal_access_token def create_personal_access_token
Runtime::Browser.visit(@address, Page::Main::Login) if @is_new_session Page::Main::Menu.perform(&:sign_out) if @is_new_session && Page::Main::Menu.perform { |p| p.has_personal_area?(wait: 0) }
do_create_personal_access_token
end 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 Resource::PersonalAccessToken.fabricate!.access_token
end end
end end
......
# 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
...@@ -16,11 +16,12 @@ module QA ...@@ -16,11 +16,12 @@ module QA
e.response e.response
end end
def get(url) def get(url, raw_response: false)
RestClient::Request.execute( RestClient::Request.execute(
method: :get, method: :get,
url: url, url: url,
verify_ssl: false) verify_ssl: false,
raw_response: raw_response)
rescue RestClient::ExceptionWithResponse => e rescue RestClient::ExceptionWithResponse => e
e.response e.response
end end
......
...@@ -16,26 +16,56 @@ describe QA::Runtime::API::Client do ...@@ -16,26 +16,56 @@ describe QA::Runtime::API::Client do
end end
describe '#personal_access_token' do 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 before do
allow(QA::Runtime::Env).to receive(:personal_access_token).and_return('a_token') allow(QA::Runtime::Env).to receive(:personal_access_token).and_return('a_token')
end end
it 'returns specified token from env' do 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
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 before do
allow(QA::Runtime::Env).to receive(:personal_access_token).and_return(nil) allow(QA::Runtime::Env).to receive(:personal_access_token).and_return(nil)
end end
it 'returns a created token' do 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).to receive(:create_personal_access_token).and_return('created_token')
expect(subject.personal_access_token).to eq 'created_token' expect(subject.personal_access_token).to eq 'created_token'
end end
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
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment