summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2018-10-16 11:38:57 +0200
committerRémy Coutable <remy@rymai.me>2018-10-22 10:03:11 +0200
commite5f01cc8a170f07a1fe623a05ccb1de020b7ea87 (patch)
treeaf6ebc4b616be96df165098bbb9a131e69f7bffb
parentfbb0f71237fca77746e84ba4cea837472a178f4d (diff)
downloadgitlab-ce-qa-backport-recent-ee-changes.tar.gz
[QA] Port recent changes from EEqa-backport-recent-ee-changes
Signed-off-by: Rémy Coutable <remy@rymai.me>
-rw-r--r--qa/qa/factory/resource/merge_request.rb1
-rw-r--r--qa/qa/factory/settings/hashed_storage.rb2
-rw-r--r--qa/qa/git/repository.rb140
-rw-r--r--qa/qa/page/project/menu.rb14
-rw-r--r--qa/spec/git/repository_spec.rb15
5 files changed, 115 insertions, 57 deletions
diff --git a/qa/qa/factory/resource/merge_request.rb b/qa/qa/factory/resource/merge_request.rb
index 18046c7a8b2..d30da8a3db0 100644
--- a/qa/qa/factory/resource/merge_request.rb
+++ b/qa/qa/factory/resource/merge_request.rb
@@ -30,6 +30,7 @@ module QA
push.project = factory.project
push.branch_name = factory.target_branch
push.remote_branch = factory.source_branch
+ push.new_branch = false
push.file_name = "added_file.txt"
push.file_content = "File Added"
end
diff --git a/qa/qa/factory/settings/hashed_storage.rb b/qa/qa/factory/settings/hashed_storage.rb
index f2e58a3ea38..5e8f883e25f 100644
--- a/qa/qa/factory/settings/hashed_storage.rb
+++ b/qa/qa/factory/settings/hashed_storage.rb
@@ -9,7 +9,7 @@ module QA
Page::Main::Menu.act { go_to_admin_area }
Page::Admin::Menu.act { go_to_repository_settings }
- Page::Admin::Settings::Main.perform do |setting|
+ Page::Admin::Settings::Repository.perform do |setting|
setting.expand_repository_storage do |page|
page.enable_hashed_storage
page.save_settings
diff --git a/qa/qa/git/repository.rb b/qa/qa/git/repository.rb
index 14cb8125fdb..c6a8891d398 100644
--- a/qa/qa/git/repository.rb
+++ b/qa/qa/git/repository.rb
@@ -1,14 +1,24 @@
+# frozen_string_literal: true
+
require 'cgi'
require 'uri'
require 'open3'
+require 'fileutils'
+require 'tmpdir'
module QA
module Git
class Repository
include Scenario::Actable
+ attr_writer :password
+ attr_accessor :env_vars
+
def initialize
- @ssh_cmd = ""
+ # We set HOME to the current working directory (which is a
+ # temporary directory created in .perform()) so the temporarily dropped
+ # .netrc can be utilised
+ self.env_vars = [%Q{HOME="#{File.dirname(netrc_file_path)}"}]
end
def self.perform(*args)
@@ -21,36 +31,27 @@ module QA
@uri = URI(address)
end
- def username=(name)
- @username = name
- @uri.user = name
- end
-
- def password=(pass)
- @password = pass
- @uri.password = CGI.escape(pass).gsub('+', '%20')
+ def username=(username)
+ @username = username
+ @uri.user = username
end
def use_default_credentials
- if ::QA::Runtime::User.ldap_user?
- self.username = Runtime::User.ldap_username
- self.password = Runtime::User.ldap_password
- else
- self.username = Runtime::User.username
- self.password = Runtime::User.password
- end
+ self.username, self.password = default_credentials
+
+ add_credentials_to_netrc unless ssh_key_set?
end
def clone(opts = '')
- run_and_redact_credentials(build_git_command("git clone #{opts} #{@uri} ./"))
+ run("git clone #{opts} #{uri} ./")
end
def checkout(branch_name)
- `git checkout "#{branch_name}"`
+ run(%Q{git checkout "#{branch_name}"})
end
def checkout_new_branch(branch_name)
- `git checkout -b "#{branch_name}"`
+ run(%Q{git checkout -b "#{branch_name}"})
end
def shallow_clone
@@ -58,12 +59,10 @@ module QA
end
def configure_identity(name, email)
- `git config user.name #{name}`
- `git config user.email #{email}`
- end
+ run(%Q{git config user.name #{name}})
+ run(%Q{git config user.email #{email}})
- def configure_ssh_command(command)
- @ssh_cmd = "GIT_SSH_COMMAND='#{command}'"
+ add_credentials_to_netrc
end
def commit_file(name, contents, message)
@@ -74,54 +73,103 @@ module QA
def add_file(name, contents)
::File.write(name, contents)
- `git add #{name}`
+ run(%Q{git add #{name}})
end
def commit(message)
- `git commit -m "#{message}"`
+ run(%Q{git commit -m "#{message}"})
end
def push_changes(branch = 'master')
- output, _ = run_and_redact_credentials(build_git_command("git push #{@uri} #{branch}"))
-
- output
+ run("git push #{uri} #{branch}")
end
def commits
- `git log --oneline`.split("\n")
+ run('git log --oneline').split("\n")
end
def use_ssh_key(key)
@private_key_file = Tempfile.new("id_#{SecureRandom.hex(8)}")
- File.binwrite(@private_key_file, key.private_key)
- File.chmod(0700, @private_key_file)
+ File.binwrite(private_key_file, key.private_key)
+ File.chmod(0700, private_key_file)
@known_hosts_file = Tempfile.new("known_hosts_#{SecureRandom.hex(8)}")
keyscan_params = ['-H']
- keyscan_params << "-p #{@uri.port}" if @uri.port
- keyscan_params << @uri.host
- run_and_redact_credentials("ssh-keyscan #{keyscan_params.join(' ')} >> #{@known_hosts_file.path}")
+ keyscan_params << "-p #{uri.port}" if uri.port
+ keyscan_params << uri.host
+ run("ssh-keyscan #{keyscan_params.join(' ')} >> #{known_hosts_file.path}")
- configure_ssh_command("ssh -i #{@private_key_file.path} -o UserKnownHostsFile=#{@known_hosts_file.path}")
+ self.env_vars << %Q{GIT_SSH_COMMAND="ssh -i #{private_key_file.path} -o UserKnownHostsFile=#{known_hosts_file.path}"}
end
def delete_ssh_key
- return unless @private_key_file
+ return unless ssh_key_set?
- @private_key_file.close(true)
- @known_hosts_file.close(true)
+ private_key_file.close(true)
+ known_hosts_file.close(true)
end
- def build_git_command(command_str)
- [@ssh_cmd, command_str].compact.join(' ')
+ private
+
+ attr_reader :uri, :username, :password, :known_hosts_file, :private_key_file
+
+ def debug?
+ Runtime::Env.respond_to?(:verbose?) && Runtime::Env.verbose?
end
- private
+ def ssh_key_set?
+ !private_key_file.nil?
+ end
+
+ def run(command_str)
+ command = [env_vars, command_str, '2>&1'].compact.join(' ')
+ warn "DEBUG: command=[#{command}]" if debug?
+
+ output, _ = Open3.capture2(command)
+ output = output.chomp.gsub(/\s+$/, '')
+ warn "DEBUG: output=[#{output}]" if debug?
+
+ output
+ end
+
+ def default_credentials
+ if ::QA::Runtime::User.ldap_user?
+ [Runtime::User.ldap_username, Runtime::User.ldap_password]
+ else
+ [Runtime::User.username, Runtime::User.password]
+ end
+ end
+
+ def tmp_netrc_directory
+ @tmp_netrc_directory ||= File.join(Dir.tmpdir, "qa-netrc-credentials", $$.to_s)
+ end
+
+ def netrc_file_path
+ @netrc_file_path ||= File.join(tmp_netrc_directory, '.netrc')
+ end
+
+ def netrc_content
+ "machine #{uri.host} login #{username} password #{password}"
+ end
+
+ def netrc_already_contains_content?
+ File.exist?(netrc_file_path) &&
+ File.readlines(netrc_file_path).grep(/^#{netrc_content}$/).any?
+ end
+
+ def add_credentials_to_netrc
+ # Despite libcurl supporting a custom .netrc location through the
+ # CURLOPT_NETRC_FILE environment variable, git does not support it :(
+ # Info: https://curl.haxx.se/libcurl/c/CURLOPT_NETRC_FILE.html
+ #
+ # This will create a .netrc in the correct working directory, which is
+ # a temporary directory created in .perform()
+ #
+ return if netrc_already_contains_content?
- # Since the remote URL contains the credentials, and git occasionally
- # outputs the URL. Note that stderr is redirected to stdout.
- def run_and_redact_credentials(command)
- Open3.capture2("#{command} 2>&1 | sed -E 's#://[^@]+@#://****@#g'")
+ FileUtils.mkdir_p(tmp_netrc_directory)
+ File.open(netrc_file_path, 'a') { |file| file.puts(netrc_content) }
+ File.chmod(0600, netrc_file_path)
end
end
end
diff --git a/qa/qa/page/project/menu.rb b/qa/qa/page/project/menu.rb
index bc125d1af88..cb4a10e1b6a 100644
--- a/qa/qa/page/project/menu.rb
+++ b/qa/qa/page/project/menu.rb
@@ -87,6 +87,14 @@ module QA
end
end
+ def go_to_labels
+ hover_issues do
+ within_submenu do
+ click_element(:labels_link)
+ end
+ end
+ end
+
def click_merge_requests
within_sidebar do
click_link('Merge Requests')
@@ -105,8 +113,10 @@ module QA
end
end
- def go_to_labels
- hover_issues { click_element :labels_link }
+ def click_repository
+ within_sidebar do
+ click_link('Repository')
+ end
end
private
diff --git a/qa/spec/git/repository_spec.rb b/qa/spec/git/repository_spec.rb
index 53bff3bf0b3..c629f802aa4 100644
--- a/qa/spec/git/repository_spec.rb
+++ b/qa/spec/git/repository_spec.rb
@@ -1,17 +1,18 @@
describe QA::Git::Repository do
+ include Support::StubENV
+
let(:repository) { described_class.new }
before do
+ stub_env('GITLAB_USERNAME', 'root')
cd_empty_temp_directory
set_bad_uri
repository.use_default_credentials
end
describe '#clone' do
- it 'redacts credentials from the URI in output' do
- output, _ = repository.clone
-
- expect(output).to include("fatal: unable to access 'http://****@foo/bar.git/'")
+ it 'is unable to resolve host' do
+ expect(repository.clone).to include("fatal: unable to access 'http://root@foo/bar.git/'")
end
end
@@ -20,10 +21,8 @@ describe QA::Git::Repository do
`git init` # need a repo to push from
end
- it 'redacts credentials from the URI in output' do
- output, _ = repository.push_changes
-
- expect(output).to include("error: failed to push some refs to 'http://****@foo/bar.git'")
+ it 'fails to push changes' do
+ expect(repository.push_changes).to include("error: failed to push some refs to 'http://root@foo/bar.git'")
end
end