Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-03-17 03:08:05 +00:00
parent 149436d2a5
commit e6ac8e40c2
24 changed files with 341 additions and 142 deletions

View File

@ -96,6 +96,8 @@ export default class Todos {
target.setAttribute('disabled', true);
target.classList.add('disabled');
target.querySelector('.gl-spinner-container').classList.add('gl-mr-2');
axios[target.dataset.method](target.dataset.href)
.then(({ data }) => {
this.updateRowState(target);
@ -118,6 +120,8 @@ export default class Todos {
target.removeAttribute('disabled');
target.classList.remove('disabled');
target.querySelector('.gl-spinner-container').classList.remove('gl-mr-2');
if (isInactive === true) {
restoreBtn.classList.add('hidden');
doneBtn.classList.remove('hidden');
@ -140,6 +144,8 @@ export default class Todos {
target.setAttribute('disabled', true);
target.classList.add('disabled');
target.querySelector('.gl-spinner-container').classList.add('gl-mr-2');
axios[target.dataset.method](target.dataset.href, {
ids: this.todo_ids,
})
@ -163,6 +169,8 @@ export default class Todos {
target.removeAttribute('disabled');
target.classList.remove('disabled');
target.querySelector('.gl-spinner-container').classList.remove('gl-mr-2');
this.todo_ids = target === markAllDoneBtn ? data.updated_ids : [];
undoAllBtn.classList.toggle('hidden');
markAllDoneBtn.classList.toggle('hidden');

View File

@ -7,7 +7,7 @@ class Analytics::CycleAnalytics::Aggregation < ApplicationRecord
validates :incremental_runtimes_in_seconds, :incremental_processed_records, :last_full_run_runtimes_in_seconds, :last_full_run_processed_records, presence: true, length: { maximum: 10 }, allow_blank: true
scope :priority_order, -> { order('last_incremental_run_at ASC NULLS FIRST') }
scope :priority_order, -> (column_to_sort = :last_incremental_run_at) { order(arel_table[column_to_sort].asc.nulls_first) }
scope :enabled, -> { where('enabled IS TRUE') }
def estimated_next_run_at
@ -55,17 +55,17 @@ class Analytics::CycleAnalytics::Aggregation < ApplicationRecord
connection.select_value("(#{max})")
end
def self.load_batch(last_run_at, batch_size = 100)
def self.load_batch(last_run_at, column_to_query = :last_incremental_run_at, batch_size = 100)
last_run_at_not_set = Analytics::CycleAnalytics::Aggregation
.enabled
.where(last_incremental_run_at: nil)
.priority_order
.where(column_to_query => nil)
.priority_order(column_to_query)
.limit(batch_size)
last_run_at_before = Analytics::CycleAnalytics::Aggregation
.enabled
.where('last_incremental_run_at < ?', last_run_at)
.priority_order
.where(arel_table[column_to_query].lt(last_run_at))
.priority_order(column_to_query)
.limit(batch_size)
Analytics::CycleAnalytics::Aggregation

View File

@ -50,12 +50,12 @@
.todo-actions.gl-ml-3
- if todo.pending?
= link_to dashboard_todo_path(todo), method: :delete, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-done-todo', data: { href: dashboard_todo_path(todo) } do
= gl_loading_icon(inline: true, css_class: 'gl-mr-2')
= gl_loading_icon(inline: true)
Done
= link_to restore_dashboard_todo_path(todo), method: :patch, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-undo-todo hidden', data: { href: restore_dashboard_todo_path(todo) } do
= gl_loading_icon(inline: true, css_class: 'gl-mr-2')
= gl_loading_icon(inline: true)
Undo
- else
= link_to restore_dashboard_todo_path(todo), method: :patch, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-add-todo', data: { href: restore_dashboard_todo_path(todo) } do
= gl_loading_icon(inline: true, css_class: 'gl-mr-2')
= gl_loading_icon(inline: true)
Add a to do

View File

@ -22,10 +22,10 @@
- if @allowed_todos.any?(&:pending?)
.gl-mr-3
= link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'gl-button btn btn-default btn-loading align-items-center js-todos-mark-all', method: :delete, data: { href: destroy_all_dashboard_todos_path(todos_filter_params) } do
= gl_loading_icon(inline: true, css_class: 'gl-mr-2')
= gl_loading_icon(inline: true)
= s_("Todos|Mark all as done")
= link_to bulk_restore_dashboard_todos_path, class: 'gl-button btn btn-default btn-loading align-items-center js-todos-undo-all hidden', method: :patch , data: { href: bulk_restore_dashboard_todos_path(todos_filter_params) } do
= gl_loading_icon(inline: true, css_class: 'gl-mr-2')
= gl_loading_icon(inline: true)
= s_("Todos|Undo mark all as done")
.todos-filters

View File

@ -0,0 +1,8 @@
---
name: vsa_consistency_worker
introduced_by_url:
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/355709
milestone: '14.9'
type: development
group: group::optimize
default_enabled: false

View File

@ -628,6 +628,9 @@ Gitlab.ee do
Settings.cron_jobs['analytics_cycle_analytics_incremental_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['analytics_cycle_analytics_incremental_worker']['cron'] ||= '*/10 * * * *'
Settings.cron_jobs['analytics_cycle_analytics_incremental_worker']['job_class'] = 'Analytics::CycleAnalytics::IncrementalWorker'
Settings.cron_jobs['analytics_cycle_analytics_consistency_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['analytics_cycle_analytics_consistency_worker']['cron'] ||= '*/30 * * * *'
Settings.cron_jobs['analytics_cycle_analytics_consistency_worker']['job_class'] = 'Analytics::CycleAnalytics::ConsistencyWorker'
Settings.cron_jobs['active_user_count_threshold_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['active_user_count_threshold_worker']['cron'] ||= '0 12 * * *'
Settings.cron_jobs['active_user_count_threshold_worker']['job_class'] = 'ActiveUserCountThresholdWorker'

View File

@ -44,6 +44,9 @@ There are two kinds of events logged:
- Instance events scoped to the whole GitLab instance, used by your Compliance team to
perform formal audits.
NOTE:
Some events are recorded and available only as [streaming audit events](audit_event_streaming.md).
### Impersonation data
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/536) in GitLab 13.0.

View File

@ -30,8 +30,7 @@ From left to right, the performance bar displays:
is enabled. It shows which server role was used for the query.
"Primary" means that the query was sent to the read/write primary server.
"Replica" means it was sent to a read-only replica.
- **Configuration name**: shows up only when the
`GITLAB_MULTIPLE_DATABASE_METRICS` environment variable is set. This is
- **Configuration name**: this is
used to distinguish between different databases configured for different
GitLab features. The name shown is the same name used to configure database
connections in GitLab.

View File

@ -1388,15 +1388,20 @@ This can happen if your `gitlab-secrets.json` file is out of date between GitLab
Pages. Follow steps 8-10 of [Running GitLab Pages on a separate server](#running-gitlab-pages-on-a-separate-server),
in all of your GitLab Pages instances.
### Intermittent 502 errors when using an AWS Network Load Balancer and GitLab Pages is running on multiple application servers
### Intermittent 502 errors when using an AWS Network Load Balancer and GitLab Pages
Connections will time out when using a Network Load Balancer with client IP preservation enabled and [the request is looped back to the source server](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-troubleshooting.html#loopback-timeout).
This can happen to GitLab instances with multiple servers
running both the core GitLab application and GitLab Pages.
running both the core GitLab application and GitLab Pages. This can also happen when a single
container is running both the core GitLab application and GitLab Pages.
AWS [recommends using an IP target type](https://aws.amazon.com/premiumsupport/knowledge-center/target-connection-fails-load-balancer/)
to resolve this issue.
Turning off [client IP preservation](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#client-ip-preservation)
may resolve this issue when the core GitLab application and GitLab Pages run on the same host or
container.
### 500 error with `securecookie: failed to generate random iv` and `Failed to save the session`
This problem most likely results from an [out-dated operating system](../package_information/supported_os.md#os-versions-that-are-no-longer-supported).

View File

@ -270,12 +270,10 @@ build pipelines:
[used (see `variables:` section)](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/.gitlab-ci.yml) when building
the `image:docs-lint-markdown`.
1. Install [`vale`](https://github.com/errata-ai/vale/releases). For example, to install using
`brew` for macOS, run:
1. Install [`vale`](https://github.com/errata-ai/vale/releases). To install for:
```shell
brew install vale
```
- macOS using `brew`, run: `brew install vale`.
- Linux, use your distribution's package manager or a [released binary](https://github.com/errata-ai/vale/releases).
These tools can be [integrated with your code editor](#configure-editors).

View File

@ -13,6 +13,9 @@ If a mailer argument needs to be added or removed, it is important to ensure
both backward and forward compatibility. Adhere to the Sidekiq steps for
[changing the arguments for a worker](sidekiq/compatibility_across_updates.md#changing-the-arguments-for-a-worker).
The same applies to a new mailer method, or a new mailer. If you introduce either,
follow the steps for [adding new workers](sidekiq/compatibility_across_updates.md#adding-new-workers).
In the following example from [`NotificationService`](https://gitlab.com/gitlab-org/gitlab/-/blob/33ccb22e4fc271dbaac94b003a7a1a2915a13441/app/services/notification_service.rb#L74)
adding or removing an argument in this mailer's definition may cause problems
during deployment before all Rails and Sidekiq nodes have the updated code.

View File

@ -69,7 +69,8 @@ stages in the `.gitlab-ci.yml` file, the `test` stage is required.
To run dependency scanning jobs, by default, you need GitLab Runner with the
[`docker`](https://docs.gitlab.com/runner/executors/docker.html) or
[`kubernetes`](https://docs.gitlab.com/runner/install/kubernetes.html) executor.
If you're using the shared runners on GitLab.com, this is enabled by default.
If you're using the shared runners on GitLab.com, this is enabled by default. The analyzer images
provided are for the Linux/amd64 architecture.
WARNING:
If you use your own runners, make sure your installed version of Docker

View File

@ -108,7 +108,8 @@ The remaining records are truncated when this limit is reached.
## Merge request violations
> Introduced in GitLab 14.6. [Deployed behind the `compliance_violations_report` flag](../../../administration/feature_flags.md). Disabled by default.
> - Introduced in GitLab 14.6. [Deployed behind the `compliance_violations_report` flag](../../../administration/feature_flags.md). Disabled by default.
> - GraphQL API [introduced](https://gitlab.com/groups/gitlab-org/-/epics/7222) in GitLab 14.9.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available,
@ -123,10 +124,10 @@ that exist in projects in a specific group. For each separation of duties compli
- Reason for the compliance violation.
- A link to the merge request that caused the compliance violation.
Merge request violations can only be access in the GitLab UI, but issues are tracking adding:
Merge request violations can be accessed:
- [A GraphQL type to allow retrieval of compliance violations](https://gitlab.com/gitlab-org/gitlab/-/issues/347325).
- [Consuming the merge request violations GraphQL type in the user interface](https://gitlab.com/gitlab-org/gitlab/-/issues/342897).
- In the GitLab UI.
- Using the [GraphQL API](../../../api/graphql/reference/index.md#complianceviolation) (GitLab 14.9 and later).
### View merge request violations
@ -134,3 +135,34 @@ To view merge request violations:
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Security & Compliance > Compliance report**.
### Severity levels scale
The following is a list of available violation severity levels, ranked from most to least severe:
| Icon | Severity level |
|:----------------------------------------------|:---------------|
| **{severity-critical, 18, gl-fill-red-800}** | Critical |
| **{severity-high, 18, gl-fill-red-600}** | High |
| **{severity-medium, 18, gl-fill-orange-400}** | Medium |
| **{severity-low, 18, gl-fill-orange-300}** | Low |
| **{severity-info, 18, gl-fill-blue-400}** | Info |
### Violation types
The following is a list of violations that are either:
- Already available.
- Aren't available, but which we are tracking in issues.
| Violation | Severity level | Category | Description | Availability |
|:-------------------------------------|:----------------|:----------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------|
| Author approved merge request | High | [Separation of duties](#approval-status-and-separation-of-duties) | The author of the merge request approved their own merge request. [Learn more](../../project/merge_requests/approvals/settings.md#prevent-approval-by-author). | [Unavailable](https://gitlab.com/groups/gitlab-org/-/epics/6870) |
| Committers approved merge request | High | [Separation of duties](#approval-status-and-separation-of-duties) | The committers of the merge request approved the merge request they contributed to. [Learn more](../../project/merge_requests/approvals/settings.md#prevent-approvals-by-users-who-add-commits). | [Unavailable](https://gitlab.com/groups/gitlab-org/-/epics/6870) |
| Fewer than two approvals | High | [Separation of duties](#approval-status-and-separation-of-duties) | The merge request was merged with fewer than two approvals. [Learn more](../../project/merge_requests/approvals/rules.md). | [Unavailable](https://gitlab.com/groups/gitlab-org/-/epics/6870) |
| Pipeline failed | Medium | [Pipeline results](../../../ci/pipelines/index.md) | The merge requests pipeline failed and was merged. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |
| Pipeline passed with warnings | Info | [Pipeline results](../../../ci/pipelines/index.md) | The merge request pipeline passed with warnings and was merged. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |
| Code coverage down more than 10% | High | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | The code coverage report for the merge request indicates a reduction in coverage of more than 10%. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |
| Code coverage down between 5% to 10% | Medium | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | The code coverage report for the merge request indicates a reduction in coverage of between 5% to 10%. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |
| Code coverage down between 1% to 5% | Low | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | The code coverage report for the merge request indicates a reduction in coverage of between 1% to 5%. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |
| Code coverage down less than 1% | Info | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | The code coverage report for the merge request indicates a reduction in coverage of less than 1%. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |

View File

@ -47,6 +47,7 @@ module Gitlab
def validate_url!(url)
Gitlab::UrlBlocker.validate!(url, allow_local_network: allow_local_requests?,
allow_localhost: allow_local_requests?,
allow_object_storage: allow_object_storage?,
dns_rebind_protection: dns_rebind_protection?)
rescue Gitlab::UrlBlocker::BlockedUrlError => e
raise Gitlab::HTTP::BlockedUrlError, "URL '#{url}' is blocked: #{e.message}"
@ -56,6 +57,10 @@ module Gitlab
options.fetch(:allow_local_requests, allow_settings_local_requests?)
end
def allow_object_storage?
options.fetch(:allow_object_storage, false)
end
def dns_rebind_protection?
return false if Gitlab.http_proxy_env?

View File

@ -62,23 +62,27 @@ module Gitlab
end
def download(url, upload_path, size_limit: nil)
File.open(upload_path, 'w') do |file|
# Download (stream) file from the uploader's location
IO.copy_stream(
URI.parse(url).open(progress_proc: file_size_limiter(size_limit)),
file
)
File.open(upload_path, 'wb') do |file|
current_size = 0
Gitlab::HTTP.get(url, stream_body: true, allow_object_storage: true) do |fragment|
if [301, 302, 307].include?(fragment.code)
Gitlab::Import::Logger.warn(message: "received redirect fragment", fragment_code: fragment.code)
elsif fragment.code == 200
current_size += fragment.bytesize
raise FileOversizedError if size_limit.present? && current_size > size_limit
file.write(fragment)
else
raise Gitlab::ImportExport::Error, "unsupported response downloading fragment #{fragment.code}"
end
end
end
rescue FileOversizedError
nil
end
def file_size_limiter(limit)
return if limit.blank?
-> (current_size) { raise FileOversizedError if current_size > limit }
end
def tar_with_options(archive:, dir:, options:)
execute_cmd(%W(tar -#{options} #{archive} -C #{dir} .))
end

View File

@ -134,11 +134,7 @@ module Gitlab
:"gitlab_transaction_db_#{counter}_total"
end
if ENV['GITLAB_MULTIPLE_DATABASE_METRICS']
current_transaction&.increment(prometheus_key, 1, { db_config_name: db_config_name })
else
current_transaction&.increment(prometheus_key, 1)
end
current_transaction&.increment(prometheus_key, 1, { db_config_name: db_config_name })
Gitlab::SafeRequestStore[log_key] = Gitlab::SafeRequestStore[log_key].to_i + 1
@ -154,11 +150,7 @@ module Gitlab
def observe(histogram, event, &block)
db_config_name = db_config_name(event.payload)
if ENV['GITLAB_MULTIPLE_DATABASE_METRICS']
current_transaction&.observe(histogram, event.duration / 1000.0, { db_config_name: db_config_name }, &block)
else
current_transaction&.observe(histogram, event.duration / 1000.0, &block)
end
current_transaction&.observe(histogram, event.duration / 1000.0, { db_config_name: db_config_name }, &block)
end
def current_transaction
@ -193,11 +185,9 @@ module Gitlab
counters << compose_metric_key(metric, role)
end
if ENV['GITLAB_MULTIPLE_DATABASE_METRICS']
::Gitlab::Database.db_config_names.each do |config_name|
counters << compose_metric_key(metric, nil, config_name) # main
counters << compose_metric_key(metric, nil, config_name + ::Gitlab::Database::LoadBalancing::LoadBalancer::REPLICA_SUFFIX) # main_replica
end
::Gitlab::Database.db_config_names.each do |config_name|
counters << compose_metric_key(metric, nil, config_name) # main
counters << compose_metric_key(metric, nil, config_name + ::Gitlab::Database::LoadBalancing::LoadBalancer::REPLICA_SUFFIX) # main_replica
end
end

View File

@ -13,6 +13,7 @@ module Gitlab
# ports - Raises error if the given URL port does is not between given ports.
# allow_localhost - Raises error if URL resolves to a localhost IP address and argument is false.
# allow_local_network - Raises error if URL resolves to a link-local address and argument is false.
# allow_object_storage - Avoid raising an error if URL resolves to an object storage endpoint and argument is true.
# ascii_only - Raises error if URL has unicode characters and argument is true.
# enforce_user - Raises error if URL user doesn't start with alphanumeric characters and argument is true.
# enforce_sanitization - Raises error if URL includes any HTML/CSS/JS tags and argument is true.
@ -25,6 +26,7 @@ module Gitlab
schemes: [],
allow_localhost: false,
allow_local_network: true,
allow_object_storage: false,
ascii_only: false,
enforce_user: false,
enforce_sanitization: false,
@ -58,6 +60,8 @@ module Gitlab
# Allow url from the GitLab instance itself but only for the configured hostname and ports
return protected_uri_with_hostname if internal?(uri)
return protected_uri_with_hostname if allow_object_storage && object_storage_endpoint?(uri)
validate_local_request(
address_info: address_info,
allow_localhost: allow_localhost,
@ -269,6 +273,30 @@ module Gitlab
get_port(uri) == config.gitlab_shell.ssh_port
end
def enabled_object_storage_endpoints
ObjectStoreSettings::SUPPORTED_TYPES.collect do |type|
section_setting = config.try(type)
next unless section_setting
object_store_setting = section_setting['object_store']
next unless object_store_setting && object_store_setting['enabled']
object_store_setting.dig('connection', 'endpoint')
end.compact.uniq
end
def object_storage_endpoint?(uri)
enabled_object_storage_endpoints.any? do |endpoint|
endpoint_uri = URI(endpoint)
uri.scheme == endpoint_uri.scheme &&
uri.hostname == endpoint_uri.hostname &&
get_port(uri) == get_port(endpoint_uri)
end
end
def domain_allowed?(uri)
Gitlab::UrlBlockers::UrlAllowlist.domain_allowed?(uri.normalized_host, port: get_port(uri))
end

View File

@ -75,14 +75,6 @@ module Peek
"Role: #{role.to_s.capitalize}"
end
def format_call_details(call)
if ENV['GITLAB_MULTIPLE_DATABASE_METRICS']
super
else
super.except(:db_config_name)
end
end
end
end
end

View File

@ -68,31 +68,126 @@ RSpec.describe Gitlab::ImportExport::CommandLineUtil do
end
describe '#download' do
before do
stub_request(:get, 'http://localhost:3000/file')
.to_return(
status: 200,
body: File.open(archive),
headers: {
'Content-Type' => 'application/x-tar'
let(:content) { File.open('spec/fixtures/rails_sample.tif') }
context 'a non-localhost uri' do
before do
stub_request(:get, url)
.to_return(
status: status,
body: content
)
end
let(:url) { 'https://gitlab.com/file' }
context 'with ok status code' do
let(:status) { HTTP::Status::OK }
it 'gets the contents' do
Tempfile.create('test') do |file|
subject.download(url, file.path)
expect(file.read).to eq(File.open('spec/fixtures/rails_sample.tif').read)
end
end
it 'streams the contents via Gitlab::HTTP' do
expect(Gitlab::HTTP).to receive(:get).with(url, hash_including(stream_body: true))
Tempfile.create('test') do |file|
subject.download(url, file.path)
end
end
it 'does not get the content over the size_limit' do
Tempfile.create('test') do |file|
subject.download(url, file.path, size_limit: 300.kilobytes)
expect(file.read).to eq('')
end
end
it 'gets the content within the size_limit' do
Tempfile.create('test') do |file|
subject.download(url, file.path, size_limit: 400.kilobytes)
expect(file.read).to eq(File.open('spec/fixtures/rails_sample.tif').read)
end
end
end
%w[MOVED_PERMANENTLY FOUND TEMPORARY_REDIRECT].each do |code|
context "with a redirect status code #{code}" do
let(:status) { HTTP::Status.const_get(code, false) }
it 'logs the redirect' do
expect(Gitlab::Import::Logger).to receive(:warn)
Tempfile.create('test') do |file|
subject.download(url, file.path)
end
end
end
end
%w[ACCEPTED UNAUTHORIZED BAD_REQUEST].each do |code|
context "with an invalid status code #{code}" do
let(:status) { HTTP::Status.const_get(code, false) }
it 'throws an error' do
Tempfile.create('test') do |file|
expect { subject.download(url, file.path) }.to raise_error(Gitlab::ImportExport::Error)
end
end
end
end
end
context 'a localhost uri' do
include StubRequests
let(:status) { HTTP::Status::OK }
let(:url) { "#{host}/foo/bar" }
let(:host) { 'http://localhost:8081' }
before do
# Note: the hostname gets changed to an ip address due to dns_rebind_protection
stub_dns(url, ip_address: '127.0.0.1')
stub_request(:get, 'http://127.0.0.1:8081/foo/bar')
.to_return(
status: status,
body: content
)
end
it 'throws a blocked url error' do
Tempfile.create('test') do |file|
expect { subject.download(url, file.path) }.to raise_error((Gitlab::HTTP::BlockedUrlError))
end
end
context 'for object_storage uri' do
let(:enabled_object_storage_setting) do
{
'object_store' =>
{
'enabled' => true,
'connection' => {
'endpoint' => host
}
}
}
)
end
end
let(:tempfile) { Tempfile.new('test', path) }
before do
allow(Settings).to receive(:external_diffs).and_return(enabled_object_storage_setting)
end
it 'downloads the file in the given path' do
subject.download('http://localhost:3000/file', tempfile)
expect(File.exist?(tempfile)).to eq(true)
expect(tempfile.size).to eq(File.size(archive))
end
it 'limit the size of the downloaded file' do
subject.download('http://localhost:3000/file', tempfile, size_limit: 1.byte)
expect(File.exist?(tempfile)).to eq(true)
expect(tempfile.size).to eq(0)
it 'gets the content' do
Tempfile.create('test') do |file|
subject.download(url, file.path)
expect(file.read).to eq(File.open('spec/fixtures/rails_sample.tif').read)
end
end
end
end
end

View File

@ -39,6 +39,73 @@ RSpec.describe Gitlab::UrlBlocker, :stub_invalid_dns_only do
end
end
context 'when URI is for a local object storage' do
let(:import_url) { "#{host}/external-diffs/merge_request_diffs/mr-1/diff-1" }
let(:enabled_object_storage_setting) do
{
'object_store' =>
{
'enabled' => true,
'connection' => {
'endpoint' => host
}
}
}
end
before do
allow(Settings).to receive(:external_diffs).and_return(enabled_object_storage_setting)
end
context 'when allow_object_storage is true' do
subject { described_class.validate!(import_url, allow_object_storage: true) }
context 'with a local domain name' do
let(:host) { 'http://review-minio-svc.svc:9000' }
before do
stub_dns(host, ip_address: '127.0.0.1')
end
it_behaves_like 'validates URI and hostname' do
let(:expected_uri) { 'http://127.0.0.1:9000/external-diffs/merge_request_diffs/mr-1/diff-1' }
let(:expected_hostname) { 'review-minio-svc.svc' }
end
end
context 'with an IP address' do
let(:host) { 'http://127.0.0.1:9000' }
it_behaves_like 'validates URI and hostname' do
let(:expected_uri) { 'http://127.0.0.1:9000/external-diffs/merge_request_diffs/mr-1/diff-1' }
let(:expected_hostname) { nil }
end
end
end
context 'when allow_object_storage is false' do
context 'with a local domain name' do
let(:host) { 'http://review-minio-svc.svc:9000' }
before do
stub_dns(host, ip_address: '127.0.0.1')
end
it 'raises an error' do
expect { subject }.to raise_error(described_class::BlockedUrlError)
end
end
context 'with an IP address' do
let(:host) { 'http://127.0.0.1:9000' }
it 'raises an error' do
expect { subject }.to raise_error(described_class::BlockedUrlError)
end
end
end
end
context 'when the URL hostname is a domain' do
context 'when domain can be resolved' do
let(:import_url) { 'https://example.org' }

View File

@ -119,16 +119,4 @@ RSpec.describe Peek::Views::ActiveRecord, :request_store do
)
)
end
context 'when the GITLAB_MULTIPLE_DATABASE_METRICS env var is disabled' do
before do
stub_env('GITLAB_MULTIPLE_DATABASE_METRICS', nil)
end
it 'does not include db_config_name field' do
ActiveSupport::Notifications.publish('sql.active_record', Time.current, Time.current + 1.second, '1', event_1)
expect(subject.results[:details][0][:db_config_name]).to be_nil
end
end
end

View File

@ -51,14 +51,14 @@ RSpec.describe Analytics::CycleAnalytics::Aggregation, type: :model do
end
describe '#load_batch' do
let!(:aggregation1) { create(:cycle_analytics_aggregation, last_incremental_run_at: nil) }
let!(:aggregation1) { create(:cycle_analytics_aggregation, last_incremental_run_at: nil, last_consistency_check_updated_at: 3.days.ago).reload }
let!(:aggregation2) { create(:cycle_analytics_aggregation, last_incremental_run_at: 5.days.ago).reload }
let!(:aggregation3) { create(:cycle_analytics_aggregation, last_incremental_run_at: nil) }
let!(:aggregation5) { create(:cycle_analytics_aggregation, last_incremental_run_at: 10.days.ago).reload }
let!(:aggregation3) { create(:cycle_analytics_aggregation, last_incremental_run_at: nil, last_consistency_check_updated_at: 2.days.ago).reload }
let!(:aggregation4) { create(:cycle_analytics_aggregation, last_incremental_run_at: 10.days.ago).reload }
before do
create(:cycle_analytics_aggregation, :disabled) # disabled rows are skipped
create(:cycle_analytics_aggregation, last_incremental_run_at: 1.day.ago) # "early" rows are filtered out
create(:cycle_analytics_aggregation, last_incremental_run_at: 1.day.ago, last_consistency_check_updated_at: 1.hour.ago) # "early" rows are filtered out
end
it 'loads records in priority order' do
@ -70,7 +70,20 @@ RSpec.describe Analytics::CycleAnalytics::Aggregation, type: :model do
# Using match_array because the order can be undeterministic for nil values.
expect(first_two).to match_array([aggregation1, aggregation3])
expect(last_two).to eq([aggregation5, aggregation2])
expect(last_two).to eq([aggregation4, aggregation2])
end
context 'when loading batch for last_consistency_check_updated_at' do
it 'loads records in priority order' do
batch = described_class.load_batch(1.day.ago, :last_consistency_check_updated_at).to_a
expect(batch.size).to eq(4)
first_two = batch.first(2)
last_two = batch.last(2)
expect(first_two).to match_array([aggregation2, aggregation4])
expect(last_two).to eq([aggregation1, aggregation3])
end
end
end

View File

@ -1,8 +0,0 @@
# frozen_string_literal: true
RSpec.configure do |config|
config.before do
# Enable this by default in all tests so it behaves like a FF
stub_env('GITLAB_MULTIPLE_DATABASE_METRICS', '1')
end
end

View File

@ -91,21 +91,6 @@ RSpec.shared_examples 'store ActiveRecord info in RequestStore' do |db_role|
end
end
end
context 'when the GITLAB_MULTIPLE_DATABASE_METRICS env var is disabled' do
before do
stub_env('GITLAB_MULTIPLE_DATABASE_METRICS', nil)
end
it 'does not include per database metrics' do
Gitlab::WithRequestStore.with_request_store do
subscriber.sql(event)
expect(described_class.db_counter_payload).not_to include(:"db_replica_#{db_config_name}_duration_s")
expect(described_class.db_counter_payload).not_to include(:"db_replica_#{db_config_name}_count")
end
end
end
end
RSpec.shared_examples 'record ActiveRecord metrics in a metrics transaction' do |db_role|
@ -160,26 +145,6 @@ RSpec.shared_examples 'record ActiveRecord metrics in a metrics transaction' do
subscriber.sql(event)
end
context 'when the GITLAB_MULTIPLE_DATABASE_METRICS env var is disabled' do
before do
stub_env('GITLAB_MULTIPLE_DATABASE_METRICS', nil)
end
it 'does not include db_config_name label' do
allow(transaction).to receive(:increment) do |*args|
labels = args[2] || {}
expect(labels).not_to include(:db_config_name)
end
allow(transaction).to receive(:observe) do |*args|
labels = args[2] || {}
expect(labels).not_to include(:db_config_name)
end
subscriber.sql(event)
end
end
end
RSpec.shared_examples 'record ActiveRecord metrics' do |db_role|