summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Lapierre <mlapierre@gmail.com>2018-06-11 18:58:06 -0400
committerMark Lapierre <mlapierre@gitlab.com>2018-09-15 11:45:10 -0400
commit0c30fcdb29558d6c2419addc17db39da6e469887 (patch)
tree969ac3d409989925a98ad8b104218d69648ae22f
parentb9ea4e35ac679a87ea16ca01a5f02bd96b3b16c3 (diff)
downloadgitlab-ce-mlapierre/gitlab-ce-ml-qa-spec-use-ssh-key.tar.gz
Add an SSH key and use it to clone and pushmlapierre/gitlab-ce-ml-qa-spec-use-ssh-key
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml2
-rw-r--r--app/views/profiles/keys/_form.html.haml6
-rw-r--r--app/views/profiles/keys/_key_details.html.haml2
-rw-r--r--qa/qa.rb2
-rw-r--r--qa/qa/factory/repository/project_push.rb18
-rw-r--r--qa/qa/factory/repository/push.rb18
-rw-r--r--qa/qa/factory/repository/wiki_push.rb4
-rw-r--r--qa/qa/factory/resource/project.rb7
-rw-r--r--qa/qa/factory/resource/ssh_key.rb40
-rw-r--r--qa/qa/git/repository.rb37
-rw-r--r--qa/qa/page/menu/profile.rb7
-rw-r--r--qa/qa/page/menu/side.rb3
-rw-r--r--qa/qa/page/profile/ssh_keys.rb34
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb31
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb40
15 files changed, 233 insertions, 18 deletions
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index 30e0e9fca27..7239780871c 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -158,7 +158,7 @@
- if project_nav_tab? :pipelines
= nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts]) do
- = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines' do
+ = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines' do
.nav-icon-container
= sprite_icon('rocket')
%span.nav-item-name
diff --git a/app/views/profiles/keys/_form.html.haml b/app/views/profiles/keys/_form.html.haml
index 5207921d6fe..700c22e1652 100644
--- a/app/views/profiles/keys/_form.html.haml
+++ b/app/views/profiles/keys/_form.html.haml
@@ -5,10 +5,10 @@
.form-group
= f.label :key, class: 'label-bold'
%p= _("Paste your public SSH key, which is usually contained in the file '~/.ssh/id_rsa.pub' and begins with 'ssh-rsa'. Don't use your private SSH key.")
- = f.text_area :key, class: "form-control js-add-ssh-key-validation-input", rows: 8, required: true, placeholder: s_('Profiles|Typically starts with "ssh-rsa …"')
+ = f.text_area :key, class: "form-control js-add-ssh-key-validation-input qa-key-public-key-field", rows: 8, required: true, placeholder: s_('Profiles|Typically starts with "ssh-rsa …"')
.form-group
= f.label :title, class: 'label-bold'
- = f.text_field :title, class: "form-control input-lg", required: true, placeholder: s_('Profiles|e.g. My MacBook key')
+ = f.text_field :title, class: "form-control input-lg qa-key-title-field", required: true, placeholder: s_('Profiles|e.g. My MacBook key')
%p.form-text.text-muted= _('Name your individual key via a title')
.js-add-ssh-key-validation-warning.hide
@@ -19,4 +19,4 @@
%button.btn.btn-create.js-add-ssh-key-validation-confirm-submit= _("Yes, add it")
.prepend-top-default
- = f.submit s_('Profiles|Add key'), class: "btn btn-create js-add-ssh-key-validation-original-submit"
+ = f.submit s_('Profiles|Add key'), class: "btn btn-create js-add-ssh-key-validation-original-submit qa-add-key-button"
diff --git a/app/views/profiles/keys/_key_details.html.haml b/app/views/profiles/keys/_key_details.html.haml
index 2ac514d3f6f..88473c7f72d 100644
--- a/app/views/profiles/keys/_key_details.html.haml
+++ b/app/views/profiles/keys/_key_details.html.haml
@@ -24,4 +24,4 @@
= @key.key
.col-md-12
.float-right
- = link_to 'Remove', path_to_key(@key, is_admin), data: {confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove delete-key"
+ = link_to 'Remove', path_to_key(@key, is_admin), data: {confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove delete-key qa-delete-key-button"
diff --git a/qa/qa.rb b/qa/qa.rb
index cb3202c8e1c..952084085d5 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -57,6 +57,7 @@ module QA
autoload :Wiki, 'qa/factory/resource/wiki'
autoload :File, 'qa/factory/resource/file'
autoload :Fork, 'qa/factory/resource/fork'
+ autoload :SSHKey, 'qa/factory/resource/ssh_key'
end
module Repository
@@ -217,6 +218,7 @@ module QA
module Profile
autoload :PersonalAccessTokens, 'qa/page/profile/personal_access_tokens'
+ autoload :SSHKeys, 'qa/page/profile/ssh_keys'
end
module Issuable
diff --git a/qa/qa/factory/repository/project_push.rb b/qa/qa/factory/repository/project_push.rb
index 4f78098d348..167f47c9141 100644
--- a/qa/qa/factory/repository/project_push.rb
+++ b/qa/qa/factory/repository/project_push.rb
@@ -11,7 +11,9 @@ module QA
factory.output
end
- product(:project) { |factory| factory.project }
+ product :project do |factory|
+ factory.project
+ end
def initialize
@file_name = 'file.txt'
@@ -21,8 +23,8 @@ module QA
@new_branch = true
end
- def repository_uri
- @repository_uri ||= begin
+ def repository_http_uri
+ @repository_http_uri ||= begin
project.visit!
Page::Project::Show.act do
choose_repository_clone_http
@@ -30,6 +32,16 @@ module QA
end
end
end
+
+ def repository_ssh_uri
+ @repository_ssh_uri ||= begin
+ project.visit!
+ Page::Project::Show.act do
+ choose_repository_clone_ssh
+ repository_location.uri
+ end
+ end
+ end
end
end
end
diff --git a/qa/qa/factory/repository/push.rb b/qa/qa/factory/repository/push.rb
index 5b7ebf6c41f..6c5088f1da5 100644
--- a/qa/qa/factory/repository/push.rb
+++ b/qa/qa/factory/repository/push.rb
@@ -5,8 +5,8 @@ module QA
module Repository
class Push < Factory::Base
attr_accessor :file_name, :file_content, :commit_message,
- :branch_name, :new_branch, :output, :repository_uri,
- :user
+ :branch_name, :new_branch, :output, :repository_http_uri,
+ :repository_ssh_uri, :ssh_key, :user
attr_writer :remote_branch
@@ -16,7 +16,8 @@ module QA
@commit_message = "This is a test commit"
@branch_name = 'master'
@new_branch = true
- @repository_uri = ""
+ @repository_http_uri = ""
+ @ssh_key = nil
end
def remote_branch
@@ -31,9 +32,14 @@ module QA
def fabricate!
Git::Repository.perform do |repository|
- repository.uri = repository_uri
+ if ssh_key
+ repository.uri = repository_ssh_uri
+ repository.use_ssh_key(ssh_key)
+ else
+ repository.uri = repository_http_uri
+ repository.use_default_credentials
+ end
- repository.use_default_credentials
username = 'GitLab QA'
email = 'root@gitlab.com'
@@ -63,6 +69,8 @@ module QA
repository.commit(commit_message)
@output = repository.push_changes("#{branch_name}:#{remote_branch}")
+
+ repository.delete_ssh_key
end
end
end
diff --git a/qa/qa/factory/repository/wiki_push.rb b/qa/qa/factory/repository/wiki_push.rb
index fb7c2bb660d..ecc6cc18c88 100644
--- a/qa/qa/factory/repository/wiki_push.rb
+++ b/qa/qa/factory/repository/wiki_push.rb
@@ -16,8 +16,8 @@ module QA
@new_branch = false
end
- def repository_uri
- @repository_uri ||= begin
+ def repository_http_uri
+ @repository_http_uri ||= begin
wiki.visit!
Page::Project::Wiki::Show.act do
go_to_clone_repository
diff --git a/qa/qa/factory/resource/project.rb b/qa/qa/factory/resource/project.rb
index 7fff22b5468..90db26ab3ab 100644
--- a/qa/qa/factory/resource/project.rb
+++ b/qa/qa/factory/resource/project.rb
@@ -20,6 +20,13 @@ module QA
end
end
+ product :repository_http_location do
+ Page::Project::Show.act do
+ choose_repository_clone_http
+ repository_location
+ end
+ end
+
def initialize
@description = 'My awesome project'
end
diff --git a/qa/qa/factory/resource/ssh_key.rb b/qa/qa/factory/resource/ssh_key.rb
new file mode 100644
index 00000000000..6c872f32d16
--- /dev/null
+++ b/qa/qa/factory/resource/ssh_key.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module QA
+ module Factory
+ module Resource
+ class SSHKey < Factory::Base
+ extend Forwardable
+
+ attr_accessor :title
+ attr_reader :private_key, :public_key, :fingerprint
+ def_delegators :key, :private_key, :public_key, :fingerprint
+
+ product :private_key do |factory|
+ factory.private_key
+ end
+
+ product :title do |factory|
+ factory.title
+ end
+
+ product :fingerprint do |factory|
+ factory.fingerprint
+ end
+
+ def key
+ @key ||= Runtime::Key::RSA.new
+ end
+
+ def fabricate!
+ Page::Menu::Main.act { go_to_profile_settings }
+ Page::Menu::Profile.act { click_ssh_keys }
+
+ Page::Profile::SSHKeys.perform do |page|
+ page.add_key(public_key, title)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/git/repository.rb b/qa/qa/git/repository.rb
index faecacd45ec..14cb8125fdb 100644
--- a/qa/qa/git/repository.rb
+++ b/qa/qa/git/repository.rb
@@ -7,6 +7,10 @@ module QA
class Repository
include Scenario::Actable
+ def initialize
+ @ssh_cmd = ""
+ end
+
def self.perform(*args)
Dir.mktmpdir do |dir|
Dir.chdir(dir) { super }
@@ -38,7 +42,7 @@ module QA
end
def clone(opts = '')
- run_and_redact_credentials("git clone #{opts} #{@uri} ./")
+ run_and_redact_credentials(build_git_command("git clone #{opts} #{@uri} ./"))
end
def checkout(branch_name)
@@ -58,6 +62,10 @@ module QA
`git config user.email #{email}`
end
+ def configure_ssh_command(command)
+ @ssh_cmd = "GIT_SSH_COMMAND='#{command}'"
+ end
+
def commit_file(name, contents, message)
add_file(name, contents)
commit(message)
@@ -74,7 +82,7 @@ module QA
end
def push_changes(branch = 'master')
- output, _ = run_and_redact_credentials("git push #{@uri} #{branch}")
+ output, _ = run_and_redact_credentials(build_git_command("git push #{@uri} #{branch}"))
output
end
@@ -83,6 +91,31 @@ module QA
`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)
+
+ @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}")
+
+ configure_ssh_command("ssh -i #{@private_key_file.path} -o UserKnownHostsFile=#{@known_hosts_file.path}")
+ end
+
+ def delete_ssh_key
+ return unless @private_key_file
+
+ @private_key_file.close(true)
+ @known_hosts_file.close(true)
+ end
+
+ def build_git_command(command_str)
+ [@ssh_cmd, command_str].compact.join(' ')
+ end
+
private
# Since the remote URL contains the credentials, and git occasionally
diff --git a/qa/qa/page/menu/profile.rb b/qa/qa/page/menu/profile.rb
index 95e88d863e4..7e24fa85c33 100644
--- a/qa/qa/page/menu/profile.rb
+++ b/qa/qa/page/menu/profile.rb
@@ -6,6 +6,7 @@ module QA
element :access_token_link, 'link_to profile_personal_access_tokens_path'
element :access_token_title, 'Access Tokens'
element :top_level_items, '.sidebar-top-level-items'
+ element :ssh_keys, 'SSH Keys'
end
def click_access_tokens
@@ -14,6 +15,12 @@ module QA
end
end
+ def click_ssh_keys
+ within_sidebar do
+ click_link('SSH Keys')
+ end
+ end
+
private
def within_sidebar
diff --git a/qa/qa/page/menu/side.rb b/qa/qa/page/menu/side.rb
index 354ccec2a5a..a1eedfea42e 100644
--- a/qa/qa/page/menu/side.rb
+++ b/qa/qa/page/menu/side.rb
@@ -6,6 +6,7 @@ module QA
element :settings_item
element :settings_link, 'link_to edit_project_path'
element :repository_link, "title: _('Repository')"
+ element :link_pipelines
element :pipelines_settings_link, "title: _('CI / CD')"
element :operations_kubernetes_link, "title: _('Kubernetes')"
element :issues_link, /link_to.*shortcuts-issues/
@@ -49,7 +50,7 @@ module QA
def click_ci_cd_pipelines
within_sidebar do
- click_link('CI / CD')
+ click_element :link_pipelines
end
end
diff --git a/qa/qa/page/profile/ssh_keys.rb b/qa/qa/page/profile/ssh_keys.rb
new file mode 100644
index 00000000000..ce1813b14d0
--- /dev/null
+++ b/qa/qa/page/profile/ssh_keys.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Profile
+ class SSHKeys < Page::Base
+ view 'app/views/profiles/keys/_form.html.haml' do
+ element :key_title_field
+ element :key_public_key_field
+ element :add_key_button
+ end
+
+ view 'app/views/profiles/keys/_key_details.html.haml' do
+ element :delete_key_button
+ end
+
+ def add_key(public_key, title)
+ fill_element :key_public_key_field, public_key
+ fill_element :key_title_field, title
+
+ click_element :add_key_button
+ end
+
+ def remove_key(title)
+ click_link(title)
+
+ accept_alert do
+ click_element :delete_key_button
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb
new file mode 100644
index 00000000000..84f663c4866
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module QA
+ context :create do
+ describe 'SSH keys support' do
+ let(:key_title) { "key for ssh tests #{Time.now.to_f}" }
+
+ it 'user adds and then removes an SSH key' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ key = Factory::Resource::SSHKey.fabricate! do |resource|
+ resource.title = key_title
+ end
+
+ expect(page).to have_content("Title: #{key_title}")
+ expect(page).to have_content(key.fingerprint)
+
+ Page::Menu::Main.act { go_to_profile_settings }
+ Page::Menu::Profile.act { click_ssh_keys }
+
+ Page::Profile::SSHKeys.perform do |ssh_keys|
+ ssh_keys.remove_key(key_title)
+ end
+
+ expect(page).not_to have_content("Title: #{key_title}")
+ expect(page).not_to have_content(key.fingerprint)
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb
new file mode 100644
index 00000000000..7c989bfd8cc
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module QA
+ context :create do
+ describe 'SSH key support' do
+ # Note: If you run this test against GDK make sure you've enabled sshd
+ # See: https://gitlab.com/gitlab-org/gitlab-qa/blob/master/docs/run_qa_against_gdk.md
+
+ let(:key_title) { "key for ssh tests #{Time.now.to_f}" }
+
+ it 'user adds an ssh key and pushes code to the repository' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ key = Factory::Resource::SSHKey.fabricate! do |resource|
+ resource.title = key_title
+ end
+
+ Factory::Repository::ProjectPush.fabricate! do |push|
+ push.ssh_key = key
+ push.file_name = 'README.md'
+ push.file_content = '# Test Use SSH Key'
+ push.commit_message = 'Add README.md'
+ end
+
+ Page::Project::Show.act { wait_for_push }
+
+ expect(page).to have_content('README.md')
+ expect(page).to have_content('Test Use SSH Key')
+
+ Page::Menu::Main.act { go_to_profile_settings }
+ Page::Menu::Profile.act { click_ssh_keys }
+
+ Page::Profile::SSHKeys.perform do |ssh_keys|
+ ssh_keys.remove_key(key_title)
+ end
+ end
+ end
+ end
+end