diff options
63 files changed, 516 insertions, 124 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4e8453726a3..1ea9ce1f497 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -388,13 +388,11 @@ flaky-examples-check: .assets-compile-cache: &assets-compile-cache cache: - key: "assets-compile:vendor_ruby:.yarn-cache:tmp_cache_assets_sprockets:v4" + key: "assets-compile:vendor_ruby:.yarn-cache:tmp_cache_assets_sprockets:v5" paths: - vendor/ruby/ - .yarn-cache/ - # We have disabled caching of sprockets for now, as it fails to pick up changes in SCSS: - # https://gitlab.com/gitlab-org/gitlab-ce/issues/57431 - # - tmp/cache/assets/sprockets + - tmp/cache/assets/sprockets compile-assets: <<: *dedicated-runner diff --git a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue index 74faa35358d..1ec2784cc5a 100644 --- a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue +++ b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue @@ -134,6 +134,13 @@ export default { >ms / <span title="Invoke Count">{{ currentRequest.details.gc.invokes }}</span> gc </span> </div> + <div + v-if="currentRequest.details && currentRequest.details.tracing" + id="peek-view-trace" + class="view" + > + <a :href="currentRequest.details.tracing.tracing_url"> trace </a> + </div> <request-selector v-if="currentRequest" :current-request="currentRequest" diff --git a/app/assets/javascripts/vue_shared/components/pikaday.vue b/app/assets/javascripts/vue_shared/components/pikaday.vue index 13eb46437dd..fa502b9beb9 100644 --- a/app/assets/javascripts/vue_shared/components/pikaday.vue +++ b/app/assets/javascripts/vue_shared/components/pikaday.vue @@ -1,6 +1,7 @@ <script> import Pikaday from 'pikaday'; import { parsePikadayDate, pikadayToString } from '~/lib/utils/datetime_utility'; +import { __ } from '~/locale'; export default { name: 'DatePicker', @@ -8,7 +9,7 @@ export default { label: { type: String, required: false, - default: 'Date picker', + default: __('Date picker'), }, selectedDate: { type: Date, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue b/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue index 6c0c7f15943..45f01a6fced 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue @@ -4,6 +4,7 @@ import datePicker from '../pikaday.vue'; import toggleSidebar from './toggle_sidebar.vue'; import collapsedCalendarIcon from './collapsed_calendar_icon.vue'; import { dateInWords } from '../../../lib/utils/datetime_utility'; +import { __ } from '~/locale'; export default { name: 'SidebarDatePicker', @@ -42,7 +43,7 @@ export default { label: { type: String, required: false, - default: 'Date picker', + default: __('Date picker'), }, selectedDate: { type: Date, diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb index c8969351ed9..46d0898014e 100644 --- a/app/models/clusters/platforms/kubernetes.rb +++ b/app/models/clusters/platforms/kubernetes.rb @@ -43,6 +43,7 @@ module Clusters # We expect to be `active?` only when enabled and cluster is created (the api_url is assigned) validates :api_url, url: true, presence: true validates :token, presence: true + validates :ca_cert, certificate: true, allow_blank: true, if: :ca_cert_changed? validate :prevent_modification, on: :update diff --git a/changelogs/unreleased/55447-validate-k8s-ca-cert.yml b/changelogs/unreleased/55447-validate-k8s-ca-cert.yml new file mode 100644 index 00000000000..e0448d403da --- /dev/null +++ b/changelogs/unreleased/55447-validate-k8s-ca-cert.yml @@ -0,0 +1,5 @@ +--- +title: Validate kubernetes cluster CA certificate +merge_request: 24990 +author: +type: changed diff --git a/changelogs/unreleased/an-peek-jaeger.yml b/changelogs/unreleased/an-peek-jaeger.yml new file mode 100644 index 00000000000..8659ee4f9e0 --- /dev/null +++ b/changelogs/unreleased/an-peek-jaeger.yml @@ -0,0 +1,5 @@ +--- +title: Provide a performance bar link to the Jaeger UI +merge_request: 24902 +author: +type: other diff --git a/config/initializers/peek.rb b/config/initializers/peek.rb index a6f43415ec5..e051e5c68c4 100644 --- a/config/initializers/peek.rb +++ b/config/initializers/peek.rb @@ -19,6 +19,7 @@ Peek.into Peek::Views::Gitaly Peek.into Peek::Views::Rblineprof Peek.into Peek::Views::Redis Peek.into Peek::Views::GC +Peek.into Peek::Views::Tracing if Gitlab::Tracing.tracing_url_enabled? # rubocop:disable Naming/ClassAndModuleCamelCase class PEEK_DB_CLIENT diff --git a/config/initializers/zz_metrics.rb b/config/initializers/zz_metrics.rb index 462e8c811a6..151cad3ef9a 100644 --- a/config/initializers/zz_metrics.rb +++ b/config/initializers/zz_metrics.rb @@ -173,7 +173,7 @@ if Gitlab::Metrics.enabled? && !Rails.env.test? && !(Rails.env.development? && d def connect(*args) val = super - if current_transaction = Gitlab::Metrics::Transaction.current + if current_transaction = ::Gitlab::Metrics::Transaction.current current_transaction.increment(:new_redis_connections, 1) end diff --git a/doc/administration/restart_gitlab.md b/doc/administration/restart_gitlab.md index b561c2f82aa..7d245b3effd 100644 --- a/doc/administration/restart_gitlab.md +++ b/doc/administration/restart_gitlab.md @@ -62,7 +62,8 @@ sudo gitlab-ctl status Notice that all services say `ok: run`. -Sometimes, components time out during the restart and sometimes they get stuck. +Sometimes, components time out (look for `timeout` in the logs) during the +restart and sometimes they get stuck. In that case, you can use `gitlab-ctl kill <service>` to send the `SIGKILL` signal to the service, for example `sidekiq`. After that, a restart should perform fine. diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md index aac98c6ee7f..287a472d0d8 100644 --- a/doc/development/documentation/index.md +++ b/doc/development/documentation/index.md @@ -12,7 +12,7 @@ In addition to this page, the following resources to help craft and contribute d - [Structure and template](structure.md) - Learn the typical parts of a doc page and how to write each one. - [Workflow](workflow.md) - A landing page for our key workflows: - [Feature-change documentation workflow](feature-change-workflow.md) - Adding required documentation when developing a GitLab feature. - - [Documentation improvement worflow](improvement-workflow.md) - New content not associated with a new feature. + - [Documentation improvement workflow](improvement-workflow.md) - New content not associated with a new feature. - [Markdown Guide](https://about.gitlab.com/handbook/product/technical-writing/markdown-guide/) - A reference for the markdown implementation used by GitLab's documentation site and about.gitlab.com. - [Site architecture](site_architecture/index.md) - How docs.gitlab.com is built. diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md index 463bdd59282..91be3e3d45d 100644 --- a/doc/topics/autodevops/index.md +++ b/doc/topics/autodevops/index.md @@ -128,7 +128,7 @@ Auto Deploy, and Auto Monitoring will be silently skipped. NOTE: **Note** `AUTO_DEVOPS_DOMAIN` environment variable is deprecated and -[is scheduled to be removed](https://gitlab.com/gitlab-org/gitlab-ce/issues/56959) in GitLab 12.0. +[is scheduled to be removed](https://gitlab.com/gitlab-org/gitlab-ce/issues/56959). The Auto DevOps base domain is required if you want to make use of [Auto Review Apps](#auto-review-apps) and [Auto Deploy](#auto-deploy). It can be defined @@ -211,8 +211,7 @@ other environments. NOTE: **Note:** From GitLab 11.8, `KUBE_INGRESS_BASE_DOMAIN` replaces `AUTO_DEVOPS_DOMAIN`. -`AUTO_DEVOPS_DOMAIN` [is scheduled to be removed](https://gitlab.com/gitlab-org/gitlab-ce/issues/56959) -in GitLab 12.0. +`AUTO_DEVOPS_DOMAIN` [is scheduled to be removed](https://gitlab.com/gitlab-org/gitlab-ce/issues/56959). ## Enabling/Disabling Auto DevOps @@ -685,7 +684,7 @@ also be customized, and you can easily use a [custom buildpack](#custom-buildpac | **Variable** | **Description** | | ------------ | --------------- | -| `AUTO_DEVOPS_DOMAIN` | The [Auto DevOps domain](#auto-devops-domain). By default, set automatically by the [Auto DevOps setting](#enabling-auto-devops). This variable is deprecated and [is scheduled to be removed](https://gitlab.com/gitlab-org/gitlab-ce/issues/56959) in GitLab 12.0. Use `KUBE_INGRESS_BASE_DOMAIN` instead. | +| `AUTO_DEVOPS_DOMAIN` | The [Auto DevOps domain](#auto-devops-domain). By default, set automatically by the [Auto DevOps setting](#enabling-auto-devops). This variable is deprecated and [is scheduled to be removed](https://gitlab.com/gitlab-org/gitlab-ce/issues/56959). Use `KUBE_INGRESS_BASE_DOMAIN` instead. | | `AUTO_DEVOPS_CHART` | The Helm Chart used to deploy your apps; defaults to the one [provided by GitLab](https://gitlab.com/charts/auto-deploy-app). | | `AUTO_DEVOPS_CHART_REPOSITORY` | The Helm Chart repository used to search for charts; defaults to `https://charts.gitlab.io`. | | `REPLICAS` | The number of replicas to deploy; defaults to 1. | diff --git a/lib/gitlab/patch/sprockets_base_file_digest_key.rb b/lib/gitlab/patch/sprockets_base_file_digest_key.rb index 3925cdbbada..1c472638145 100644 --- a/lib/gitlab/patch/sprockets_base_file_digest_key.rb +++ b/lib/gitlab/patch/sprockets_base_file_digest_key.rb @@ -9,7 +9,7 @@ module Gitlab def file_digest(path) if stat = self.stat(path) digest = self.stat_digest(path, stat) - integrity_uri = self.hexdigest_integrity_uri(digest) + integrity_uri = self.integrity_uri(digest) key = Sprockets::UnloadedAsset.new(path, self).file_digest_key(integrity_uri) cache.fetch(key) do diff --git a/lib/gitlab/tracing.rb b/lib/gitlab/tracing.rb index 3c4db42ac06..0d9b0be1c8e 100644 --- a/lib/gitlab/tracing.rb +++ b/lib/gitlab/tracing.rb @@ -13,5 +13,24 @@ module Gitlab def self.connection_string ENV['GITLAB_TRACING'] end + + def self.tracing_url_template + ENV['GITLAB_TRACING_URL'] + end + + def self.tracing_url_enabled? + enabled? && tracing_url_template.present? + end + + # This will provide a link into the distributed tracing for the current trace, + # if it has been captured. + def self.tracing_url + return unless tracing_url_enabled? + + tracing_url_template % { + correlation_id: Gitlab::CorrelationId.current_id.to_s, + service: Gitlab.process_name + } + end end end diff --git a/lib/peek/views/tracing.rb b/lib/peek/views/tracing.rb new file mode 100644 index 00000000000..0de32a8fdda --- /dev/null +++ b/lib/peek/views/tracing.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Peek + module Views + class Tracing < View + def results + { + tracing_url: Gitlab::Tracing.tracing_url + } + end + end + end +end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index c3349980d60..8d7ed7a5b88 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2501,6 +2501,9 @@ msgstr "" msgid "Data is still calculating..." msgstr "" +msgid "Date picker" +msgstr "" + msgid "Debug" msgstr "" @@ -62,6 +62,11 @@ module QA autoload :Fork, 'qa/resource/fork' autoload :SSHKey, 'qa/resource/ssh_key' + module Events + autoload :Base, 'qa/resource/events/base' + autoload :Project, 'qa/resource/events/project' + end + module Repository autoload :Push, 'qa/resource/repository/push' autoload :ProjectPush, 'qa/resource/repository/project_push' @@ -361,6 +366,7 @@ module QA autoload :Logging, 'qa/support/page/logging' end autoload :Api, 'qa/support/api' + autoload :Waiter, 'qa/support/waiter' end end diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb index b1f27131207..69a8e691ceb 100644 --- a/qa/qa/page/base.rb +++ b/qa/qa/page/base.rb @@ -18,19 +18,10 @@ module QA page.refresh end - def wait(max: 60, time: 0.1, reload: true) - start = Time.now - - while Time.now - start < max - result = yield - return result if result - - sleep(time) - - refresh if reload + def wait(max: 60, interval: 0.1, reload: true) + QA::Support::Waiter.wait(max: max, interval: interval) do + yield || (reload && refresh && false) end - - false end def with_retry(max_attempts: 3, reload: false) @@ -73,7 +64,7 @@ module QA xhr.send(); JS - return false unless wait(time: 0.5, max: 60, reload: false) do + return false unless wait(interval: 0.5, max: 60, reload: false) do page.evaluate_script('xhr.readyState == XMLHttpRequest.DONE') end diff --git a/qa/qa/page/component/clone_panel.rb b/qa/qa/page/component/clone_panel.rb index d37b63c716a..b80877f5ecd 100644 --- a/qa/qa/page/component/clone_panel.rb +++ b/qa/qa/page/component/clone_panel.rb @@ -21,11 +21,6 @@ module QA repository_clone_location(:ssh_clone_url) end - def wait_for_push - sleep 5 - refresh - end - private def repository_clone_location(kind) diff --git a/qa/qa/page/component/legacy_clone_panel.rb b/qa/qa/page/component/legacy_clone_panel.rb index 99132190f3f..e495cf4ef04 100644 --- a/qa/qa/page/component/legacy_clone_panel.rb +++ b/qa/qa/page/component/legacy_clone_panel.rb @@ -27,11 +27,6 @@ module QA Git::Location.new(find('#project_clone').value) end - def wait_for_push - sleep 5 - refresh - end - private def choose_repository_clone(kind, detect_text) diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb index f54bea880a0..976e431186d 100644 --- a/qa/qa/page/merge_request/show.rb +++ b/qa/qa/page/merge_request/show.rb @@ -148,7 +148,7 @@ module QA end def add_comment_to_diff(text) - wait(time: 5) do + wait(interval: 5) do has_text?("No newline at end of file") end all_elements(:new_diff_line).first.hover diff --git a/qa/qa/page/project/new.rb b/qa/qa/page/project/new.rb index a588af07e4a..9f1867ef8a5 100644 --- a/qa/qa/page/project/new.rb +++ b/qa/qa/page/project/new.rb @@ -26,7 +26,7 @@ module QA def choose_test_namespace click_element :project_namespace_select - select_item(Runtime::Namespace.path) + search_and_select(Runtime::Namespace.path) end def go_to_import_project diff --git a/qa/qa/page/project/settings/mirroring_repositories.rb b/qa/qa/page/project/settings/mirroring_repositories.rb index a73be7dfeda..831166f6373 100644 --- a/qa/qa/page/project/settings/mirroring_repositories.rb +++ b/qa/qa/page/project/settings/mirroring_repositories.rb @@ -62,7 +62,7 @@ module QA sleep 5 refresh - wait(time: 1) do + wait(interval: 1) do within_element_by_index(:mirrored_repository_row, row_index) do last_update = find_element(:mirror_last_update_at, wait: 0) last_update.has_text?('just now') || last_update.has_text?('seconds') diff --git a/qa/qa/resource/base.rb b/qa/qa/resource/base.rb index ffe8633dd16..523d92c7ef3 100644 --- a/qa/qa/resource/base.rb +++ b/qa/qa/resource/base.rb @@ -27,6 +27,10 @@ module QA attributes.each(&method(:public_send)) end + def wait(max: 60, interval: 0.1) + QA::Support::Waiter.wait(max: max, interval: interval) + end + private def populate_attribute(name, block) diff --git a/qa/qa/resource/events/base.rb b/qa/qa/resource/events/base.rb new file mode 100644 index 00000000000..b50b620b143 --- /dev/null +++ b/qa/qa/resource/events/base.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module QA + module Resource + module Events + MAX_WAIT = 10 + + EventNotFoundError = Class.new(RuntimeError) + + module Base + def events(action: nil) + path = [api_get_events] + path << "?action=#{CGI.escape(action)}" if action + parse_body(api_get_from("#{path.join}")) + end + + private + + def api_get_events + "#{api_get_path}/events" + end + + def wait_for_event + event_found = QA::Support::Waiter.wait(max: max_wait) do + yield + end + + raise EventNotFoundError, "Timed out waiting for event" unless event_found + end + + def max_wait + MAX_WAIT + end + end + end + end +end diff --git a/qa/qa/resource/events/project.rb b/qa/qa/resource/events/project.rb new file mode 100644 index 00000000000..99c78254f42 --- /dev/null +++ b/qa/qa/resource/events/project.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module QA + module Resource + module Events + module Project + include Events::Base + + def wait_for_push(commit_message) + QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_push with commit message "#{commit_message}"]) + wait_for_event do + events(action: 'pushed').any? { |event| event.dig(:push_data, :commit_title) == commit_message } + end + end + + def wait_for_push_new_branch(branch_name = "master") + QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_push_new_branch with branch_name "#{branch_name}"]) + wait_for_event do + events(action: 'pushed').any? { |event| event.dig(:push_data, :ref) == branch_name } + end + end + end + end + end +end diff --git a/qa/qa/resource/fork.rb b/qa/qa/resource/fork.rb index c6243ff43fa..03bc1f0820b 100644 --- a/qa/qa/resource/fork.rb +++ b/qa/qa/resource/fork.rb @@ -5,12 +5,12 @@ module QA class Fork < Base attribute :project do Resource::Project.fabricate! do |resource| - resource.name = push.project.name - resource.path_with_namespace = "#{user.name}/#{push.project.name}" + resource.name = upstream.project.name + resource.path_with_namespace = "#{user.name}/#{upstream.project.name}" end end - attribute :push do + attribute :upstream do Repository::ProjectPush.fabricate! end @@ -24,7 +24,7 @@ module QA end def fabricate! - populate(:push, :user) + populate(:upstream, :user) # Sign out as admin and sign is as the fork user Page::Main::Menu.perform(&:sign_out) @@ -33,7 +33,7 @@ module QA login.sign_in_using_credentials(user) end - push.project.visit! + upstream.project.visit! Page::Project::Show.perform(&:fork_project) diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb index a7a6f931e28..d7f9ec6a836 100644 --- a/qa/qa/resource/group.rb +++ b/qa/qa/resource/group.rb @@ -33,7 +33,7 @@ module QA end # Ensure that the group was actually created - group_show.wait(time: 1) do + group_show.wait(interval: 1) do group_show.has_text?(path) && group_show.has_new_project_or_subgroup_dropdown? end diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb index 7150098a00a..45cb317e0eb 100644 --- a/qa/qa/resource/merge_request.rb +++ b/qa/qa/resource/merge_request.rb @@ -58,10 +58,7 @@ module QA populate(:target, :source) project.visit! - Page::Project::Show.perform do |project| - project.wait_for_push - project.new_merge_request - end + Page::Project::Show.perform(&:new_merge_request) Page::MergeRequest::New.perform do |page| page.fill_title(@title) page.fill_description(@description) diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb index 433e5a8f7c9..de1e9f04c36 100644 --- a/qa/qa/resource/project.rb +++ b/qa/qa/resource/project.rb @@ -5,6 +5,8 @@ require 'securerandom' module QA module Resource class Project < Base + include Events::Project + attribute :name attribute :description diff --git a/qa/qa/resource/repository/project_push.rb b/qa/qa/resource/repository/project_push.rb index f4692c3dd4d..cad89ebb0bb 100644 --- a/qa/qa/resource/repository/project_push.rb +++ b/qa/qa/resource/repository/project_push.rb @@ -4,6 +4,8 @@ module QA module Resource module Repository class ProjectPush < Repository::Push + attr_writer :wait_for_push + attribute :project do Project.fabricate! do |resource| resource.name = 'project-with-code' @@ -17,6 +19,7 @@ module QA @commit_message = "This is a test commit" @branch_name = 'master' @new_branch = true + @wait_for_push = true end def repository_http_uri @@ -30,6 +33,7 @@ module QA def fabricate! super project.visit! + project.wait_for_push @commit_message if @wait_for_push end end end diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb index 545da0a8b85..60836a7b98d 100644 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb @@ -26,7 +26,6 @@ module QA push.file_content = "Test with unicode characters ❤✓€❄" end - Page::Project::Show.perform(&:wait_for_push) merge_request.visit! expect(page).to have_text('to be squashed') @@ -38,9 +37,7 @@ module QA merge_request.project.visit! Git::Repository.perform do |repository| - repository.uri = Page::Project::Show.act do - repository_clone_http_location.uri - end + repository.uri = merge_request.project.repository_http_location.uri repository.use_default_credentials diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb index 3567ddca1a1..8e181eb28c6 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb @@ -23,7 +23,6 @@ module QA proj.name = 'project-qa-test' proj.description = 'project for qa test' end - project.visit! Git::Repository.perform do |repository| repository.uri = project.repository_http_location.uri @@ -53,7 +52,8 @@ module QA push_changes(third_branch) end end - Page::Project::Show.perform(&:wait_for_push) + project.wait_for_push commit_message_of_third_branch + project.visit! end it 'branches are correctly listed after CRUD operations' do diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb index 571cae4a3c5..f2584f55a60 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb @@ -3,22 +3,18 @@ module QA context 'Create' do describe 'Git clone over HTTP', :ldap_no_tls do - let(:location) do - Page::Project::Show.perform(&:repository_clone_http_location).uri - end - - before do + before(:all) do Runtime::Browser.visit(:gitlab, Page::Main::Login) Page::Main::Login.perform(&:sign_in_using_credentials) - project = Resource::Project.fabricate! do |scenario| + @project = Resource::Project.fabricate! do |scenario| scenario.name = 'project-with-code' scenario.description = 'project for git clone tests' end - project.visit! + @project.visit! Git::Repository.perform do |repository| - repository.uri = location + repository.uri = @project.repository_http_location.uri repository.use_default_credentials repository.act do @@ -29,12 +25,12 @@ module QA push_changes end end - Page::Project::Show.perform(&:wait_for_push) + @project.wait_for_push_new_branch end it 'user performs a deep clone' do Git::Repository.perform do |repository| - repository.uri = location + repository.uri = @project.repository_http_location.uri repository.use_default_credentials repository.clone @@ -45,7 +41,7 @@ module QA it 'user performs a shallow clone' do Git::Repository.perform do |repository| - repository.uri = location + repository.uri = @project.repository_http_location.uri repository.use_default_credentials repository.shallow_clone diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb index 43894372cf5..d1535d6519d 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb @@ -35,7 +35,7 @@ module QA end project.visit! - Page::Project::Show.perform(&:wait_for_push) + project.wait_for_push_new_branch # Check that the push worked expect(page).to have_content(file_name) diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb index 135925c007f..48800cc81e5 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb @@ -70,7 +70,7 @@ module QA end project.visit! - Page::Project::Show.perform(&:wait_for_push) + project.wait_for_push_new_branch # Check that the push worked expect(page).to have_content(file_name) diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb index 73f020e7d05..1f4fb08accc 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb @@ -23,10 +23,7 @@ module QA push.project.visit! - Page::Project::Show.perform do |page| - page.wait_for_push - page.wait_for_viewers_to_load - end + Page::Project::Show.perform(&:wait_for_viewers_to_load) expect(page).to have_content('README.md') expect(page).to have_content('This is a test project') 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 9d31a25ab35..2e4915b898d 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 @@ -20,8 +20,6 @@ module QA end source_project_push.project.visit! - Page::Project::Show.perform(&:wait_for_push) - Page::Project::Menu.perform(&:click_repository_settings) Page::Project::Settings::Repository.perform do |settings| settings.expand_mirroring_repositories do |mirror_settings| diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb index 23ea55c2e61..7d96da32423 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb @@ -31,7 +31,7 @@ module QA set_file_size_limit(5) expect(page).to have_content("Application settings saved successfully") - push = push_new_file('oversize_file_1.bin') + push = push_new_file('oversize_file_1.bin', wait_for_push: true) expect(push.output).not_to have_content 'remote: fatal: pack exceeds maximum allowed size' end @@ -39,7 +39,7 @@ module QA set_file_size_limit(1) expect(page).to have_content("Application settings saved successfully") - push = push_new_file('oversize_file_2.bin') + push = push_new_file('oversize_file_2.bin', wait_for_push: false) expect(push.output).to have_content 'remote: fatal: pack exceeds maximum allowed size' end @@ -55,7 +55,7 @@ module QA end end - def push_new_file(file_name) + def push_new_file(file_name, wait_for_push: true) @project.visit! Resource::Repository::ProjectPush.fabricate! do |p| @@ -63,6 +63,7 @@ module QA p.file_name = file_name p.file_content = SecureRandom.random_bytes(2000000) p.commit_message = 'Adding a new file' + p.wait_for_push = wait_for_push end end end diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb index d10ad896b3b..58e6c160a3a 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb @@ -5,7 +5,7 @@ module QA describe 'Git push over HTTP', :ldap_no_tls do it 'user pushes code to the repository' do Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } + Page::Main::Login.perform(&:sign_in_using_credentials) project_push = Resource::Repository::ProjectPush.fabricate! do |push| push.file_name = 'README.md' @@ -13,7 +13,6 @@ module QA push.commit_message = 'Add README.md' end project_push.project.visit! - Page::Project::Show.act { wait_for_push } expect(page).to have_content('README.md') expect(page).to have_content('This is a test project') diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb index 73a3dc14a65..4464fb812b7 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb @@ -63,6 +63,7 @@ module QA resource.commit_message = 'Add new_file.md' resource.branch_name = branch_name resource.new_branch = false + resource.wait_for_push = false 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 index 509a639c130..7223831d96f 100644 --- 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 @@ -10,7 +10,7 @@ module QA 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 } + Page::Main::Login.perform(&:sign_in_using_credentials) key = Resource::SSHKey.fabricate! do |resource| resource.title = key_title @@ -24,13 +24,12 @@ module QA end project_push.project.visit! - Page::Project::Show.act { wait_for_push } expect(page).to have_content('README.md') expect(page).to have_content('Test Use SSH Key') - Page::Main::Menu.act { go_to_profile_settings } - Page::Profile::Menu.act { click_ssh_keys } + Page::Main::Menu.perform(&:go_to_profile_settings) + Page::Profile::Menu.perform(&:click_ssh_keys) Page::Profile::SSHKeys.perform do |ssh_keys| ssh_keys.remove_key(key_title) diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb index 25cbe41c684..2238d6c382e 100644 --- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb @@ -11,7 +11,7 @@ module QA it 'users creates a pipeline which gets processed' do Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } + Page::Main::Login.perform(&:sign_in_using_credentials) project = Resource::Project.fabricate! do |project| project.name = 'project-with-pipelines' @@ -60,11 +60,9 @@ module QA EOF end - Page::Project::Show.act { wait_for_push } - expect(page).to have_content('Add .gitlab-ci.yml') - Page::Project::Menu.act { click_ci_cd_pipelines } + Page::Project::Menu.perform(&:click_ci_cd_pipelines) expect(page).to have_content('All 1') expect(page).to have_content('Add .gitlab-ci.yml') @@ -72,7 +70,7 @@ module QA puts 'Waiting for the runner to process the pipeline' sleep 15 # Runner should process all jobs within 15 seconds. - Page::Project::Pipeline::Index.act { go_to_latest_pipeline } + Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline) Page::Project::Pipeline::Show.perform do |pipeline| expect(pipeline).to be_running diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb index 97d36095a69..2375aa4ce91 100644 --- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb +++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb @@ -8,7 +8,7 @@ module QA describe 'Git clone using a deploy key' do def login Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } + Page::Main::Login.perform(&:sign_in_using_credentials) end before(:all) do @@ -29,7 +29,7 @@ module QA resource.image = 'gitlab/gitlab-runner:ubuntu' end - Page::Main::Menu.act { sign_out } + Page::Main::Menu.perform(&:sign_out) end after(:all) do @@ -90,10 +90,9 @@ module QA sha1sum = Digest::SHA1.hexdigest(gitlab_ci) - Page::Project::Show.act { wait_for_push } - Page::Project::Menu.act { click_ci_cd_pipelines } - Page::Project::Pipeline::Index.act { go_to_latest_pipeline } - Page::Project::Pipeline::Show.act { go_to_first_job } + Page::Project::Menu.perform(&:click_ci_cd_pipelines) + Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline) + Page::Project::Pipeline::Show.perform(&:go_to_first_job) Page::Project::Job::Show.perform do |job| expect(job).to be_successful, "Job status did not become \"passed\"." diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb index 5c8ec465143..8cd353fa250 100644 --- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb +++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb @@ -8,7 +8,7 @@ module QA describe 'Auto DevOps support' do def login Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } + Page::Main::Login.perform(&:sign_in_using_credentials) end [true, false].each do |rbac| @@ -38,8 +38,6 @@ module QA push.commit_message = 'Create Auto DevOps compatible rack application' end - Page::Project::Show.act { wait_for_push } - # Create and connect K8s cluster @cluster = Service::KubernetesCluster.new(rbac: rbac).create! kubernetes_cluster = Resource::KubernetesCluster.fabricate! do |cluster| @@ -53,7 +51,7 @@ module QA kubernetes_cluster.populate(:ingress_ip) @project.visit! - Page::Project::Menu.act { click_ci_cd_settings } + Page::Project::Menu.perform(&:click_ci_cd_settings) Page::Project::Settings::CICD.perform do |p| p.enable_auto_devops end @@ -71,8 +69,8 @@ module QA it 'runs auto devops' do @project.visit! - Page::Project::Menu.act { click_ci_cd_pipelines } - Page::Project::Pipeline::Index.act { go_to_latest_pipeline } + Page::Project::Menu.perform(&:click_ci_cd_pipelines) + Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline) Page::Project::Pipeline::Show.perform do |pipeline| pipeline.go_to_job('build') @@ -101,7 +99,7 @@ module QA job.click_element(:pipeline_path) end - Page::Project::Menu.act { click_operations_environments } + Page::Project::Menu.perform(&:click_operations_environments) Page::Project::Operations::Environments::Index.perform do |index| index.go_to_environment('production') end @@ -132,8 +130,8 @@ module QA end @project.visit! - Page::Project::Menu.act { click_ci_cd_pipelines } - Page::Project::Pipeline::Index.act { go_to_latest_pipeline } + Page::Project::Menu.perform(&:click_ci_cd_pipelines) + Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline) Page::Project::Pipeline::Show.perform do |pipeline| pipeline.go_to_job('build') @@ -162,7 +160,7 @@ module QA job.click_element(:pipeline_path) end - Page::Project::Menu.act { click_operations_environments } + Page::Project::Menu.perform(&:click_operations_environments) Page::Project::Operations::Environments::Index.perform do |index| index.go_to_environment('production') diff --git a/qa/qa/support/page/logging.rb b/qa/qa/support/page/logging.rb index f2cd0194b6b..5e97a92a6e3 100644 --- a/qa/qa/support/page/logging.rb +++ b/qa/qa/support/page/logging.rb @@ -10,15 +10,11 @@ module QA super end - def wait(max: 60, time: 0.1, reload: true) - log("with wait: max #{max}; time #{time}; reload #{reload}") - now = Time.now - - element = super + def wait(max: 60, interval: 0.1, reload: true) + log("next wait uses reload: #{reload}") + # Logging of wait start/end/duration is handled by QA::Support::Waiter - log("ended wait after #{Time.now - now} seconds") - - element + super end def scroll_to(selector, text: nil) diff --git a/qa/qa/support/waiter.rb b/qa/qa/support/waiter.rb new file mode 100644 index 00000000000..21a399b4a5f --- /dev/null +++ b/qa/qa/support/waiter.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module QA + module Support + module Waiter + module_function + + def wait(max: 60, interval: 0.1) + QA::Runtime::Logger.debug("with wait: max #{max}; interval #{interval}") + start = Time.now + + while Time.now - start < max + result = yield + if result + log_end(Time.now - start) + return result + end + + sleep(interval) + end + log_end(Time.now - start) + + false + end + + def self.log_end(duration) + QA::Runtime::Logger.debug("ended wait after #{duration} seconds") + end + end + end +end diff --git a/qa/spec/git/repository_spec.rb b/qa/spec/git/repository_spec.rb index 4a350cd6c42..62c81050bd9 100644 --- a/qa/spec/git/repository_spec.rb +++ b/qa/spec/git/repository_spec.rb @@ -1,5 +1,5 @@ describe QA::Git::Repository do - include Support::StubENV + include Helpers::StubENV shared_context 'git directory' do let(:repository) { described_class.new } diff --git a/qa/spec/support/stub_env.rb b/qa/spec/helpers/stub_env.rb index 4788e0ab46c..62b4a1df787 100644 --- a/qa/spec/support/stub_env.rb +++ b/qa/spec/helpers/stub_env.rb @@ -1,5 +1,5 @@ # Inspired by https://github.com/ljkbennett/stub_env/blob/master/lib/stub_env/helpers.rb -module Support +module Helpers module StubENV def stub_env(key_or_hash, value = nil) init_stub unless env_stubbed? diff --git a/qa/spec/page/base_spec.rb b/qa/spec/page/base_spec.rb index 076a8087db5..32a350f2154 100644 --- a/qa/spec/page/base_spec.rb +++ b/qa/spec/page/base_spec.rb @@ -59,4 +59,34 @@ describe QA::Page::Base do end end end + + describe '#wait' do + subject { Class.new(described_class).new } + + context 'when the condition is true' do + it 'does not refresh' do + expect(subject).not_to receive(:refresh) + + subject.wait(max: 0.01) { true } + end + + it 'returns true' do + expect(subject.wait(max: 0.1) { true }).to be_truthy + end + end + + context 'when the condition is false' do + it 'refreshes' do + expect(subject).to receive(:refresh).at_least(:once) + + subject.wait(max: 0.01) { false } + end + + it 'returns false' do + allow(subject).to receive(:refresh) + + expect(subject.wait(max: 0.01) { false }).to be_falsey + end + end + end end diff --git a/qa/spec/page/logging_spec.rb b/qa/spec/page/logging_spec.rb index f289ee3c2bb..a6e9601cee4 100644 --- a/qa/spec/page/logging_spec.rb +++ b/qa/spec/page/logging_spec.rb @@ -4,8 +4,6 @@ require 'capybara/dsl' require 'logger' describe QA::Support::Page::Logging do - include Support::StubENV - let(:page) { double.as_null_object } before do @@ -31,11 +29,22 @@ describe QA::Support::Page::Logging do it 'logs wait' do expect { subject.wait(max: 0) {} } + .to output(/next wait uses reload: true/).to_stdout_from_any_process + expect { subject.wait(max: 0) {} } .to output(/with wait/).to_stdout_from_any_process expect { subject.wait(max: 0) {} } .to output(/ended wait after .* seconds$/).to_stdout_from_any_process end + it 'logs wait with reload false' do + expect { subject.wait(max: 0, reload: false) {} } + .to output(/next wait uses reload: false/).to_stdout_from_any_process + expect { subject.wait(max: 0, reload: false) {} } + .to output(/with wait/).to_stdout_from_any_process + expect { subject.wait(max: 0, reload: false) {} } + .to output(/ended wait after .* seconds$/).to_stdout_from_any_process + end + it 'logs scroll_to' do expect { subject.scroll_to(:element) } .to output(/scrolling to :element/).to_stdout_from_any_process diff --git a/qa/spec/resource/base_spec.rb b/qa/spec/resource/base_spec.rb index a2a3ad01749..4a6b76c869f 100644 --- a/qa/spec/resource/base_spec.rb +++ b/qa/spec/resource/base_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true describe QA::Resource::Base do - include Support::StubENV + include Helpers::StubENV let(:resource) { spy('resource') } let(:location) { 'http://location' } diff --git a/qa/spec/resource/events/base_spec.rb b/qa/spec/resource/events/base_spec.rb new file mode 100644 index 00000000000..9cdf4785092 --- /dev/null +++ b/qa/spec/resource/events/base_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +describe QA::Resource::Events::Base do + let(:resource) do + Class.new(QA::Resource::Base) do + def api_get_path + '/foo' + end + end + end + + subject { resource.tap { |f| f.include(described_class) }.new } + + describe "#events" do + it 'fetches all events when called without parameters' do + allow(subject).to receive(:parse_body).and_return('returned') + + expect(subject).to receive(:api_get_from).with('/foo/events') + expect(subject.events).to eq('returned') + end + + it 'fetches events with a specified action type' do + allow(subject).to receive(:parse_body).and_return('returned') + + expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed') + expect(subject.events(action: 'pushed')).to eq('returned') + end + end +end diff --git a/qa/spec/resource/events/project_spec.rb b/qa/spec/resource/events/project_spec.rb new file mode 100644 index 00000000000..b3efdb518f3 --- /dev/null +++ b/qa/spec/resource/events/project_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +describe QA::Resource::Events::Project do + let(:resource) do + Class.new(QA::Resource::Base) do + def api_get_path + '/foo' + end + end + end + let(:all_events) do + [ + { + "action_name": "pushed", + "push_data": { + "commit_title": "foo commit" + } + }, + { + "action_name": "pushed", + "push_data": { + "ref": "master" + } + }, + { + "action_name": "pushed", + "push_data": { + "ref": "another-branch" + } + } + ] + end + + before do + allow(subject).to receive(:max_wait).and_return(0.01) + allow(subject).to receive(:parse_body).and_return(all_events) + end + + subject { resource.tap { |f| f.include(described_class) }.new } + + describe "#wait_for_push" do + it 'waits for a push with a specified commit message' do + expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed') + expect { subject.wait_for_push('foo commit') }.not_to raise_error + end + + it 'raises an error if a push with the specified commit message is not found' do + expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed').at_least(:once) + expect { subject.wait_for_push('bar') }.to raise_error(QA::Resource::Events::EventNotFoundError) + end + end + + describe "#wait_for_push_new_branch" do + it 'waits for a push to master if no branch is given' do + expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed') + expect { subject.wait_for_push_new_branch }.not_to raise_error + end + + it 'waits for a push to the given branch' do + expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed') + expect { subject.wait_for_push_new_branch('another-branch') }.not_to raise_error + end + + it 'raises an error if a push with the specified branch is not found' do + expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed').at_least(:once) + expect { subject.wait_for_push_new_branch('bar') }.to raise_error(QA::Resource::Events::EventNotFoundError) + end + end +end diff --git a/qa/spec/runtime/api/client_spec.rb b/qa/spec/runtime/api/client_spec.rb index 975586b505f..af43facc73d 100644 --- a/qa/spec/runtime/api/client_spec.rb +++ b/qa/spec/runtime/api/client_spec.rb @@ -1,5 +1,5 @@ describe QA::Runtime::API::Client do - include Support::StubENV + include Helpers::StubENV describe 'initialization' do it 'defaults to :gitlab address' do diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb index bc0ec08d66d..fc51f45c3a1 100644 --- a/qa/spec/runtime/env_spec.rb +++ b/qa/spec/runtime/env_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true describe QA::Runtime::Env do - include Support::StubENV + include Helpers::StubENV shared_examples 'boolean method' do |**kwargs| it_behaves_like 'boolean method with parameter', kwargs diff --git a/qa/spec/support/shared_examples/scenario_shared_examples.rb b/qa/spec/shared_examples/scenario_shared_examples.rb index 5fd55d7d96b..5fd55d7d96b 100644 --- a/qa/spec/support/shared_examples/scenario_shared_examples.rb +++ b/qa/spec/shared_examples/scenario_shared_examples.rb diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb index 0f3cf5f4408..3e7a6dd26ee 100644 --- a/qa/spec/spec_helper.rb +++ b/qa/spec/spec_helper.rb @@ -1,6 +1,8 @@ require_relative '../qa' -Dir[::File.join(__dir__, 'support', '**', '*.rb')].each { |f| require f } +%w[helpers shared_examples].each do |d| + Dir[::File.join(__dir__, d, '**', '*.rb')].each { |f| require f } +end RSpec.configure do |config| ServerNotRespondingError = Class.new(RuntimeError) diff --git a/qa/spec/support/waiter_spec.rb b/qa/spec/support/waiter_spec.rb new file mode 100644 index 00000000000..8283b65e1be --- /dev/null +++ b/qa/spec/support/waiter_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'logger' + +describe QA::Support::Waiter do + before do + logger = ::Logger.new $stdout + logger.level = ::Logger::DEBUG + QA::Runtime::Logger.logger = logger + end + + describe '.wait' do + context 'when the condition is true' do + it 'logs the start' do + expect { subject.wait(max: 0) {} } + .to output(/with wait: max 0; interval 0.1/).to_stdout_from_any_process + end + + it 'logs the end' do + expect { subject.wait(max: 0) {} } + .to output(/ended wait after .* seconds$/).to_stdout_from_any_process + end + end + + context 'when the condition is false' do + it 'logs the start' do + expect { subject.wait(max: 0) { false } } + .to output(/with wait: max 0; interval 0.1/).to_stdout_from_any_process + end + + it 'logs the end' do + expect { subject.wait(max: 0) { false } } + .to output(/ended wait after .* seconds$/).to_stdout_from_any_process + end + end + end +end diff --git a/spec/fixtures/clusters/sample_cert.pem b/spec/fixtures/clusters/sample_cert.pem index e39a2b34416..00e6ce44d87 100644 --- a/spec/fixtures/clusters/sample_cert.pem +++ b/spec/fixtures/clusters/sample_cert.pem @@ -30,4 +30,4 @@ TkIdFE47ZisEDhIdF6wC1izEMLeMEsPAO7/Y6MY4nRxsinSe95lRaw+yQpzx+mvJ Q7n1kiHI9Pd5M3+CiQda0d/GO1o5ORJnUGJRvr9HKuNmE7Lif0As/N0AlywjzE7A 6Z8AEiWyRV1ffshu1k2UKmzvZuZeGGKRtrIjbJIRAtpRVtVZZGzhq5/sojCLoJ+u texqFBUo/4mFRZa4pDItUdyOlDy2/LO/ag== ------END CERTIFICATE----- +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/spec/lib/gitlab/tracing_spec.rb b/spec/lib/gitlab/tracing_spec.rb new file mode 100644 index 00000000000..2cddc895026 --- /dev/null +++ b/spec/lib/gitlab/tracing_spec.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' +require 'rspec-parameterized' + +describe Gitlab::Tracing do + using RSpec::Parameterized::TableSyntax + + describe '.enabled?' do + where(:connection_string, :enabled_state) do + nil | false + "" | false + "opentracing://jaeger" | true + end + + with_them do + it 'should return the correct state for .enabled?' do + expect(described_class).to receive(:connection_string).and_return(connection_string) + + expect(described_class.enabled?).to eq(enabled_state) + end + end + end + + describe '.tracing_url_enabled?' do + where(:enabled?, :tracing_url_template, :tracing_url_enabled_state) do + false | nil | false + false | "" | false + false | "http://localhost" | false + true | nil | false + true | "" | false + true | "http://localhost" | true + end + + with_them do + it 'should return the correct state for .tracing_url_enabled?' do + expect(described_class).to receive(:enabled?).and_return(enabled?) + allow(described_class).to receive(:tracing_url_template).and_return(tracing_url_template) + + expect(described_class.tracing_url_enabled?).to eq(tracing_url_enabled_state) + end + end + end + + describe '.tracing_url' do + where(:tracing_url_enabled?, :tracing_url_template, :correlation_id, :process_name, :tracing_url) do + false | "https://localhost" | "123" | "web" | nil + true | "https://localhost" | "123" | "web" | "https://localhost" + true | "https://localhost?service=%{service}" | "123" | "web" | "https://localhost?service=web" + true | "https://localhost?c=%{correlation_id}" | "123" | "web" | "https://localhost?c=123" + true | "https://localhost?c=%{correlation_id}&s=%{service}" | "123" | "web" | "https://localhost?c=123&s=web" + true | "https://localhost?c=%{correlation_id}" | nil | "web" | "https://localhost?c=" + end + + with_them do + it 'should return the correct state for .tracing_url' do + expect(described_class).to receive(:tracing_url_enabled?).and_return(tracing_url_enabled?) + allow(described_class).to receive(:tracing_url_template).and_return(tracing_url_template) + allow(Gitlab::CorrelationId).to receive(:current_id).and_return(correlation_id) + allow(Gitlab).to receive(:process_name).and_return(process_name) + + expect(described_class.tracing_url).to eq(tracing_url) + end + end + end +end diff --git a/spec/models/clusters/kubernetes_namespace_spec.rb b/spec/models/clusters/kubernetes_namespace_spec.rb index 235e2ee4e69..b865909c7fd 100644 --- a/spec/models/clusters/kubernetes_namespace_spec.rb +++ b/spec/models/clusters/kubernetes_namespace_spec.rb @@ -97,7 +97,7 @@ RSpec.describe Clusters::KubernetesNamespace, type: :model do let(:platform) { create(:cluster_platform_kubernetes, api_url: api_url, ca_cert: ca_pem, token: token) } let(:api_url) { 'https://kube.domain.com' } - let(:ca_pem) { 'CA PEM DATA' } + let(:ca_pem) { File.read(Rails.root.join('spec/fixtures/clusters/sample_cert.pem')) } let(:token) { 'token' } let(:kubeconfig) do diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb index c273fa7e164..4068d98d8f7 100644 --- a/spec/models/clusters/platforms/kubernetes_spec.rb +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -114,6 +114,36 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching end end + context 'ca_cert' do + let(:kubernetes) { build(:cluster_platform_kubernetes, ca_pem: ca_pem) } + + context 'with a valid certificate' do + let(:ca_pem) { File.read(Rails.root.join('spec/fixtures/clusters/sample_cert.pem')) } + + it { is_expected.to be_truthy } + end + + context 'with an invalid certificate' do + let(:ca_pem) { "invalid" } + + it { is_expected.to be_falsey } + + context 'but the certificate is not being updated' do + before do + allow(kubernetes).to receive(:ca_cert_changed?).and_return(false) + end + + it { is_expected.to be_truthy } + end + end + + context 'with no certificate' do + let(:ca_pem) { "" } + + it { is_expected.to be_truthy } + end + end + describe 'when using reserved namespaces' do subject { build(:cluster_platform_kubernetes, namespace: namespace) } @@ -202,7 +232,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching let!(:cluster) { create(:cluster, :project, platform_kubernetes: kubernetes) } let(:kubernetes) { create(:cluster_platform_kubernetes, api_url: api_url, ca_cert: ca_pem) } let(:api_url) { 'https://kube.domain.com' } - let(:ca_pem) { 'CA PEM DATA' } + let(:ca_pem) { File.read(Rails.root.join('spec/fixtures/clusters/sample_cert.pem')) } subject { kubernetes.predefined_variables(project: cluster.project) } |