diff options
author | Mark Lapierre <mlapierre@gitlab.com> | 2018-11-21 11:41:33 -0500 |
---|---|---|
committer | Mark Lapierre <mlapierre@gitlab.com> | 2019-07-30 09:01:27 +1000 |
commit | becd401ba50359145ca73266dff6b5f32c26988a (patch) | |
tree | 20367ed4a926e84712073f456a74b30943ef567f | |
parent | f52e9d55ded0e392bfea5d9bf963615766d5a1a3 (diff) | |
download | gitlab-ce-qa-ssh-push-mirror-tests.tar.gz |
Add e2e test: SSH push mirroring with private keyqa-ssh-push-mirror-tests
Adds an end-to-end test of push mirroring a repository over SSH using
a private key
11 files changed, 128 insertions, 19 deletions
diff --git a/app/views/projects/deploy_keys/_form.html.haml b/app/views/projects/deploy_keys/_form.html.haml index 568930595a2..17a431e391d 100644 --- a/app/views/projects/deploy_keys/_form.html.haml +++ b/app/views/projects/deploy_keys/_form.html.haml @@ -14,7 +14,7 @@ = f.fields_for :deploy_keys_projects do |deploy_keys_project_form| .form-group.row = deploy_keys_project_form.label :can_push do - = deploy_keys_project_form.check_box :can_push + = deploy_keys_project_form.check_box :can_push, data: { qa_selector: "write_access_allowed_checkbox" } %strong Write access allowed .form-group.row %p.light.append-bottom-0 diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml index e68fa5d08c7..e897020272c 100644 --- a/app/views/projects/mirrors/_mirror_repos.html.haml +++ b/app/views/projects/mirrors/_mirror_repos.html.haml @@ -1,7 +1,7 @@ - expanded = expanded_by_default? - protocols = Gitlab::UrlSanitizer::ALLOWED_SCHEMES.join('|') -%section.settings.project-mirror-settings.js-mirror-settings.no-animate.qa-mirroring-repositories-settings#js-push-remote-settings{ class: ('expanded' if expanded) } +%section.settings.project-mirror-settings.js-mirror-settings.no-animate#js-push-remote-settings{ class: ('expanded' if expanded), data: { qa_selector: 'mirroring_repositories_settings_section' } } .settings-header %h4= _('Mirroring repositories') %button.btn.js-settings-toggle @@ -58,10 +58,10 @@ - if mirror.disabled? = render 'projects/mirrors/disabled_mirror_badge' - if mirror.last_error.present? - .badge.mirror-error-badge{ data: { toggle: 'tooltip', html: 'true' }, title: html_escape(mirror.last_error.try(:strip)) }= _('Error') + .badge.mirror-error-badge{ data: { toggle: 'tooltip', html: 'true', qa_selector: 'mirror_error_badge' }, title: html_escape(mirror.last_error.try(:strip)) }= _('Error') %td .btn-group.mirror-actions-group.pull-right{ role: 'group' } - if mirror.ssh_key_auth? - = clipboard_button(text: mirror.ssh_public_key, class: 'btn btn-default', title: _('Copy SSH public key')) + = clipboard_button(text: mirror.ssh_public_key, class: 'btn btn-default', title: _('Copy SSH public key'), qa_selector: 'copy_public_key_button') = render 'shared/remote_mirror_update_button', remote_mirror: mirror %button.js-delete-mirror.qa-delete-mirror.btn.btn-danger{ type: 'button', data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' }, title: _('Remove') }= icon('trash-o') diff --git a/app/views/projects/mirrors/_ssh_host_keys.html.haml b/app/views/projects/mirrors/_ssh_host_keys.html.haml index 7762fb4b844..3279d3eb251 100644 --- a/app/views/projects/mirrors/_ssh_host_keys.html.haml +++ b/app/views/projects/mirrors/_ssh_host_keys.html.haml @@ -3,13 +3,13 @@ - verified_at = mirror.ssh_known_hosts_verified_at .form-group.js-ssh-host-keys-section{ class: ('collapse' unless mirror.ssh_mirror_url?) } - %button.btn.btn-inverted.btn-secondary.inline.js-detect-host-keys.append-right-10{ type: 'button' } + %button.btn.btn-inverted.btn-secondary.inline.js-detect-host-keys.append-right-10{ type: 'button', data: { qa_selector: 'detect_host_keys' } } = icon('spinner spin', class: 'js-spinner d-none') = _('Detect host keys') .fingerprint-ssh-info.js-fingerprint-ssh-info.prepend-top-10.append-bottom-10{ class: ('collapse' unless mirror.ssh_mirror_url?) } %label.label-bold = _('Fingerprints') - .fingerprints-list.js-fingerprints-list + .fingerprints-list.js-fingerprints-list{ data: { qa_selector: 'fingerprints_list' } } - mirror.ssh_known_hosts_fingerprints.each do |fp| %code= fp.fingerprint - if verified_at diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb index 45496c6b245..42fe431bfbd 100644 --- a/qa/qa/page/base.rb +++ b/qa/qa/page/base.rb @@ -15,6 +15,10 @@ module QA def_delegators :evaluator, :view, :views + def assert_no_element(name) + assert_no_selector(element_selector_css(name)) + end + def refresh page.refresh end @@ -102,9 +106,9 @@ module QA def select_element(name, value) element = find_element(name) - return if element.text.downcase.to_s == value.to_s + return if element.text == value - element.select value.to_s.capitalize + element.select value end def has_element?(name, text: nil, wait: Capybara.default_max_wait_time) diff --git a/qa/qa/page/project/settings/deploy_keys.rb b/qa/qa/page/project/settings/deploy_keys.rb index b8d961274a9..feb1f5af87c 100644 --- a/qa/qa/page/project/settings/deploy_keys.rb +++ b/qa/qa/page/project/settings/deploy_keys.rb @@ -8,6 +8,7 @@ module QA view 'app/views/projects/deploy_keys/_form.html.haml' do element :deploy_key_title, 'text_field :title' # rubocop:disable QA/ElementWithPattern element :deploy_key_key, 'text_area :key' # rubocop:disable QA/ElementWithPattern + element :write_access_allowed_checkbox end view 'app/assets/javascripts/deploy_keys/components/app.vue' do @@ -59,6 +60,10 @@ module QA end end + def allow_write_access + check_element :write_access_allowed_checkbox + end + private def within_project_deploy_keys diff --git a/qa/qa/page/project/settings/mirroring_repositories.rb b/qa/qa/page/project/settings/mirroring_repositories.rb index 831166f6373..995f57bfd5f 100644 --- a/qa/qa/page/project/settings/mirroring_repositories.rb +++ b/qa/qa/page/project/settings/mirroring_repositories.rb @@ -15,7 +15,9 @@ module QA element :mirror_repository_button element :mirror_repository_url element :mirror_last_update_at + element :mirror_error_badge element :mirrored_repository_row + element :copy_public_key_button end view 'app/views/projects/mirrors/_mirror_repos_form.html.haml' do @@ -26,6 +28,16 @@ module QA element :update_now_button end + view 'app/views/projects/mirrors/_ssh_host_keys.html.haml' do + element :detect_host_keys + element :fingerprints_list + end + + view 'app/views/projects/mirrors/_authentication_method.html.haml' do + element :authentication_method + element :password + end + def repository_url=(value) fill_element :mirror_repository_url_input, value end @@ -35,17 +47,35 @@ module QA end def mirror_direction=(value) - raise ArgumentError, "Mirror direction must be :push or :pull" unless [:push, :pull].include? value + raise ArgumentError, "Mirror direction must be 'Push' or 'Pull'" unless %w(Push Pull).include? value select_element(:mirror_direction, value) end def authentication_method=(value) - raise ArgumentError, "Authentication method must be :password or :none" unless [:password, :none].include? value + raise ArgumentError, "Authentication method must be 'SSH public key', 'Password', or 'None'" unless %w(Password None SSH\ public\ key).include? value select_element(:authentication_method, value) end + def public_key(url) + row_index = find_repository_row_index url + + within_element_by_index(:mirrored_repository_row, row_index) do + find_element(:copy_public_key_button)['data-clipboard-text'] + end + end + + def detect_host_keys + click_element :detect_host_keys + + # The host key detection process is interrupted if we navigate away + # from the page before the fingerprint appears. + wait(max: 5) do + find_element(:fingerprints_list).has_text? /.*/ + end + end + def mirror_repository click_element :mirror_repository_button end @@ -72,16 +102,19 @@ module QA # Fail early if the page still shows that there has been no update within_element_by_index(:mirrored_repository_row, row_index) do find_element(:mirror_last_update_at, wait: 0).assert_no_text('Never') + assert_no_element(:mirror_error_badge) end end private def find_repository_row_index(target_url) - all_elements(:mirror_repository_url).index do |url| - # The url might be a sanitized url but the target_url won't be so - # we compare just the paths instead of the full url - URI.parse(url.text).path == target_url.path + wait(max: 5, reload: false) do + all_elements(:mirror_repository_url).index do |url| + # The url might be a sanitized url but the target_url won't be so + # we compare just the paths instead of the full url + URI.parse(url.text).path == target_url.path + end end end end diff --git a/qa/qa/page/project/settings/repository.rb b/qa/qa/page/project/settings/repository.rb index 437a945aceb..27f05c043f8 100644 --- a/qa/qa/page/project/settings/repository.rb +++ b/qa/qa/page/project/settings/repository.rb @@ -16,7 +16,7 @@ module QA end view 'app/views/projects/mirrors/_mirror_repos.html.haml' do - element :mirroring_repositories_settings + element :mirroring_repositories_settings_section end def expand_deploy_keys(&block) @@ -38,7 +38,7 @@ module QA end def expand_mirroring_repositories(&block) - expand_section(:mirroring_repositories_settings) do + expand_section(:mirroring_repositories_settings_section) do MirroringRepositories.perform(&block) end end diff --git a/qa/qa/resource/deploy_key.rb b/qa/qa/resource/deploy_key.rb index 869e2a71e47..25ea32ce303 100644 --- a/qa/qa/resource/deploy_key.rb +++ b/qa/qa/resource/deploy_key.rb @@ -3,7 +3,7 @@ module QA module Resource class DeployKey < Base - attr_accessor :title, :key + attr_accessor :title, :key, :allow_write_access attribute :fingerprint do Page::Project::Settings::Repository.perform do |setting| @@ -29,6 +29,7 @@ module QA setting.expand_deploy_keys do |page| page.fill_key_title(title) page.fill_key_value(key) + page.allow_write_access if allow_write_access page.add_key end diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb index 448d4980727..059362704b4 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb @@ -25,8 +25,8 @@ module QA settings.expand_mirroring_repositories do |mirror_settings| # Configure the source project to push to the target project mirror_settings.repository_url = target_project_uri - mirror_settings.mirror_direction = :push - mirror_settings.authentication_method = :password + mirror_settings.mirror_direction = 'Push' + mirror_settings.authentication_method = 'Password' mirror_settings.password = Runtime::User.password mirror_settings.mirror_repository mirror_settings.update target_project_uri diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_ssh_with_key_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_ssh_with_key_spec.rb new file mode 100644 index 00000000000..8b0f716ee08 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_ssh_with_key_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module QA + context 'Create' do + describe 'Push mirror a repository over SSH with a private key' do + it 'configures and syncs a (push) mirrored repository' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.perform(&:sign_in_using_credentials) + + target_project = Resource::Project.fabricate! do |project| + project.name = 'push-mirror-target-project' + end + target_project_uri = target_project.repository_ssh_location.uri + + source_project_push = Resource::Repository::ProjectPush.fabricate! do |push| + push.file_name = 'README.md' + push.file_content = '# This is a test project' + push.commit_message = 'Add README.md' + end + source_project_push.project.visit! + + # Configure the source project to push to the target project and get + # the public key to be used as a deploy key + Page::Project::Menu.perform(&:go_to_repository_settings) + public_key = Page::Project::Settings::Repository.perform do |settings| + settings.expand_mirroring_repositories do |mirror_settings| + mirror_settings.repository_url = target_project_uri + mirror_settings.mirror_direction = 'Push' + mirror_settings.authentication_method = 'SSH public key' + mirror_settings.detect_host_keys + mirror_settings.mirror_repository + mirror_settings.public_key target_project_uri + end + end + + # Add the public key to the target project as a deploy key + Resource::DeployKey.fabricate! do |resource| + resource.project = target_project + resource.title = "push mirror key #{Time.now.to_f}" + resource.key = public_key + resource.allow_write_access = true + end + + # Sync the repositories + source_project_push.project.visit! + Page::Project::Menu.perform(&:go_to_repository_settings) + Page::Project::Settings::Repository.perform do |settings| + settings.expand_mirroring_repositories do |mirror_settings| + mirror_settings.update target_project_uri + end + end + + # Check that the target project has the commit from the source + target_project.visit! + expect(page).to have_content('README.md') + expect(page).to have_content('This is a test project') + end + end + end +end diff --git a/qa/qa/support/page/logging.rb b/qa/qa/support/page/logging.rb index 93d8fa99c0a..606e8d7be93 100644 --- a/qa/qa/support/page/logging.rb +++ b/qa/qa/support/page/logging.rb @@ -4,6 +4,12 @@ module QA module Support module Page module Logging + def assert_no_element(name) + log("asserting no element :#{name}") + + super + end + def refresh log("refreshing #{current_url}") |