Add latest changes from gitlab-org/gitlab@14-4-stable-ee

This commit is contained in:
GitLab Bot 2021-11-08 10:33:01 +00:00
parent 305ea394ef
commit 6edb7e9bb1
19 changed files with 383 additions and 66 deletions

View File

@ -430,7 +430,7 @@
height: $input-height;
}
.issue-boards-content {
.issue-boards-content:not(.breadcrumbs) {
isolation: isolate;
}

View File

@ -13,7 +13,7 @@ class LegacyDiffNote < Note
validates :line_code, presence: true, line_code: true
before_create :set_diff
before_create :set_diff, unless: :skip_setting_st_diff?
def discussion_class(*)
LegacyDiffDiscussion
@ -90,6 +90,10 @@ class LegacyDiffNote < Note
self.st_diff = diff.to_hash if diff
end
def skip_setting_st_diff?
st_diff.present? && importing?
end
def diff_for_line_code
attributes = {
noteable_type: noteable_type,

View File

@ -27,12 +27,17 @@ class ProtectedBranch < ApplicationRecord
# Check if branch name is marked as protected in the system
def self.protected?(project, ref_name)
return true if project.empty_repo? && project.default_branch_protected?
return false if ref_name.blank?
Rails.cache.fetch("protected_ref-#{ref_name}-#{project.cache_key}") do
Rails.cache.fetch(protected_ref_cache_key(project, ref_name)) do
self.matching(ref_name, protected_refs: protected_refs(project)).present?
end
end
def self.protected_ref_cache_key(project, ref_name)
"protected_ref-#{project.cache_key}-#{Digest::SHA1.hexdigest(ref_name)}"
end
def self.allow_force_push?(project, ref_name)
project.protected_branches.allowing_force_push.matching(ref_name).any?
end

View File

@ -2,7 +2,7 @@
- @no_breadcrumb_container = true
- @no_container = true
- @content_wrapper_class = "#{@content_wrapper_class} gl-relative"
- @content_class = "js-focus-mode-board"
- @content_class = "issue-boards-content js-focus-mode-board"
- is_epic_board = board.to_type == "EpicBoard"
- if is_epic_board
- breadcrumb_title _("Epic Boards")

View File

@ -0,0 +1,60 @@
- title: Scheduled DAST scans
body: |
GitLabs Dynamic Application Security Testing (DAST) now supports scheduled on-demand scans. Previously, on-demand DAST scans could only be manually triggered, which limited the usability to scans that you wanted to run immediately. With this new scheduler, you can set a DAST scan to run either once at a specific time in the future, or on a recurring basis. If adding DAST to your pipelines is not an option for your organization, or if the security or compliance regulations for your area require a scan to be scheduled, this feature provides an easy way to create a scheduled scan to meet your needs. The scan can be associated with the default branch, which allows for the results to show on the Secure Dashboard and Vulnerability list. Combined with the scan and site profiles, the scheduled on-demand scans give you quick and easy access to DAST results for your application or API, on a schedule that works for your development and security teams.
stage: Secure
self-managed: true
gitlab-com: true
packages: [Ultimate]
url: 'https://docs.gitlab.com/ee/user/application_security/dast/index.html#schedule-an-on-demand-scan'
image_url: https://about.gitlab.com/images/14_4/dast_on_demand_schedule.png
published_at: 2021-10-22
release: 14.4
- title: Remote Repositories for GitLab in Visual Studio Code
body: |
When working in your editor you may need to refer to another project or upstream library for additional information. When you don't have that project already cloned locally, you're forced to either leave your editor and browse the project on GitLab, or locate and then clone the project so you can browse it in your editor. Both of those tasks break your current context, introduce delays, and can take you to a less familiar interface for working with code.
[GitLab Workflow](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow) version `3.33.0` provides an option to open a remote repository. Open the command palette and use the `GitLab: Open Remote Repository` command to find and then open a project.
Opening a remote repository allows you to browse a read-only version of a project in your familiar VS Code environment. You can then quickly find the information you're looking for, compare an implementation, or copy a snippet you need.
stage: Create
self-managed: true
gitlab-com: true
packages: [Free, Premium, Ultimate]
url: 'https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/blob/main/README.md#browse-a-repository-without-cloning'
image_url: https://img.youtube.com/vi/p4GTVx_Nd2s/hqdefault.jpg
published_at: 2021-10-22
release: 14.4
- title: The GitLab Operator is Generally Available
body: |
GitLab 14.4 is proud to announce the general availability of [the GitLab Operator](https://about.gitlab.com/blog/2021/10/12/open-shift-ga/), with the ability to run production instances of GitLab on Kubernetes platforms, including Red Hat OpenShift. The GitLab Operator also automates day 2 operations such as upgrading components, application reconfiguration, and autoscaling. Check out the [GitLab Operator installation documentation](https://docs.gitlab.com/charts/installation/operator.html) for additional information.
stage: Enablement
self-managed: true
gitlab-com: false
packages: [Free, Premium, Ultimate]
url: 'https://docs.gitlab.com/charts/installation/operator.html'
image_url: https://img.youtube.com/vi/sEBnuhzYD2I/hqdefault.jpg
published_at: 2021-10-22
release: 14.4
- title: DevOps Adoption trend graph
body: |
In GitLab 14.4, we added a new graph to group-level DevOps Adoption for trend over time. This graph shows you how groups adopt DevOps features over time and can give insights into how quickly groups are adopting additional DevOps processes. This is broken down by Dev, Sec, and Ops functionality.
stage: Manage
self-managed: true
gitlab-com: true
packages: [Ultimate]
url: 'https://docs.gitlab.com/ee/user/group/devops_adoption/#adoption-over-time'
image_url: https://about.gitlab.com/images/14_4/devops_adop_table.png
published_at: 2021-10-22
release: 14.4
- title: Integrated error tracking inside GitLab without a Sentry instance
body: |
Prior to GitLab 14.4, you could integrate with Sentry Error Tracking by supplying an endpoint for a Sentry backend (either self-deployed or in their cloud service). With Gitlab 14.4, you now have access to a Sentry-compatible backend built into your GitLab instance. This allows you to quickly instrument your apps so your errors show up directly in GitLab without the need for a separate Sentry instance.
stage: Manage
self-managed: true
gitlab-com: true
packages: [Free, Premium, Ultimate]
url: 'https://docs.gitlab.com/ee/operations/error_tracking.html#integrated-error-tracking'
image_url: https://about.gitlab.com/images/14_4/monitor-integrated-error-tracking.png
published_at: 2021-10-22
release: 14.4

View File

@ -6,7 +6,9 @@ class AddTemporaryIndexToIssueMetrics < Gitlab::Database::Migration[1.0]
INDEX_NAME = 'index_issue_metrics_first_mentioned_in_commit'
def up
add_concurrent_index :issue_metrics, :issue_id, where: 'EXTRACT(YEAR FROM first_mentioned_in_commit_at) > 2019', name: INDEX_NAME
condition = Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt::TmpIssueMetrics
.first_mentioned_in_commit_at_condition
add_concurrent_index :issue_metrics, :issue_id, where: condition, name: INDEX_NAME
end
def down

View File

@ -8,8 +8,8 @@ class ScheduleFixFirstMentionedInCommitAtJob < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
scope = define_batchable_model('issue_metrics')
.where('EXTRACT(YEAR FROM first_mentioned_in_commit_at) > 2019')
scope = Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt::TmpIssueMetrics
.from_2020
queue_background_migration_jobs_by_range_at_intervals(
scope,

View File

@ -1581,11 +1581,29 @@ all state associated with a given repository including:
sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml remove-repository -virtual-storage <virtual-storage> -repository <repository>
```
- `-virtual-storage` is the virtual storage the repository is located in.
- `-repository` is the repository's relative path in the storage.
- `-virtual-storage` is the virtual storage the repository is located in. Virtual storages are configured in `/etc/gitlab/gitlab.rb` under `praefect['virtual_storages]` and looks like the following:
Sometimes parts of the repository continue to exist after running `remove-repository`. This can be caused
because of:
```ruby
praefect['virtual_storages'] = {
'default' => {
...
},
'storage-1' => {
...
}
}
```
In this example, the virtual storage to specify is `default` or `storage-1`.
- `-repository` is the repository's relative path in the storage [beginning with `@hashed`](../repository_storage_types.md#hashed-storage).
For example:
```plaintext
@hashed/f5/ca/f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b.git
```
Parts of the repository can continue to exist after running `remove-repository`. This can be because of:
- A deletion error.
- An in-flight RPC call targeting the repository.
@ -1609,8 +1627,53 @@ The command outputs:
Each entry is a complete JSON string with a newline at the end (configurable using the
`-delimiter` flag). For example:
```shell
```plaintext
sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml list-untracked-repositories
{"virtual_storage":"default","storage":"gitaly-1","relative_path":"@hashed/ab/cd/abcd123456789012345678901234567890123456789012345678901234567890.git"}
{"virtual_storage":"default","storage":"gitaly-1","relative_path":"@hashed/ab/cd/abcd123456789012345678901234567890123456789012345678901234567891.git"}
```
### Manually track repositories
> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5658) in GitLab 14.4.
The `track-repository` Praefect sub-command adds repositories on disk to the Praefect database to be tracked.
```shell
sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml track-repository -virtual-storage <virtual-storage> -repository <repository>
```
- `-virtual-storage` is the virtual storage the repository is located in. Virtual storages are configured in `/etc/gitlab/gitlab.rb` under `praefect['virtual_storages]` and looks like the following:
```ruby
praefect['virtual_storages'] = {
'default' => {
...
},
'storage-1' => {
...
}
}
```
In this example, the virtual storage to specify is `default` or `storage-1`.
- `-repository` is the repository's relative path in the storage [beginning with `@hashed`](../repository_storage_types.md#hashed-storage).
For example:
```plaintext
@hashed/f5/ca/f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b.git
```
- `-authoritative-storage` is the storage we want Praefect to treat as the primary. Required if
[per-repository replication](#configure-replication-factor) is set as the replication strategy.
The command outputs:
- Results to `STDOUT` and the command's logs.
- Errors to `STDERR`.
This command fails if:
- The repository is already being tracked by the Praefect database.
- The repository does not exist on disk.

View File

@ -50,7 +50,7 @@ If the highest number stable branch is unclear, check the [GitLab blog](https://
| Software | Minimum version | Notes |
| -------- | --------------- | ----- |
| [Ruby](#2-ruby) | `2.7` | From GitLab 13.6, Ruby 2.7 is required. Ruby 3.0 is not supported yet (see [the relevant epic](https://gitlab.com/groups/gitlab-org/-/epics/5149) for the current status). You must use the standard MRI implementation of Ruby. We love [JRuby](https://www.jruby.org/) and [Rubinius](https://github.com/rubinius/rubinius#the-rubinius-language-platform), but GitLab needs several Gems that have native extensions. |
| [Go](#3-go) | `1.15` | |
| [Go](#3-go) | `1.16` | |
| [Git](#git) | `2.33.x` | From GitLab 14.4, Git 2.33.x and later is required. It's highly recommended that you use the [Git version provided by Gitaly](#git). |
| [Node.js](#4-node) | `12.22.1` | GitLab uses [webpack](https://webpack.js.org/) to compile frontend assets. Node.js 14.x is recommended, as it's faster. You can check which version you're running with `node -v`. You need to update it to a newer version if needed. |
@ -251,11 +251,11 @@ page](https://golang.org/dl).
# Remove former Go installation folder
sudo rm -rf /usr/local/go
curl --remote-name --progress-bar "https://dl.google.com/go/go1.15.12.linux-amd64.tar.gz"
echo 'bbdb935699e0b24d90e2451346da76121b2412d30930eabcd80907c230d098b7 go1.15.12.linux-amd64.tar.gz' | shasum -a256 -c - && \
sudo tar -C /usr/local -xzf go1.15.12.linux-amd64.tar.gz
sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/
rm go1.15.12.linux-amd64.tar.gz
curl --remote-name --progress-bar "https://golang.org/dl/go1.16.10.linux-amd64.tar.gz"
echo '414cd18ce1d193769b9e97d2401ad718755ab47816e13b2a1cde203d263b55cf go1.16.10.linux-amd64.tar.gz' | shasum -a256 -c - && \
sudo tar -C /usr/local -xzf go1.16.10.linux-amd64.tar.gz
sudo ln -sf /usr/local/go/bin/{go,gofmt} /usr/local/bin/
rm go1.16.10.linux-amd64.tar.gz
```
## 4. Node

View File

@ -107,12 +107,11 @@ Download and install Go (for Linux, 64-bit):
# Remove former Go installation folder
sudo rm -rf /usr/local/go
curl --remote-name --progress-bar "https://dl.google.com/go/go1.15.12.linux-amd64.tar.gz"
echo 'bbdb935699e0b24d90e2451346da76121b2412d30930eabcd80907c230d098b7 go1.15.12.linux-amd64.tar.gz' | shasum -a256 -c - && \
sudo tar -C /usr/local -xzf go1.15.12.linux-amd64.tar.gz
sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/
rm go1.15.12.linux-amd64.tar.gz
curl --remote-name --progress-bar "https://golang.org/dl/go1.16.10.linux-amd64.tar.gz"
echo '414cd18ce1d193769b9e97d2401ad718755ab47816e13b2a1cde203d263b55cf go1.16.10.linux-amd64.tar.gz' | shasum -a256 -c - && \
sudo tar -C /usr/local -xzf go1.16.10.linux-amd64.tar.gz
sudo ln -sf /usr/local/go/bin/{go,gofmt} /usr/local/bin/
rm go1.16.10.linux-amd64.tar.gz
```
### 6. Update Git

View File

@ -14,7 +14,15 @@ module Gitlab
self.table_name = 'issue_metrics'
def self.from_2020
where('EXTRACT(YEAR FROM first_mentioned_in_commit_at) > 2019')
where(first_mentioned_in_commit_at_condition)
end
def self.first_mentioned_in_commit_at_condition
if columns_hash['first_mentioned_in_commit_at'].sql_type == 'timestamp without time zone'
'EXTRACT(YEAR FROM first_mentioned_in_commit_at) > 2019'
else
"EXTRACT(YEAR FROM first_mentioned_in_commit_at at time zone 'UTC') > 2019"
end
end
end
# rubocop: enable Style/Documentation

View File

@ -52,7 +52,10 @@ module Gitlab
connection = host.connection
return yield connection
rescue StandardError => error
if serialization_failure?(error)
if primary_only?
# If we only have primary configured, retrying is pointless
raise error
elsif serialization_failure?(error)
# This error can occur when a query conflicts. See
# https://www.postgresql.org/docs/current/static/hot-standby.html#HOT-STANDBY-CONFLICT
# for more information.

View File

@ -28,15 +28,21 @@ module Gitlab
#
# The worker classes aren't constants here, because that would force
# Application Settings to be loaded earlier causing failures loading
# the environmant in rake tasks
# the environment in rake tasks
EXEMPT_WORKER_NAMES = ["BackgroundMigrationWorker", "Database::BatchedBackgroundMigrationWorker"].to_set
JOB_STATUS_KEY = 'size_limiter'
class << self
def validate!(worker_class, job)
return if EXEMPT_WORKER_NAMES.include?(worker_class.to_s)
return if validated?(job)
new(worker_class, job).validate!
end
def validated?(job)
job.has_key?(JOB_STATUS_KEY)
end
end
DEFAULT_SIZE_LIMIT = 0
@ -64,6 +70,8 @@ module Gitlab
end
def validate!
@job[JOB_STATUS_KEY] = 'validated'
job_args = compress_if_necessary(::Sidekiq.dump_json(@job['args']))
return if @size_limit == 0
@ -72,8 +80,10 @@ module Gitlab
exception = exceed_limit_error(job_args)
if compress_mode?
@job.delete(JOB_STATUS_KEY)
raise exception
else
@job[JOB_STATUS_KEY] = 'tracked'
track(exception)
end
end

View File

@ -48,7 +48,7 @@ module QA
# with the attribute `data-qa-selector` since such element is not unique when the
# `is-focused` class is not set, and it was not possible to find a better solution.
def focused_board
find('.js-focus-mode-board.is-focused')
find('.issue-boards-content.js-focus-mode-board.is-focused')
end
def boards_dropdown

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20211004110500_add_temporary_index_to_issue_metrics.rb')
RSpec.describe Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt, :migration, schema: 20211004110500 do
let(:namespaces) { table(:namespaces) }
@ -99,42 +100,67 @@ RSpec.describe Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt, :migrat
.perform(issue_metrics.minimum(:issue_id), issue_metrics.maximum(:issue_id))
end
it "marks successful slices as completed" do
min_issue_id = issue_metrics.minimum(:issue_id)
max_issue_id = issue_metrics.maximum(:issue_id)
shared_examples 'fixes first_mentioned_in_commit_at' do
it "marks successful slices as completed" do
min_issue_id = issue_metrics.minimum(:issue_id)
max_issue_id = issue_metrics.maximum(:issue_id)
expect(subject).to receive(:mark_job_as_succeeded).with(min_issue_id, max_issue_id)
expect(subject).to receive(:mark_job_as_succeeded).with(min_issue_id, max_issue_id)
subject.perform(min_issue_id, max_issue_id)
end
subject.perform(min_issue_id, max_issue_id)
end
context 'when the persisted first_mentioned_in_commit_at is later than the first commit authored_date' do
it 'updates the issue_metrics record' do
record1 = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: Time.current)
record2 = issue_metrics.create!(issue_id: issue2.id, first_mentioned_in_commit_at: Time.current)
context 'when the persisted first_mentioned_in_commit_at is later than the first commit authored_date' do
it 'updates the issue_metrics record' do
record1 = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: Time.current)
record2 = issue_metrics.create!(issue_id: issue2.id, first_mentioned_in_commit_at: Time.current)
run_migration
record1.reload
record2.reload
run_migration
record1.reload
record2.reload
expect(record1.first_mentioned_in_commit_at).to be_within(2.seconds).of(commit2.authored_date)
expect(record2.first_mentioned_in_commit_at).to be_within(2.seconds).of(commit3.authored_date)
expect(record1.first_mentioned_in_commit_at).to be_within(2.seconds).of(commit2.authored_date)
expect(record2.first_mentioned_in_commit_at).to be_within(2.seconds).of(commit3.authored_date)
end
end
context 'when the persisted first_mentioned_in_commit_at is earlier than the first commit authored_date' do
it 'does not update the issue_metrics record' do
record = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: 20.days.ago)
expect { run_migration }.not_to change { record.reload.first_mentioned_in_commit_at }
end
end
context 'when the first_mentioned_in_commit_at is null' do
it 'does nothing' do
record = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: nil)
expect { run_migration }.not_to change { record.reload.first_mentioned_in_commit_at }
end
end
end
context 'when the persisted first_mentioned_in_commit_at is earlier than the first commit authored_date' do
it 'does not update the issue_metrics record' do
record = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: 20.days.ago)
expect { run_migration }.not_to change { record.reload.first_mentioned_in_commit_at }
end
describe 'running the migration when first_mentioned_in_commit_at is timestamp without time zone' do
it_behaves_like 'fixes first_mentioned_in_commit_at'
end
context 'when the first_mentioned_in_commit_at is null' do
it 'does nothing' do
record = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: nil)
describe 'running the migration when first_mentioned_in_commit_at is timestamp with time zone' do
around do |example|
AddTemporaryIndexToIssueMetrics.new.down
expect { run_migration }.not_to change { record.reload.first_mentioned_in_commit_at }
ActiveRecord::Base.connection.execute "ALTER TABLE issue_metrics ALTER first_mentioned_in_commit_at type timestamp with time zone"
Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt::TmpIssueMetrics.reset_column_information
AddTemporaryIndexToIssueMetrics.new.up
example.run
AddTemporaryIndexToIssueMetrics.new.down
ActiveRecord::Base.connection.execute "ALTER TABLE issue_metrics ALTER first_mentioned_in_commit_at type timestamp without time zone"
Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt::TmpIssueMetrics.reset_column_information
AddTemporaryIndexToIssueMetrics.new.up
end
it_behaves_like 'fixes first_mentioned_in_commit_at'
end
end

View File

@ -140,6 +140,24 @@ RSpec.describe Gitlab::Database::LoadBalancing::LoadBalancer, :request_store do
lb.read { raise conflict_error }
end
context 'only primary is configured' do
let(:lb) do
config = Gitlab::Database::LoadBalancing::Configuration.new(ActiveRecord::Base)
allow(config).to receive(:load_balancing_enabled?).and_return(false)
described_class.new(config)
end
it 'does not retry a query on connection error if only the primary is configured' do
host = double(:host, query_cache_enabled: true)
allow(lb).to receive(:host).and_return(host)
allow(host).to receive(:connection).and_raise(PG::UnableToSend)
expect { lb.read }.to raise_error(PG::UnableToSend)
end
end
it 'uses the primary if no secondaries are available' do
allow(lb).to receive(:connection_error?).and_return(true)

View File

@ -187,37 +187,51 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_fai
context 'when size limit is 0' do
let(:size_limit) { 0 }
let(:job) { job_payload(a: 'a' * 300) }
it 'does not track jobs' do
expect(Gitlab::ErrorTracking).not_to receive(:track_exception)
validate.call(TestSizeLimiterWorker, job_payload(a: 'a' * 300))
validate.call(TestSizeLimiterWorker, job)
end
it 'does not raise exception' do
expect do
validate.call(TestSizeLimiterWorker, job_payload(a: 'a' * 300))
validate.call(TestSizeLimiterWorker, job)
end.not_to raise_error
end
it 'marks the job as validated' do
validate.call(TestSizeLimiterWorker, job)
expect(job['size_limiter']).to eq('validated')
end
end
context 'when job size is bigger than size limit' do
let(:size_limit) { 50 }
let(:job) { job_payload(a: 'a' * 300) }
it 'tracks job' do
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(
be_a(Gitlab::SidekiqMiddleware::SizeLimiter::ExceedLimitError)
)
validate.call(TestSizeLimiterWorker, job_payload(a: 'a' * 100))
validate.call(TestSizeLimiterWorker, job)
end
it 'does not raise an exception' do
expect do
validate.call(TestSizeLimiterWorker, job_payload(a: 'a' * 300))
validate.call(TestSizeLimiterWorker, job)
end.not_to raise_error
end
it 'marks the job as tracked' do
validate.call(TestSizeLimiterWorker, job)
expect(job['size_limiter']).to eq('tracked')
end
context 'when the worker has big_payload attribute' do
before do
worker_class.big_payload!
@ -238,20 +252,33 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_fai
validate.call('TestSizeLimiterWorker', job_payload(a: 'a' * 300))
end.not_to raise_error
end
it 'marks the job as validated' do
validate.call(TestSizeLimiterWorker, job)
expect(job['size_limiter']).to eq('validated')
end
end
end
context 'when job size is less than size limit' do
let(:size_limit) { 50 }
let(:job) { job_payload(a: 'a') }
it 'does not track job' do
expect(Gitlab::ErrorTracking).not_to receive(:track_exception)
validate.call(TestSizeLimiterWorker, job_payload(a: 'a'))
validate.call(TestSizeLimiterWorker, job)
end
it 'does not raise an exception' do
expect { validate.call(TestSizeLimiterWorker, job_payload(a: 'a')) }.not_to raise_error
expect { validate.call(TestSizeLimiterWorker, job) }.not_to raise_error
end
it 'marks the job as validated' do
validate.call(TestSizeLimiterWorker, job)
expect(job['size_limiter']).to eq('validated')
end
end
end
@ -266,7 +293,13 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_fai
it 'does not raise an exception' do
expect(::Gitlab::SidekiqMiddleware::SizeLimiter::Compressor).not_to receive(:compress)
expect { validate.call(TestSizeLimiterWorker, job_payload(a: 'a')) }.not_to raise_error
expect { validate.call(TestSizeLimiterWorker, job) }.not_to raise_error
end
it 'marks the job as validated' do
validate.call(TestSizeLimiterWorker, job)
expect(job['size_limiter']).to eq('validated')
end
end
@ -283,6 +316,12 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_fai
validate.call(TestSizeLimiterWorker, job)
end.not_to raise_error
end
it 'marks the job as validated' do
validate.call(TestSizeLimiterWorker, job)
expect(job['size_limiter']).to eq('validated')
end
end
context 'when job size is bigger than compression threshold and size limit is 0' do
@ -299,6 +338,12 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_fai
validate.call(TestSizeLimiterWorker, job)
end.not_to raise_error
end
it 'marks the job as validated' do
validate.call(TestSizeLimiterWorker, job)
expect(job['size_limiter']).to eq('validated')
end
end
context 'when the job was already compressed' do
@ -326,6 +371,8 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_fai
expect do
validate.call(TestSizeLimiterWorker, job)
end.to raise_error(Gitlab::SidekiqMiddleware::SizeLimiter::ExceedLimitError)
expect(job['size_limiter']).to eq(nil)
end
it 'does not raise an exception when the worker allows big payloads' do
@ -338,6 +385,8 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_fai
expect do
validate.call(TestSizeLimiterWorker, job)
end.not_to raise_error
expect(job['size_limiter']).to eq('validated')
end
end
end
@ -363,6 +412,29 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_fai
validate.call(class_name.constantize, job_payload)
end
end
it "skips jobs that are already validated" do
expect(described_class).to receive(:new).once.and_call_original
job = job_payload
described_class.validate!(TestSizeLimiterWorker, job)
described_class.validate!(TestSizeLimiterWorker, job)
end
end
describe '.validated?' do
let(:job) { job_payload }
it 'returns true when the job is already validated' do
described_class.validate!(TestSizeLimiterWorker, job)
expect(described_class.validated?(job)).to eq(true)
end
it 'returns false when job is not yet validated' do
expect(described_class.validated?(job)).to eq(false)
end
end
describe '#validate!' do

View File

@ -8,4 +8,46 @@ RSpec.describe LegacyDiffNote do
it { is_expected.to eq('note') }
end
describe 'callbacks' do
describe '#set_diff' do
let(:note) do
build(:legacy_diff_note_on_merge_request, st_diff: '_st_diff_').tap do |record|
record.instance_variable_set(:@diff, {})
end
end
context 'when not importing' do
it 'updates st_diff' do
note.save!(validate: false)
expect(note.st_diff).to eq({})
end
end
context 'when importing' do
before do
note.importing = true
end
it 'does not update st_diff' do
note.save!(validate: false)
expect(note.st_diff).to eq('_st_diff_')
end
context 'when st_diff is blank' do
before do
note.st_diff = nil
end
it 'updates st_diff' do
note.save!(validate: false)
expect(note.st_diff).to eq({})
end
end
end
end
end
end

View File

@ -163,27 +163,32 @@ RSpec.describe ProtectedBranch do
expect(described_class.protected?(project, 'staging/some-branch')).to eq(false)
end
it 'returns false when branch name is nil' do
expect(described_class.protected?(project, nil)).to eq(false)
end
context 'with caching', :use_clean_rails_memory_store_caching do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:protected_branch) { create(:protected_branch, project: project, name: "jawn") }
let_it_be(:protected_branch) { create(:protected_branch, project: project, name: "jawn") }
before do
allow(described_class).to receive(:matching).once.and_call_original
allow(described_class).to receive(:matching).with(protected_branch.name, protected_refs: anything).once.and_call_original
# the original call works and warms the cache
described_class.protected?(project, 'jawn')
described_class.protected?(project, protected_branch.name)
end
it 'correctly invalidates a cache' do
expect(described_class).to receive(:matching).once.and_call_original
expect(described_class).to receive(:matching).with(protected_branch.name, protected_refs: anything).once.and_call_original
create(:protected_branch, project: project, name: "bar")
# the cache is invalidated because the project has been "updated"
expect(described_class.protected?(project, 'jawn')).to eq(true)
expect(described_class.protected?(project, protected_branch.name)).to eq(true)
end
it 'correctly uses the cached version' do
expect(described_class).not_to receive(:matching)
expect(described_class.protected?(project, 'jawn')).to eq(true)
expect(described_class.protected?(project, protected_branch.name)).to eq(true)
end
end
end