Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
d738ba980c
commit
e7cbe1006f
21 changed files with 324 additions and 90 deletions
103
.gitlab/merge_request_templates/Removals.md
Normal file
103
.gitlab/merge_request_templates/Removals.md
Normal file
|
@ -0,0 +1,103 @@
|
|||
<!-- Set the correct label and milestone using autocomplete for guidance. Please @mention only the DRI(s) for each stage or group rather than an entire department. -->
|
||||
|
||||
**Be sure to link this MR to the relevant deprecation issue(s).**
|
||||
|
||||
If the MR does not have a deprecation issue, hit pause and:
|
||||
|
||||
- Review [this handbook documentation](https://about.gitlab.com/handbook/product/gitlab-the-product/#process-for-deprecating-and-removing-a-feature).
|
||||
- Connect with the Product Manager DRI.
|
||||
|
||||
Removals must be [announced as Deprecations](https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecations) at least 2 milestones in advance of the planned removal date. Removals can only be removed in a XX.0 major release if it creates a [breaking change](https://about.gitlab.com/handbook/product/gitlab-the-product/#breaking-changes-deprecations-and-removing-features).
|
||||
|
||||
**By the 10th**: Assign this MR to these team members as reviewers, and for approval:
|
||||
|
||||
- Required:
|
||||
- Product Group Manager or Director: `@PM`
|
||||
- Engineering Manager: `@EM`
|
||||
- Technical writer: `@TW`
|
||||
- Optional:
|
||||
- Product Designer(s): `@ProductDesigners`
|
||||
- Product Marketing: `@PMM`
|
||||
|
||||
**By 7:59 PM UTC 15th (11:59 AM PT)**: EM/PM assigns this MR to the TW reviewer for final review and merge: `@EM/PM`
|
||||
|
||||
**By 7:59 AM UTC 18th (11:59 PM PT 17th)**: TW Reviewer updates Docs by merging this MR to `master`: `@TW`
|
||||
|
||||
---
|
||||
|
||||
Please review the [guidelines for removals](https://about.gitlab.com/handbook/marketing/blog/release-posts/#removals).
|
||||
|
||||
## Links
|
||||
|
||||
- Removal Issue:
|
||||
- Removal MR (optional):
|
||||
|
||||
## EM/PM release post item checklist
|
||||
|
||||
- [ ] Set yourself as the Assignee, meaning you are the DRI.
|
||||
- [ ] If the removal is a [breaking change](https://about.gitlab.com/handbook/product/gitlab-the-product/#breaking-change), add label `breaking change`.
|
||||
- [ ] Follow the process to [create a removal YAML file](https://about.gitlab.com/handbook/marketing/blog/release-posts/#creating-a-removal-entry).
|
||||
- [ ] Add reviewers by the 10th.
|
||||
- [ ] When ready to be merged and not later than the 15th, add the ~ready label and @ message the TW for final review and merge.
|
||||
|
||||
## Reviewers
|
||||
|
||||
When the content is ready for review, the Technical Writer and Engineering Manager _must_
|
||||
review it. Optional reviewers can include Product Marketing, Product Design, and the Product Leaders
|
||||
for this area. Use the
|
||||
[Reviewers for Merge Requests](https://docs.gitlab.com/ee/user/project/merge_requests/getting_started#reviewer)
|
||||
feature for all reviews. Reviewers will `approve` the MR and remove themselves from the reviewers list when their review is complete.
|
||||
|
||||
- [ ] (Recommended) PMM
|
||||
- [ ] (Optional) Product Designer
|
||||
- [ ] (Optional) Group Manager or Director
|
||||
- [ ] Required review and approval: [Technical Writer designated to the corresponding DevOps stage/group](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments).
|
||||
|
||||
### Tech writer review
|
||||
|
||||
The TW should review according to the criteria listed below. Review a removal MR
|
||||
with the same process as regular docs MRs. Add suggestions as needed, @ message
|
||||
the PM to inform them the first review is complete, and remove
|
||||
yourself as a reviewer if it's not yet ready for merge.
|
||||
|
||||
<details>
|
||||
<summary>Expand for Details</summary>
|
||||
|
||||
- [ ] Title:
|
||||
- Length limit: 7 words (not including articles or prepositions).
|
||||
- Capitalization: ensure the title is [sentence cased](https://design.gitlab.com/content/punctuation#case).
|
||||
- No Markdown `` `code` `` formatting in the title, as it doesn't render correctly in the release post.
|
||||
- [ ] Consistency:
|
||||
- Ensure that all resources (docs, removal, etc.) refer to the feature with the same term / feature name.
|
||||
- [ ] Content:
|
||||
- Make sure the removal is accurate based on your understanding. Look for typos or grammar mistakes. Work with PM and PMM to ensure a consistent GitLab style and tone for messaging, based on other features and removals.
|
||||
- Review use of whitespace and bullet lists. Will the removal item be easily scannable when published? Consider adding line breaks or breaking content into bullets if you have more than a few sentences.
|
||||
- Make sure there aren't acronyms readers may not understand per <https://about.gitlab.com/handbook/communication/#writing-style-guidelines>.
|
||||
- [ ] Links:
|
||||
- All links must be full URLs, as the removal YAML files are used in multiple projects. Do not use relative links. The generated doc is an exception to the relative link rule and currently uses absolute links only.
|
||||
- Make sure all links and anchors are correct. Do not link to the H1 (top) anchor on a docs page.
|
||||
- [ ] Code. Make sure any included code is wrapped in code blocks.
|
||||
- [ ] Capitalization. Make sure to capitalize feature names. Stay consistent with the Documentation Style Guidance on [Capitalization](https://docs.gitlab.com/ee/development/documentation/styleguide.html#capitalization).
|
||||
- [ ] Blank spaces. Remove unnecessary spaces (end of line spaces, double spaces, extra blank lines, and lines with only spaces).
|
||||
|
||||
</details>
|
||||
|
||||
When the PM indicates it is ready for merge and all issues have been addressed, start the merge process.
|
||||
|
||||
#### Technical writer merge process
|
||||
|
||||
The [removals doc's `.md` file](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/update/removals.md)
|
||||
must be updated before this MR is merged:
|
||||
|
||||
1. Check out the MR's branch (in the [`gitlab-org/gitlab`](https://gitlab.com/gitlab-org/gitlab) project).
|
||||
1. From the command line (in the branch), run `bin/rake gitlab:docs:compile_removals`.
|
||||
If you want to double check that it worked, you can run `bin/rake gitlab:docs:check_removals`
|
||||
to verify that the doc is up to date.
|
||||
1. Commit the updated file and push the changes.
|
||||
1. Set the MR to merge when the pipeline succeeds (or merge if the pipeline is already complete).
|
||||
|
||||
If you have trouble running the rake task, check the [troubleshooting steps](https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecation-rake-task-troubleshooting).
|
||||
|
||||
/label ~"release post" ~"release post item" ~"Technical Writing" ~devops:: ~group:: ~"release post item::removal"
|
||||
/milestone %
|
||||
/assign `@EM/PM` (choose the DRI; remove backticks here, and below)
|
|
@ -1,5 +1,6 @@
|
|||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import VueRouter from 'vue-router';
|
||||
import TableOfContents from '~/blob/components/table_contents.vue';
|
||||
import PipelineTourSuccessModal from '~/blob/pipeline_tour_success_modal.vue';
|
||||
import { BlobViewer, initAuxiliaryViewer } from '~/blob/viewer/index';
|
||||
|
@ -12,11 +13,14 @@ import BlobContentViewer from '~/repository/components/blob_content_viewer.vue';
|
|||
import '~/sourcegraph/load';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
Vue.use(VueRouter);
|
||||
|
||||
const apolloProvider = new VueApollo({
|
||||
defaultClient: createDefaultClient(),
|
||||
});
|
||||
|
||||
const router = new VueRouter({ mode: 'history' });
|
||||
|
||||
const viewBlobEl = document.querySelector('#js-view-blob-app');
|
||||
|
||||
if (viewBlobEl) {
|
||||
|
@ -25,6 +29,7 @@ if (viewBlobEl) {
|
|||
// eslint-disable-next-line no-new
|
||||
new Vue({
|
||||
el: viewBlobEl,
|
||||
router,
|
||||
apolloProvider,
|
||||
provide: {
|
||||
targetBranch,
|
||||
|
|
|
@ -20,10 +20,9 @@ export default {
|
|||
v-for="line in lines"
|
||||
:id="`L${line}`"
|
||||
:key="line"
|
||||
class="diff-line-num"
|
||||
:href="`#LC${line}`"
|
||||
class="diff-line-num gl-shadow-none!"
|
||||
:to="`#LC${line}`"
|
||||
:data-line-number="line"
|
||||
@click="$emit('select-line', `#LC${line}`)"
|
||||
>
|
||||
<gl-icon :size="12" name="link" />
|
||||
{{ line }}
|
||||
|
|
|
@ -56,6 +56,9 @@ export default {
|
|||
highlightedContent() {
|
||||
this.$nextTick(() => this.selectLine());
|
||||
},
|
||||
$route() {
|
||||
this.selectLine();
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
this.hljs = await this.loadHighlightJS();
|
||||
|
@ -90,7 +93,8 @@ export default {
|
|||
.join('\r\n')
|
||||
);
|
||||
},
|
||||
selectLine(hash = sanitize(window.location.hash)) {
|
||||
selectLine() {
|
||||
const hash = sanitize(this.$route.hash);
|
||||
const lineToSelect = hash && this.$el.querySelector(hash);
|
||||
|
||||
if (!lineToSelect) {
|
||||
|
@ -112,7 +116,7 @@ export default {
|
|||
</script>
|
||||
<template>
|
||||
<div class="file-content code js-syntax-highlight" :class="$options.userColorScheme">
|
||||
<line-numbers :lines="lineNumbers" @select-line="selectLine" />
|
||||
<line-numbers :lines="lineNumbers" />
|
||||
<pre class="code"><code v-safe-html="highlightedContent"></code>
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class LooseForeignKeys::DeletedRecord < ApplicationRecord
|
||||
class LooseForeignKeys::DeletedRecord < Gitlab::Database::SharedModel
|
||||
PARTITION_DURATION = 1.day
|
||||
|
||||
include PartitionedTable
|
||||
|
|
|
@ -4,7 +4,7 @@ module LooseForeignKeys
|
|||
class ModificationTracker
|
||||
MAX_DELETES = 100_000
|
||||
MAX_UPDATES = 50_000
|
||||
MAX_RUNTIME = 3.minutes
|
||||
MAX_RUNTIME = 30.seconds # must be less than the scheduling frequency of the LooseForeignKeys::CleanupWorker cron worker
|
||||
|
||||
delegate :monotonic_time, to: :'Gitlab::Metrics::System'
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ module LooseForeignKeys
|
|||
|
||||
def execute
|
||||
modification_tracker = ModificationTracker.new
|
||||
|
||||
tracked_tables.cycle do |table|
|
||||
records = load_batch_for_table(table)
|
||||
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
= cache_if(Feature.enabled?(:cached_mr_widget, @merge_request.project), [@merge_request.project, @merge_request, current_user], expires_in: 10.minutes) do
|
||||
- artifacts_endpoint_placeholder = ':pipeline_artifacts_id'
|
||||
- artifacts_endpoint_placeholder = ':pipeline_artifacts_id'
|
||||
|
||||
= javascript_tag do
|
||||
:plain
|
||||
window.gl = window.gl || {};
|
||||
window.gl.mrWidgetData = #{serialize_issuable(@merge_request, serializer: 'widget', issues_links: true)}
|
||||
= javascript_tag do
|
||||
:plain
|
||||
window.gl = window.gl || {};
|
||||
window.gl.mrWidgetData = #{serialize_issuable(@merge_request, serializer: 'widget', issues_links: true)}
|
||||
|
||||
window.gl.mrWidgetData.artifacts_endpoint = '#{downloadable_artifacts_project_pipeline_path(@project, artifacts_endpoint_placeholder, format: :json)}';
|
||||
window.gl.mrWidgetData.artifacts_endpoint_placeholder = '#{artifacts_endpoint_placeholder}';
|
||||
window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}';
|
||||
window.gl.mrWidgetData.ci_troubleshooting_docs_path = '#{help_page_path('ci/troubleshooting.md')}';
|
||||
window.gl.mrWidgetData.mr_troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/reviews/index.md', anchor: 'troubleshooting')}';
|
||||
window.gl.mrWidgetData.pipeline_must_succeed_docs_path = '#{help_page_path('user/project/merge_requests/merge_when_pipeline_succeeds.md', anchor: 'only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds')}';
|
||||
window.gl.mrWidgetData.security_approvals_help_page_path = '#{help_page_path('user/application_security/index.md', anchor: 'security-approvals-in-merge-requests')}';
|
||||
window.gl.mrWidgetData.license_compliance_docs_path = '#{help_page_path('user/compliance/license_compliance/index.md', anchor: 'policies')}';
|
||||
window.gl.mrWidgetData.eligible_approvers_docs_path = '#{help_page_path('user/project/merge_requests/approvals/rules.md', anchor: 'eligible-approvers')}';
|
||||
window.gl.mrWidgetData.approvals_help_path = '#{help_page_path("user/project/merge_requests/approvals/index.md")}';
|
||||
window.gl.mrWidgetData.pipelines_empty_svg_path = '#{image_path('illustrations/pipelines_empty.svg')}';
|
||||
window.gl.mrWidgetData.codequality_help_path = '#{help_page_path("user/project/merge_requests/code_quality", anchor: "code-quality-reports")}';
|
||||
window.gl.mrWidgetData.false_positive_doc_url = '#{help_page_path('user/application_security/vulnerabilities/index')}';
|
||||
window.gl.mrWidgetData.can_view_false_positive = '#{@merge_request.project.licensed_feature_available?(:sast_fp_reduction).to_s}';
|
||||
window.gl.mrWidgetData.user_preferences_gitpod_path = '#{profile_preferences_path(anchor: 'user_gitpod_enabled')}';
|
||||
window.gl.mrWidgetData.user_profile_enable_gitpod_path = '#{profile_path(user: { gitpod_enabled: true })}';
|
||||
window.gl.mrWidgetData.artifacts_endpoint = '#{downloadable_artifacts_project_pipeline_path(@project, artifacts_endpoint_placeholder, format: :json)}';
|
||||
window.gl.mrWidgetData.artifacts_endpoint_placeholder = '#{artifacts_endpoint_placeholder}';
|
||||
window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}';
|
||||
window.gl.mrWidgetData.ci_troubleshooting_docs_path = '#{help_page_path('ci/troubleshooting.md')}';
|
||||
window.gl.mrWidgetData.mr_troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/reviews/index.md', anchor: 'troubleshooting')}';
|
||||
window.gl.mrWidgetData.pipeline_must_succeed_docs_path = '#{help_page_path('user/project/merge_requests/merge_when_pipeline_succeeds.md', anchor: 'only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds')}';
|
||||
window.gl.mrWidgetData.security_approvals_help_page_path = '#{help_page_path('user/application_security/index.md', anchor: 'security-approvals-in-merge-requests')}';
|
||||
window.gl.mrWidgetData.license_compliance_docs_path = '#{help_page_path('user/compliance/license_compliance/index.md', anchor: 'policies')}';
|
||||
window.gl.mrWidgetData.eligible_approvers_docs_path = '#{help_page_path('user/project/merge_requests/approvals/rules.md', anchor: 'eligible-approvers')}';
|
||||
window.gl.mrWidgetData.approvals_help_path = '#{help_page_path("user/project/merge_requests/approvals/index.md")}';
|
||||
window.gl.mrWidgetData.pipelines_empty_svg_path = '#{image_path('illustrations/pipelines_empty.svg')}';
|
||||
window.gl.mrWidgetData.codequality_help_path = '#{help_page_path("user/project/merge_requests/code_quality", anchor: "code-quality-reports")}';
|
||||
window.gl.mrWidgetData.false_positive_doc_url = '#{help_page_path('user/application_security/vulnerabilities/index')}';
|
||||
window.gl.mrWidgetData.can_view_false_positive = '#{@merge_request.project.licensed_feature_available?(:sast_fp_reduction).to_s}';
|
||||
window.gl.mrWidgetData.user_preferences_gitpod_path = '#{profile_preferences_path(anchor: 'user_gitpod_enabled')}';
|
||||
window.gl.mrWidgetData.user_profile_enable_gitpod_path = '#{profile_path(user: { gitpod_enabled: true })}';
|
||||
|
||||
#js-vue-mr-widget.mr-widget
|
||||
#js-vue-mr-widget.mr-widget
|
||||
|
|
|
@ -6,6 +6,7 @@ module LooseForeignKeys
|
|||
include Gitlab::ExclusiveLeaseHelpers
|
||||
include CronjobQueue # rubocop: disable Scalability/CronWorkerContext
|
||||
|
||||
sidekiq_options retry: false
|
||||
feature_category :sharding
|
||||
data_consistency :always
|
||||
idempotent!
|
||||
|
@ -13,13 +14,30 @@ module LooseForeignKeys
|
|||
def perform
|
||||
return if Feature.disabled?(:loose_foreign_key_cleanup, default_enabled: :yaml)
|
||||
|
||||
ttl = ModificationTracker::MAX_RUNTIME + 1.minute
|
||||
in_lock(self.class.name.underscore, ttl: ttl, retries: 0) do
|
||||
# TODO: Iterate over the connections
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/341513
|
||||
stats = ProcessDeletedRecordsService.new(connection: ApplicationRecord.connection).execute
|
||||
in_lock(self.class.name.underscore, ttl: ModificationTracker::MAX_RUNTIME, retries: 0) do
|
||||
stats = {}
|
||||
|
||||
connection_name, base_model = current_connection_name_and_base_model
|
||||
|
||||
Gitlab::Database::SharedModel.using_connection(base_model.connection) do
|
||||
stats = ProcessDeletedRecordsService.new(connection: base_model.connection).execute
|
||||
stats[:connection] = connection_name
|
||||
end
|
||||
|
||||
log_extra_metadata_on_done(:stats, stats)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Rotate the databases every minute
|
||||
#
|
||||
# If one DB is configured: every minute use the configured DB
|
||||
# If two DBs are configured (Main, CI): minute 1 -> Main, minute 2 -> CI
|
||||
def current_connection_name_and_base_model
|
||||
minutes_since_epoch = Time.current.to_i / 60
|
||||
connections_with_name = Gitlab::Database.database_base_models.to_a # this will never be empty
|
||||
connections_with_name[minutes_since_epoch % connections_with_name.count]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: cached_mr_widget
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61584
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330803
|
||||
milestone: '13.12'
|
||||
type: development
|
||||
group: group::code review
|
||||
default_enabled: false
|
|
@ -735,7 +735,7 @@ Gitlab.ee do
|
|||
Settings.cron_jobs['app_sec_dast_profile_schedule_worker']['cron'] ||= '7-59/15 * * * *'
|
||||
Settings.cron_jobs['app_sec_dast_profile_schedule_worker']['job_class'] = 'AppSec::Dast::ProfileScheduleWorker'
|
||||
Settings.cron_jobs['loose_foreign_keys_cleanup_worker'] ||= Settingslogic.new({})
|
||||
Settings.cron_jobs['loose_foreign_keys_cleanup_worker']['cron'] ||= '*/5 * * * *'
|
||||
Settings.cron_jobs['loose_foreign_keys_cleanup_worker']['cron'] ||= '*/1 * * * *'
|
||||
Settings.cron_jobs['loose_foreign_keys_cleanup_worker']['job_class'] = 'LooseForeignKeys::CleanupWorker'
|
||||
end
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ we can:
|
|||
|
||||
1. Create a `DELETE` trigger on the `projects` table.
|
||||
Record the deletions in a separate table (`deleted_records`).
|
||||
1. A job checks the `deleted_records` table every 5 minutes.
|
||||
1. A job checks the `deleted_records` table every minute or two.
|
||||
1. For each record in the table, delete the associated `ci_pipelines` records
|
||||
using the `project_id` column.
|
||||
|
||||
|
|
|
@ -169,7 +169,8 @@ module Gitlab
|
|||
return -1 if args.any?(&:negative?)
|
||||
|
||||
args.sum
|
||||
rescue StandardError
|
||||
rescue StandardError => error
|
||||
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
|
||||
FALLBACK
|
||||
end
|
||||
|
||||
|
@ -179,7 +180,8 @@ module Gitlab
|
|||
else
|
||||
value
|
||||
end
|
||||
rescue StandardError
|
||||
rescue StandardError => error
|
||||
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
|
||||
fallback
|
||||
end
|
||||
|
||||
|
@ -295,13 +297,15 @@ module Gitlab
|
|||
|
||||
def redis_usage_counter
|
||||
yield
|
||||
rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent, Gitlab::UsageDataCounters::HLLRedisCounter::EventError
|
||||
rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent, Gitlab::UsageDataCounters::HLLRedisCounter::EventError => error
|
||||
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
|
||||
FALLBACK
|
||||
end
|
||||
|
||||
def redis_usage_data_totals(counter)
|
||||
counter.totals
|
||||
rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent
|
||||
rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent => error
|
||||
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
|
||||
counter.fallback_totals
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13300,6 +13300,12 @@ msgstr ""
|
|||
msgid "Enable repository checks"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable security training"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable security training to help your developers learn how to fix vulnerabilities. Developers can view security training from selected educational providers, relevant to the detected vulnerability."
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable shared runners for all projects and subgroups in this group."
|
||||
msgstr ""
|
||||
|
||||
|
@ -29353,6 +29359,9 @@ msgstr ""
|
|||
msgid "Reduce project visibility"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reduce risk and triage fewer vulnerabilities with security training"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reduce this project’s visibility?"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ describe('Line Numbers component', () => {
|
|||
expect(findLineNumbers().length).toBe(lines);
|
||||
expect(findFirstLineNumber().attributes()).toMatchObject({
|
||||
id: 'L1',
|
||||
href: '#LC1',
|
||||
to: '#LC1',
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -34,15 +34,4 @@ describe('Line Numbers component', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('clicking a line number', () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(wrapper.vm, '$emit');
|
||||
findFirstLineNumber().vm.$emit('click');
|
||||
});
|
||||
|
||||
it('emits a select-line event', () => {
|
||||
expect(wrapper.vm.$emit).toHaveBeenCalledWith('select-line', '#LC1');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import hljs from 'highlight.js/lib/core';
|
||||
import Vue, { nextTick } from 'vue';
|
||||
import VueRouter from 'vue-router';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import SourceViewer from '~/vue_shared/components/source_viewer.vue';
|
||||
import LineNumbers from '~/vue_shared/components/line_numbers.vue';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
|
||||
jest.mock('highlight.js/lib/core');
|
||||
Vue.use(VueRouter);
|
||||
const router = new VueRouter();
|
||||
|
||||
describe('Source Viewer component', () => {
|
||||
let wrapper;
|
||||
|
@ -16,7 +20,10 @@ describe('Source Viewer component', () => {
|
|||
hljs.highlightAuto.mockImplementation(() => ({ value: highlightedContent }));
|
||||
|
||||
const createComponent = async (props = {}) => {
|
||||
wrapper = shallowMountExtended(SourceViewer, { propsData: { content, language, ...props } });
|
||||
wrapper = shallowMountExtended(SourceViewer, {
|
||||
router,
|
||||
propsData: { content, language, ...props },
|
||||
});
|
||||
await waitForPromises();
|
||||
};
|
||||
|
||||
|
@ -69,16 +76,18 @@ describe('Source Viewer component', () => {
|
|||
jest.spyOn(firstLineElement, 'scrollIntoView');
|
||||
jest.spyOn(firstLineElement.classList, 'add');
|
||||
jest.spyOn(firstLineElement.classList, 'remove');
|
||||
|
||||
findLineNumbers().vm.$emit('select-line', '#LC1');
|
||||
});
|
||||
|
||||
it('adds the highlight (hll) class', () => {
|
||||
it('adds the highlight (hll) class', async () => {
|
||||
wrapper.vm.$router.push('#LC1');
|
||||
await nextTick();
|
||||
|
||||
expect(firstLineElement.classList.add).toHaveBeenCalledWith('hll');
|
||||
});
|
||||
|
||||
it('removes the highlight (hll) class from a previously highlighted line', () => {
|
||||
findLineNumbers().vm.$emit('select-line', '#LC2');
|
||||
it('removes the highlight (hll) class from a previously highlighted line', async () => {
|
||||
wrapper.vm.$router.push('#LC2');
|
||||
await nextTick();
|
||||
|
||||
expect(firstLineElement.classList.remove).toHaveBeenCalledWith('hll');
|
||||
});
|
||||
|
|
|
@ -17,9 +17,25 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::GenericMetric do
|
|||
end
|
||||
|
||||
context 'when raising an exception' do
|
||||
it 'return the custom fallback' do
|
||||
before do
|
||||
allow(Gitlab::ErrorTracking).to receive(:should_raise_for_dev?).and_return(should_raise_for_dev)
|
||||
expect(ApplicationRecord.database).to receive(:version).and_raise('Error')
|
||||
expect(subject.value).to eq(custom_fallback)
|
||||
end
|
||||
|
||||
context 'with should_raise_for_dev? false' do
|
||||
let(:should_raise_for_dev) { false }
|
||||
|
||||
it 'return the custom fallback' do
|
||||
expect(subject.value).to eq(custom_fallback)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with should_raise_for_dev? true' do
|
||||
let(:should_raise_for_dev) { true }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { subject.value }.to raise_error('Error')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -38,9 +54,25 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::GenericMetric do
|
|||
end
|
||||
|
||||
context 'when raising an exception' do
|
||||
it 'return the default fallback' do
|
||||
before do
|
||||
allow(Gitlab::ErrorTracking).to receive(:should_raise_for_dev?).and_return(should_raise_for_dev)
|
||||
expect(ApplicationRecord.database).to receive(:version).and_raise('Error')
|
||||
expect(subject.value).to eq(described_class::FALLBACK)
|
||||
end
|
||||
|
||||
context 'with should_raise_for_dev? false' do
|
||||
let(:should_raise_for_dev) { false }
|
||||
|
||||
it 'return the default fallback' do
|
||||
expect(subject.value).to eq(described_class::FALLBACK)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with should_raise_for_dev? true' do
|
||||
let(:should_raise_for_dev) { true }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { subject.value }.to raise_error('Error')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -925,10 +925,25 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
end
|
||||
|
||||
context 'when retrieve component setting meets exception' do
|
||||
it 'returns -1 for component enable status' do
|
||||
before do
|
||||
allow(Gitlab::ErrorTracking).to receive(:should_raise_for_dev?).and_return(should_raise_for_dev)
|
||||
allow(Settings).to receive(:[]).with(component).and_raise(StandardError)
|
||||
end
|
||||
|
||||
expect(subject).to eq({ enabled: -1 })
|
||||
context 'with should_raise_for_dev? false' do
|
||||
let(:should_raise_for_dev) { false }
|
||||
|
||||
it 'returns -1 for component enable status' do
|
||||
expect(subject).to eq({ enabled: -1 })
|
||||
end
|
||||
end
|
||||
|
||||
context 'with should_raise_for_dev? true' do
|
||||
let(:should_raise_for_dev) { true }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { subject.value }.to raise_error(StandardError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,11 +5,13 @@ require 'spec_helper'
|
|||
RSpec.describe Gitlab::Utils::UsageData do
|
||||
include Database::DatabaseHelpers
|
||||
|
||||
shared_examples 'failing hardening method' do
|
||||
shared_examples 'failing hardening method' do |raised_exception|
|
||||
let(:exception) { raised_exception || ActiveRecord::StatementInvalid }
|
||||
|
||||
before do
|
||||
allow(Gitlab::ErrorTracking).to receive(:should_raise_for_dev?).and_return(should_raise_for_dev)
|
||||
stub_const("Gitlab::Utils::UsageData::FALLBACK", fallback)
|
||||
allow(failing_class).to receive(failing_method).and_raise(ActiveRecord::StatementInvalid)
|
||||
allow(failing_class).to receive(failing_method).and_raise(exception) unless failing_class.nil?
|
||||
end
|
||||
|
||||
context 'with should_raise_for_dev? false' do
|
||||
|
@ -24,7 +26,7 @@ RSpec.describe Gitlab::Utils::UsageData do
|
|||
let(:should_raise_for_dev) { true }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { subject }.to raise_error(ActiveRecord::StatementInvalid)
|
||||
expect { subject }.to raise_error(exception)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -366,8 +368,13 @@ RSpec.describe Gitlab::Utils::UsageData do
|
|||
expect(described_class.add).to eq(0)
|
||||
end
|
||||
|
||||
it 'returns the fallback value when adding fails' do
|
||||
expect(described_class.add(nil, 3)).to eq(-1)
|
||||
context 'when adding fails' do
|
||||
subject { described_class.add(nil, 3) }
|
||||
|
||||
let(:fallback) { -1 }
|
||||
let(:failing_class) { nil }
|
||||
|
||||
it_behaves_like 'failing hardening method', StandardError
|
||||
end
|
||||
|
||||
it 'returns the fallback value one of the arguments is negative' do
|
||||
|
@ -376,8 +383,13 @@ RSpec.describe Gitlab::Utils::UsageData do
|
|||
end
|
||||
|
||||
describe '#alt_usage_data' do
|
||||
it 'returns the fallback when it gets an error' do
|
||||
expect(described_class.alt_usage_data { raise StandardError } ).to eq(-1)
|
||||
context 'when method fails' do
|
||||
subject { described_class.alt_usage_data { raise StandardError } }
|
||||
|
||||
let(:fallback) { -1 }
|
||||
let(:failing_class) { nil }
|
||||
|
||||
it_behaves_like 'failing hardening method', StandardError
|
||||
end
|
||||
|
||||
it 'returns the evaluated block when give' do
|
||||
|
@ -391,14 +403,22 @@ RSpec.describe Gitlab::Utils::UsageData do
|
|||
|
||||
describe '#redis_usage_data' do
|
||||
context 'with block given' do
|
||||
it 'returns the fallback when it gets an error' do
|
||||
expect(described_class.redis_usage_data { raise ::Redis::CommandError } ).to eq(-1)
|
||||
context 'when method fails' do
|
||||
subject { described_class.redis_usage_data { raise ::Redis::CommandError } }
|
||||
|
||||
let(:fallback) { -1 }
|
||||
let(:failing_class) { nil }
|
||||
|
||||
it_behaves_like 'failing hardening method', ::Redis::CommandError
|
||||
end
|
||||
|
||||
it 'returns the fallback when Redis HLL raises any error' do
|
||||
stub_const("Gitlab::Utils::UsageData::FALLBACK", 15)
|
||||
context 'when Redis HLL raises any error' do
|
||||
subject { described_class.redis_usage_data { raise Gitlab::UsageDataCounters::HLLRedisCounter::CategoryMismatch } }
|
||||
|
||||
expect(described_class.redis_usage_data { raise Gitlab::UsageDataCounters::HLLRedisCounter::CategoryMismatch } ).to eq(15)
|
||||
let(:fallback) { 15 }
|
||||
let(:failing_class) { nil }
|
||||
|
||||
it_behaves_like 'failing hardening method', Gitlab::UsageDataCounters::HLLRedisCounter::CategoryMismatch
|
||||
end
|
||||
|
||||
it 'returns the evaluated block when given' do
|
||||
|
@ -407,9 +427,14 @@ RSpec.describe Gitlab::Utils::UsageData do
|
|||
end
|
||||
|
||||
context 'with counter given' do
|
||||
it 'returns the falback values for all counter keys when it gets an error' do
|
||||
allow(::Gitlab::UsageDataCounters::WikiPageCounter).to receive(:totals).and_raise(::Redis::CommandError)
|
||||
expect(described_class.redis_usage_data(::Gitlab::UsageDataCounters::WikiPageCounter)).to eql(::Gitlab::UsageDataCounters::WikiPageCounter.fallback_totals)
|
||||
context 'when gets an error' do
|
||||
subject { described_class.redis_usage_data(::Gitlab::UsageDataCounters::WikiPageCounter) }
|
||||
|
||||
let(:fallback) { ::Gitlab::UsageDataCounters::WikiPageCounter.fallback_totals }
|
||||
let(:failing_class) { ::Gitlab::UsageDataCounters::WikiPageCounter }
|
||||
let(:failing_method) { :totals }
|
||||
|
||||
it_behaves_like 'failing hardening method', ::Redis::CommandError
|
||||
end
|
||||
|
||||
it 'returns the totals when couter is given' do
|
||||
|
|
|
@ -1167,9 +1167,13 @@ RSpec.describe GroupPolicy do
|
|||
end
|
||||
|
||||
context 'when crm_enabled is false' do
|
||||
let(:group) { create(:group, :crm_enabled) }
|
||||
let(:current_user) { owner }
|
||||
|
||||
before_all do
|
||||
group.crm_settings.enabled = false
|
||||
group.crm_settings.save!
|
||||
end
|
||||
|
||||
it { is_expected.to be_disallowed(:read_crm_contact) }
|
||||
it { is_expected.to be_disallowed(:read_crm_organization) }
|
||||
it { is_expected.to be_disallowed(:admin_crm_contact) }
|
||||
|
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe LooseForeignKeys::CleanupWorker do
|
||||
include MigrationsHelpers
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
def create_table_structure
|
||||
migration = ActiveRecord::Migration.new.extend(Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers)
|
||||
|
@ -149,4 +150,31 @@ RSpec.describe LooseForeignKeys::CleanupWorker do
|
|||
expect { described_class.new.perform }.not_to change { LooseForeignKeys::DeletedRecord.status_processed.count }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'multi-database support' do
|
||||
where(:current_minute, :configured_base_models, :expected_connection) do
|
||||
2 | { main: ApplicationRecord, ci: Ci::ApplicationRecord } | ApplicationRecord.connection
|
||||
3 | { main: ApplicationRecord, ci: Ci::ApplicationRecord } | Ci::ApplicationRecord.connection
|
||||
2 | { main: ApplicationRecord } | ApplicationRecord.connection
|
||||
3 | { main: ApplicationRecord } | ApplicationRecord.connection
|
||||
end
|
||||
|
||||
with_them do
|
||||
before do
|
||||
allow(Gitlab::Database).to receive(:database_base_models).and_return(configured_base_models)
|
||||
end
|
||||
|
||||
it 'uses the correct connection' do
|
||||
LooseForeignKeys::DeletedRecord.count.times do
|
||||
expect_next_found_instance_of(LooseForeignKeys::DeletedRecord) do |instance|
|
||||
expect(instance.class.connection).to eq(expected_connection)
|
||||
end
|
||||
end
|
||||
|
||||
travel_to DateTime.new(2019, 1, 1, 10, current_minute) do
|
||||
described_class.new.perform
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue