Commit f15e5d07 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 8e4cdb89 d70ae250
......@@ -54,11 +54,11 @@ class Service < ApplicationRecord
validates :project_id, presence: true, unless: -> { template? || instance? || group_id }
validates :group_id, presence: true, unless: -> { template? || instance? || project_id }
validates :project_id, :group_id, absence: true, if: -> { template? || instance? }
validates :type, uniqueness: { scope: :project_id }, unless: -> { template? || instance? || group_id }, on: :create
validates :type, uniqueness: { scope: :group_id }, unless: -> { template? || instance? || project_id }
validates :type, presence: true
validates :template, uniqueness: { scope: :type }, if: -> { template? }
validates :instance, uniqueness: { scope: :type }, if: -> { instance? }
validates :type, uniqueness: { scope: :template }, if: :template?
validates :type, uniqueness: { scope: :instance }, if: :instance?
validates :type, uniqueness: { scope: :project_id }, if: :project_id?
validates :type, uniqueness: { scope: :group_id }, if: :group_id?
validate :validate_is_instance_or_template
validate :validate_belongs_to_project_or_group
......
---
title: Clean up uniqueness validations for service type
merge_request: 52565
author:
type: changed
......@@ -11,4 +11,4 @@ link: https://docs.gitlab.com/ee/development/documentation/styleguide.html
level: warning
ignorecase: true
swap:
'admin ?\w*': '(?:Admin Area|[Aa]dminist(ration|rator|er|rative))'
'admin ?\w*': '(?:Admin Area|[Aa]dminist(ration|rator|rators|er|rative))'
......@@ -102,6 +102,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
#### Updating GitLab
- [GitLab versions and maintenance policy](../policy/maintenance.md): Understand GitLab versions and releases (Major, Minor, Patch, Security), as well as update recommendations.
- [GitLab in maintenance mode](maintenance_mode/index.md): Put GitLab in maintenance mode.
- [Update GitLab](../update/README.md): Update guides to upgrade your installation to a new version.
- [Upgrading without downtime](../update/README.md#upgrading-without-downtime): Upgrade to a newer major, minor, or patch version of GitLab without taking your GitLab instance offline.
- [Migrate your GitLab CI/CD data to another version of GitLab](../migrate_ci_to_ce/README.md): If you have an old GitLab installation (older than 8.0), follow this guide to migrate your existing GitLab CI/CD data to another version of GitLab.
......
---
stage: Enablement
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# GitLab in maintenance mode **PREMIUM SELF**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2149) in GitLab Premium 13.9.
In maintenance mode, most write operations are disabled at the application level.
This means that GitLab is effectively in a read-only mode for all non-administrative
users (administrators are still able to edit application settings). Regular users
are able to log in to GitLab, view the interface and perform other read-only
operations, such as `git clone` or `git pull`.
## Enable maintenance mode
There are three ways to enable maintenance mode as an administrator:
- **Web UI**:
1. Navigate to the **Admin Area > Application settings > General** and toggle
the maintenance mode. You can optionally add a message for the banner as well.
1. Click **Save** for the changes to take effect.
- **API**:
```shell
curl --request PUT --header "PRIVATE-TOKEN:$ADMIN_TOKEN" "<gitlab-url>/api/v4/application/settings?maintenance_mode=true"
```
- [**Rails console**](../operations/rails_console.md#starting-a-rails-console-session):
```ruby
::Gitlab::CurrentSettings.update_attributes!(maintenance_mode: true)
::Gitlab::CurrentSettings.update_attributes!(maintenance_mode_message: "New message")
```
## Disable maintenance mode
There are three ways to disable maintenance mode:
- **Web UI**:
1. Navigate to the **Admin Area > Application settings > General** and toggle
the maintenance mode. You can optionally add a message for the banner as well.
1. Click **Save** for the changes to take effect.
- **API**:
```shell
curl --request PUT --header "PRIVATE-TOKEN:$ADMIN_TOKEN" "<gitlab-url>/api/v4/application/settings?maintenance_mode=false"
```
- [**Rails console**](../operations/rails_console.md#starting-a-rails-console-session):
```ruby
::Gitlab::CurrentSettings.update_attributes!(maintenance_mode: false)
```
## Behavior in maintenance mode
When maintenance mode is enabled, a banner is displayed at the top of the page.
The banner can be customized with a specific message.
An error is displayed when a user tries to perform a write operation that isn't allowed.
The API will return a 403 or 503 error for failed write requests.
NOTE:
In some cases, the visual feedback from an action could be misleading, for example
when starring a project, the **Star** button changes to show the **Unstar** action,
however, this is only the frontend update, and it doesn't take into account the
failed status of the POST request. These visual bugs are to be fixed
[in follow-up iterations](https://gitlab.com/gitlab-org/gitlab/-/issues/295197).
### Application settings
In maintenance mode, admins can edit the application settings. This will allow
them to disable maintenance mode after it's been enabled.
### Logging in/out
All users can log in and out of the GitLab instance.
### CI/CD
In maintenance mode:
- No new jobs are started. Already running jobs stay in 'running'
status but their logs are no longer updated.
- If the job has been in 'running' state for longer than the project's time limit,
it will **not** time out.
- Pipelines cannot be started, retried or canceled in maintenance mode.
No new jobs can be created either.
Once maintenance mode is disabled, new jobs are picked up again. The jobs that were
in the running state before enabling maintenance mode, will resume, and their logs
will start getting updated again.
### Git actions
All read-only Git operations will continue to work in maintenance mode, for example
`git clone` and `git pull`, but all write operations will fail, both through the CLI
and Web IDE.
Geo secondaries are read-only instances that allow Git pushes because they are
proxied to the primary instance. However, in maintenance mode, Git pushes to
both primary and secondaries will fail.
### Merge requests, issues, epics
All write actions except those mentioned above will fail. So, in maintenace mode, a user cannot update merge requests, issues, etc.
### Container Registry
In maintenance mode, `docker push` is blocked, but `docker pull` is available.
### Auto Deploys
It is recommended to disable auto deploys during maintenance mode, and enable
them once maintenance mode is disabled.
### Background jobs
Background jobs (cron jobs, Sidekiq) will continue running as is, because maintenance
mode does not disable any background jobs.
[During a planned Geo failover](../geo/disaster_recovery/planned_failover.md#prevent-updates-to-the-primary-node),
it is recommended that you disable all cron jobs except for those related to Geo.
You can monitor queues and disable jobs in **Admin Area > Monitoring > Background Jobs**.
### Geo secondaries
The maintenance mode setting will be propagated to the secondary as they sync up.
It is important that you do not disable replication before enabling maintenance mode.
Replication and verification will continue to work in maintenance mode.
......@@ -38,7 +38,7 @@ apt-get install ruby-dev
The Dpl provides support for vast number of services, including: Heroku, Cloud Foundry, AWS/S3, and more.
To use it simply define provider and any additional parameters required by the provider.
For example if you want to use it to deploy your application to Heroku, you need to specify `heroku` as provider, specify `api-key` and `app`.
For example if you want to use it to deploy your application to Heroku, you need to specify `heroku` as provider, specify `api_key` and `app`.
All possible parameters can be found in the [Heroku API section](https://github.com/travis-ci/dpl#heroku-api).
```yaml
......@@ -46,7 +46,7 @@ staging:
stage: deploy
script:
- gem install dpl
- dpl --provider=heroku --app=my-app-staging --api-key=$HEROKU_STAGING_API_KEY
- dpl --provider=heroku --app=my-app-staging --api_key=$HEROKU_STAGING_API_KEY
```
In the above example we use Dpl to deploy `my-app-staging` to Heroku server with API key stored in `HEROKU_STAGING_API_KEY` secure variable.
......@@ -67,7 +67,7 @@ staging:
- apt-get update -yq
- apt-get install -y ruby-dev
- gem install dpl
- dpl --provider=heroku --app=my-app-staging --api-key=$HEROKU_STAGING_API_KEY
- dpl --provider=heroku --app=my-app-staging --api_key=$HEROKU_STAGING_API_KEY
only:
- master
```
......@@ -90,7 +90,7 @@ staging:
stage: deploy
script:
- gem install dpl
- dpl --provider=heroku --app=my-app-staging --api-key=$HEROKU_STAGING_API_KEY
- dpl --provider=heroku --app=my-app-staging --api_key=$HEROKU_STAGING_API_KEY
only:
- master
......@@ -98,7 +98,7 @@ production:
stage: deploy
script:
- gem install dpl
- dpl --provider=heroku --app=my-app-production --api-key=$HEROKU_PRODUCTION_API_KEY
- dpl --provider=heroku --app=my-app-production --api_key=$HEROKU_PRODUCTION_API_KEY
only:
- tags
```
......
......@@ -70,7 +70,7 @@ The current state of existing package registries availability is:
| Maven | Yes | Yes | Yes |
| Conan | Yes | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/11679) | Yes |
| NPM | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/36853) | Yes | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/36853) |
| NuGet | Yes | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/36423) | No |
| NuGet | Yes | Yes | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/36425) |
| PyPI | Yes | No | No |
| Go | Yes | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/213900) | No - [open-issue](https://gitlab.com/gitlab-org/gitlab/-/issues/213902) |
| Composer | Yes | Yes | No |
......
......@@ -14,31 +14,32 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
| Tag | Description |
|-----|-------------|
| `:elasticsearch` | The test requires an Elasticsearch service. It is used by the [instance-level scenario](https://gitlab.com/gitlab-org/gitlab-qa#definitions) [`Test::Integration::Elasticsearch`](https://gitlab.com/gitlab-org/gitlab/-/blob/72b62b51bdf513e2936301cb6c7c91ec27c35b4d/qa/qa/ee/scenario/test/integration/elasticsearch.rb) to include only tests that require Elasticsearch. |
| `:geo` | The test requires two GitLab Geo instances - a primary and a secondary - to be spun up. |
| `:gitaly_cluster` | The test runs against a GitLab instance where repositories are stored on redundant Gitaly nodes behind a Praefect node. All nodes are [separate containers](../../../administration/gitaly/praefect.md#requirements-for-configuring-a-gitaly-cluster). Tests that use this tag have a longer setup time since there are three additional containers that need to be started. |
| `:github` | The test requires a GitHub personal access token. |
| `:group_saml` | The test requires a GitLab instance that has SAML SSO enabled at the group level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
| `:instance_saml` | The test requires a GitLab instance that has SAML SSO enabled at the instance level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
| `:jira` | The test requires a Jira Server. [GitLab-QA](https://gitlab.com/gitlab-org/gitlab-qa) provisions the Jira Server in a Docker container when the `Test::Integration::Jira` test scenario is run.
| `:kubernetes` | The test includes a GitLab instance that is configured to be run behind an SSH tunnel, allowing a TLS-accessible GitLab. This test also includes provisioning of at least one Kubernetes cluster to test against. _This tag is often be paired with `:orchestrated`._ |
| `:ldap_no_server` | The test requires a GitLab instance to be configured to use LDAP. To be used with the `:orchestrated` tag. It does not spin up an LDAP server at orchestration time. Instead, it creates the LDAP server at runtime. |
| `:ldap_no_tls` | The test requires a GitLab instance to be configured to use an external LDAP server with TLS not enabled. |
| `:ldap_tls` | The test requires a GitLab instance to be configured to use an external LDAP server with TLS enabled. |
| `:mattermost` | The test requires a GitLab Mattermost service on the GitLab instance. |
| `:object_storage` | The test requires a GitLab instance to be configured to use multiple [object storage types](../../../administration/object_storage.md). Uses MinIO as the object storage server. |
| `:only` | The test is only to be run against specific environments or pipelines. See [Environment selection](environment_selection.md) for more information. |
| `:orchestrated` | The GitLab instance under test may be [configured by `gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/what_tests_can_be_run.md#orchestrated-tests) to be different to the default GitLab configuration, or `gitlab-qa` may launch additional services in separate Docker containers, or both. Tests tagged with `:orchestrated` are excluded when testing environments where we can't dynamically modify the GitLab configuration (for example, Staging). |
| `:packages` | The test requires a GitLab instance that has the [Package Registry](../../../administration/packages/#gitlab-package-registry-administration) enabled. |
| `:quarantine` | The test has been [quarantined](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#quarantining-tests), runs in a separate job that only includes quarantined tests, and is allowed to fail. The test is skipped in its regular job so that if it fails it doesn't hold up the pipeline. Note that you can also [quarantine a test only when it runs against specific environment](environment_selection.md#quarantining-a-test-for-a-specific-environment). |
| `:relative_url` | The test requires a GitLab instance to be installed under a [relative URL](../../../install/relative_url.md). |
| `:reliable` | The test has been [promoted to a reliable test](https://about.gitlab.com/handbook/engineering/quality/guidelines/reliable-tests/#promoting-an-existing-test-to-reliable) meaning it passes consistently in all pipelines, including merge requests. |
| `:repository_storage` | The test requires a GitLab instance to be configured to use multiple [repository storage paths](../../../administration/repository_storage_paths.md). Paired with the `:orchestrated` tag. |
| `:requires_admin` | The test requires an admin account. Tests with the tag are excluded when run against Canary and Production environments. |
| `:requires_git_protocol_v2` | The test requires that Git protocol version 2 is enabled on the server. It's assumed to be enabled by default but if not the test can be skipped by setting `QA_CAN_TEST_GIT_PROTOCOL_V2` to `false`. |
| `:requires_praefect` | The test requires that the GitLab instance uses [Gitaly Cluster](../../../administration/gitaly/praefect.md) (a.k.a. Praefect) as the repository storage . It's assumed to be used by default but if not the test can be skipped by setting `QA_CAN_TEST_PRAEFECT` to `false`. |
| `:runner` | The test depends on and sets up a GitLab Runner instance, typically to run a pipeline. |
| `:skip_live_env` | The test is excluded when run against live deployed environments such as Staging, Canary, and Production. |
| `:testcase` | The link to the test case issue in the [Quality Testcases project](https://gitlab.com/gitlab-org/quality/testcases/). |
| `:mattermost` | The test requires a GitLab Mattermost service on the GitLab instance. |
| `:ldap_no_server` | The test requires a GitLab instance to be configured to use LDAP. To be used with the `:orchestrated` tag. It does not spin up an LDAP server at orchestration time. Instead, it creates the LDAP server at runtime. |
| `:ldap_no_tls` | The test requires a GitLab instance to be configured to use an external LDAP server with TLS not enabled. |
| `:ldap_tls` | The test requires a GitLab instance to be configured to use an external LDAP server with TLS enabled. |
| `:object_storage` | The test requires a GitLab instance to be configured to use multiple [object storage types](../../../administration/object_storage.md). Uses MinIO as the object storage server. |
| `:smtp` | The test requires a GitLab instance to be configured to use an SMTP server. Tests SMTP notification email delivery from GitLab by using MailHog. |
| `:group_saml` | The test requires a GitLab instance that has SAML SSO enabled at the group level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
| `:instance_saml` | The test requires a GitLab instance that has SAML SSO enabled at the instance level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
| `:skip_signup_disabled` | The test uses UI to sign up a new user and is skipped in any environment that does not allow new user registration via the UI. |
| `:smoke` | The test belongs to the test suite which verifies basic functionality of a GitLab instance.|
| `:github` | The test requires a GitHub personal access token. |
| `:repository_storage` | The test requires a GitLab instance to be configured to use multiple [repository storage paths](../../../administration/repository_storage_paths.md). Paired with the `:orchestrated` tag. |
| `:geo` | The test requires two GitLab Geo instances - a primary and a secondary - to be spun up. |
| `:relative_url` | The test requires a GitLab instance to be installed under a [relative URL](../../../install/relative_url.md). |
| `:requires_git_protocol_v2` | The test requires that Git protocol version 2 is enabled on the server. It's assumed to be enabled by default but if not the test can be skipped by setting `QA_CAN_TEST_GIT_PROTOCOL_V2` to `false`. |
| `:requires_praefect` | The test requires that the GitLab instance uses [Gitaly Cluster](../../../administration/gitaly/praefect.md) (a.k.a. Praefect) as the repository storage . It's assumed to be used by default but if not the test can be skipped by setting `QA_CAN_TEST_PRAEFECT` to `false`. |
| `:packages` | The test requires a GitLab instance that has the [Package Registry](../../../administration/packages/#gitlab-package-registry-administration) enabled. |
| `:smtp` | The test requires a GitLab instance to be configured to use an SMTP server. Tests SMTP notification email delivery from GitLab by using MailHog. |
| `:testcase` | The link to the test case issue in the [Quality Testcases project](https://gitlab.com/gitlab-org/quality/testcases/). |
| `:transient` | The test tests transient bugs. It is excluded by default. |
......@@ -147,7 +147,7 @@ Find where your version sits in the upgrade path below, and upgrade GitLab
accordingly, while also consulting the
[version-specific upgrade instructions](#version-specific-upgrading-instructions):
`8.11.x` -> `8.12.0` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.1.11` - > `13.5.3`
`8.11.x` -> `8.12.0` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.1.11` - > `13.x (latest)`
The following table, while not exhaustive, shows some examples of the supported
upgrade paths.
......
......@@ -92,10 +92,10 @@ You can authenticate using:
#### Authenticate within CI/CD
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/280582) in GitLab 13.7.
> - Automatic runner authentication [added](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27302) in GitLab 13.9
> - Automatic runner authentication [added](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27302) in GitLab 13.9.
Runners will log into the Dependency Proxy automatically. We can pull through
the dependency proxy using the `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX`
Runners log in to the Dependency Proxy automatically. To pull through
the Dependency Proxy, use the `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX`
environment variable:
```yaml
......@@ -103,7 +103,7 @@ environment variable:
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/node:latest
```
There are other additional predefined environment variables we can also use:
There are other additional predefined environment variables you can also use:
- `CI_DEPENDENCY_PROXY_USER`: A CI user for logging in to the Dependency Proxy.
- `CI_DEPENDENCY_PROXY_PASSWORD`: A CI password for logging in to the Dependency Proxy.
......@@ -111,9 +111,9 @@ There are other additional predefined environment variables we can also use:
- `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX`: The image prefix for pulling images through the Dependency Proxy.
`CI_DEPENDENCY_PROXY_SERVER` and `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX`
include the server port. So if you explicitly include the Dependency Proxy
path, the port must be included unless you have logged into the dependency
proxy manually without including the port:
include the server port. If you explicitly include the Dependency Proxy
path, the port must be included, unless you have logged into the Dependency
Proxy manually without including the port:
```shell
docker pull gitlab.example.com:443/my-group/dependency_proxy/containers/alpine:latest
......
......@@ -52,6 +52,10 @@ class VulnerabilityPresenter < Gitlab::View::Presenter::Delegated
)
end
def description
vulnerability.description || finding.description
end
private
def location_link_for(path)
......
---
title: Properly populate descriptions in an issue created from a vulnerability
merge_request: 52592
author:
type: fixed
......@@ -9,7 +9,7 @@ RSpec.describe VulnerabilityPresenter do
{ type: 'sast', status: 'success', start_time: 'placeholder', end_time: 'placeholder' }
end
let_it_be(:finding) { create(:vulnerabilities_finding, :with_secret_detection, pipelines: [pipeline], project: project) }
let_it_be(:finding) { create(:vulnerabilities_finding, :with_secret_detection, pipelines: [pipeline], project: project, description: 'Finding Description') }
let_it_be(:finding2) { create(:vulnerabilities_finding, :with_secret_detection, scan: sast_scan) }
subject { described_class.new(finding.vulnerability) }
......@@ -127,4 +127,26 @@ RSpec.describe VulnerabilityPresenter do
expect(jira_issue_description).to eq(expected_jira_issue_description)
end
end
describe '#description' do
let(:vulnerability) { finding.vulnerability }
context 'when the vulnerability description field is populated' do
it 'returns the description for the vulnerability' do
expect(subject.description).to eq(vulnerability.description)
end
end
context 'when the vulnerability description field is empty' do
before do
vulnerability.description = nil
vulnerability.save!
end
it 'returns the description for the vulnerability finding' do
expect(subject.description).not_to eq(vulnerability.description)
expect(subject.description).to eq(finding.description)
end
end
end
end
......@@ -86,6 +86,8 @@ module QA
end
def fabricate_via_api!
raise ResourceNotFoundError unless id
resource_web_url(api_get)
rescue ResourceNotFoundError
populate_target_and_source_if_required
......
......@@ -411,6 +411,10 @@ module QA
ENV.fetch('GITLAB_AGENTK_VERSION', 'v13.7.0')
end
def transient_trials
ENV.fetch('GITLAB_QA_TRANSIENT_TRIALS', 10).to_i
end
private
def remote_grid_credentials
......
......@@ -3,7 +3,7 @@
require 'securerandom'
module QA
RSpec.describe 'Release', :runner do
RSpec.describe 'Verify', :runner do
describe 'Pipelines for merged results and merge trains' do
let(:group) { Resource::Group.fabricate_via_api! }
......
# frozen_string_literal: true
require 'securerandom'
module QA
RSpec.describe 'Verify', :runner, :transient do
describe 'Merge trains transient bugs' do
let(:group) { Resource::Group.fabricate_via_api! }
let!(:runner) do
Resource::Runner.fabricate_via_api! do |runner|
runner.token = group.reload!.runners_token
runner.name = group.name
runner.tags = [group.name]
runner.project = project
end
end
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'merge-trains-transient-bugs'
project.group = group
end
end
before do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
commit.add_files(
[
{
file_path: '.gitlab-ci.yml',
content: <<~EOF
test:
tags: [#{group.name}]
script: echo 'OK'
only:
- merge_requests
EOF
}
]
)
end
Flow::Login.sign_in
project.visit!
Page::Project::Menu.perform(&:go_to_general_settings)
Page::Project::Settings::Main.perform do |main|
main.expand_merge_requests_settings do |settings|
settings.click_pipelines_for_merged_results_checkbox
settings.click_merge_trains_checkbox
settings.click_save_changes
end
end
end
after do
runner.remove_via_api! if runner
project.remove_via_api!
group.remove_via_api!
end
it 'confirms that a merge train consistently completes and updates the UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1608' do
Runtime::Env.transient_trials.times do |i|
QA::Runtime::Logger.info("Transient bug test action - Trial #{i}")
random_string_for_this_trial = SecureRandom.hex(8)
branch_name = "merge-train-#{random_string_for_this_trial}"
title = "merge train transient bug test #{random_string_for_this_trial}"
# Create a branch that will be merged into the default branch
Resource::Repository::ProjectPush.fabricate! do |project_push|
project_push.project = project
project_push.new_branch = true
project_push.branch_name = branch_name
project_push.file_name = "file-#{random_string_for_this_trial}.txt"
project_push.file_content = "merge me"
end
# Create a merge request to merge the branch we just created
Resource::MergeRequest.fabricate_via_api! do |merge_request|
merge_request.project = project
merge_request.source_branch = branch_name
merge_request.no_preparation = true
merge_request.title = title
end.visit!
Page::MergeRequest::Show.perform do |show|
pipeline_passed = show.retry_until(max_attempts: 5, sleep_interval: 5) do
show.has_pipeline_status?(/Merged result pipeline #\d+ passed/)
end
expect(pipeline_passed).to be_truthy, "Expected the merged result pipeline to pass."
show.merge_via_merge_train
# This is also tested in pipelines_for_merged_results_and_merge_trains_spec.rb as a regular e2e test.
# That test reloads the page at this point to avoid the problem of the merge status failing to update
# That's the transient UX issue this test is checking for, so if the MR is merged but the UI still shows the
# status as unmerged, the test will fail.
merge_request = project.merge_request_with_title(title)
expect(merge_request).not_to be_nil, "There was a problem fetching the merge request"
# We use the API to wait until the MR has been merged so that we know the UI should be ready to update
show.wait_until(reload: false) do
mr = Resource::MergeRequest.fabricate_via_api! do |mr|
mr.project = project
mr.id = merge_request[:iid]
end
mr.state == 'merged'
end
expect(show).to be_merged, "Expected content 'The changes were merged' but it did not appear."
expect(show).to have_pipeline_status(/Merge train pipeline #\d+ passed/)
end
end
end
end
end
end
......@@ -37,7 +37,7 @@ module QA
if tags.any?
tags.each { |tag| tags_for_rspec.push(['--tag', tag.to_s]) }
else
tags_for_rspec.push(%w[--tag ~orchestrated]) unless (%w[-t --tag] & options).any?
tags_for_rspec.push(%w[--tag ~orchestrated --tag ~transient]) unless (%w[-t --tag] & options).any?
end
tags_for_rspec.push(%w[--tag ~geo]) unless QA::Runtime::Env.geo_environment?
......
......@@ -3,9 +3,9 @@
require 'active_support/core_ext/hash'
RSpec.describe QA::Specs::Runner do
shared_examples 'excludes orchestrated and geo' do
it 'excludes the orchestrated and geo tags and includes default args' do
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS])
shared_examples 'excludes orchestrated, transient, and geo' do
it 'excludes the orchestrated, transient, and geo tags, and includes default args' do
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS])
subject.perform
end
......@@ -18,13 +18,13 @@ RSpec.describe QA::Specs::Runner do
QA::Runtime::Scenario.define(:gitlab_address, "http://gitlab.test")
end
it_behaves_like 'excludes orchestrated and geo'
it_behaves_like 'excludes orchestrated, transient, and geo'
context 'when tty is set' do
subject { described_class.new.tap { |runner| runner.tty = true } }
it 'sets the `--tty` flag' do
expect_rspec_runner_arguments(['--tty', '--tag', '~orchestrated', '--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS])
expect_rspec_runner_arguments(['--tty', '--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS])
subject.perform
end
......@@ -43,7 +43,7 @@ RSpec.describe QA::Specs::Runner do
context 'when "--tag smoke" is set as options' do
subject { described_class.new.tap { |runner| runner.options = %w[--tag smoke] } }
it 'focuses on the given tag without excluded the orchestrated tag' do
it 'focuses on the given tag without excluded tags' do
expect_rspec_runner_arguments(['--tag', '~geo', '--tag', 'smoke', *described_class::DEFAULT_TEST_PATH_ARGS])
subject.perform
......@@ -53,8 +53,8 @@ RSpec.describe QA::Specs::Runner do
context 'when "qa/specs/features/foo" is set as options' do
subject { described_class.new.tap { |runner| runner.options = %w[qa/specs/features/foo] } }
it 'passes the given tests path and excludes the orchestrated and geo tags' do
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~geo', 'qa/specs/features/foo'])
it 'passes the given tests path and excludes the orchestrated, transient, and geo tags' do
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', 'qa/specs/features/foo'])
subject.perform
end
......@@ -63,7 +63,7 @@ RSpec.describe QA::Specs::Runner do
context 'when "--tag smoke" and "qa/specs/features/foo" are set as options' do
subject { described_class.new.tap { |runner| runner.options = %w[--tag smoke qa/specs/features/foo] } }
it 'focuses on the given tag and includes the path without excluding the orchestrated tag' do
it 'focuses on the given tag and includes the path without excluding the orchestrated or transient tags' do
expect_rspec_runner_arguments(['--tag', '~geo', '--tag', 'smoke', 'qa/specs/features/foo'])
subject.perform
......@@ -76,7 +76,7 @@ RSpec.describe QA::Specs::Runner do
end
it 'includes default args and excludes the skip_signup_disabled tag' do
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~geo', '--tag', '~skip_signup_disabled', *described_class::DEFAULT_TEST_PATH_ARGS])
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', '--tag', '~skip_signup_disabled', *described_class::DEFAULT_TEST_PATH_ARGS])
subject.perform
end
......@@ -88,7 +88,7 @@ RSpec.describe QA::Specs::Runner do
end
it 'includes default args and excludes the skip_live_env tag' do
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~geo', '--tag', '~skip_live_env', *described_class::DEFAULT_TEST_PATH_ARGS])
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', '--tag', '~skip_live_env', *described_class::DEFAULT_TEST_PATH_ARGS])
subject.perform
end
end
......@@ -121,7 +121,7 @@ RSpec.describe QA::Specs::Runner do
end
it 'includes default args and excludes all unsupported tags' do
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~geo', *excluded_feature_tags_except(feature), *described_class::DEFAULT_TEST_PATH_ARGS])
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', *excluded_feature_tags_except(feature), *described_class::DEFAULT_TEST_PATH_ARGS])
subject.perform
end
......@@ -146,11 +146,11 @@ RSpec.describe QA::Specs::Runner do
end
end
it_behaves_like 'excludes orchestrated and geo'
it_behaves_like 'excludes orchestrated, transient, and geo'
end
context 'when features are not specified' do
it_behaves_like 'excludes orchestrated and geo'
it_behaves_like 'excludes orchestrated, transient, and geo'
end
end
......
/* eslint-disable global-require, import/no-unresolved */
/* eslint-disable global-require */
// We use "require" rather than `fs` so that this works in a browser environment.
/* eslint "import/no-unresolved": 0 */
// We don't want to require *all* fixtures to be generated (especailly in a local environment).
// We use `eslint` instead of `eslint-disable`, so that we also don't trigger an `Unused eslint-disable directive` when all fixtures are present.
import { memoize } from 'lodash';
const createFactoryWithDefault = (fn, defaultValue) => () => {
......
......@@ -39,35 +39,29 @@ RSpec.describe Service do
end
end
context 'with an existing service template' do
before do
context 'with existing services' do
before_all do
create(:service, :template)
create(:service, :instance)
create(:service, project: project)
create(:service, group: group, project: nil)
end
it 'validates only one service template per type' do
it 'allows only one service template per type' do
expect(build(:service, :template)).to be_invalid
end
end
context 'with an existing instance service' do
before do
create(:service, :instance)
end
it 'validates only one service instance per type' do
it 'allows only one instance service per type' do
expect(build(:service, :instance)).to be_invalid
end
end
it 'validates uniqueness of type and project_id on create' do
expect(create(:service, project: project, type: 'Service')).to be_valid
expect(build(:service, project: project, type: 'Service').valid?(:create)).to eq(false)
expect(build(:service, project: project, type: 'Service').valid?(:update)).to eq(true)
end
it 'allows only one project service per type' do
expect(build(:service, project: project)).to be_invalid
end
it 'validates uniqueness of type and group_id' do
expect(create(:service, group_id: group.id, project_id: nil, type: 'Service')).to be_valid
expect(build(:service, group_id: group.id, project_id: nil, type: 'Service')).to be_invalid
it 'allows only one group service per type' do
expect(build(:service, group: group, project: nil)).to be_invalid
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment