Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-08-19 03:12:19 +00:00
parent 65530963a3
commit b0c61201a7
43 changed files with 406 additions and 112 deletions

View file

@ -485,7 +485,7 @@ gem 'ssh_data', '~> 1.3'
gem 'spamcheck', '~> 0.1.0'
# Gitaly GRPC protocol definitions
gem 'gitaly', '~> 15.3.0-rc3'
gem 'gitaly', '~> 15.3.0-rc4'
# KAS GRPC protocol definitions
gem 'kas-grpc', '~> 0.0.2'

View file

@ -508,7 +508,7 @@ GEM
rails (>= 3.2.0)
git (1.11.0)
rchardet (~> 1.8)
gitaly (15.3.0.pre.rc3)
gitaly (15.3.0.pre.rc4)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab (4.16.1)
@ -1574,7 +1574,7 @@ DEPENDENCIES
gettext (~> 3.3)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
gitaly (~> 15.3.0.pre.rc3)
gitaly (~> 15.3.0.pre.rc4)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 3.5.0)

View file

@ -42,7 +42,6 @@ export default {
formInputGroupProps() {
return {
id: this.$options.tokenInputId,
class: 'qa-created-access-token',
'data-qa-selector': 'created_access_token_field',
name: this.$options.tokenInputId,
};

View file

@ -176,7 +176,11 @@ export default {
:placeholder="placeholder"
/>
</form>
<ul v-if="isCreatingNewFile" class="file-templates gl-mt-3 list-inline qa-template-list">
<ul
v-if="isCreatingNewFile"
class="file-templates gl-mt-3 list-inline"
data-qa-selector="template_list_content"
>
<li v-for="(template, index) in templateTypes" :key="index" class="list-inline-item">
<gl-button
variant="dashed"

View file

@ -197,7 +197,7 @@ export default {
</script>
<template>
<div>
<gl-loading-icon v-if="isLoading" size="lg" class="qa-loading-animation gl-mt-6" />
<gl-loading-icon v-if="isLoading" size="lg" class="gl-mt-6" />
<template v-else-if="shouldRenderContent">
<div class="build-page" data-testid="job-content">

View file

@ -158,7 +158,7 @@ export default {
:href="detailsPath"
:title="tooltipText"
:class="jobClasses"
class="js-pipeline-graph-job-link qa-job-link menu-item gl-text-gray-900 gl-active-text-decoration-none gl-focus-text-decoration-none gl-hover-text-decoration-none"
class="js-pipeline-graph-job-link menu-item gl-text-gray-900 gl-active-text-decoration-none gl-focus-text-decoration-none gl-hover-text-decoration-none"
data-testid="job-with-link"
@click.stop="hideTooltips"
@mouseout="hideTooltips"

View file

@ -83,9 +83,7 @@ export default {
<span class="font-weight-bold">{{ __('Pipeline') }}</span>
<a :href="pipeline.path" class="js-pipeline-path link-commit qa-pipeline-path"
>#{{ pipeline.id }}</a
>
<a :href="pipeline.path" class="js-pipeline-path link-commit">#{{ pipeline.id }}</a>
<template v-if="hasRef">
{{ __('from') }}
<a :href="pipeline.ref.path" class="link-commit ref-name">{{ pipeline.ref.name }}</a>

View file

@ -3,7 +3,6 @@ import { GlLink, GlIcon, GlButton } from '@gitlab/ui';
import { __ } from '~/locale';
import {
issuableIconMap,
issuableQaClassMap,
linkedIssueTypesMap,
linkedIssueTypesTextMap,
issuablesBlockHeaderTextMap,
@ -142,9 +141,6 @@ export default {
issuableTypeIcon() {
return issuableIconMap[this.issuableType];
},
qaClass() {
return issuableQaClassMap[this.issuableType];
},
toggleIcon() {
return this.isOpen ? 'chevron-lg-up' : 'chevron-lg-down';
},
@ -205,7 +201,6 @@ export default {
data-qa-selector="related_issues_plus_button"
data-testid="related-issues-plus-button"
:aria-label="addIssuableButtonText"
:class="qaClass"
class="gl-ml-3"
@click="addButtonClick"
>

View file

@ -99,15 +99,6 @@ export const issuableIconMap = {
[issuableTypesMap.EPIC]: 'epic',
};
/**
* These are used to map issuableType to the correct QA class.
* Since these are never used for any display purposes, don't wrap
* them inside i18n functions.
*/
export const issuableQaClassMap = {
[issuableTypesMap.EPIC]: 'qa-add-epics-button',
};
export const PathIdSeparator = {
Epic: '&',
Issue: '#',

View file

@ -191,7 +191,7 @@ export default {
href: `${this.newBlobPath}/${
this.currentPath ? encodeURIComponent(this.currentPath) : ''
}`,
class: 'qa-new-file-option',
'data-qa-selector': 'new_file_menu_item',
},
text: __('New file'),
},
@ -300,7 +300,11 @@ export default {
</router-link>
</li>
<li v-if="renderAddToTreeDropdown" class="breadcrumb-item">
<gl-dropdown toggle-class="add-to-tree qa-add-to-tree gl-ml-2">
<gl-dropdown
toggle-class="add-to-tree gl-ml-2"
data-testid="add-to-tree"
data-qa-selector="add_to_tree_dropdown"
>
<template #button-content>
<span class="sr-only">{{ __('Add to tree') }}</span>
<gl-icon name="plus" :size="16" class="float-left" />

View file

@ -135,7 +135,7 @@ export default {
<div
class="commit-detail flex-list gl-display-flex gl-justify-content-space-between gl-align-items-flex-start gl-flex-grow-1 gl-min-w-0"
>
<div class="commit-content qa-commit-content">
<div class="commit-content" data-qa-selector="commit_content">
<gl-link
v-safe-html:[$options.safeHtmlConfig]="commit.titleHtml"
:href="commit.webPath"

View file

@ -57,13 +57,19 @@ export default {
},
cssClass() {
const className = this.status.group;
return className ? `ci-status ci-${className} qa-status-badge` : 'ci-status qa-status-badge';
return className ? `ci-status ci-${className}` : 'ci-status';
},
},
};
</script>
<template>
<a v-gl-tooltip :href="detailsPath" :class="cssClass" :title="title">
<a
v-gl-tooltip
:href="detailsPath"
:class="cssClass"
:title="title"
data-qa-selector="status_badge_link"
>
<ci-icon :status="status" :css-classes="iconClasses" />
<template v-if="showText">

View file

@ -47,8 +47,31 @@ module Integrations
private
def notify(message, opts)
url = webhook.dup
key = parse_thread_key(message)
url = Gitlab::Utils.add_url_parameters(url, { threadKey: key }) if key
simple_text = parse_simple_text_message(message)
::HangoutsChat::Sender.new(webhook).simple(simple_text)
::HangoutsChat::Sender.new(url).simple(simple_text)
end
# Returns an appropriate key for threading messages in google chat
def parse_thread_key(message)
case message
when Integrations::ChatMessage::NoteMessage
message.target
when Integrations::ChatMessage::IssueMessage
"issue #{Issue.reference_prefix}#{message.issue_iid}"
when Integrations::ChatMessage::MergeMessage
"merge request #{MergeRequest.reference_prefix}#{message.merge_request_iid}"
when Integrations::ChatMessage::PushMessage
"push #{message.project_name}_#{message.ref}"
when Integrations::ChatMessage::PipelineMessage
"pipeline #{message.pipeline_id}"
when Integrations::ChatMessage::WikiPageMessage
"wiki_page #{message.wiki_page_url}"
end
end
def parse_simple_text_message(message)

View file

@ -3,7 +3,7 @@
= _('Your new %{type}') % { type: type }
.form-group
.input-group
= text_field_tag 'created-personal-access-token', new_token_value, readonly: true, class: 'qa-created-access-token form-control js-select-on-focus', 'aria-describedby' => 'created-token-help-block'
= text_field_tag 'created-personal-access-token', new_token_value, readonly: true, class: 'form-control js-select-on-focus', data: { qa_selector: 'created_access_token_field' }, 'aria-describedby' => 'created-token-help-block'
%span.input-group-append
= clipboard_button(text: new_token_value, title: _('Copy %{type}') % { type: type }, placement: 'left', class: 'input-group-text btn-default btn-clipboard')
%span#created-token-help-block.form-text.text-muted.text-danger

View file

@ -660,7 +660,14 @@ The code removed from GitLab during the Gitaly migration project affected these
performance workaround for these NFS-based deployments, we re-introduced some of the old Rugged
code. This re-introduced code is informally referred to as the "Rugged patches".
### How it works
### Automatic detection
> Automatic detection for Rugged [disabled](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95445) in GitLab 15.3.
FLAG:
On self-managed GitLab, by default automatic detection of whether Rugged should be used (per storage) is not available.
To make it available, ask an administrator to [disable the feature flag](../../administration/feature_flags.md) named
`skip_rugged_auto_detect`.
The Ruby methods that perform direct Git access are behind
[feature flags](../../development/gitaly.md#legacy-rugged-code), disabled by default. It wasn't
@ -685,12 +692,13 @@ To see if GitLab can access the repository file system directly, we use the foll
- GitLab Rails tries to read the metadata file directly. If it exists, and if the UUID's match,
assume we have direct access.
Versions of GitLab 15.3 and later disable direct Git access by default.
Direct Git access is:
For versions of GitLab prior to 15.3, direct Git access is enabled by
default in Omnibus GitLab because it fills in the correct repository
paths in the GitLab configuration file `config/gitlab.yml`. This
satisfies the UUID check.
- [Disabled](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95445) by default in GitLab 15.3 and later for
compatibility with [Praefect-generated replica paths](#praefect-generated-replica-paths-gitlab-150-and-later). It
can be enabled if Rugged [feature flags](../../development/gitaly.md#legacy-rugged-code) are enabled.
- Enabled by default in GitLab 15.2 and earlier because it fills in the correct repository paths in the GitLab
configuration file `config/gitlab.yml`. This satisfies the UUID check.
### Transition to Gitaly Cluster

View file

@ -95,34 +95,22 @@ We are investigating the use of
## Improving NFS performance with GitLab
NFS performance with GitLab can in some cases be improved with
[direct Git access](gitaly/index.md#direct-access-to-git-in-gitlab) using
[Rugged](https://github.com/libgit2/rugged).
[direct Git access](gitaly/index.md#direct-access-to-git-in-gitlab) using [Rugged](https://github.com/libgit2/rugged).
Versions of GitLab after 12.2 and prior to 15.3 automatically detect if
Rugged can and should be used per storage.
Depending on the GitLab version, GitLab [automatically detects](gitaly/index.md#automatic-detection) if Rugged can and should
be used per storage.
NOTE:
GitLab 15.3 and later disables this automatic detection. Auto-detection can be enabled via the
`skip_rugged_auto_detect` feature flag:
```ruby
Feature.disable(:skip_rugged_auto_detect)
```
In addition, if you previously enabled Rugged using the feature flag and
you want to use automatic detection instead, you must unset the feature
flag:
If the Rugged feature flag is explicitly set to either `true` or `false`, GitLab uses the value explicitly set. If you
previously enabled Rugged using the feature flag and you want to use automatic detection instead, you must unset
the feature flag:
```shell
sudo gitlab-rake gitlab:features:unset_rugged
```
If the Rugged feature flag is explicitly set to either `true` or `false`, GitLab uses the value explicitly set.
From GitLab 12.7, Rugged is only automatically enabled for use with Puma
if the [Puma thread count is set to `1`](../install/requirements.md#puma-settings).
To use Rugged with a Puma thread count of more than `1`, enable Rugged using the [feature flag](../development/gitaly.md#legacy-rugged-code).
From GitLab 12.7, Rugged is only automatically enabled for use with Puma if the
[Puma thread count is set to `1`](../install/requirements.md#puma-settings). To use Rugged with a Puma thread count of
more than `1`, enable Rugged using the [feature flag](../development/gitaly.md#legacy-rugged-code).
## NFS server

View file

@ -156,10 +156,8 @@ For deployments where NFS is used to store Git repositories, GitLab uses
[direct Git access](../gitaly/index.md#direct-access-to-git-in-gitlab) to improve performance by using
[Rugged](https://github.com/libgit2/rugged).
Rugged usage is automatically enabled if direct Git access
[is available](../gitaly/index.md#how-it-works)
and Puma is running single threaded, unless it is disabled by a
[feature flag](../../development/gitaly.md#legacy-rugged-code).
Rugged usage is automatically enabled if direct Git access [is available](../gitaly/index.md#automatic-detection) and
Puma is running single threaded, unless it is disabled by a [feature flag](../../development/gitaly.md#legacy-rugged-code).
MRI Ruby uses a Global VM Lock (GVL). GVL allows MRI Ruby to be multi-threaded, but running at
most on a single core.

View file

@ -1444,7 +1444,7 @@ response attributes:
| Attribute | Type | Description |
|:-------------------|:-------|:-------------------------------------------------------------------------------------|
| `[].name` | string | Name of the SAML group |
| `[].access_level` | string | Minimum [access level](members.md#valid-access-levels) for members of the SAML group |
| `[].access_level` | integer | Minimum [access level](members.md#valid-access-levels) for members of the SAML group |
Example request:
@ -1458,11 +1458,11 @@ Example response:
[
{
"name": "saml-group-1",
"access_level": "Guest"
"access_level": 10
},
{
"name": "saml-group-2",
"access_level": "Maintainer"
"access_level": 40
}
]
```
@ -1488,7 +1488,7 @@ response attributes:
| Attribute | Type | Description |
|:---------------|:-------|:-------------------------------------------------------------------------------------|
| `name` | string | Name of the SAML group |
| `access_level` | string | Minimum [access level](members.md#valid-access-levels) for members of the SAML group |
| `access_level` | integer | Minimum [access level](members.md#valid-access-levels) for members of the SAML group |
Example request:
@ -1501,7 +1501,7 @@ Example response:
```json
{
"name": "saml-group-1",
"access_level": "Guest"
"access_level": 10
}
```
@ -1519,7 +1519,7 @@ Supported attributes:
|:-------------------|:---------------|:---------|:-------------------------------------------------------------------------------------|
| `id` | integer/string | yes | ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
| `saml_group_name` | string | yes | Name of a SAML group |
| `access_level` | string | yes | Minimum [access level](members.md#valid-access-levels) for members of the SAML group |
| `access_level` | integer | yes | Minimum [access level](members.md#valid-access-levels) for members of the SAML group |
If successful, returns [`201`](index.md#status-codes) and the following
response attributes:
@ -1527,7 +1527,7 @@ response attributes:
| Attribute | Type | Description |
|:---------------|:-------|:-------------------------------------------------------------------------------------|
| `name` | string | Name of the SAML group |
| `access_level` | string | Minimum [access level](members.md#valid-access-levels) for members of the SAML group |
| `access_level` | integer | Minimum [access level](members.md#valid-access-levels) for members of the SAML group |
Example request:
@ -1540,7 +1540,7 @@ Example response:
```json
{
"name": "saml-group-1",
"access_level": "Guest"
"access_level": 10
}
```

View file

@ -274,6 +274,7 @@ listed in the descriptions of the relevant settings.
| `container_registry_token_expire_delay` | integer | no | Container Registry token duration in minutes. |
| `package_registry_cleanup_policies_worker_capacity` | integer | no | Number of workers assigned to the packages cleanup policies. |
| `deactivate_dormant_users` | boolean | no | Enable [automatic deactivation of dormant users](../user/admin_area/moderate_users.md#automatically-deactivate-dormant-users). |
| `deactivate_dormant_users_period` | integer | no | Length of time (in days) after which a user is considered dormant. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336747) in GitLab 15.3. |
| `default_artifacts_expire_in` | string | no | Set the default expiration time for each job's artifacts. |
| `default_branch_name` | string | no | [Instance-level custom initial branch name](../user/project/repository/branches/default.md#instance-level-custom-initial-branch-name) ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/225258) in GitLab 13.2). |
| `default_branch_protection` | integer | no | Determine if developers can push to the default branch. Can take: `0` _(not protected, both users with the Developer role or Maintainer role can push new commits and force push)_, `1` _(partially protected, users with the Developer role or Maintainer role can push new commits, but cannot force push)_ or `2` _(fully protected, users with the Developer or Maintainer role cannot push new commits, but users with the Developer or Maintainer role can; no one can force push)_ as a parameter. Default is `2`. |

View file

@ -121,6 +121,8 @@ On self-managed GitLab, migrating project resources are not available by default
- Members ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/341886) in GitLab 14.8)
- Merge Requests ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/339403) in GitLab 14.5)
- Multiple merge request assignees ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/339520) in GitLab 15.3)
- Merge request reviewers ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/339520) in GitLab 15.3)
- Merge request approvers ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/339520) in GitLab 15.3)
- Migrate Push Rules ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/339403) in GitLab 14.6)
- Pull Requests (including external pull requests) ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/339409) in GitLab 14.5)
- Pipeline History ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/339412) in GitLab 14.6)

View file

@ -43,7 +43,8 @@ configured for personal access tokens.
## Create a group access token using UI
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214045) in GitLab 14.7.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214045) in GitLab 14.7.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348660) in GitLab 15.3, default expiration of 30 days and default role of Guest is populated in the UI.
To create a group access token:

View file

@ -40,6 +40,8 @@ Use impersonation tokens to automate authentication as a specific user.
## Create a personal access token
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348660) in GitLab 15.3, default expiration of 30 days is populated in the UI.
You can create as many personal access tokens as you like.
1. In the top-right corner, select your avatar.

View file

@ -43,7 +43,8 @@ configured for personal access tokens.
## Create a project access token
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89114) in GitLab 15.1, Owners can select Owner role for project access tokens.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89114) in GitLab 15.1, Owners can select Owner role for project access tokens.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348660) in GitLab 15.3, default expiration of 30 days and default role of Guest is populated in the UI.
To create a project access token:

View file

@ -9,19 +9,3 @@
00_uri: &00_uri
- regex: '(href|data-src)(=")(.*?)(test-file\.(png|zip)")'
replacement: '\1\2URI_PREFIX\4'
07_01_00__gitlab_specific_markdown__footnotes__001:
html:
static:
shared:
07_01_00_href: &07_01_00_href
- regex: '(href)(=")(.+?)(")'
replacement: '\1\2REF\4'
07_01_00_id: &07_01_00_id
- regex: '(id)(=")(.+?)(")'
replacement: '\1\2ID\4'
canonical:
07_01_00_href: *07_01_00_href
07_01_00_id: *07_01_00_id
snapshot:
07_01_00_href: *07_01_00_href
07_01_00_id: *07_01_00_id

View file

@ -26,6 +26,19 @@ module Gitlab
storage_specific(disk_statistics)
end
def readiness_check
request = Gitaly::ReadinessCheckRequest.new(timeout: GitalyClient.medium_timeout)
response = GitalyClient.call(@storage, :server_service, :readiness_check, request, timeout: GitalyClient.default_timeout)
return { success: true } if response.ok_response
failed_checks = response.failure_response.failed_checks.map do |failed_check|
["#{failed_check.name}: #{failed_check.error_message}"]
end
{ success: false, message: failed_checks.join("\n") }
end
private
def storage_specific(response)

View file

@ -27,17 +27,35 @@ module Gitlab
end
def check(storage_name)
serv = Gitlab::GitalyClient::HealthCheckService.new(storage_name)
result = serv.check
storage_healthy = healthy(storage_name)
unless storage_healthy[:success]
return HealthChecks::Result.new(
name,
storage_healthy[:success],
storage_healthy[:message],
shard: storage_name
)
end
storage_ready = ready(storage_name)
HealthChecks::Result.new(
name,
result[:success],
result[:message],
storage_ready[:success],
storage_ready[:message],
shard: storage_name
)
end
def healthy(storage_name)
serv = Gitlab::GitalyClient::HealthCheckService.new(storage_name)
serv.check
end
def ready(storage_name)
serv = Gitlab::GitalyClient::ServerService.new(storage_name)
serv.readiness_check
end
private
def metric_prefix

View file

@ -18,6 +18,10 @@ module QA
element :expiry_date_field
end
base.view 'app/views/shared/access_tokens/_created_container.html.haml' do
element :created_access_token_field
end
base.view 'app/views/shared/access_tokens/_form.html.haml' do
element :access_token_name_field
element :create_token_button
@ -32,7 +36,7 @@ module QA
end
base.view 'app/assets/javascripts/access_tokens/components/new_access_token_app.vue' do
element :created_access_token
element :created_access_token_field
end
base.view 'app/assets/javascripts/access_tokens/components/access_token_table_app.vue' do
@ -53,7 +57,7 @@ module QA
end
def created_access_token
find_element(:created_access_token, wait: 30).value
find_element(:created_access_token_field, wait: 30).value
end
def fill_expiry_date(date)

View file

@ -32,12 +32,12 @@ module QA
super
base.view 'app/assets/javascripts/vue_shared/components/ci_badge_link.vue' do
element :status_badge
element :status_badge_link
end
end
def status_badge
find_element(:status_badge).text
find_element(:status_badge_link).text
end
def completed?(timeout: 60)

View file

@ -9,7 +9,7 @@ module QA
view 'app/assets/javascripts/ide/components/new_dropdown/modal.vue' do
element :file_name_field, required: true
element :new_file_modal, required: true
element :template_list
element :template_list_content
end
end
end

View file

@ -14,6 +14,10 @@ module QA
element :commit_message_field
end
base.view 'app/assets/javascripts/repository/components/last_commit.vue' do
element :commit_content
end
base.view 'app/views/shared/_commit_message_container.html.haml' do
element :commit_message_field
end

View file

@ -58,8 +58,8 @@ module QA
end
view 'app/assets/javascripts/repository/components/breadcrumbs.vue' do
element :add_to_tree
element :new_file_option
element :add_to_tree_dropdown
element :new_file_menu_item
end
view 'app/assets/javascripts/vue_shared/components/web_ide_link.vue' do
@ -90,8 +90,8 @@ module QA
end
def create_new_file!
click_element :add_to_tree
click_element :new_file_option
click_element :add_to_tree_dropdown
click_element :new_file_menu_item
end
def fork_project

View file

@ -163,7 +163,7 @@ module QA
def create_new_file_from_template(file_name, template)
click_element(:new_file_button, Page::Component::WebIDE::Modal::CreateNewFile)
within_element(:template_list) do
within_element(:template_list_content) do
click_on file_name
rescue Capybara::ElementNotFound
raise ElementNotFound, %Q(Couldn't find file template named "#{file_name}". Please confirm that it is a valid option.)

View file

@ -39,7 +39,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
# The dropdown above the tree
page.within('.repo-breadcrumb') do
find('.qa-add-to-tree').click # rubocop:disable QA/SelectorUsage
find('[data-testid="add-to-tree"]').click
aggregate_failures 'dropdown links above the repo tree' do
expect(page).to have_link('New file')
@ -71,7 +71,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
find_new_menu_toggle.click
end
expect(page).not_to have_selector('.qa-add-to-tree') # rubocop:disable QA/SelectorUsage
expect(page).not_to have_selector('[data-testid="add-to-tree"]')
expect(page).not_to have_link('Web IDE')
end

View file

@ -78,7 +78,6 @@ describe('~/access_tokens/components/new_access_token_app', () => {
.findByLabelText(sprintf(__('Your new %{accessTokenType}'), { accessTokenType }))
.attributes();
expect(inputAttributes).toMatchObject({
class: expect.stringContaining('qa-created-access-token'),
'data-qa-selector': 'created_access_token_field',
});
});

View file

@ -20,7 +20,8 @@ exports[`Repository last commit component renders commit widget 1`] = `
class="commit-detail flex-list gl-display-flex gl-justify-content-space-between gl-align-items-flex-start gl-flex-grow-1 gl-min-w-0"
>
<div
class="commit-content qa-commit-content"
class="commit-content"
data-qa-selector="commit_content"
>
<gl-link-stub
class="commit-row-message item-title"

View file

@ -0,0 +1,42 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::GitalyClient::ServerService do
let(:storage) { 'default' }
describe '#readiness_check' do
before do
::Gitlab::GitalyClient.clear_stubs!
end
let(:request) do
Gitaly::ReadinessCheckRequest.new(timeout: 30)
end
subject(:readiness_check) { described_class.new(storage).readiness_check }
it 'returns a positive success if no failures happened' do
expect_next_instance_of(Gitaly::ServerService::Stub) do |service|
response = Gitaly::ReadinessCheckResponse.new(ok_response: Gitaly::ReadinessCheckResponse::Ok.new)
expect(service).to receive(:readiness_check).with(request, kind_of(Hash)).and_return(response)
end
expect(readiness_check[:success]).to eq(true)
end
it 'returns a negative success and a compiled message if at least one failure happened' do
failure1 = Gitaly::ReadinessCheckResponse::Failure::Response.new(name: '1', error_message: 'msg 1')
failure2 = Gitaly::ReadinessCheckResponse::Failure::Response.new(name: '2', error_message: 'msg 2')
failures = Gitaly::ReadinessCheckResponse::Failure.new(failed_checks: [failure1, failure2])
response = Gitaly::ReadinessCheckResponse.new(failure_response: failures)
expect_next_instance_of(Gitaly::ServerService::Stub) do |service|
expect(service).to receive(:readiness_check).with(request, kind_of(Hash)).and_return(response)
end
expect(readiness_check[:success]).to eq(false)
expect(readiness_check[:message]).to eq("1: msg 1\n2: msg 2")
end
end
end

View file

@ -14,20 +14,36 @@ RSpec.describe Gitlab::HealthChecks::GitalyCheck do
subject { described_class.readiness }
before do
expect(Gitlab::GitalyClient::HealthCheckService).to receive(:new).and_return(gitaly_check)
expect(Gitlab::GitalyClient::HealthCheckService).to receive(:new).and_return(healthy_check)
end
context 'Gitaly server is up' do
let(:gitaly_check) { double(check: { success: true }) }
before do
expect(Gitlab::GitalyClient::ServerService).to receive(:new).and_return(ready_check)
end
let(:healthy_check) { double(check: { success: true }) }
let(:ready_check) { double(readiness_check: { success: true }) }
it { is_expected.to eq([result_class.new('gitaly_check', true, nil, shard: 'default')]) }
end
context 'Gitaly server is down' do
let(:gitaly_check) { double(check: { success: false, message: 'Connection refused' }) }
let(:healthy_check) { double(check: { success: false, message: 'Connection refused' }) }
it { is_expected.to eq([result_class.new('gitaly_check', false, 'Connection refused', shard: 'default')]) }
end
context 'Gitaly server is not ready' do
before do
expect(Gitlab::GitalyClient::ServerService).to receive(:new).and_return(ready_check)
end
let(:healthy_check) { double(check: { success: true }) }
let(:ready_check) { double(readiness_check: { success: false, message: 'Clock is out of sync' }) }
it { is_expected.to match_array([result_class.new('gitaly_check', false, 'Clock is out of sync', shard: 'default')]) }
end
end
describe '#metrics' do

View file

@ -24,6 +24,10 @@ RSpec.describe Gitlab::HealthChecks::Probes::Collection do
end
it 'responds with readiness checks data' do
expect_next_instance_of(Gitlab::GitalyClient::ServerService) do |service|
expect(service).to receive(:readiness_check).and_return({ success: true })
end
expect(subject.http_status).to eq(200)
expect(subject.json[:status]).to eq('ok')

View file

@ -12,4 +12,175 @@ RSpec.describe Integrations::HangoutsChat do
}
end
end
let(:chat_integration) { described_class.new }
let(:webhook_url) { 'https://example.gitlab.com/' }
let(:webhook_url_regex) { /\A#{webhook_url}.*/ }
describe "#execute" do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository, :wiki_repo) }
before do
allow(chat_integration).to receive_messages(
project: project,
project_id: project.id,
webhook: webhook_url
)
WebMock.stub_request(:post, webhook_url_regex)
end
context 'with push events' do
let(:push_sample_data) do
Gitlab::DataBuilder::Push.build_sample(project, user)
end
it "adds thread key for push events" do
expect(chat_integration.execute(push_sample_data)).to be(true)
expect(WebMock).to have_requested(:post, webhook_url)
.with(query: hash_including({ "threadKey" => /push .*?/ }))
.once
end
end
context 'with issue events' do
let(:issues_sample_data) { create(:issue).to_hook_data(user) }
it "adds thread key for issue events" do
expect(chat_integration.execute(issues_sample_data)).to be(true)
expect(WebMock).to have_requested(:post, webhook_url)
.with(query: hash_including({ "threadKey" => /issue .*?/ }))
.once
end
end
context 'with merge events' do
let(:merge_sample_data) { create(:merge_request).to_hook_data(user) }
it "adds thread key for merge events" do
expect(chat_integration.execute(merge_sample_data)).to be(true)
expect(WebMock).to have_requested(:post, webhook_url)
.with(query: hash_including({ "threadKey" => /merge request .*?/ }))
.once
end
end
context 'with wiki page events' do
let(:wiki_page_sample_data) do
Gitlab::DataBuilder::WikiPage.build(create(:wiki_page, message: 'foo'), user, 'create')
end
it "adds thread key for wiki page events" do
expect(chat_integration.execute(wiki_page_sample_data)).to be(true)
expect(WebMock).to have_requested(:post, webhook_url)
.with(query: hash_including({ "threadKey" => /wiki_page .*?/ }))
.once
end
end
context 'with pipeline events' do
let(:pipeline) do
create(:ci_pipeline, :failed, project: project, sha: project.commit.sha, ref: project.default_branch)
end
let(:pipeline_sample_data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
it "adds thread key for pipeline events" do
expect(chat_integration.execute(pipeline_sample_data)).to be(true)
expect(WebMock).to have_requested(:post, webhook_url)
.with(query: hash_including({ "threadKey" => /pipeline .*?/ }))
.once
end
end
end
describe "Note events" do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository, creator: user) }
before do
allow(chat_integration).to receive_messages(
project: project,
project_id: project.id,
webhook: webhook_url
)
WebMock.stub_request(:post, webhook_url_regex)
end
context 'when commit comment event executed' do
let(:commit_note) do
create(:note_on_commit, author: user,
project: project,
commit_id: project.repository.commit.id,
note: 'a comment on a commit')
end
it "adds thread key" do
data = Gitlab::DataBuilder::Note.build(commit_note, user)
expect(chat_integration.execute(data)).to be(true)
expect(WebMock).to have_requested(:post, webhook_url)
.with(query: hash_including({ "threadKey" => /commit .*?/ }))
.once
end
end
context 'when merge request comment event executed' do
let(:merge_request_note) do
create(:note_on_merge_request, project: project,
note: "merge request note")
end
it "adds thread key" do
data = Gitlab::DataBuilder::Note.build(merge_request_note, user)
expect(chat_integration.execute(data)).to be(true)
expect(WebMock).to have_requested(:post, webhook_url)
.with(query: hash_including({ "threadKey" => /merge request .*?/ }))
.once
end
end
context 'when issue comment event executed' do
let(:issue_note) do
create(:note_on_issue, project: project, note: "issue note")
end
it "adds thread key" do
data = Gitlab::DataBuilder::Note.build(issue_note, user)
expect(chat_integration.execute(data)).to be(true)
expect(WebMock).to have_requested(:post, webhook_url)
.with(query: hash_including({ "threadKey" => /issue .*?/ }))
.once
end
end
context 'when snippet comment event executed' do
let(:snippet_note) do
create(:note_on_project_snippet, project: project,
note: "snippet note")
end
it "adds thread key" do
data = Gitlab::DataBuilder::Note.build(snippet_note, user)
expect(chat_integration.execute(data)).to be(true)
expect(WebMock).to have_requested(:post, webhook_url)
.with(query: hash_including({ "threadKey" => /snippet .*?/ }))
.once
end
end
end
end

View file

@ -127,6 +127,10 @@ RSpec.describe HealthController do
end
it 'responds with readiness checks data' do
expect_next_instance_of(Gitlab::GitalyClient::ServerService) do |service|
expect(service).to receive(:readiness_check).and_return({ success: true })
end
subject
expect(json_response['db_check']).to contain_exactly({ 'status' => 'ok' })

View file

@ -10,6 +10,14 @@ RSpec.shared_context 'with API::Markdown Snapshot shared context' do |glfm_speci
let_it_be(:user) { create(:user) }
let_it_be(:api_url) { api('/markdown', user) }
before do
# Set 'GITLAB_TEST_FOOTNOTE_ID' in order to override random number generation in
# Banzai::Filter::FootnoteFilter#random_number, and thus avoid the need to
# perform normalization on the value. See:
# https://docs.gitlab.com/ee/development/gitlab_flavored_markdown/specification_guide/#normalization
stub_env('GITLAB_TEST_FOOTNOTE_ID', 42)
end
markdown_examples, html_examples = %w[markdown.yml html.yml].map do |file_name|
yaml = File.read("#{glfm_specification_dir}/example_snapshots/#{file_name}")
YAML.safe_load(yaml, symbolize_names: true, aliases: true)

View file

@ -36,6 +36,7 @@ RSpec.shared_examples "chat integration" do |integration_name|
let_it_be_with_reload(:project) { create(:project, :repository) }
let(:webhook_url) { "https://example.gitlab.com/" }
let(:webhook_url_regex) { /\A#{webhook_url}.*/ }
before do
allow(subject).to receive_messages(
@ -45,7 +46,7 @@ RSpec.shared_examples "chat integration" do |integration_name|
webhook: webhook_url
)
WebMock.stub_request(:post, webhook_url)
WebMock.stub_request(:post, webhook_url_regex)
end
shared_examples "triggered #{integration_name} integration" do |branches_to_be_notified: nil|
@ -57,7 +58,7 @@ RSpec.shared_examples "chat integration" do |integration_name|
result = subject.execute(sample_data)
expect(result).to be(true)
expect(WebMock).to have_requested(:post, webhook_url).once.with { |req|
expect(WebMock).to have_requested(:post, webhook_url_regex).once.with { |req|
json_body = Gitlab::Json.parse(req.body).with_indifferent_access
expect(json_body).to include(payload)
}
@ -73,7 +74,7 @@ RSpec.shared_examples "chat integration" do |integration_name|
result = subject.execute(sample_data)
expect(result).to be_falsy
expect(WebMock).not_to have_requested(:post, webhook_url)
expect(WebMock).not_to have_requested(:post, webhook_url_regex)
end
end

View file

@ -22,6 +22,10 @@ RSpec.describe RepositoryCheck::DispatchWorker do
end
it 'dispatches work to RepositoryCheck::BatchWorker' do
expect_next_instance_of(Gitlab::GitalyClient::ServerService) do |service|
expect(service).to receive(:readiness_check).and_return({ success: true })
end
expect(RepositoryCheck::BatchWorker).to receive(:perform_async).at_least(:once)
subject.perform