Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-11-01 15:09:40 +00:00
parent 0a0c5aaca5
commit b21334799a
34 changed files with 225 additions and 101 deletions

View File

@ -246,7 +246,6 @@ gem 'acts-as-taggable-on', '~> 10.0' # rubocop:todo Gemfile/MissingFeatureCatego
# Background jobs
gem 'sidekiq', '~> 6.5.10' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'sidekiq-cron', '~> 1.8.0' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'redis-namespace', '~> 1.9.0' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'gitlab-sidekiq-fetcher', path: 'vendor/gems/sidekiq-reliable-fetch', require: 'sidekiq-reliable-fetch' # rubocop:todo Gemfile/MissingFeatureCategory
# Cron Parser

View File

@ -507,7 +507,6 @@
{"name":"redcarpet","version":"3.6.0","platform":"ruby","checksum":"8ad1889c0355ff4c47174af14edd06d62f45a326da1da6e8a121d59bdcd2e9e9"},
{"name":"redis","version":"4.8.0","platform":"ruby","checksum":"2000cf5014669c9dc821704b6d322a35a9a33852a95208911d9175d63b448a44"},
{"name":"redis-actionpack","version":"5.3.0","platform":"ruby","checksum":"3fb1ad0a8fd9d26a289c9399bb609dcaef38bf37711e6f677a53ca728fc19140"},
{"name":"redis-namespace","version":"1.9.0","platform":"ruby","checksum":"0923961f38cf15b86cb57d92507e0a3b32480729eb5033249f5de8b12e0d8612"},
{"name":"redis-rack","version":"2.1.4","platform":"ruby","checksum":"0872eecb303e483c3863d6bd0d47323d230640d41c1a4ac4a2c7596ec0b1774c"},
{"name":"redis-store","version":"1.9.1","platform":"ruby","checksum":"7b4c7438d46f7b7ce8f67fc0eda3a04fc67d32d28cf606cc98a5df4d2b77071d"},
{"name":"regexp_parser","version":"2.6.0","platform":"ruby","checksum":"f163ba463a45ca2f2730e0902f2475bb0eefcd536dfc2f900a86d1e5a7d7a556"},

View File

@ -1316,8 +1316,6 @@ GEM
actionpack (>= 5, < 8)
redis-rack (>= 2.1.0, < 3)
redis-store (>= 1.1.0, < 2)
redis-namespace (1.9.0)
redis (>= 4)
redis-rack (2.1.4)
rack (>= 2.0.8, < 3)
redis-store (>= 1.2, < 2)
@ -1971,7 +1969,6 @@ DEPENDENCIES
recaptcha (~> 5.12)
redis (~> 4.8.0)
redis-actionpack (~> 5.3.0)
redis-namespace (~> 1.9.0)
request_store (~> 1.5.1)
responders (~> 3.0)
retriable (~> 3.1.2)

View File

@ -58,7 +58,7 @@ export default {
</template>
<template #user>
<gl-link
class="js-user-link gl-reset-color gl-reset-font-size gl-font-weight-bold"
class="js-user-link gl-reset-color gl-font-weight-bold"
:href="createdBy.webUrl"
:data-user-id="createdById"
:data-username="createdBy.username"

View File

@ -1,7 +1,9 @@
import * as Sentry from '~/sentry/sentry_browser_wrapper';
import axios from '~/lib/utils/axios_utils';
import { logError } from '~/lib/logger';
function reportErrorAndThrow(e) {
logError(e);
Sentry.captureException(e);
throw e;
}

View File

@ -1,4 +1,6 @@
<script>
import * as Sentry from '~/sentry/sentry_browser_wrapper';
import { logError } from '~/lib/logger';
import { buildClient } from '../client';
import ObservabilityLoader from './loader/index.vue';
import { CONTENT_STATE } from './loader/constants';
@ -72,8 +74,9 @@ export default {
this.$emit('observability-client-ready', this.observabilityClient);
this.loaderContentState = CONTENT_STATE.LOADED;
} else if (status === 'error') {
// eslint-disable-next-line @gitlab/require-i18n-strings,no-console
console.error('GOB auth failed with error:', message, statusCode);
const error = new Error(`GOB auth failed with error: ${message} - status: ${statusCode}`);
Sentry.captureException(error);
logError(error);
this.loaderContentState = CONTENT_STATE.ERROR;
}
this.authCompleted = true;

View File

@ -121,4 +121,8 @@ export default {
text: s__('ProjectTemplates|Laravel Framework'),
icon: '.template-option .icon-laravel',
},
astro_tailwind: {
text: s__('ProjectTemplates|Astro Tailwind'),
icon: '.template-option .icon-gitlab_logo',
},
};

View File

@ -143,7 +143,7 @@ export default {
<gl-icon
v-if="isAllowedIcon"
:name="note.system_note_icon_name"
size="12"
:size="12"
data-testid="timeline-icon"
/>
</div>

View File

@ -14,8 +14,9 @@ module Ci
end
def resources(namespace: nil, sort: nil, search: nil)
relation = all_resources(search)
relation = all_resources
relation = by_namespace(relation, namespace)
relation = by_search(relation, search)
case sort.to_s
when 'name_desc' then relation.order_by_name_desc
@ -32,9 +33,9 @@ module Ci
attr_reader :current_user
def all_resources(search)
def all_resources
Ci::Catalog::Resource.joins(:project).includes(:project)
.merge(find_projects(search))
.merge(Project.public_or_visible_to_user(current_user))
end
def by_namespace(relation, namespace)
@ -44,13 +45,11 @@ module Ci
relation.merge(Project.in_namespace(namespace.self_and_descendant_ids))
end
def find_projects(search)
finder_params = {
minimum_search_length: MIN_SEARCH_LENGTH,
search: search
}
def by_search(relation, search)
return relation unless search
return relation.none if search.length < MIN_SEARCH_LENGTH
ProjectsFinder.new(params: finder_params, current_user: current_user).execute
relation.search(search)
end
end
end

View File

@ -8,6 +8,8 @@ module Ci
# dependency on the Project model and its need to join with that table
# in order to generate the CI/CD catalog.
class Resource < ::ApplicationRecord
include Gitlab::SQL::Pattern
self.table_name = 'catalog_resources'
belongs_to :project
@ -15,6 +17,8 @@ module Ci
has_many :versions, class_name: 'Ci::Catalog::Resources::Version', inverse_of: :catalog_resource
scope :for_projects, ->(project_ids) { where(project_id: project_ids) }
scope :search, ->(query) { fuzzy_search(query, [:name, :description], use_minimum_char_limit: false) }
scope :order_by_created_at_desc, -> { reorder(created_at: :desc) }
scope :order_by_created_at_asc, -> { reorder(created_at: :asc) }
scope :order_by_name_desc, -> { reorder(arel_table[:name].desc.nulls_last) }

View File

@ -111,6 +111,10 @@ module Releases
# overridden in EE
def project_group_id; end
def audit(release, action:)
# overridden in EE
end
end
end

View File

@ -64,6 +64,8 @@ module Releases
create_evidence!(release, evidence_pipeline)
audit(release, action: :created)
success(tag: tag, release: release)
rescue StandardError => e
error(e.message, 400)

View File

@ -11,6 +11,8 @@ module Releases
execute_hooks(release, 'delete')
audit(release, action: :deleted)
success(tag: existing_tag, release: release)
else
error(release.errors.messages || '400 Bad request', 400)

View File

@ -19,6 +19,8 @@ module Releases
ApplicationRecord.transaction do
if release.update(params)
execute_hooks(release, 'update')
audit(release, action: :updated)
audit(release, action: :milestones_updated) if milestones_updated?(previous_milestones)
success(tag: existing_tag, release: release, milestones_updated: milestones_updated?(previous_milestones))
else
error(release.errors.messages || '400 Bad request', 400)

View File

@ -0,0 +1,8 @@
---
name: activity_filter_has_remediations
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135009
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/429262
milestone: '16.6'
type: development
group: group::threat insights
default_enabled: false

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
class AddPathToCatalogResourceComponents < Gitlab::Database::Migration[2.2]
milestone '16.6'
disable_ddl_transaction!
def up
with_lock_retries do
add_column :catalog_resource_components, :path, :text, if_not_exists: true
end
add_text_limit :catalog_resource_components, :path, 255
end
def down
with_lock_retries do
remove_column :catalog_resource_components, :path, :text, if_exists: true
end
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class CleanupCiPipelineMessagesPipelineIdBigint < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
TABLE = :ci_pipeline_messages
COLUMNS = [:pipeline_id]
def up
with_lock_retries(raise_on_exhaustion: true) do
lock_tables(:ci_pipelines, TABLE)
cleanup_conversion_of_integer_to_bigint(TABLE, COLUMNS) # rubocop:disable Migration/WithLockRetriesDisallowedMethod
end
end
def down
restore_conversion_of_integer_to_bigint(TABLE, COLUMNS)
add_concurrent_index(
TABLE, :pipeline_id_convert_to_bigint,
name: :index_ci_pipeline_messages_on_pipeline_id_convert_to_bigint
)
add_concurrent_foreign_key(
TABLE, :ci_pipelines,
column: :pipeline_id_convert_to_bigint,
on_delete: :cascade, validate: true, reverse_lock_order: true
)
end
end

View File

@ -0,0 +1,66 @@
# frozen_string_literal: true
class SwapColumnsForCiStagesPipelineIdBigintForSelfHost < Gitlab::Database::Migration[2.2]
include Gitlab::Database::MigrationHelpers::Swapping
milestone '16.6'
disable_ddl_transaction!
TABLE_NAME = :ci_stages
TRIGGER_FUNCTION_NAME = :trigger_07bc3c48f407
COLUMN_NAME = :pipeline_id
BIGINT_COLUMN_NAME = :pipeline_id_convert_to_bigint
FK_NAME = :fk_fb57e6cc56
BIGINT_FK_NAME = :fk_c5ddde695f
INDEX_NAMES = %i[
index_ci_stages_on_pipeline_id
index_ci_stages_on_pipeline_id_and_id
index_ci_stages_on_pipeline_id_and_name
index_ci_stages_on_pipeline_id_and_position
]
BIGINT_INDEX_NAMES = %i[
index_ci_stages_on_pipeline_id_convert_to_bigint
index_ci_stages_on_pipeline_id_convert_to_bigint_and_id
index_ci_stages_on_pipeline_id_convert_to_bigint_and_name
index_ci_stages_on_pipeline_id_convert_to_bigint_and_position
]
def up
return if column_type_of?(:bigint)
swap
end
def down
return if column_type_of?(:integer)
swap
end
private
def column_type_of?(type)
column_for(TABLE_NAME, COLUMN_NAME).sql_type.to_s == type.to_s
end
def swap
with_lock_retries(raise_on_exhaustion: true) do
# Lock the tables involved.
lock_tables(:ci_pipelines, :ci_stages)
# Rename the columns to swap names
swap_columns(TABLE_NAME, COLUMN_NAME, BIGINT_COLUMN_NAME)
# Reset the trigger function
reset_trigger_function(TRIGGER_FUNCTION_NAME)
# Swap fkey constraint
swap_foreign_keys(TABLE_NAME, FK_NAME, BIGINT_FK_NAME)
# Swap index
INDEX_NAMES.each_with_index do |index_name, i|
swap_indexes(TABLE_NAME, index_name, BIGINT_INDEX_NAMES[i])
end
end
end
end

View File

@ -0,0 +1 @@
fd51e236973eaf1d4a2719eaa34dbd7955c2d73e37adf244472c8c69fc486fdf

View File

@ -0,0 +1 @@
7dc72ca807126bb992c22879a6d989f282e442ff2c6e15b046e6f3d0f464237f

View File

@ -0,0 +1 @@
4de438a35ae2cbeee4cec03961cf7b5dddfcce2454a1e3ce08985e28b7065a0d

View File

@ -341,15 +341,6 @@ BEGIN
END;
$$;
CREATE FUNCTION trigger_bfad0e2b9c86() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW."pipeline_id_convert_to_bigint" := NEW."pipeline_id";
RETURN NEW;
END;
$$;
CREATE FUNCTION unset_has_issues_on_vulnerability_reads() RETURNS trigger
LANGUAGE plpgsql
AS $$
@ -13196,6 +13187,8 @@ CREATE TABLE catalog_resource_components (
resource_type smallint DEFAULT 1 NOT NULL,
inputs jsonb DEFAULT '{}'::jsonb NOT NULL,
name text NOT NULL,
path text,
CONSTRAINT check_a76bfd47fe CHECK ((char_length(path) <= 255)),
CONSTRAINT check_ddca729980 CHECK ((char_length(name) <= 255))
);
@ -13919,7 +13912,6 @@ ALTER SEQUENCE ci_pipeline_chat_data_id_seq OWNED BY ci_pipeline_chat_data.id;
CREATE TABLE ci_pipeline_messages (
id bigint NOT NULL,
severity smallint DEFAULT 0 NOT NULL,
pipeline_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
content text NOT NULL,
pipeline_id bigint NOT NULL,
CONSTRAINT check_58ca2981b2 CHECK ((char_length(content) <= 10000))
@ -31934,8 +31926,6 @@ CREATE UNIQUE INDEX index_ci_pipeline_chat_data_on_pipeline_id ON ci_pipeline_ch
CREATE INDEX index_ci_pipeline_messages_on_pipeline_id ON ci_pipeline_messages USING btree (pipeline_id);
CREATE INDEX index_ci_pipeline_messages_on_pipeline_id_convert_to_bigint ON ci_pipeline_messages USING btree (pipeline_id_convert_to_bigint);
CREATE INDEX index_ci_pipeline_metadata_on_project_id ON ci_pipeline_metadata USING btree (project_id);
CREATE UNIQUE INDEX index_ci_pipeline_schedule_variables_on_schedule_id_and_key ON ci_pipeline_schedule_variables USING btree (pipeline_schedule_id, key);
@ -36832,8 +36822,6 @@ CREATE TRIGGER trigger_7f3d66a7d7f5 BEFORE INSERT OR UPDATE ON ci_pipeline_varia
CREATE TRIGGER trigger_b2d852e1e2cb BEFORE INSERT OR UPDATE ON ci_pipelines FOR EACH ROW EXECUTE FUNCTION trigger_b2d852e1e2cb();
CREATE TRIGGER trigger_bfad0e2b9c86 BEFORE INSERT OR UPDATE ON ci_pipeline_messages FOR EACH ROW EXECUTE FUNCTION trigger_bfad0e2b9c86();
CREATE TRIGGER trigger_delete_project_namespace_on_project_delete AFTER DELETE ON projects FOR EACH ROW WHEN ((old.project_namespace_id IS NOT NULL)) EXECUTE FUNCTION delete_associated_project_namespace();
CREATE TRIGGER trigger_has_external_issue_tracker_on_delete AFTER DELETE ON integrations FOR EACH ROW WHEN ((((old.category)::text = 'issue_tracker'::text) AND (old.active = true) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();
@ -36924,9 +36912,6 @@ ALTER TABLE ONLY user_interacted_projects
ALTER TABLE ONLY merge_request_assignment_events
ADD CONSTRAINT fk_08f7602bfd FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
ALTER TABLE ONLY ci_pipeline_messages
ADD CONSTRAINT fk_0946fea681 FOREIGN KEY (pipeline_id_convert_to_bigint) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
ALTER TABLE ONLY remote_development_agent_configs
ADD CONSTRAINT fk_0a3c0ada56 FOREIGN KEY (cluster_agent_id) REFERENCES cluster_agents(id) ON DELETE CASCADE;

View File

@ -13,7 +13,7 @@ All other features are considered to be Generally Available (GA).
## Experiment
Support is not provided for features listed as "Experimental" or "Alpha" or any similar designation. Issues regarding such features should be opened in the GitLab issue tracker. Teams should release features as GA from the start unless there are strong reasons to release them as Experiment or Beta versions first.
All Experimental features must [initiate Production Readiness Review](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#process) and complete the [experiment section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#experiment).
All Experimental features that [meet the review criteria](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#criteria-for-starting-a-production-readiness-review) must [initiate Production Readiness Review](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#process) and complete the [experiment section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#experiment).
Experimental features are:
@ -36,7 +36,7 @@ Experimental features are:
## Beta
Commercially-reasonable efforts are made to provide limited support for features designated as "Beta," with the expectation that issues require extra time and assistance from development to troubleshoot.
All Beta features must complete all sections up to and including the [beta section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#beta) by following the [Production Readiness Review process](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#process).
All Beta features that [meet the review criteria](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#criteria-for-starting-a-production-readiness-review) must complete all sections up to and including the [beta section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#beta) by following the [Production Readiness Review process](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#process).
Beta features are:
@ -56,7 +56,7 @@ Beta features are:
## Generally Available (GA)
Generally Available features must complete the [Production Readiness Review](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness) and complete all sections up to and including the [GA section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#general-availability).
Generally Available features that [meet the review criteria](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#criteria-for-starting-a-production-readiness-review) must complete the [Production Readiness Review](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness) and complete all sections up to and including the [GA section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#general-availability).
GA features are:

View File

@ -270,8 +270,6 @@ module API
.execute
if result[:status] == :success
log_release_created_audit_event(result[:release])
present result[:release], with: Entities::Release, current_user: current_user
else
render_api_error!(result[:message], result[:http_status])
@ -317,9 +315,6 @@ module API
.execute
if result[:status] == :success
log_release_updated_audit_event
log_release_milestones_updated_audit_event if result[:milestones_updated]
present result[:release], with: Entities::Release, current_user: current_user
else
render_api_error!(result[:message], result[:http_status])
@ -350,8 +345,6 @@ module API
.execute
if result[:status] == :success
log_release_deleted_audit_event
present result[:release], with: Entities::Release, current_user: current_user
else
render_api_error!(result[:message], result[:http_status])
@ -406,22 +399,6 @@ module API
Rack::Utils.parse_nested_query(@request.query_string)
end
def log_release_created_audit_event(release)
# extended in EE
end
def log_release_updated_audit_event
# extended in EE
end
def log_release_deleted_audit_event
# extended in EE
end
def log_release_milestones_updated_audit_event
# extended in EE
end
def release_cli?
request.env['HTTP_USER_AGENT']&.include?(RELEASE_CLI_USER_AGENT) == true
end

View File

@ -81,7 +81,8 @@ module Gitlab
ProjectTemplate.new('cluster_management', 'GitLab Cluster Management', _('An example project for managing Kubernetes clusters integrated with GitLab'), 'https://gitlab.com/gitlab-org/project-templates/cluster-management'),
ProjectTemplate.new('kotlin_native_linux', 'Kotlin Native Linux', _('A basic template for developing Linux programs using Kotlin Native'), 'https://gitlab.com/gitlab-org/project-templates/kotlin-native-linux'),
ProjectTemplate.new('typo3_distribution', 'TYPO3 Distribution', _('A template for starting a new TYPO3 project'), 'https://gitlab.com/gitlab-org/project-templates/typo3-distribution', 'illustrations/logos/typo3.svg'),
ProjectTemplate.new('laravel', 'Laravel Framework', _('A basic folder structure of a Laravel application, to help you get started.'), 'https://gitlab.com/gitlab-org/project-templates/laravel', 'illustrations/logos/laravel.svg')
ProjectTemplate.new('laravel', 'Laravel Framework', _('A basic folder structure of a Laravel application, to help you get started.'), 'https://gitlab.com/gitlab-org/project-templates/laravel', 'illustrations/logos/laravel.svg'),
ProjectTemplate.new('astro_tailwind', 'Astro Tailwind', _('A basic folder structure of Astro Starter Kit, to help you get started.'), 'https://gitlab.com/gitlab-org/project-templates/astro-tailwind')
]
end
# rubocop:enable Metrics/AbcSize

View File

@ -380,7 +380,7 @@ module Gitlab
end
def redis_store?(store)
store.is_a?(::Redis) || store.is_a?(::Redis::Namespace)
store.is_a?(::Redis)
end
def validate_stores!

View File

@ -1765,6 +1765,9 @@ msgstr ""
msgid "A Work Item can be a parent or a child, but not both."
msgstr ""
msgid "A basic folder structure of Astro Starter Kit, to help you get started."
msgstr ""
msgid "A basic folder structure of a Laravel application, to help you get started."
msgstr ""
@ -37845,6 +37848,9 @@ msgstr ""
msgid "ProjectTemplates|Android"
msgstr ""
msgid "ProjectTemplates|Astro Tailwind"
msgstr ""
msgid "ProjectTemplates|GitLab Cluster Management"
msgstr ""
@ -43462,6 +43468,12 @@ msgstr ""
msgid "SecurityReports|Investigate this vulnerability by creating an issue"
msgstr ""
msgid "SecurityReports|Is available"
msgstr ""
msgid "SecurityReports|Is not available"
msgstr ""
msgid "SecurityReports|Issue"
msgstr ""
@ -43578,6 +43590,9 @@ msgid_plural "SecurityReports|Show %d items"
msgstr[0] ""
msgstr[1] ""
msgid "SecurityReports|Solution available"
msgstr ""
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""

View File

@ -2,9 +2,11 @@ import MockAdapter from 'axios-mock-adapter';
import * as Sentry from '~/sentry/sentry_browser_wrapper';
import { buildClient } from '~/observability/client';
import axios from '~/lib/utils/axios_utils';
import { logError } from '~/lib/logger';
jest.mock('~/lib/utils/axios_utils');
jest.mock('~/sentry/sentry_browser_wrapper');
jest.mock('~/lib/logger');
describe('buildClient', () => {
let client;
@ -32,6 +34,11 @@ describe('buildClient', () => {
axiosMock.restore();
});
const expectErrorToBeReported = (e) => {
expect(Sentry.captureException).toHaveBeenCalledWith(e);
expect(logError).toHaveBeenCalledWith(e);
};
describe('buildClient', () => {
it('rejects if params are missing', () => {
const e = new Error(
@ -89,7 +96,7 @@ describe('buildClient', () => {
const e = 'Request failed with status code 500';
await expect(client.isObservabilityEnabled()).rejects.toThrow(e);
expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
expectErrorToBeReported(new Error(e));
});
it('throws in case of unexpected response', async () => {
@ -97,7 +104,7 @@ describe('buildClient', () => {
const e = 'Failed to check provisioning';
await expect(client.isObservabilityEnabled()).rejects.toThrow(e);
expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
expectErrorToBeReported(new Error(e));
});
});
@ -120,7 +127,7 @@ describe('buildClient', () => {
const e = 'Request failed with status code 401';
await expect(client.enableObservability()).rejects.toThrow(e);
expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
expectErrorToBeReported(new Error(e));
});
});
@ -156,14 +163,14 @@ describe('buildClient', () => {
axiosMock.onGet(tracingUrl).reply(200, { traces: [] });
await expect(client.fetchTrace('trace-1')).rejects.toThrow(FETCHING_TRACES_ERROR);
expect(Sentry.captureException).toHaveBeenCalledWith(new Error(FETCHING_TRACES_ERROR));
expectErrorToBeReported(new Error(FETCHING_TRACES_ERROR));
});
it('rejects if traces are invalid', async () => {
axiosMock.onGet(tracingUrl).reply(200, { traces: 'invalid' });
await expect(client.fetchTraces()).rejects.toThrow(FETCHING_TRACES_ERROR);
expect(Sentry.captureException).toHaveBeenCalledWith(new Error(FETCHING_TRACES_ERROR));
expectErrorToBeReported(new Error(FETCHING_TRACES_ERROR));
});
});
@ -196,14 +203,14 @@ describe('buildClient', () => {
axiosMock.onGet(tracingUrl).reply(200, {});
await expect(client.fetchTraces()).rejects.toThrow(FETCHING_TRACES_ERROR);
expect(Sentry.captureException).toHaveBeenCalledWith(new Error(FETCHING_TRACES_ERROR));
expectErrorToBeReported(new Error(FETCHING_TRACES_ERROR));
});
it('rejects if traces are invalid', async () => {
axiosMock.onGet(tracingUrl).reply(200, { traces: 'invalid' });
await expect(client.fetchTraces()).rejects.toThrow(FETCHING_TRACES_ERROR);
expect(Sentry.captureException).toHaveBeenCalledWith(new Error(FETCHING_TRACES_ERROR));
expectErrorToBeReported(new Error(FETCHING_TRACES_ERROR));
});
describe('query filter', () => {
@ -348,7 +355,7 @@ describe('buildClient', () => {
const e = 'failed to fetch services. invalid response';
await expect(client.fetchServices()).rejects.toThrow(e);
expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
expectErrorToBeReported(new Error(e));
});
});
@ -375,7 +382,7 @@ describe('buildClient', () => {
it('rejects if serviceName is missing', async () => {
const e = 'fetchOperations() - serviceName is required.';
await expect(client.fetchOperations()).rejects.toThrow(e);
expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
expectErrorToBeReported(new Error(e));
});
it('rejects if operationUrl does not contain $SERVICE_NAME$', async () => {
@ -387,7 +394,7 @@ describe('buildClient', () => {
});
const e = 'fetchOperations() - operationsUrl must contain $SERVICE_NAME$';
await expect(client.fetchOperations(serviceName)).rejects.toThrow(e);
expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
expectErrorToBeReported(new Error(e));
});
it('rejects if operations are missing', async () => {
@ -395,7 +402,7 @@ describe('buildClient', () => {
const e = 'failed to fetch operations. invalid response';
await expect(client.fetchOperations(serviceName)).rejects.toThrow(e);
expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
expectErrorToBeReported(new Error(e));
});
});
});

View File

@ -3,10 +3,13 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ObservabilityContainer from '~/observability/components/observability_container.vue';
import ObservabilityLoader from '~/observability/components/loader/index.vue';
import { CONTENT_STATE } from '~/observability/components/loader/constants';
import { buildClient } from '~/observability/client';
import * as Sentry from '~/sentry/sentry_browser_wrapper';
import { logError } from '~/lib/logger';
jest.mock('~/observability/client');
jest.mock('~/sentry/sentry_browser_wrapper');
jest.mock('~/lib/logger');
describe('ObservabilityContainer', () => {
let wrapper;
@ -49,6 +52,8 @@ describe('ObservabilityContainer', () => {
data: {
type: 'AUTH_COMPLETION',
status,
message: 'test-message',
statusCode: 'test-code',
},
origin: origin ?? new URL(OAUTH_URL).origin,
}),
@ -130,6 +135,12 @@ describe('ObservabilityContainer', () => {
it('does not emit observability-client-ready', () => {
expect(wrapper.emitted('observability-client-ready')).toBeUndefined();
});
it('reports the error', () => {
const e = new Error('GOB auth failed with error: test-message - status: test-code');
expect(Sentry.captureException).toHaveBeenCalledWith(e);
expect(logError).toHaveBeenCalledWith(e);
});
});
it('handles oauth message only once', async () => {

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Gitlab::ProjectTemplate do
RSpec.describe Gitlab::ProjectTemplate, feature_category: :source_code_management do
include ProjectTemplateTestHelper
describe '.all' do

View File

@ -56,7 +56,6 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
context 'when primary_store is not a ::Redis instance' do
before do
allow(primary_store).to receive(:is_a?).with(::Redis).and_return(false)
allow(primary_store).to receive(:is_a?).with(::Redis::Namespace).and_return(false)
end
it 'fails with exception' do
@ -65,21 +64,9 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
end
end
context 'when primary_store is a ::Redis::Namespace instance' do
before do
allow(primary_store).to receive(:is_a?).with(::Redis).and_return(false)
allow(primary_store).to receive(:is_a?).with(::Redis::Namespace).and_return(true)
end
it 'fails with exception' do
expect { described_class.new(primary_store, secondary_store, instance_name) }.not_to raise_error
end
end
context 'when secondary_store is not a ::Redis instance' do
before do
allow(secondary_store).to receive(:is_a?).with(::Redis).and_return(false)
allow(secondary_store).to receive(:is_a?).with(::Redis::Namespace).and_return(false)
end
it 'fails with exception' do
@ -88,17 +75,6 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
end
end
context 'when secondary_store is a ::Redis::Namespace instance' do
before do
allow(secondary_store).to receive(:is_a?).with(::Redis).and_return(false)
allow(secondary_store).to receive(:is_a?).with(::Redis::Namespace).and_return(true)
end
it 'fails with exception' do
expect { described_class.new(primary_store, secondary_store, instance_name) }.not_to raise_error
end
end
# rubocop:disable RSpec/MultipleMemoizedHelpers
context 'with READ redis commands' do
subject do

View File

@ -9,7 +9,7 @@ RSpec.describe Ci::Catalog::Resource, feature_category: :pipeline_composition do
let_it_be_with_reload(:project) { create(:project, name: 'A') }
let_it_be(:project_2) { build(:project, name: 'Z') }
let_it_be(:project_3) { build(:project, name: 'L') }
let_it_be(:project_3) { build(:project, name: 'L', description: 'Z') }
let_it_be_with_reload(:resource) { create(:ci_catalog_resource, project: project, latest_released_at: tomorrow) }
let_it_be(:resource_2) { create(:ci_catalog_resource, project: project_2, latest_released_at: today) }
let_it_be(:resource_3) { create(:ci_catalog_resource, project: project_3, latest_released_at: nil) }
@ -36,6 +36,14 @@ RSpec.describe Ci::Catalog::Resource, feature_category: :pipeline_composition do
end
end
describe '.search' do
it 'returns catalog resources whose name or description match the search term' do
resources = described_class.search('Z')
expect(resources).to contain_exactly(resource_2, resource_3)
end
end
describe '.order_by_created_at_desc' do
it 'returns catalog resources sorted by descending created at' do
ordered_resources = described_class.order_by_created_at_desc

View File

@ -10,6 +10,7 @@ module ProjectTemplateTestHelper
serverless_framework tencent_serverless_framework
jsonnet cluster_management kotlin_native_linux
pelican bridgetown typo3_distribution laravel
astro_tailwind
]
end
end

Binary file not shown.