Skip to content
Snippets Groups Projects
Unverified Commit b0135a9c authored by Andrejs Cunskis's avatar Andrejs Cunskis Committed by GitLab
Browse files

Merge branch 'andrey-remove-group-caching' into 'master'

Remove group name caching in e2e tests

Closes gitlab-org/quality/quality-engineering/team-tasks#3089

See merge request https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168615



Merged-by: default avatarAndrejs Cunskis <acunskis@gitlab.com>
Approved-by: default avatarJohn McDonnell <jmcdonnell@gitlab.com>
Approved-by: default avatarMark Lapierre <mlapierre@gitlab.com>
Reviewed-by: default avatarAndrejs Cunskis <acunskis@gitlab.com>
parents 40e68c11 0a7e1640
Branches andrey-remove-group-caching
No related tags found
No related merge requests found
Showing
with 167 additions and 220 deletions
Loading
Loading
@@ -16,7 +16,7 @@ class New < Page::Base
element 'select-namespace-dropdown'
end
 
def fork_project(namespace = Runtime::Namespace.path)
def fork_project(namespace)
choose_namespace(namespace)
click_element('fork-privacy-button', privacy_level: 'public')
click_element('fork-project-button')
Loading
Loading
Loading
Loading
@@ -13,10 +13,10 @@ class RepoByURL < Page::Base
element 'project-create-button'
end
 
def import!(gitlab_repo_path, name)
def import!(gitlab_repo_path, name, namespace)
fill_git_repository_url_link(gitlab_repo_path)
fill_project_name(name)
choose_test_namespace
choose_namespace(namespace)
click_create_button
 
wait_for_success
Loading
Loading
@@ -32,10 +32,6 @@ def fill_project_name(name)
fill_in 'project_name', with: name
end
 
def choose_test_namespace
choose_namespace(Runtime::Namespace.path)
end
def choose_namespace(namespace)
retry_on_exception do
click_element 'select-namespace-dropdown'
Loading
Loading
Loading
Loading
@@ -43,10 +43,6 @@ def click_create_from_template_link
click_element('panel-link', panel_name: 'create_from_template')
end
 
def choose_test_namespace
choose_namespace(Runtime::Namespace.path)
end
def choose_namespace(namespace)
# The current group is the default, we use end_with? in case we want to select the top level group
return if find_element('select-namespace-dropdown').text.end_with?(namespace)
Loading
Loading
Loading
Loading
@@ -3,20 +3,12 @@
module QA
module Resource
class Group < GroupBase
attributes :require_two_factor_authentication, :description, :path
attributes :require_two_factor_authentication, :description
 
attribute :full_path do
determine_full_path
end
 
attribute :name do
@name || @path || Runtime::Namespace.name
end
attribute :path do
@path || @name || Runtime::Namespace.name
end
attribute :sandbox do
if Runtime::Env.personal_access_tokens_disabled?
Resource::Sandbox.fabricate! do |sandbox|
Loading
Loading
@@ -29,8 +21,13 @@ class Group < GroupBase
end
end
 
attribute :name do
path
end
def initialize
@description = "QA test run at #{Runtime::Namespace.time}"
@path = Runtime::Namespace.group_name
@require_two_factor_authentication = false
# Add visibility to enable create private group
@visibility = 'public'
Loading
Loading
Loading
Loading
@@ -9,11 +9,12 @@ class GroupBase < Base
 
MAX_NAME_LENGTH = 255
 
attr_accessor :path, :avatar
attr_accessor :avatar
 
attributes :id,
:runners_token,
:name,
:path,
:full_path,
# Add visibility to enable create private group
:visibility
Loading
Loading
Loading
Loading
@@ -106,11 +106,7 @@ def fabricate!
Page::Project::New.perform(&:click_blank_project_link)
 
Page::Project::New.perform do |new_page|
if @personal_namespace
new_page.choose_namespace(@personal_namespace)
else
new_page.choose_test_namespace
end
new_page.choose_namespace(@personal_namespace || group.path)
 
new_page.choose_name(@name)
new_page.add_description(@description) if @description
Loading
Loading
Loading
Loading
@@ -17,7 +17,7 @@ def fabricate!
end
 
Page::Project::Import::RepoByURL.perform do |import_page|
import_page.import!(@gitlab_repository_path, @name)
import_page.import!(@gitlab_repository_path, @name, group.full_path)
end
end
end
Loading
Loading
Loading
Loading
@@ -21,26 +21,11 @@ def self.blank_page?
true
end
 
##
# Visit a page that belongs to a GitLab instance under given address.
#
# Example:
#
# visit(:gitlab, Page::Main::Login)
# visit('http://gitlab.example/users/sign_in')
#
# In case of an address that is a symbol we will try to guess address
# based on `Runtime::Scenario#something_address`.
#
def visit(address, page_class, &block)
Browser::Session.new(address, page_class).perform(&block)
def self.visit(address, page_class, &)
new.visit(address, page_class, &)
end
 
def self.visit(address, page_class, &block)
new.visit(address, page_class, &block)
end
def self.configure! # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
def self.configure! # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity -- TODO: Break up this method
return if QA::Runtime::Env.dry_run
return if @configured
 
Loading
Loading
@@ -205,10 +190,7 @@ def self.configure! # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplex
end
 
Capybara::Screenshot.register_filename_prefix_formatter(:rspec) do |example|
::File.join(
QA::Runtime::Namespace.name(reset_cache: false),
example.full_description.downcase.parameterize(separator: "_")[0..79]
)
::File.join("failure_screenshots", example.full_description.downcase.parameterize(separator: "_")[0..79])
end
 
Capybara.configure do |config|
Loading
Loading
@@ -236,11 +218,69 @@ def self.chrome_profile_location
::File.expand_path('../../tmp/qa-profile', __dir__)
end
 
##
# Visit a page that belongs to a GitLab instance under given address.
#
# Example:
#
# visit(:gitlab, Page::Main::Login)
# visit('http://gitlab.example/users/sign_in')
#
# In case of an address that is a symbol we will try to guess address
# based on `Runtime::Scenario#something_address`.
#
def visit(address, page_class, &)
Browser::Session.new(address, page_class).perform(&)
end
class Session
include Capybara::DSL
 
attr_reader :page_class
 
# To redirect the browser to a canary or non-canary web node
# after loading a subject test page
# @param [Boolean] Send to canary true or false
# @example:
# Runtime::Browser::Session.target_canary(true)
def self.target_canary(enable_canary)
if QA::Runtime::Env.qa_cookies.to_s.include?("gitlab_canary=true")
QA::Runtime::Logger.warn("WARNING: Setting cookie through QA_COOKIES var is incompatible with this method.")
return
end
browser = Capybara.current_session.driver.browser
if enable_canary
browser.manage.add_cookie name: "gitlab_canary", value: "true"
else
browser.manage.delete_cookie("gitlab_canary")
end
browser.navigate.refresh
end
def self.enable_interception
script = File.read("#{__dir__}/script_extensions/interceptor.js")
command = {
cmd: 'Page.addScriptToEvaluateOnNewDocument',
params: {
source: script
}
}
@interceptor_script_params = Capybara.current_session.driver.browser.send(:bridge).send_command(command)
end
def self.disable_interception
return unless @interceptor_script_params
command = {
cmd: 'Page.removeScriptToEvaluateOnNewDocument',
params: @interceptor_script_params
}
Capybara.current_session.driver.browser.send(:bridge).send_command(command)
end
def initialize(instance, page_class)
@session_address = Runtime::Address.new(instance, page_class)
@page_class = page_class
Loading
Loading
@@ -274,28 +314,6 @@ def perform(&block)
yield.tap { clear! } if block
end
 
# To redirect the browser to a canary or non-canary web node
# after loading a subject test page
# @param [Boolean] Send to canary true or false
# @example:
# Runtime::Browser::Session.target_canary(true)
def self.target_canary(enable_canary)
if QA::Runtime::Env.qa_cookies.to_s.include?("gitlab_canary=true")
QA::Runtime::Logger.warn("WARNING: Setting cookie through QA_COOKIES var is incompatible with this method.")
return
end
browser = Capybara.current_session.driver.browser
if enable_canary
browser.manage.add_cookie name: "gitlab_canary", value: "true"
else
browser.manage.delete_cookie("gitlab_canary")
end
browser.navigate.refresh
end
##
# Selenium allows to reset session cookies for current domain only.
#
Loading
Loading
@@ -307,27 +325,6 @@ def clear!
@network_conditions_configured = false
end
 
def self.enable_interception
script = File.read("#{__dir__}/script_extensions/interceptor.js")
command = {
cmd: 'Page.addScriptToEvaluateOnNewDocument',
params: {
source: script
}
}
@interceptor_script_params = Capybara.current_session.driver.browser.send(:bridge).send_command(command)
end
def self.disable_interception
return unless @interceptor_script_params
command = {
cmd: 'Page.removeScriptToEvaluateOnNewDocument',
params: @interceptor_script_params
}
Capybara.current_session.driver.browser.send(:bridge).send_command(command)
end
private
 
def simulate_slow_connection
Loading
Loading
Loading
Loading
@@ -410,10 +410,6 @@ def qa_hostname
ENV['QA_HOSTNAME']
end
 
def cache_namespace_name?
enabled?(ENV['CACHE_NAMESPACE_NAME'], default: true)
end
def knapsack?
ENV['CI_NODE_TOTAL'].to_i > 1 && ENV['NO_KNAPSACK'] != "true"
end
Loading
Loading
Loading
Loading
@@ -2,35 +2,33 @@
 
module QA
module Runtime
# Global helper methods for unique group name generation
#
# Avoid using directly, instead use through fabricated instances of Sandbox and Group resources
module Namespace
extend self
class << self
def time
@time ||= Time.now
end
 
def time
@time ||= Time.now
end
def name(reset_cache: !Runtime::Env.cache_namespace_name?)
# If any changes are made to the name tag, following script has to be considered:
# https://ops.gitlab.net/gitlab-com/gl-infra/traffic-generator/blob/master/bin/janitor.bash
reset_name_cache if reset_cache
@name ||= Runtime::Env.namespace_name || "qa-test-#{time.strftime('%Y-%m-%d-%H-%M-%S')}-#{SecureRandom.hex(8)}" # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
def reset_name_cache
@name = nil # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
def path
"#{sandbox_name}/#{name(reset_cache: false)}"
end
# Random group name with specific pattern
#
# @return [String]
def group_name
Env.namespace_name || "qa-test-#{time.strftime('%Y-%m-%d-%H-%M-%S')}-#{SecureRandom.hex(8)}"
end
 
def sandbox_name
@sandbox_name ||= Runtime::Env.sandbox_name ||
if !QA::Runtime::Env.running_on_dot_com? && QA::Runtime::Env.run_in_parallel?
"gitlab-qa-sandbox-group-#{SecureRandom.hex(4)}-#{Time.now.wday + 1}"
else
"gitlab-qa-sandbox-group-#{Time.now.wday + 1}"
end
# Predefined top level group name
#
# @return [String]
def sandbox_name
@sandbox_name ||= Runtime::Env.sandbox_name ||
if !QA::Runtime::Env.running_on_dot_com? && QA::Runtime::Env.run_in_parallel?
"gitlab-qa-sandbox-group-#{SecureRandom.hex(4)}-#{Time.now.wday + 1}"
else
"gitlab-qa-sandbox-group-#{Time.now.wday + 1}"
end
end
end
end
end
Loading
Loading
Loading
Loading
@@ -8,9 +8,18 @@ module QA
include Runtime::Fixtures
include Support::Helpers::MaskToken
 
let!(:registry_scope) { Runtime::Namespace.sandbox_name }
let!(:personal_access_token) do
Resource::PersonalAccessToken.fabricate_via_api!.token
let!(:personal_access_token) { Resource::PersonalAccessToken.fabricate_via_api!.token }
let!(:group) { create(:group) }
let!(:registry_scope) { group.sandbox.name }
let!(:project) { create(:project, name: 'npm-group-publish', group: group) }
let!(:another_project) { create(:project, name: 'npm-group-install', group: group) }
let!(:runner) do
create(:group_runner,
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{group.name}"],
executor: :docker,
group: group)
end
 
let(:project_deploy_token) do
Loading
Loading
@@ -26,19 +35,7 @@ module QA
 
let(:gitlab_address_without_port) { Support::GitlabAddress.address_with_port(with_default_port: false) }
let(:gitlab_host_without_port) { Support::GitlabAddress.host_with_port(with_default_port: false) }
let!(:project) { create(:project, name: 'npm-group-level-publish') }
let!(:another_project) { create(:project, name: 'npm-group-level-install', group: project.group) }
let!(:runner) do
create(:group_runner,
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.group.name}"],
executor: :docker,
group: project.group)
end
let(:package) do
build(:package, name: "@#{registry_scope}/#{project.name}-#{SecureRandom.hex(8)}", project: project)
end
let(:package) { build(:package, name: "@#{registry_scope}/#{project.name}", project: project) }
 
before do
Flow::Login.sign_in
Loading
Loading
Loading
Loading
@@ -8,9 +8,18 @@ module QA
include Runtime::Fixtures
include Support::Helpers::MaskToken
 
let!(:registry_scope) { Runtime::Namespace.sandbox_name }
let!(:personal_access_token) do
Resource::PersonalAccessToken.fabricate_via_api!.token
let!(:personal_access_token) { Resource::PersonalAccessToken.fabricate_via_api!.token }
let!(:group) { create(:group) }
let!(:registry_scope) { group.sandbox.name }
let!(:project) { create(:project, name: 'npm-instance-publish', group: group) }
let!(:another_project) { create(:project, name: 'npm-instance-install', group: group) }
let!(:runner) do
create(:group_runner,
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{group.name}"],
executor: :docker,
group: group)
end
 
let(:project_deploy_token) do
Loading
Loading
@@ -26,19 +35,7 @@ module QA
 
let(:gitlab_address_without_port) { Support::GitlabAddress.address_with_port(with_default_port: false) }
let(:gitlab_host_without_port) { Support::GitlabAddress.host_with_port(with_default_port: false) }
let!(:project) { create(:project, name: 'npm-instance-level-publish') }
let!(:another_project) { create(:project, name: 'npm-instance-level-install', group: project.group) }
let!(:runner) do
create(:group_runner,
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.group.name}"],
executor: :docker,
group: project.group)
end
let(:package) do
build(:package, name: "@#{registry_scope}/#{project.name}-#{SecureRandom.hex(8)}", project: project)
end
let(:package) { build(:package, name: "@#{registry_scope}/#{project.name}", project: project) }
 
before do
Flow::Login.sign_in
Loading
Loading
Loading
Loading
@@ -8,9 +8,16 @@ module QA
include Runtime::Fixtures
include Support::Helpers::MaskToken
 
let!(:registry_scope) { Runtime::Namespace.sandbox_name }
let!(:personal_access_token) do
Resource::PersonalAccessToken.fabricate_via_api!.token
let!(:group) { create(:group) }
let!(:registry_scope) { group.sandbox.name }
let!(:personal_access_token) { Resource::PersonalAccessToken.fabricate_via_api!.token }
let!(:project) { create(:project, :private, name: 'npm-project-level', group: group) }
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)
end
 
let(:project_deploy_token) do
Loading
Loading
@@ -26,15 +33,6 @@ module QA
 
let(:gitlab_address_without_port) { Support::GitlabAddress.address_with_port(with_default_port: false) }
let(:gitlab_host_without_port) { Support::GitlabAddress.host_with_port(with_default_port: false) }
let!(:project) { create(:project, :private, name: 'npm-project-level') }
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)
end
let(:package) { build(:package, name: "@#{registry_scope}/mypackage-#{SecureRandom.hex(8)}", project: project) }
 
before do
Loading
Loading
Loading
Loading
@@ -3,6 +3,21 @@
module QA
RSpec.describe 'Create' do
describe 'Project templates', product_group: :source_code do
let!(:group) { create(:group) }
let(:sandbox) { group.sandbox }
let(:template_container_group_name) { "instance-template-container-group-#{SecureRandom.hex(8)}" }
let(:template_container_group) do
create(
:group,
path: template_container_group_name,
description: 'Instance template container group',
sandbox: sandbox
)
end
let(:template_project) { create(:project, name: 'template-project-1', group: template_container_group) }
let(:files) do
[
{
Loading
Loading
@@ -16,14 +31,6 @@ module QA
]
end
 
let(:template_container_group_name) { "instance-template-container-group-#{SecureRandom.hex(8)}" }
let(:template_container_group) do
create(:group, path: template_container_group_name, description: 'Instance template container group')
end
let(:template_project) { create(:project, name: 'template-project-1', group: template_container_group) }
before do
Resource::Repository::ProjectPush.fabricate! do |push|
push.project = template_project
Loading
Loading
@@ -41,7 +48,7 @@ module QA
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347932' do
built_in = 'Ruby on Rails'
 
create(:group).visit!
group.visit!
Page::Group::Show.perform(&:go_to_new_project)
 
QA::Flow::Project.go_to_create_project_from_template
Loading
Loading
@@ -52,7 +59,7 @@ module QA
 
create_project_using_template(
project_name: 'Project using built-in project template',
namespace: Runtime::Namespace.name(reset_cache: false),
namespace: group.name,
template_name: built_in
)
 
Loading
Loading
@@ -86,7 +93,7 @@ module QA
end
end
 
create(:group).visit!
group.visit!
 
Page::Group::Show.perform(&:go_to_new_project)
 
Loading
Loading
@@ -115,7 +122,7 @@ module QA
 
create_project_using_template(
project_name: 'Project using instance level project template',
namespace: Runtime::Namespace.path,
namespace: group.full_path,
template_name: template_project.name
)
 
Loading
Loading
@@ -134,7 +141,7 @@ module QA
Flow::Login.sign_in
 
Page::Main::Menu.perform(&:go_to_groups)
Page::Dashboard::Groups.perform { |groups| groups.click_group(Runtime::Namespace.sandbox_name) }
Page::Dashboard::Groups.perform { |groups| groups.click_group(sandbox.name) }
 
Page::Group::Menu.perform(&:go_to_general_settings)
 
Loading
Loading
@@ -148,7 +155,6 @@ module QA
end
end
 
group = create(:group)
group.visit!
 
Page::Group::Show.perform(&:go_to_new_project)
Loading
Loading
@@ -172,7 +178,7 @@ module QA
 
create_project_using_template(
project_name: 'Project using group level project template',
namespace: Runtime::Namespace.sandbox_name,
namespace: sandbox.name,
template_name: template_project.name
)
 
Loading
Loading
Loading
Loading
@@ -3,54 +3,26 @@
RSpec.describe QA::Runtime::Namespace do
include QA::Support::Helpers::StubEnv
 
describe '.name' do
context 'when CACHE_NAMESPACE_NAME is not defined' do
before do
stub_env('CACHE_NAMESPACE_NAME', nil)
end
let!(:time) { described_class.time }
 
it 'caches name by default' do
name = described_class.name
expect(described_class.name).to eq(name)
end
it 'does not cache name when reset_cache is true' do
name = described_class.name
expect(described_class.name(reset_cache: true)).not_to eq(name)
end
end
context 'when CACHE_NAMESPACE_NAME is defined' do
before do
stub_env('CACHE_NAMESPACE_NAME', 'true')
end
it 'caches name by default' do
name = described_class.name
expect(described_class.name).to eq(name)
end
it 'caches name when reset_cache is false' do
name = described_class.name
expect(described_class.name(reset_cache: false)).to eq(name)
end
before(:context) do
described_class.instance_variable_set(:@time, nil)
described_class.instance_variable_set(:@sandbox_name, nil)
end
 
it 'does not cache name when reset_cache is true' do
name = described_class.name
expect(described_class.name(reset_cache: true)).not_to eq(name)
end
describe '.group_name' do
it "returns unique name with predefined pattern" do
expect(described_class.group_name).to match(/qa-test-#{time.strftime('%Y-%m-%d-%H-%M-%S')}-[a-f0-9]{16}/)
end
end
 
describe '.path' do
describe '.sandbox_name' do
before do
allow(QA::Runtime::Scenario).to receive(:gitlab_address).and_return("http://gitlab.test")
described_class.instance_variable_set(:@sandbox_name, nil)
end
 
it 'is always cached' do
path = described_class.path
expect(described_class.path).to eq(path)
it "returns day specific sandbox name" do
expect(described_class.sandbox_name).to match(%r{gitlab-qa-sandbox-group-#{time.wday + 1}})
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment