Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-06-25 12:09:00 +00:00
parent e2dcb7987a
commit 08d789003a
38 changed files with 340 additions and 6867 deletions

File diff suppressed because it is too large Load Diff

View File

@ -7,12 +7,14 @@ import eventHub from '../eventhub';
import DeployKeysService from '../service';
import DeployKeysStore from '../store';
import KeysPanel from './keys_panel.vue';
import Icon from '~/vue_shared/components/icon.vue';
export default {
components: {
KeysPanel,
NavigationTabs,
GlLoadingIcon,
Icon,
},
props: {
endpoint: {
@ -123,8 +125,8 @@ export default {
/>
<template v-else-if="hasKeys">
<div class="top-area scrolling-tabs-container inner-page-scroll-tabs">
<div class="fade-left"><i class="fa fa-angle-left" aria-hidden="true"> </i></div>
<div class="fade-right"><i class="fa fa-angle-right" aria-hidden="true"> </i></div>
<div class="fade-left"><icon name="chevron-lg-left" :size="12" /></div>
<div class="fade-right"><icon name="chevron-lg-right" :size="12" /></div>
<navigation-tabs :tabs="tabs" scope="deployKeys" @onChangeTab="onChangeTab" />
</div>

View File

@ -9,6 +9,7 @@ import NavigationTabs from '~/vue_shared/components/navigation_tabs.vue';
import NavigationControls from './nav_controls.vue';
import { getParameterByName } from '~/lib/utils/common_utils';
import CIPaginationMixin from '~/vue_shared/mixins/ci_pagination_api_mixin';
import Icon from '~/vue_shared/components/icon.vue';
import PipelinesFilteredSearch from './pipelines_filtered_search.vue';
import { validateParams } from '../../utils';
import { ANY_TRIGGER_AUTHOR, RAW_TEXT_WARNING, FILTER_TAG_IDENTIFIER } from '../../constants';
@ -20,6 +21,7 @@ export default {
NavigationTabs,
NavigationControls,
PipelinesFilteredSearch,
Icon,
},
mixins: [pipelinesMixin, CIPaginationMixin, glFeatureFlagsMixin()],
props: {
@ -298,8 +300,8 @@ export default {
v-if="shouldRenderTabs || shouldRenderButtons"
class="top-area scrolling-tabs-container inner-page-scroll-tabs"
>
<div class="fade-left"><i class="fa fa-angle-left" aria-hidden="true"> </i></div>
<div class="fade-right"><i class="fa fa-angle-right" aria-hidden="true"> </i></div>
<div class="fade-left"><icon name="chevron-lg-left" :size="12" /></div>
<div class="fade-right"><icon name="chevron-lg-right" :size="12" /></div>
<navigation-tabs
v-if="shouldRenderTabs"

View File

@ -137,7 +137,8 @@
transition-duration: 0.3s;
}
.fa {
.fa,
svg {
position: relative;
top: 5px;
font-size: 18px;

View File

@ -313,7 +313,7 @@
right: 0;
text-align: right;
.fa {
svg {
right: 5px;
}
}
@ -323,7 +323,7 @@
left: 0;
text-align: left;
.fa {
svg {
left: 5px;
}
}

View File

@ -1,38 +0,0 @@
# frozen_string_literal: true
module BuildsHelper
def build_summary(build, skip: false)
if build.has_trace?
if skip
link_to _("View job log"), pipeline_job_url(build.pipeline, build)
else
build.trace.html(last_lines: 10).html_safe
end
else
_("No job log")
end
end
def sidebar_build_class(build, current_build)
build_class = []
build_class << 'active' if build.id === current_build.id
build_class << 'retried' if build.retried?
build_class.join(' ')
end
def javascript_build_options
{
page_path: project_job_path(@project, @build),
build_status: @build.status,
build_stage: @build.stage,
log_state: ''
}
end
def build_failed_issue_options
{
title: _("Job Failed #%{build_id}") % { build_id: @build.id },
description: project_job_url(@project, @build)
}
end
end

View File

@ -0,0 +1,40 @@
# frozen_string_literal: true
module Ci
module BuildsHelper
def build_summary(build, skip: false)
if build.has_trace?
if skip
link_to _('View job log'), pipeline_job_url(build.pipeline, build)
else
build.trace.html(last_lines: 10).html_safe
end
else
_('No job log')
end
end
def sidebar_build_class(build, current_build)
build_class = []
build_class << 'active' if build.id === current_build.id
build_class << 'retried' if build.retried?
build_class.join(' ')
end
def javascript_build_options
{
page_path: project_job_path(@project, @build),
build_status: @build.status,
build_stage: @build.stage,
log_state: ''
}
end
def build_failed_issue_options
{
title: _("Job Failed #%{build_id}") % { build_id: @build.id },
description: project_job_url(@project, @build)
}
end
end
end

View File

@ -0,0 +1,54 @@
# frozen_string_literal: true
module Ci
module VariablesHelper
def ci_variable_protected_by_default?
Gitlab::CurrentSettings.current_application_settings.protected_ci_variables
end
def create_deploy_token_path(entity, opts = {})
if entity.is_a?(::Group)
create_deploy_token_group_settings_repository_path(entity, opts)
else
# TODO: change this path to 'create_deploy_token_project_settings_ci_cd_path'
# See MR comment for more detail: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27059#note_311585356
create_deploy_token_project_settings_repository_path(entity, opts)
end
end
def revoke_deploy_token_path(entity, token)
if entity.is_a?(::Group)
revoke_group_deploy_token_path(entity, token)
else
revoke_project_deploy_token_path(entity, token)
end
end
def ci_variable_protected?(variable, only_key_value)
if variable && !only_key_value
variable.protected
else
ci_variable_protected_by_default?
end
end
def ci_variable_masked?(variable, only_key_value)
if variable && !only_key_value
variable.masked
else
false
end
end
def ci_variable_type_options
[
%w(Variable env_var),
%w(File file)
]
end
def ci_variable_maskable_regex
Ci::Maskable::REGEX.inspect.sub('\\A', '^').sub('\\z', '$').sub(/^\//, '').sub(/\/[a-z]*$/, '').gsub('\/', '/')
end
end
end

View File

@ -1,52 +0,0 @@
# frozen_string_literal: true
module CiVariablesHelper
def ci_variable_protected_by_default?
Gitlab::CurrentSettings.current_application_settings.protected_ci_variables
end
def create_deploy_token_path(entity, opts = {})
if entity.is_a?(Group)
create_deploy_token_group_settings_repository_path(entity, opts)
else
# TODO: change this path to 'create_deploy_token_project_settings_ci_cd_path'
# See MR comment for more detail: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27059#note_311585356
create_deploy_token_project_settings_repository_path(entity, opts)
end
end
def revoke_deploy_token_path(entity, token)
if entity.is_a?(Group)
revoke_group_deploy_token_path(entity, token)
else
revoke_project_deploy_token_path(entity, token)
end
end
def ci_variable_protected?(variable, only_key_value)
if variable && !only_key_value
variable.protected
else
ci_variable_protected_by_default?
end
end
def ci_variable_masked?(variable, only_key_value)
if variable && !only_key_value
variable.masked
else
false
end
end
def ci_variable_type_options
[
%w(Variable env_var),
%w(File file)
]
end
def ci_variable_maskable_regex
Ci::Maskable::REGEX.inspect.sub('\\A', '^').sub('\\z', '$').sub(/^\//, '').sub(/\/[a-z]*$/, '').gsub('\/', '/')
end
end

View File

@ -8,20 +8,19 @@ class Repositories::BaseService < BaseService
attr_reader :repository
delegate :container, :disk_path, :full_path, to: :repository
delegate :repository_storage, to: :container
def initialize(repository)
@repository = repository
end
def repo_exists?(path)
gitlab_shell.repository_exists?(repository_storage, path + '.git')
gitlab_shell.repository_exists?(repository.shard, path + '.git')
end
def mv_repository(from_path, to_path)
return true unless repo_exists?(from_path)
gitlab_shell.mv_repository(repository_storage, from_path, to_path)
gitlab_shell.mv_repository(repository.shard, from_path, to_path)
end
# Build a path for removing repositories

View File

@ -9,7 +9,7 @@ class Repositories::ShellDestroyService < Repositories::BaseService
GitlabShellWorker.perform_in(delay,
:remove_repository,
repository_storage,
repository.shard,
removal_path)
end
end

View File

@ -2,9 +2,9 @@
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
.fade-left
= icon('angle-left')
= sprite_icon('chevron-lg-left', size: 12)
.fade-right
= icon('angle-right')
= sprite_icon('chevron-lg-right', size: 12)
%ul.nav-links.nav.nav-tabs.scrolling-tabs
= nav_link(html_options: { class: active_when(params[:filter].nil?) }) do
= link_to admin_users_path do

View File

@ -12,8 +12,8 @@
= link_to _("New project"), new_project_path, class: "btn btn-success"
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
.fade-left= sprite_icon('chevron-lg-left', size: 12)
.fade-right= sprite_icon('chevron-lg-right', size: 12)
%ul.nav-links.scrolling-tabs.mobile-separator.nav.nav-tabs{ class: ('border-0' if feature_project_list_filter_bar) }
= nav_link(page: [dashboard_projects_path, root_path]) do
= link_to dashboard_projects_path, class: 'shortcuts-activity', data: {placement: 'right'} do

View File

@ -19,8 +19,8 @@
.groups-listing{ data: { endpoints: { default: group_children_path(@group, format: :json), shared: group_shared_projects_path(@group, format: :json) } } }
.top-area.group-nav-container.justify-content-between
.scrolling-tabs-container.inner-page-scroll-tabs
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
.fade-left= sprite_icon('chevron-lg-left', size: 12)
.fade-right= sprite_icon('chevron-lg-right', size: 12)
%ul.nav-links.scrolling-tabs.mobile-separator.nav.nav-tabs
%li.js-subgroups_and_projects-tab
= link_to group_path, data: { target: 'div#subgroups_and_projects', action: 'subgroups_and_projects', toggle: 'tab'} do

View File

@ -20,8 +20,8 @@
.merge-request-tabs-holder{ class: ("js-tabs-affix" unless ENV['RAILS_ENV'] == 'test') }
.merge-request-tabs-container
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
.fade-left= sprite_icon('chevron-lg-left', size: 12)
.fade-right= sprite_icon('chevron-lg-right', size: 12)
%ul.merge-request-tabs.nav.nav-tabs.nav-links.no-top.no-bottom.js-tabs-affix
%li.commits-tab.new-tab
= link_to url_for(safe_params), data: {target: 'div#commits', action: 'new', toggle: 'tabvue'} do

View File

@ -1,5 +1,5 @@
- content_for :create_access_levels do
.create_access_levels-container
.create_access_levels-container{ data: { qa_selector: 'access_levels_content' } }
= dropdown_tag('Select',
options: { toggle_class: 'js-allowed-to-create wide',
dropdown_class: 'dropdown-menu-selectable capitalize-header',

View File

@ -3,8 +3,8 @@
= search_filter_link 'users', _("Users")
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
.fade-left= sprite_icon('chevron-lg-left', size: 12)
.fade-right= sprite_icon('chevron-lg-right', size: 12)
%ul.nav-links.search-filter.scrolling-tabs.nav.nav-tabs
- if @project
- if project_search_tabs?(:blobs)

View File

@ -1,8 +1,8 @@
- show_group_events = local_assigns.fetch(:show_group_events, false)
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller.flex-fill
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
.fade-left= sprite_icon('chevron-lg-left', size: 12)
.fade-right= sprite_icon('chevron-lg-right', size: 12)
%ul.nav-links.event-filter.scrolling-tabs.nav.nav-tabs
= event_filter_link EventFilter::ALL, _('All'), s_('EventFilterBy|Filter by all')
- if event_filter_visible(:repository)

View File

@ -1,6 +1,6 @@
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
.fade-left= sprite_icon('chevron-lg-left', size: 12)
.fade-right= sprite_icon('chevron-lg-right', size: 12)
%ul.nav-links.scrolling-tabs.js-milestone-tabs.nav.nav-tabs
%li.nav-item
= link_to '#tab-issues', class: 'nav-link active', data: { toggle: 'tab', show: '.tab-issues-buttons' } do

View File

@ -89,8 +89,8 @@
- unless profile_tabs.empty?
.scrolling-tabs-container
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
.fade-left= sprite_icon('chevron-lg-left', size: 12)
.fade-right= sprite_icon('chevron-lg-right', size: 12)
%ul.nav-links.user-profile-nav.scrolling-tabs.nav.nav-tabs
- if profile_tab?(:overview)
%li.js-overview-tab

View File

@ -0,0 +1,5 @@
---
title: Expand healtchecks `500`s when DB is not available
merge_request: 34844
author:
type: fixed

View File

@ -375,6 +375,8 @@ otherwise the external file won't be included.
| [`remote`](#includeremote) | Include a file from a remote URL. Must be publicly accessible. |
| [`template`](#includetemplate) | Include templates which are provided by GitLab. |
The `include` methods do not support [variable expansion](../variables/where_variables_can_be_used.md#variables-usage).
NOTE: **Note:**
`.gitlab-ci.yml` configuration included by all methods is evaluated at pipeline creation.
The configuration is a snapshot in time and persisted in the database. Any changes to

View File

@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
# GitLab CI/CD YAML includes
# GitLab CI/CD include examples
In addition to the [`includes` examples](README.md#include) listed in the
[GitLab CI YAML reference](README.md), this page lists more variations of `include`

View File

@ -111,11 +111,7 @@ Patterns:
- `'"((?:\\"|[^"]|\\")*)"'`: captures terms inside quotes, removing the quotes
- `"'((?:\\'|[^']|\\')*)'"`: same as above, for single-quotes
- `'\.([^.]+)(?=\.|\s|\Z)'`: separate terms with periods in-between
- `'\/?([^\/]+)(?=\/|\b)'`: separate path terms `like/this/one`
#### `edgeNGram_filter`
Uses an [Edge NGram token filter](https://www.elastic.co/guide/en/elasticsearch/reference/5.5/analysis-edgengram-tokenfilter.html) to allow inputs with only parts of a token to find the token. For example it would turn `glasses` into permutations starting with `gl` and ending with `glasses`, which would allow a search for "`glass`" to find the original token `glasses`
- `'([\p{L}_.-]+)'` : some common chars in file names to keep the whole filename intact (eg. `my_file-ñame.txt`)
## Gotchas

View File

@ -178,6 +178,10 @@ For example, to add support for files referenced by a `Widget` model with a
mount_uploader :file, WidgetUploader
def self.replicables_for_geo_node
# Should be implemented. The idea of the method is to restrict
# the set of synced items depending on synchronization settings
end
...
end
```
@ -257,19 +261,30 @@ For example, to add support for files referenced by a `Widget` model with a
class Geo::WidgetRegistry < Geo::BaseRegistry
include Geo::StateMachineRegistry
MODEL_CLASS = ::Widget
MODEL_FOREIGN_KEY = :widget_id
belongs_to :widget, class_name: 'Widget'
def self.has_create_events?
true
end
end
```
The method `has_create_events?` should return `true` in most of the cases.
However, if the entity you add doesn't have the create event, don't add the
method at all.
1. Update `REGISTRY_CLASSES` in `ee/app/workers/geo/secondary/registry_consistency_worker.rb`.
1. Create `ee/spec/factories/geo/widget_registry.rb`:
```ruby
# frozen_string_literal: true
FactoryBot.define do
factory :widget_registry, class: 'Geo::WidgetRegistry' do
factory :geo_widget_registry, class: 'Geo::WidgetRegistry' do
widget
state { Geo::WidgetRegistry.state_value(:pending) }
@ -302,13 +317,17 @@ For example, to add support for files referenced by a `Widget` model with a
require 'spec_helper'
RSpec.describe Geo::WidgetRegistry, :geo, type: :model do
let_it_be(:registry) { create(:widget_registry) }
let_it_be(:registry) { create(:geo_widget_registry) }
specify 'factory is valid' do
expect(registry).to be_valid
end
include_examples 'a Geo framework registry'
describe '.find_registry_differences' do
... # To be implemented
end
end
```
@ -429,7 +448,7 @@ Widgets should now be verified by Geo!
require 'spec_helper'
RSpec.describe Resolvers::Geo::WidgetRegistriesResolver do
it_behaves_like 'a Geo registries resolver', :widget_registry
it_behaves_like 'a Geo registries resolver', :geo_widget_registry
end
```
@ -453,7 +472,7 @@ Widgets should now be verified by Geo!
require 'spec_helper'
RSpec.describe Geo::WidgetRegistryFinder do
it_behaves_like 'a framework registry finder', :widget_registry
it_behaves_like 'a framework registry finder', :geo_widget_registry
end
```
@ -503,7 +522,7 @@ Widgets should now be verified by Geo!
it_behaves_like 'gets registries for', {
field_name: 'widgetRegistries',
registry_class_name: 'WidgetRegistry',
registry_factory: :widget_registry,
registry_factory: :geo_widget_registry,
registry_foreign_key_field_name: 'widgetId'
}
```

View File

@ -137,8 +137,8 @@ This check is being exempt from Rack Attack.
## Access token (Deprecated)
> NOTE: **Note:**
> Access token has been deprecated in GitLab 9.4 in favor of [IP whitelist](#ip-whitelist).
NOTE: **Note:**
Access token has been deprecated in GitLab 9.4 in favor of [IP whitelist](#ip-whitelist).
An access token needs to be provided while accessing the probe endpoints. The current
accepted token can be found under the **Admin Area > Monitoring > Health check**
@ -152,6 +152,10 @@ The access token can be passed as a URL parameter:
https://gitlab.example.com/-/readiness?token=ACCESS_TOKEN
```
NOTE: **Note:**
In case the database or Redis service are unaccessible, the probe endpoints response is not guaranteed to be correct.
You should switch to [IP whitelist](#ip-whitelist) from deprecated access token to avoid it.
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues

View File

@ -118,8 +118,8 @@ module API
{
repository: repository.gitaly_repository,
address: Gitlab::GitalyClient.address(container.repository_storage),
token: Gitlab::GitalyClient.token(container.repository_storage),
address: Gitlab::GitalyClient.address(repository.shard),
token: Gitlab::GitalyClient.token(repository.shard),
features: Feature::Gitaly.server_feature_flags
}
end

View File

@ -20,6 +20,12 @@ module Gitlab
success ? 200 : 503,
status(success).merge(payload(readiness))
)
rescue => e
exception_payload = { message: "#{e.class} : #{e.message}" }
Probes::Status.new(
500,
status(false).merge(exception_payload))
end
private

View File

@ -72,7 +72,7 @@ module Gitlab
end
def redis_cluster_validate!(command)
RedisClusterValidator.validate!(command) if @redis_cluster_validation
::Gitlab::Instrumentation::RedisClusterValidator.validate!(command) if @redis_cluster_validation
end
def enable_redis_cluster_validation

View File

@ -216,8 +216,8 @@ module Gitlab
def gitaly_server_hash(repository)
{
address: Gitlab::GitalyClient.address(repository.container.repository_storage),
token: Gitlab::GitalyClient.token(repository.container.repository_storage),
address: Gitlab::GitalyClient.address(repository.shard),
token: Gitlab::GitalyClient.token(repository.shard),
features: Feature::Gitaly.server_feature_flags
}
end

View File

@ -183,7 +183,6 @@ module QA
autoload :OAuth, 'qa/page/main/oauth'
autoload :SignUp, 'qa/page/main/sign_up'
autoload :Terms, 'qa/page/main/terms'
autoload :Onboarding, 'qa/page/main/onboarding'
end
module Settings

View File

@ -165,10 +165,6 @@ module QA
terms.accept_terms if terms.visible?
end
QA::Page::Main::Onboarding.perform do |onboarding|
onboarding.skip_for_now if onboarding.respond_to?(:skip_for_now) && onboarding.visible?
end
Page::Main::Menu.validate_elements_present! unless skip_page_validation
end

View File

@ -1,12 +0,0 @@
# frozen_string_literal: true
module QA
module Page
module Main
class Onboarding < Page::Base
end
end
end
end
QA::Page::Main::Onboarding.prepend_if_ee('QA::EE::Page::Main::Onboarding')

View File

@ -15,7 +15,7 @@ module QA
end
def accept_terms
click_element :accept_terms_button
click_element :accept_terms_button, Page::Main::Menu
end
end
end

View File

@ -12,6 +12,7 @@ module QA
end
view 'app/views/projects/protected_tags/_create_protected_tag.html.haml' do
element :access_levels_content
element :access_levels_dropdown
end
@ -26,7 +27,9 @@ module QA
def choose_access_level_role(role)
click_element :access_levels_dropdown
click_on role
within_element(:access_levels_content) do
click_on role
end
end
def click_protect_tag_button

View File

@ -0,0 +1,111 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::BuildsHelper do
describe '#build_summary' do
subject { helper.build_summary(build, skip: skip) }
context 'when build has no trace' do
let(:build) { instance_double(Ci::Build, has_trace?: false) }
context 'when skip is false' do
let(:skip) { false }
it 'returns no job log' do
expect(subject).to eq('No job log')
end
end
context 'when skip is true' do
let(:skip) { true }
it 'returns no job log' do
expect(subject).to eq('No job log')
end
end
end
context 'when build has trace' do
let(:build) { create(:ci_build, :trace_live) }
context 'when skip is true' do
let(:skip) { true }
it 'returns link to logs' do
expect(subject).to include('View job log')
expect(subject).to include(pipeline_job_url(build.pipeline, build))
end
end
context 'when skip is false' do
let(:skip) { false }
it 'returns log lines' do
expect(subject).to include(build.trace.html(last_lines: 10).html_safe)
end
end
end
end
describe '#sidebar_build_class' do
using RSpec::Parameterized::TableSyntax
where(:build_id, :current_build_id, :retried, :expected_result) do
1 | 1 | true | 'active retried'
1 | 1 | false | 'active'
1 | 2 | false | ''
1 | 2 | true | 'retried'
end
let(:build) { instance_double(Ci::Build, retried?: retried, id: build_id) }
let(:current_build) { instance_double(Ci::Build, retried?: true, id: current_build_id ) }
subject { helper.sidebar_build_class(build, current_build) }
with_them do
it 'builds sidebar html class' do
expect(subject).to eq(expected_result)
end
end
end
describe '#javascript_build_options' do
subject { helper.javascript_build_options }
it 'returns build options' do
project = assign_project
ci_build = assign_build
expect(subject).to eq({
page_path: project_job_path(project, ci_build),
build_status: ci_build.status,
build_stage: ci_build.stage,
log_state: ''
})
end
end
describe '#build_failed_issue_options' do
subject { helper.build_failed_issue_options }
it 'returns failed title and description' do
project = assign_project
ci_build = assign_build
expect(subject).to eq(title: "Job Failed \##{ci_build.id}", description: project_job_url(project, ci_build))
end
end
def assign_project
build(:project).tap do |project|
assign(:project, project)
end
end
def assign_build
create(:ci_build).tap do |ci_build|
assign(:build, ci_build)
end
end
end

View File

@ -47,6 +47,20 @@ RSpec.describe Gitlab::HealthChecks::Probes::Collection do
status: 'failed', message: 'check error')
end
end
context 'when check raises exception not handled inside the check' do
before do
expect(Gitlab::HealthChecks::Redis::RedisCheck).to receive(:readiness).and_raise(
::Redis::CannotConnectError, 'Redis down')
end
it 'responds with failure including the exception info' do
expect(subject.http_status).to eq(500)
expect(subject.json[:status]).to eq('failed')
expect(subject.json[:message]).to eq('Redis::CannotConnectError : Redis down')
end
end
end
context 'without checks' do

View File

@ -129,6 +129,40 @@ RSpec.describe HealthController do
expect(response).to have_gitlab_http_status(:service_unavailable)
expect(response.headers['X-GitLab-Custom-Error']).to eq(1)
end
context 'when DB is not accessible and connection raises an exception' do
before do
expect(Gitlab::HealthChecks::DbCheck)
.to receive(:readiness)
.and_raise(PG::ConnectionBad, 'could not connect to server')
end
it 'responds with 500 including the exception info' do
subject
expect(response).to have_gitlab_http_status(:internal_server_error)
expect(response.headers['X-GitLab-Custom-Error']).to eq(1)
expect(json_response).to eq(
{ 'status' => 'failed', 'message' => 'PG::ConnectionBad : could not connect to server' })
end
end
context 'when any exception happens during the probing' do
before do
expect(Gitlab::HealthChecks::Redis::RedisCheck)
.to receive(:readiness)
.and_raise(::Redis::CannotConnectError, 'Redis down')
end
it 'responds with 500 including the exception info' do
subject
expect(response).to have_gitlab_http_status(:internal_server_error)
expect(response.headers['X-GitLab-Custom-Error']).to eq(1)
expect(json_response).to eq(
{ 'status' => 'failed', 'message' => 'Redis::CannotConnectError : Redis down' })
end
end
end
end