Commit ade18c9d authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent ba836d98
...@@ -402,7 +402,6 @@ RSpec/RepeatedExample: ...@@ -402,7 +402,6 @@ RSpec/RepeatedExample:
- 'spec/graphql/gitlab_schema_spec.rb' - 'spec/graphql/gitlab_schema_spec.rb'
- 'spec/helpers/users_helper_spec.rb' - 'spec/helpers/users_helper_spec.rb'
- 'spec/lib/banzai/filter/autolink_filter_spec.rb' - 'spec/lib/banzai/filter/autolink_filter_spec.rb'
- 'spec/lib/banzai/filter/issuable_state_filter_spec.rb'
- 'spec/lib/gitlab/closing_issue_extractor_spec.rb' - 'spec/lib/gitlab/closing_issue_extractor_spec.rb'
- 'spec/lib/gitlab/danger/changelog_spec.rb' - 'spec/lib/gitlab/danger/changelog_spec.rb'
- 'spec/lib/gitlab/git/blob_spec.rb' - 'spec/lib/gitlab/git/blob_spec.rb'
......
...@@ -208,24 +208,12 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -208,24 +208,12 @@ class Projects::BlobController < Projects::ApplicationController
.last_for_path(@repository, @ref, @path).sha .last_for_path(@repository, @ref, @path).sha
end end
def set_code_navigation_build
return if Feature.disabled?(:code_navigation, @project)
artifact =
Ci::JobArtifact
.for_sha(@blob.commit_id, @project.id)
.for_job_name(Ci::Build::CODE_NAVIGATION_JOB_NAME)
.last
@code_navigation_build = artifact&.job
end
def show_html def show_html
environment_params = @repository.branch_exists?(@ref) ? { ref: @ref } : { commit: @commit } environment_params = @repository.branch_exists?(@ref) ? { ref: @ref } : { commit: @commit }
environment_params[:find_latest] = true environment_params[:find_latest] = true
@environment = EnvironmentsFinder.new(@project, current_user, environment_params).execute.last @environment = EnvironmentsFinder.new(@project, current_user, environment_params).execute.last
@last_commit = @repository.last_commit_for_path(@commit.id, @blob.path) @last_commit = @repository.last_commit_for_path(@commit.id, @blob.path)
set_code_navigation_build @code_navigation_path = Gitlab::CodeNavigationPath.new(@project, @blob.commit_id).full_json_path_for(@blob.path)
render 'show' render 'show'
end end
......
...@@ -33,8 +33,6 @@ module Ci ...@@ -33,8 +33,6 @@ module Ci
scheduler_failure: 2 scheduler_failure: 2
}.freeze }.freeze
CODE_NAVIGATION_JOB_NAME = 'code_navigation'
has_one :deployment, as: :deployable, class_name: 'Deployment' has_one :deployment, as: :deployable, class_name: 'Deployment'
has_one :resource, class_name: 'Ci::Resource', inverse_of: :build has_one :resource, class_name: 'Ci::Resource', inverse_of: :build
has_many :trace_sections, class_name: 'Ci::BuildTraceSection' has_many :trace_sections, class_name: 'Ci::BuildTraceSection'
......
...@@ -64,6 +64,10 @@ class DiffFileEntity < DiffFileBaseEntity ...@@ -64,6 +64,10 @@ class DiffFileEntity < DiffFileBaseEntity
# Used for parallel diffs # Used for parallel diffs
expose :parallel_diff_lines, using: DiffLineParallelEntity, if: -> (diff_file, options) { parallel_diff_view?(options, diff_file) && diff_file.text? } expose :parallel_diff_lines, using: DiffLineParallelEntity, if: -> (diff_file, options) { parallel_diff_view?(options, diff_file) && diff_file.text? }
expose :code_navigation_path, if: -> (diff_file) { options[:code_navigation_path] } do |diff_file|
options[:code_navigation_path].full_json_path_for(diff_file.new_path)
end
private private
def parallel_diff_view?(options, diff_file) def parallel_diff_view?(options, diff_file)
......
...@@ -70,13 +70,21 @@ class DiffsEntity < Grape::Entity ...@@ -70,13 +70,21 @@ class DiffsEntity < Grape::Entity
expose :diff_files do |diffs, options| expose :diff_files do |diffs, options|
submodule_links = Gitlab::SubmoduleLinks.new(merge_request.project.repository) submodule_links = Gitlab::SubmoduleLinks.new(merge_request.project.repository)
DiffFileEntity.represent(diffs.diff_files, options.merge(submodule_links: submodule_links)) code_navigation_path =
Gitlab::CodeNavigationPath.new(merge_request.project, diffs.diff_refs.head_sha)
DiffFileEntity.represent(diffs.diff_files,
options.merge(submodule_links: submodule_links, code_navigation_path: code_navigation_path))
end end
expose :merge_request_diffs, using: MergeRequestDiffEntity, if: -> (_, options) { options[:merge_request_diffs]&.any? } do |diffs| expose :merge_request_diffs, using: MergeRequestDiffEntity, if: -> (_, options) { options[:merge_request_diffs]&.any? } do |diffs|
options[:merge_request_diffs] options[:merge_request_diffs]
end end
expose :definition_path_prefix, if: -> (diff_file) { Feature.enabled?(:code_navigation, merge_request.project) } do |diffs|
project_blob_path(merge_request.project, diffs.diff_refs.head_sha)
end
def merge_request def merge_request
options[:merge_request] options[:merge_request]
end end
......
...@@ -10,7 +10,11 @@ class PaginatedDiffEntity < Grape::Entity ...@@ -10,7 +10,11 @@ class PaginatedDiffEntity < Grape::Entity
expose :diff_files do |diffs, options| expose :diff_files do |diffs, options|
submodule_links = Gitlab::SubmoduleLinks.new(merge_request.project.repository) submodule_links = Gitlab::SubmoduleLinks.new(merge_request.project.repository)
DiffFileEntity.represent(diffs.diff_files, options.merge(submodule_links: submodule_links)) code_navigation_path =
Gitlab::CodeNavigationPath.new(merge_request.project, diffs.diff_refs.head_sha)
DiffFileEntity.represent(diffs.diff_files,
options.merge(submodule_links: submodule_links, code_navigation_path: code_navigation_path))
end end
expose :pagination do expose :pagination do
......
...@@ -45,9 +45,30 @@ module Metrics ...@@ -45,9 +45,30 @@ module Metrics
# Returns a new dashboard Hash, supplemented with DB info # Returns a new dashboard Hash, supplemented with DB info
def process_dashboard def process_dashboard
::Gitlab::Metrics::Dashboard::Processor # Get the dashboard from cache/disk before beginning the benchmark.
.new(project, raw_dashboard, sequence, process_params) dashboard = raw_dashboard
.process processed_dashboard = nil
benchmark_processing do
processed_dashboard = ::Gitlab::Metrics::Dashboard::Processor
.new(project, dashboard, sequence, process_params)
.process
end
processed_dashboard
end
def benchmark_processing
output = nil
processing_time_seconds = Benchmark.realtime { output = yield }
if output
processing_time_metric.observe(
processing_time_metric_labels,
processing_time_seconds * 1_000
)
end
end end
def process_params def process_params
...@@ -72,6 +93,26 @@ module Metrics ...@@ -72,6 +93,26 @@ module Metrics
def sequence def sequence
SEQUENCE SEQUENCE
end end
def processing_time_metric
@processing_time_metric ||= ::Gitlab::Metrics.summary(
:gitlab_metrics_dashboard_processing_time_ms,
'Metrics dashboard processing time in milliseconds'
)
end
def processing_time_metric_labels
{
stages: sequence_string,
service: self.class.name
}
end
# If @sequence is [STAGES::CommonMetricsInserter, STAGES::CustomMetricsInserter],
# this function will output `CommonMetricsInserter-CustomMetricsInserter`.
def sequence_string
sequence.map { |stage_class| stage_class.to_s.split('::').last }.join('-')
end
end end
end end
end end
......
...@@ -9,9 +9,8 @@ ...@@ -9,9 +9,8 @@
= render "projects/blob/auxiliary_viewer", blob: blob = render "projects/blob/auxiliary_viewer", blob: blob
#blob-content-holder.blob-content-holder #blob-content-holder.blob-content-holder
- if @code_navigation_build - if @code_navigation_path
- code_nav_url = raw_project_job_artifacts_url(@project, @code_navigation_build, path: "lsif/#{blob.path}") #js-code-navigation{ data: { code_nav_url: @code_navigation_path, definition_path_prefix: project_blob_path(@project, @ref) } }
#js-code-navigation{ data: { code_nav_url: "#{code_nav_url}.json", definition_path_prefix: project_blob_path(@project, @ref) } }
%article.file-holder %article.file-holder
= render 'projects/blob/header', blob: blob = render 'projects/blob/header', blob: blob
= render 'projects/blob/content', blob: blob = render 'projects/blob/content', blob: blob
---
title: Optimize suggestions counters
merge_request: 26443
author:
type: performance
...@@ -71,7 +71,6 @@ ...@@ -71,7 +71,6 @@
- kubernetes_management - kubernetes_management
- language_specific - language_specific
- license_compliance - license_compliance
- live_coding
- load_testing - load_testing
- logging - logging
- malware_scanning - malware_scanning
......
# frozen_string_literal: true
class AddIndexOnAuthorIdAndCreatedAtAndIdToNotes < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_index :notes, [:author_id, :created_at, :id]
remove_concurrent_index :notes, [:author_id, :created_at]
end
def down
add_concurrent_index :notes, [:author_id, :created_at]
remove_concurrent_index :notes, [:author_id, :created_at, :id]
end
end
...@@ -9519,7 +9519,7 @@ CREATE INDEX index_namespaces_on_type_partial ON public.namespaces USING btree ( ...@@ -9519,7 +9519,7 @@ CREATE INDEX index_namespaces_on_type_partial ON public.namespaces USING btree (
CREATE UNIQUE INDEX index_note_diff_files_on_diff_note_id ON public.note_diff_files USING btree (diff_note_id); CREATE UNIQUE INDEX index_note_diff_files_on_diff_note_id ON public.note_diff_files USING btree (diff_note_id);
CREATE INDEX index_notes_on_author_id_and_created_at ON public.notes USING btree (author_id, created_at); CREATE INDEX index_notes_on_author_id_and_created_at_and_id ON public.notes USING btree (author_id, created_at, id);
CREATE INDEX index_notes_on_commit_id ON public.notes USING btree (commit_id); CREATE INDEX index_notes_on_commit_id ON public.notes USING btree (commit_id);
...@@ -12925,5 +12925,6 @@ COPY "schema_migrations" (version) FROM STDIN; ...@@ -12925,5 +12925,6 @@ COPY "schema_migrations" (version) FROM STDIN;
20200326144443 20200326144443
20200326145443 20200326145443
20200330074719 20200330074719
20200330132913
\. \.
...@@ -256,9 +256,9 @@ application server, or a Gitaly node. ...@@ -256,9 +256,9 @@ application server, or a Gitaly node.
```ruby ```ruby
# Name of storage hash must match storage name in git_data_dirs on GitLab # Name of storage hash must match storage name in git_data_dirs on GitLab
# server ('praefect') and in git_data_dirs on Gitaly nodes ('gitaly-1') # server ('storage_1') and in git_data_dirs on Gitaly nodes ('gitaly-1')
praefect['virtual_storages'] = { praefect['virtual_storages'] = {
'praefect' => { 'storage_1' => {
'gitaly-1' => { 'gitaly-1' => {
'address' => 'tcp://GITALY_HOST:8075', 'address' => 'tcp://GITALY_HOST:8075',
'token' => 'PRAEFECT_INTERNAL_TOKEN', 'token' => 'PRAEFECT_INTERNAL_TOKEN',
...@@ -430,7 +430,7 @@ documentation](index.md#3-gitaly-server-configuration). ...@@ -430,7 +430,7 @@ documentation](index.md#3-gitaly-server-configuration).
gitlab-ctl restart gitaly gitlab-ctl restart gitaly
``` ```
**Complete these steps for each Gitaly node!** **The steps above must be completed for each Gitaly node!**
After all Gitaly nodes are configured, you can run the Praefect connection After all Gitaly nodes are configured, you can run the Praefect connection
checker to verify Praefect can connect to all Gitaly servers in the Praefect checker to verify Praefect can connect to all Gitaly servers in the Praefect
...@@ -442,6 +442,34 @@ config. ...@@ -442,6 +442,34 @@ config.
sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes
``` ```
1. Enable automatic failover by editing `/etc/gitlab/gitlab.rb`:
```ruby
praefect['failover_enabled'] = true
```
When automatic failover is enabled, Praefect checks the health of internal
Gitaly nodes. If the primary has a certain amount of health checks fail, it
will promote one of the secondaries to be primary, and demote the primary to
be a secondary.
Manual failover is possible by updating `praefect['virtual_storages']` and
nominating a new primary node.
NOTE: **Note:**: Automatic failover is not yet supported for setups with
multiple Praefect nodes. There is currently no coordination between Praefect
nodes, which could result in two Praefect instances thinking two different
Gitaly nodes are the primary. Follow issue
[#2547](https://gitlab.com/gitlab-org/gitaly/-/issues/2547) for
updates.
1. Save the changes to `/etc/gitlab/gitlab.rb` and [reconfigure
Praefect](../restart_gitlab.md#omnibus-gitlab-reconfigure):
```shell
gitlab-ctl reconfigure
```
### GitLab ### GitLab
To complete this section you will need: To complete this section you will need:
...@@ -560,133 +588,80 @@ Particular attention should be shown to: ...@@ -560,133 +588,80 @@ Particular attention should be shown to:
- Deselect the **default** storage location - Deselect the **default** storage location
- Select the **praefect** storage location - Select the **praefect** storage location
![Update repository storage](img/praefect_storage_v12_10.png)
1. Verify everything is still working by creating a new project. Check the 1. Verify everything is still working by creating a new project. Check the
"Initialize repository with a README" box so that there is content in the "Initialize repository with a README" box so that there is content in the
repository that viewed. If the project is created, and you can see the repository that viewed. If the project is created, and you can see the
README file, it works! README file, it works!
Congratulations! You have configured a highly available Praefect cluster. ### Grafana
### Failover
There are two ways to do a failover from one internal Gitaly node to another as the primary. Manually, or automatically. Grafana is included with GitLab, and can be used to monitor your Praefect
cluster. See [Grafana Dashboard
As an example, in this `config.toml` we have one virtual storage named "default" with two internal Gitaly nodes behind it. Service](https://docs.gitlab.com/omnibus/settings/grafana.html)
One is deemed the "primary". This means that read and write traffic will go to `internal_storage_0`, and writes for detailed documentation.
will get replicated to `internal_storage_1`:
```toml
socket_path = "/path/to/Praefect.socket"
# failover_enabled will enable automatic failover
failover_enabled = false
[logging]
format = "json"
level = "info"
[[virtual_storage]]
name = "default"
[[virtual_storage.node]]
name = "internal_storage_0"
address = "tcp://localhost:9999"
primary = true
token = "supersecret"
[[virtual_storage.node]] To get started quickly:
name = "internal_storage_1"
address = "tcp://localhost:9998"
token = "supersecret"
```
#### Manual failover 1. SSH into the **GitLab** node and login as root:
In order to failover from using one internal Gitaly node to using another, a manual failover step can be used. Unless `failover_enabled` is set to `true` ```shell
in the `config.toml`, the only way to fail over from one primary to using another node as the primary is to do a manual failover. sudo -i
```
1. Move `primary = true` from the current `[[virtual_storage.node]]` to another node in `/etc/gitlab/gitlab.rb`: 1. Enable the Grafana login form by editing `/etc/gitlab/gitlab.rb`.
```ruby ```ruby
praefect['virtual_storages'] = { grafana['disable_login_form'] = false
'praefect' => {
'gitaly-1' => {
'address' => 'tcp://GITALY_HOST:8075',
'token' => 'PRAEFECT_INTERNAL_TOKEN',
# no longer the primary
},
'gitaly-2' => {
'address' => 'tcp://GITALY_HOST:8075',
'token' => 'PRAEFECT_INTERNAL_TOKEN',
# this is the new primary
'primary' => true
},
'gitaly-3' => {
'address' => 'tcp://GITALY_HOST:8075',
'token' => 'PRAEFECT_INTERNAL_TOKEN',
}
}
}
``` ```
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure). 1. Save the changes to `/etc/gitlab/gitlab.rb` and [reconfigure
GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure):
On a restart, Praefect will send write traffic to `internal_storage_1`. `internal_storage_0` is the new secondary now, ```shell
and replication jobs will be created to replicate repository data to `internal_storage_0` **from** `internal_storage_1` gitlab-ctl reconfigure
```
#### Automatic failover 1. Set the Grafana admin password. This command will prompt you to enter a new
password:
When automatic failover is enabled, Praefect will do automatic detection of the health of internal Gitaly nodes. If the ```shell
primary has a certain amount of health checks fail, it will decide to promote one of the secondaries to be primary, and gitlab-ctl set-grafana-password
demote the primary to be a secondary. ```
1. To enable automatic failover, edit `/etc/gitlab/gitlab.rb`: 1. In your web browser, open `/-/grafana` (e.g.
`https://gitlab.example.com/-/grafana`) on your GitLab server.
```ruby Login using the password you set, and the username `admin`.
# failover_enabled turns on automatic failover
praefect['failover_enabled'] = true
praefect['virtual_storages'] = {
'praefect' => {
'gitaly-1' => {
'address' => 'tcp://GITALY_HOST:8075',
'token' => 'PRAEFECT_INTERNAL_TOKEN',
'primary' => true
},
'gitaly-2' => {
'address' => 'tcp://GITALY_HOST:8075',
'token' => 'PRAEFECT_INTERNAL_TOKEN'
},
'gitaly-3' => {
'address' => 'tcp://GITALY_HOST:8075',
'token' => 'PRAEFECT_INTERNAL_TOKEN'
}
}
}
```
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure). 1. Go to **Explore** and query `gitlab_build_info` to verify that you are
getting metrics from all your machines.
Below is the picture when Praefect starts up with the config.toml above: Congratulations! You've configured an observable highly available Praefect
cluster.
```mermaid ## Automatic failover and leader election
graph TD
A[Praefect] -->|Mutator RPC| B(internal_storage_0)
B --> |Replication|C[internal_storage_1]
```
Let's say suddenly `internal_storage_0` goes down. Praefect will detect this and Praefect regularly checks the health of each backend Gitaly node. This
automatically switch over to `internal_storage_1`, and `internal_storage_0` will serve as a secondary: information can be used to automatically failover to a new primary node if the
current primary node is found to be unhealthy.
```mermaid - **Manual:** Automatic failover is disabled. The primary node can be
graph TD reconfigured in `/etc/gitlab/gitlab.rb` on the Praefect node. Modify the
A[Praefect] -->|Mutator RPC| B(internal_storage_1) `praefect['virtual_storages']` field by moving the `primary = true` to promote
B --> |Replication|C[internal_storage_0] a different Gitaly node to primary. In the steps above, `gitaly-1` was set to
``` the primary.
- **Memory:** Enabled by setting `praefect['failover_enabled'] = true` in
`/etc/gitlab/gitlab.rb` on the Praefect node. If a sufficient number of health
checks fail for the current primary backend Gitaly node, and new primary will
be elected. **Do not use with multiple Praefect nodes!** Using with multiple
Praefect nodes is likely to result in a split brain.
- **PostgreSQL:** Coming soon. See isse
[#2547](https://gitlab.com/gitlab-org/gitaly/-/issues/2547) for updates.
NOTE: **Note:**: Currently this feature is supported for setups that only have 1 Praefect instance. Praefect instances running, It is likely that we will implement support for Consul, and a cloud native
for example behind a load balancer, `failover_enabled` should be disabled. The reason is The reason is because there strategy in the future.
is no coordination that currently happens across different Praefect instances, so there could be a situation where
two Praefect instances think two different Gitaly nodes are the primary.
## Backend Node Recovery ## Backend Node Recovery
...@@ -711,49 +686,6 @@ The command will return a list of repositories that were found to be ...@@ -711,49 +686,6 @@ The command will return a list of repositories that were found to be
inconsistent against the current primary. Each of these inconsistencies will inconsistent against the current primary. Each of these inconsistencies will
also be logged with an accompanying replication job ID. also be logged with an accompanying replication job ID.
## Grafana
Grafana is included with GitLab, and can be used to monitor your Praefect
cluster. See [Grafana Dashboard
Service](https://docs.gitlab.com/omnibus/settings/grafana.html)
for detailed documentation.
To get started quickly:
1. SSH into the **GitLab** node and login as root:
```shell
sudo -i
```
1. Enable the Grafana login form by editing `/etc/gitlab/gitlab.rb`.
```ruby
grafana['disable_login_form'] = false
```
1. Save the changes to `/etc/gitlab/gitlab.rb` and [reconfigure
GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure):
```shell
gitlab-ctl reconfigure
```
1. Set the Grafana admin password. This command will prompt you to enter a new
password:
```shell
gitlab-ctl set-grafana-password
```
1. In your web browser, open `/-/grafana` (e.g.
`https://gitlab.example.com/-/grafana`) on your GitLab server.
Login using the password you set, and the username `admin`.
1. Go to **Explore** and query `gitlab_build_info` to verify that you are
getting metrics from all your machines.
## Migrating existing repositories to Praefect ## Migrating existing repositories to Praefect
If your GitLab instance already has repositories, these won't be migrated If your GitLab instance already has repositories, these won't be migrated
......
...@@ -92,6 +92,7 @@ The following metrics are available: ...@@ -92,6 +92,7 @@ The following metrics are available:
| `failed_login_captcha_total` | Gauge | 11.0 | Counter of failed CAPTCHA attempts during login | | | `failed_login_captcha_total` | Gauge | 11.0 | Counter of failed CAPTCHA attempts during login | |
| `successful_login_captcha_total` | Gauge | 11.0 | Counter of successful CAPTCHA attempts during login | | | `successful_login_captcha_total` | Gauge | 11.0 | Counter of successful CAPTCHA attempts during login | |
| `auto_devops_pipelines_completed_total` | Counter | 12.7 | Counter of completed Auto DevOps pipelines, labeled by status | | | `auto_devops_pipelines_completed_total` | Counter | 12.7 | Counter of completed Auto DevOps pipelines, labeled by status | |
| `gitlab_metrics_dashboard_processing_time_ms` | Summary | 12.10 | Metrics dashboard processing time in milliseconds | service, stages |
## Metrics controlled by a feature flag ## Metrics controlled by a feature flag
......
# frozen_string_literal: true
module Gitlab
class CodeNavigationPath
include Gitlab::Utils::StrongMemoize
include Gitlab::Routing
CODE_NAVIGATION_JOB_NAME = 'code_navigation'
def initialize(project, commit_sha)
@project = project
@commit_sha = commit_sha
end
def full_json_path_for(path)
return if Feature.disabled?(:code_navigation, project)
return unless build
raw_project_job_artifacts_path(project, build, path: "lsif/#{path}.json")
end
private
attr_reader :project, :commit_sha
def build
strong_memoize(:build) do
artifact = ::Ci::JobArtifact
.for_sha(commit_sha, project.id)
.for_job_name(CODE_NAVIGATION_JOB_NAME)
.last
artifact&.job
end
end
end
end
...@@ -118,32 +118,6 @@ describe Projects::BlobController do ...@@ -118,32 +118,6 @@ describe Projects::BlobController do
end end
end end
end end
context 'when there is an artifact with code navigation data' do
let!(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.id) }
let!(:job) { create(:ci_build, pipeline: pipeline, name: Ci::Build::CODE_NAVIGATION_JOB_NAME) }
let!(:artifact) { create(:ci_job_artifact, :lsif, job: job) }
let(:id) { 'master/README.md' }
it 'assigns code_navigation_build variable' do
request
expect(assigns[:code_navigation_build]).to eq(job)
end
context 'when code_navigation feature is disabled' do
before do
stub_feature_flags(code_navigation: false)
end
it 'does not assign code_navigation_build variable' do
request
expect(assigns[:code_navigation_build]).to be_nil
end
end
end
end end
describe 'GET diff' do describe 'GET diff' do
......
...@@ -156,20 +156,6 @@ describe Banzai::Filter::IssuableStateFilter do ...@@ -156,20 +156,6 @@ describe Banzai::Filter::IssuableStateFilter do
expect(doc.css('a').last.text).to eq(merge_request.to_reference) expect(doc.css('a').last.text).to eq(merge_request.to_reference)
end end
it 'ignores reopened merge request references' do
merge_request = create_merge_request(:opened)
link = create_link(
merge_request.to_reference,
merge_request: merge_request.id,
reference_type: 'merge_request'
)
doc = filter(link, context)
expect(doc.css('a').last.text).to eq(merge_request.to_reference)
end
it 'ignores locked merge request references' do it 'ignores locked merge request references' do
merge_request = create_merge_request(:locked) merge_request = create_merge_request(:locked)
......
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::CodeNavigationPath do
context 'when there is an artifact with code navigation data' do
let(:project) { create(:project, :repository) }
let(:sha) { project.commit.id }
let(:build_name) { Gitlab::CodeNavigationPath::CODE_NAVIGATION_JOB_NAME }
let(:path) { 'lib/app.rb' }
let!(:pipeline) { create(:ci_pipeline, project: project, sha: sha) }
let!(:job) { create(:ci_build, pipeline: pipeline, name: build_name) }
let!(:artifact) { create(:ci_job_artifact, :lsif, job: job) }
subject { described_class.new(project, sha).full_json_path_for(path) }
it 'assigns code_navigation_build variable' do
expect(subject).to eq("/#{project.full_path}/-/jobs/#{job.id}/artifacts/raw/lsif/#{path}.json")
end
context 'when code_navigation feature is disabled' do
before do
stub_feature_flags(code_navigation: false)
end
it 'does not assign code_navigation_build variable' do
expect(subject).to be_nil
end
end
end
end
...@@ -5,7 +5,7 @@ require 'spec_helper' ...@@ -5,7 +5,7 @@ require 'spec_helper'
describe DiffFileEntity do describe DiffFileEntity do
include RepoHelpers include RepoHelpers
let(:project) { create(:project, :repository) } let_it_be(:project) { create(:project, :repository) }
let(:repository) { project.repository } let(:repository) { project.repository }
let(:commit) { project.commit(sample_commit.id) } let(:commit) { project.commit(sample_commit.id) }
let(:diff_refs) { commit.diff_refs } let(:diff_refs) { commit.diff_refs }
...@@ -21,10 +21,11 @@ describe DiffFileEntity do ...@@ -21,10 +21,11 @@ describe DiffFileEntity do
end end
context 'when there is a merge request' do context 'when there is a merge request' do
let_it_be(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:code_navigation_path) { Gitlab::CodeNavigationPath.new(project, project.commit.sha) }
let(:request) { EntityRequest.new(project: project, current_user: user) } let(:request) { EntityRequest.new(project: project, current_user: user) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } let(:entity) { described_class.new(diff_file, options.merge(request: request, merge_request: merge_request, code_navigation_path: code_navigation_path)) }
let(:entity) { described_class.new(diff_file, options.merge(request: request, merge_request: merge_request)) }
let(:exposed_urls) { %i(edit_path view_path context_lines_path) } let(:exposed_urls) { %i(edit_path view_path context_lines_path) }
it_behaves_like 'diff file entity' it_behaves_like 'diff file entity'
...@@ -32,6 +33,7 @@ describe DiffFileEntity do ...@@ -32,6 +33,7 @@ describe DiffFileEntity do
it 'exposes additional attributes' do it 'exposes additional attributes' do
expect(subject).to include(*exposed_urls) expect(subject).to include(*exposed_urls)
expect(subject).to include(:replaced_view_path) expect(subject).to include(:replaced_view_path)
expect(subject).to include(:code_navigation_path)
end end
it 'points all urls to merge request target project' do it 'points all urls to merge request target project' do
......
...@@ -23,7 +23,7 @@ describe DiffsEntity do ...@@ -23,7 +23,7 @@ describe DiffsEntity do
:start_version, :latest_diff, :latest_version_path, :start_version, :latest_diff, :latest_version_path,
:added_lines, :removed_lines, :render_overflow_warning, :added_lines, :removed_lines, :render_overflow_warning,
:email_patch_path, :plain_diff_path, :diff_files, :email_patch_path, :plain_diff_path, :diff_files,
:merge_request_diffs :merge_request_diffs, :definition_path_prefix
) )
end end
end end
......
...@@ -28,8 +28,8 @@ describe DiffsMetadataEntity do ...@@ -28,8 +28,8 @@ describe DiffsMetadataEntity do
:start_version, :latest_diff, :latest_version_path, :start_version, :latest_diff, :latest_version_path,
:added_lines, :removed_lines, :render_overflow_warning, :added_lines, :removed_lines, :render_overflow_warning,
:email_patch_path, :plain_diff_path, :email_patch_path, :plain_diff_path,
:merge_request_diffs, :merge_request_diffs, :context_commits,
:context_commits, :definition_path_prefix,
# Attributes # Attributes
:diff_files :diff_files
) )
......
...@@ -16,10 +16,20 @@ describe Metrics::Dashboard::CustomDashboardService, :use_clean_rails_memory_sto ...@@ -16,10 +16,20 @@ describe Metrics::Dashboard::CustomDashboardService, :use_clean_rails_memory_sto
describe '#get_dashboard' do describe '#get_dashboard' do
let(:dashboard_path) { '.gitlab/dashboards/test.yml' } let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] } let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
let(:service_call) { described_class.new(*service_params).get_dashboard } let(:service_call) { subject.get_dashboard }
subject { described_class.new(*service_params) }
context 'when the dashboard does not exist' do context 'when the dashboard does not exist' do
it_behaves_like 'misconfigured dashboard service response', :not_found it_behaves_like 'misconfigured dashboard service response', :not_found
it 'does not update gitlab_metrics_dashboard_processing_time_ms metric', :prometheus do
service_call
metric = subject.send(:processing_time_metric)
labels = subject.send(:processing_time_metric_labels)
expect(metric.get(labels)).to eq(0)
end
end end
it_behaves_like 'raises error for users with insufficient permissions' it_behaves_like 'raises error for users with insufficient permissions'
...@@ -28,6 +38,7 @@ describe Metrics::Dashboard::CustomDashboardService, :use_clean_rails_memory_sto ...@@ -28,6 +38,7 @@ describe Metrics::Dashboard::CustomDashboardService, :use_clean_rails_memory_sto
let(:project) { project_with_dashboard(dashboard_path) } let(:project) { project_with_dashboard(dashboard_path) }
it_behaves_like 'valid dashboard service response' it_behaves_like 'valid dashboard service response'
it_behaves_like 'updates gitlab_metrics_dashboard_processing_time_ms metric'
it 'caches the unprocessed dashboard for subsequent calls' do it 'caches the unprocessed dashboard for subsequent calls' do
expect_any_instance_of(described_class) expect_any_instance_of(described_class)
......
...@@ -36,9 +36,12 @@ describe Metrics::Dashboard::PodDashboardService, :use_clean_rails_memory_store_ ...@@ -36,9 +36,12 @@ describe Metrics::Dashboard::PodDashboardService, :use_clean_rails_memory_store_
describe '#get_dashboard' do describe '#get_dashboard' do
let(:dashboard_path) { described_class::DASHBOARD_PATH } let(:dashboard_path) { described_class::DASHBOARD_PATH }
let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] } let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
let(:service_call) { described_class.new(*service_params).get_dashboard } let(:service_call) { subject.get_dashboard }
subject { described_class.new(*service_params) }
it_behaves_like 'valid dashboard service response' it_behaves_like 'valid dashboard service response'
it_behaves_like 'caches the unprocessed dashboard for subsequent calls' it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
it_behaves_like 'updates gitlab_metrics_dashboard_processing_time_ms metric'
end end
end end
...@@ -16,11 +16,14 @@ describe Metrics::Dashboard::SelfMonitoringDashboardService, :use_clean_rails_me ...@@ -16,11 +16,14 @@ describe Metrics::Dashboard::SelfMonitoringDashboardService, :use_clean_rails_me
describe '#get_dashboard' do describe '#get_dashboard' do
let(:service_params) { [project, user, { environment: environment }] } let(:service_params) { [project, user, { environment: environment }] }
let(:service_call) { described_class.new(*service_params).get_dashboard } let(:service_call) { subject.get_dashboard }
subject { described_class.new(*service_params) }
it_behaves_like 'valid dashboard service response' it_behaves_like 'valid dashboard service response'
it_behaves_like 'raises error for users with insufficient permissions' it_behaves_like 'raises error for users with insufficient permissions'
it_behaves_like 'caches the unprocessed dashboard for subsequent calls' it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
it_behaves_like 'updates gitlab_metrics_dashboard_processing_time_ms metric'
end end
describe '.all_dashboard_paths' do describe '.all_dashboard_paths' do
......
...@@ -16,11 +16,14 @@ describe Metrics::Dashboard::SystemDashboardService, :use_clean_rails_memory_sto ...@@ -16,11 +16,14 @@ describe Metrics::Dashboard::SystemDashboardService, :use_clean_rails_memory_sto
describe '#get_dashboard' do describe '#get_dashboard' do
let(:dashboard_path) { described_class::DASHBOARD_PATH } let(:dashboard_path) { described_class::DASHBOARD_PATH }
let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] } let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
let(:service_call) { described_class.new(*service_params).get_dashboard } let(:service_call) { subject.get_dashboard }
subject { described_class.new(*service_params) }
it_behaves_like 'valid dashboard service response' it_behaves_like 'valid dashboard service response'
it_behaves_like 'raises error for users with insufficient permissions' it_behaves_like 'raises error for users with insufficient permissions'
it_behaves_like 'caches the unprocessed dashboard for subsequent calls' it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
it_behaves_like 'updates gitlab_metrics_dashboard_processing_time_ms metric'
context 'when called with a non-system dashboard' do context 'when called with a non-system dashboard' do
let(:dashboard_path) { 'garbage/dashboard/path' } let(:dashboard_path) { 'garbage/dashboard/path' }
......
...@@ -118,3 +118,13 @@ RSpec.shared_examples 'misconfigured dashboard service response with stepable' d ...@@ -118,3 +118,13 @@ RSpec.shared_examples 'misconfigured dashboard service response with stepable' d
expect(result[:message]).to eq(message) if message expect(result[:message]).to eq(message) if message
end end
end end
RSpec.shared_examples 'updates gitlab_metrics_dashboard_processing_time_ms metric' do
specify :prometheus do
service_call
metric = subject.send(:processing_time_metric)
labels = subject.send(:processing_time_metric_labels)
expect(metric.get(labels)).to be > 0
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