summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-19 12:10:09 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-19 12:10:09 +0000
commit690c904b5e340f14c04f93ff688b647b46f7d1a2 (patch)
tree1eeb0005de86a16132fc08608494a67d5b9f4f71
parent035cd5ee5e42fda4a896ed43147ebf455fa2f5ba (diff)
downloadgitlab-ce-690c904b5e340f14c04f93ff688b647b46f7d1a2.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/merge_request_tabs.js8
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue17
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js4
-rw-r--r--app/finders/snippets_finder.rb2
-rw-r--r--app/models/snippet.rb1
-rw-r--r--app/views/shared/runners/_form.html.haml2
-rw-r--r--config/metrics/aggregates/common.yml3
-rw-r--r--doc/administration/audit_event_streaming.md32
-rw-r--r--doc/api/snippets.md19
-rw-r--r--doc/user/analytics/index.md2
-rw-r--r--lib/api/snippets.rb12
-rw-r--r--lib/gitlab/sidekiq_daemon/memory_killer.rb41
-rw-r--r--locale/gitlab.pot35
-rw-r--r--spec/frontend/admin/signup_restrictions/mock_data.js8
-rw-r--r--spec/frontend/admin/signup_restrictions/utils_spec.js4
-rw-r--r--spec/frontend/merge_request_tabs_spec.js8
-rw-r--r--spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb77
-rw-r--r--spec/requests/api/snippets_spec.rb38
18 files changed, 257 insertions, 56 deletions
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index 94041d77bb0..ed2e6a5af58 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -177,7 +177,7 @@ export default class MergeRequestTabs {
this.peek = document.getElementById('js-peek');
this.sidebar = document.querySelector('.js-right-sidebar');
this.pageLayout = document.querySelector('.layout-page');
- this.expandSidebar = document.querySelector('.js-expand-sidebar');
+ this.expandSidebar = document.querySelectorAll('.js-expand-sidebar, .js-sidebar-toggle');
this.paddingTop = 16;
this.scrollPositions = {};
@@ -282,7 +282,11 @@ export default class MergeRequestTabs {
const tab = this.mergeRequestTabs.querySelector(`.${action}-tab`);
if (tab) tab.classList.add('active');
- this.expandSidebar?.classList.toggle('gl-display-none!', action !== 'show');
+ if (window.gon?.features?.movedMrSidebar) {
+ this.expandSidebar?.forEach((el) =>
+ el.classList.toggle('gl-display-none!', action !== 'show'),
+ );
+ }
if (action === 'commits') {
this.loadCommits(href);
diff --git a/app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue b/app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue
index 5ecacb84d65..ccb449f96e1 100644
--- a/app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue
+++ b/app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue
@@ -12,6 +12,7 @@ import {
import { toSafeInteger } from 'lodash';
import csrf from '~/lib/utils/csrf';
import { __, n__, s__, sprintf } from '~/locale';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import SignupCheckbox from './signup_checkbox.vue';
const DENYLIST_TYPE_RAW = 'raw';
@@ -31,7 +32,12 @@ export default {
GlLink,
SignupCheckbox,
GlModal,
+ PasswordComplexityCheckboxGroup: () =>
+ import(
+ 'ee_component/pages/admin/application_settings/general/components/password_complexity_checkbox_group.vue'
+ ),
},
+ mixins: [glFeatureFlagMixin()],
inject: [
'host',
'settingsPath',
@@ -178,6 +184,9 @@ export default {
this.submitForm();
},
+ setPasswordComplexity({ name, value }) {
+ this.$set(this.form, name, value);
+ },
submitForm() {
this.$refs.form.submit();
},
@@ -291,9 +300,7 @@ export default {
<template #description>
<gl-sprintf
:message="
- s__(
- 'ApplicationSettings|See GitLab\'s %{linkStart}Password Policy Guidelines%{linkEnd}.',
- )
+ s__('ApplicationSettings|See %{linkStart}password policy guidelines%{linkEnd}.')
"
>
<template #link="{ content }">
@@ -305,6 +312,10 @@ export default {
</template>
</gl-form-group>
+ <password-complexity-checkbox-group
+ v-if="glFeatures.passwordComplexity"
+ @set-password-complexity="setPasswordComplexity"
+ />
<gl-form-group
:description="$options.i18n.domainAllowListDescription"
:label="$options.i18n.domainAllowListLabel"
diff --git a/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js b/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js
index a50d8de0e88..0d5c55cb87b 100644
--- a/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js
+++ b/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js
@@ -18,6 +18,10 @@ export default function initSignupRestrictions(elementSelector = '#js-signup-for
'domainDenylistEnabled',
'denylistTypeRawSelected',
'emailRestrictionsEnabled',
+ 'passwordNumberRequired',
+ 'passwordLowercaseRequired',
+ 'passwordUppercaseRequired',
+ 'passwordSymbolRequired',
],
});
diff --git a/app/finders/snippets_finder.rb b/app/finders/snippets_finder.rb
index b1e12721712..bf20a2c2c3d 100644
--- a/app/finders/snippets_finder.rb
+++ b/app/finders/snippets_finder.rb
@@ -41,6 +41,7 @@
class SnippetsFinder < UnionFinder
include FinderMethods
include Gitlab::Utils::StrongMemoize
+ include CreatedAtFilter
attr_reader :current_user, :params
@@ -69,6 +70,7 @@ class SnippetsFinder < UnionFinder
items = init_collection
items = by_ids(items)
items = items.with_optional_visibility(visibility_from_scope)
+ items = by_created_at(items)
items.order_by(sort_param)
end
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index cf4b83d44c2..c813c5cb5b8 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -18,6 +18,7 @@ class Snippet < ApplicationRecord
include CanMoveRepositoryStorage
include AfterCommitQueue
extend ::Gitlab::Utils::Override
+ include CreatedAtFilterable
MAX_FILE_COUNT = 10
diff --git a/app/views/shared/runners/_form.html.haml b/app/views/shared/runners/_form.html.haml
index 024b06fe97a..e0079a95cec 100644
--- a/app/views/shared/runners/_form.html.haml
+++ b/app/views/shared/runners/_form.html.haml
@@ -1,5 +1,5 @@
= gitlab_ui_form_for runner, url: runner_form_url do |f|
- = form_errors(runner)
+ = form_errors(runner, pajamas_alert: true)
.form-group.row
= label :active, _("Active"), class: 'col-form-label col-sm-2'
.col-sm-10
diff --git a/config/metrics/aggregates/common.yml b/config/metrics/aggregates/common.yml
index a6585ddec23..6396187a26a 100644
--- a/config/metrics/aggregates/common.yml
+++ b/config/metrics/aggregates/common.yml
@@ -59,7 +59,6 @@
events:
- users_creating_work_items
- users_updating_work_item_title
- - users_updating_weight_estimate
feature_flag: track_work_items_activity
- name: xmau_project_management
operator: OR
@@ -68,7 +67,6 @@
events:
- users_creating_work_items
- users_updating_work_item_title
- - users_updating_weight_estimate
feature_flag: track_work_items_activity
- name: users_work_items
operator: OR
@@ -77,5 +75,4 @@
events:
- users_creating_work_items
- users_updating_work_item_title
- - users_updating_weight_estimate
feature_flag: track_work_items_activity
diff --git a/doc/administration/audit_event_streaming.md b/doc/administration/audit_event_streaming.md
index 019032c8b98..817f22debbc 100644
--- a/doc/administration/audit_event_streaming.md
+++ b/doc/administration/audit_event_streaming.md
@@ -30,7 +30,7 @@ Event streaming destinations receive **all** audit event data, which could inclu
Users with at least the Owner role for a group can add event streaming destinations for it:
1. On the top bar, select **Menu > Groups** and find your group.
-1. On the left sidebar, select **Security & Compliance > Audit events**
+1. On the left sidebar, select **Security & Compliance > Audit events**.
1. On the main area, select **Streams** tab.
- When the destination list is empty, select **Add stream** to show the section for adding destinations.
- When the destination list is not empty, select **{plus}** to show the section for adding destinations.
@@ -77,7 +77,7 @@ Users with at least the Owner role for a group can list event streaming destinat
Users with at least the Owner role for a group can list event streaming destinations:
1. On the top bar, select **Menu > Groups** and find your group.
-1. On the left sidebar, select **Security & Compliance > Audit events**
+1. On the left sidebar, select **Security & Compliance > Audit events**.
1. On the main area, select **Streams** tab.
### Use the API
@@ -116,7 +116,7 @@ When the last destination is successfully deleted, event streaming is disabled f
Users with at least the Owner role for a group can delete event streaming destinations.
1. On the top bar, select **Menu > Groups** and find your group.
-1. On the left sidebar, select **Security & Compliance > Audit events**
+1. On the left sidebar, select **Security & Compliance > Audit events**.
1. On the main area, select **Streams** tab.
1. Select **{remove}** at the right side of each item.
@@ -185,7 +185,7 @@ not available. The UI for this feature is not ready for production use.
Users with at least the Owner role for a group can add event streaming destinations and custom HTTP headers for it:
1. On the top bar, select **Menu > Groups** and find your group.
-1. On the left sidebar, select **Security & Compliance > Audit events**
+1. On the left sidebar, select **Security & Compliance > Audit events**.
1. On the main area, select **Streams** tab.
- When the destination list is empty, select **Add stream** to show the section for adding destinations.
- When the destination list is not empty, select **{plus}** to show the section for adding destinations.
@@ -221,7 +221,7 @@ mutation {
### Deleting custom HTTP headers
Group owners can remove a HTTP header using the GraphQL `auditEventsStreamingHeadersDestroy` mutation. You can retrieve the header ID
-by [listing all the custom headers](#list-all-custom-headers-with-the-api) on the group.
+by [listing all the custom headers](#list-all-custom-headers) on the group.
```graphql
mutation {
@@ -233,7 +233,11 @@ mutation {
The header is deleted if the returned `errors` object is empty.
-### List all custom headers with the API
+### List all custom headers
+
+List all custom HTTP headers with the API or GitLab UI.
+
+#### Use the API
You can list all custom headers for a top-level group as well as their value and ID using the GraphQL `externalAuditEventDestinations` query. The ID
value returned by this query is what you need to pass to the `deletion` mutation.
@@ -259,6 +263,22 @@ query {
}
```
+#### Use the GitLab UI
+
+FLAG:
+On self-managed GitLab, by default the UI for this feature is not available. To make it available per group, ask an administrator to
+[enable the feature flag](../administration/feature_flags.md) named `custom_headers_streaming_audit_events_ui`. On GitLab.com, the UI for this feature is
+not available. The UI for this feature is not ready for production use.
+
+Users with at least the Owner role for a group can add event streaming destinations and custom HTTP headers for it:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Security & Compliance > Audit events**.
+1. On the main area, select **Streams** tab.
+1. Select **{pencil}** at the right side of an item.
+1. A read-only view of the items custom headers is shown. To track progress on adding editing functionality, see the [relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/361925).
+1. Select **Cancel** to close the read-only view.
+
## Verify event authenticity
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345424) in GitLab 14.8.
diff --git a/doc/api/snippets.md b/doc/api/snippets.md
index 52bcd072de9..e3bc3573ed7 100644
--- a/doc/api/snippets.md
+++ b/doc/api/snippets.md
@@ -31,6 +31,15 @@ Get a list of the current user's snippets.
GET /snippets
```
+Parameters:
+
+| Attribute | Type | Required | Description |
+|------------------|----------|----------|-----------------------------------------------------------------------------------------------------|
+| `per_page` | integer | no | Number of snippets to return per page. |
+| `page` | integer | no | Page to retrieve. |
+| `created_after` | datetime | no | Return snippets created after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
+| `created_before` | datetime | no | Return snippets created before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
+
Example request:
```shell
@@ -389,10 +398,12 @@ GET /snippets/public
Parameters:
-| Attribute | Type | Required | Description |
-|:-----------|:--------|:---------|:---------------------------------------|
-| `per_page` | integer | no | Number of snippets to return per page. |
-| `page` | integer | no | Page to retrieve. |
+| Attribute | Type | Required | Description |
+|------------------|----------|----------|-----------------------------------------------------------------------------------------------------|
+| `per_page` | integer | no | Number of snippets to return per page. |
+| `page` | integer | no | Page to retrieve. |
+| `created_after` | datetime | no | Return snippets created after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
+| `created_before` | datetime | no | Return snippets created before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
Example request:
diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md
index b8c0e9af745..f699fa6d0fb 100644
--- a/doc/user/analytics/index.md
+++ b/doc/user/analytics/index.md
@@ -131,7 +131,7 @@ To retrieve metrics for change failure rate, use the [GraphQL](../../api/graphql
| `lead_time_for_changes` | Project | [GitLab 13.10 and later](../../api/dora/metrics.md) | GitLab 13.11 and later | Unit in seconds. Aggregation method is median. |
| `lead_time_for_changes` | Group | [GitLab 13.10 and later](../../api/dora/metrics.md) | GitLab 14.0 and later | Unit in seconds. Aggregation method is median. |
| `time_to_restore_service` | Project and group | [GitLab 14.9 and later](../../api/dora/metrics.md) | GitLab 15.1 and later | Unit in days. Aggregation method is median. |
-| `change_failure_rate` | Project and group | [GitLab 14.10 and later](../../api/dora/metrics.md) | Not supported | |
+| `change_failure_rate` | Project and group | [GitLab 14.10 and later](../../api/dora/metrics.md) | GitLab 15.2 and later | Percentage of deployments. | |
## Definitions
diff --git a/lib/api/snippets.rb b/lib/api/snippets.rb
index 496532a15b2..4e70ebddf94 100644
--- a/lib/api/snippets.rb
+++ b/lib/api/snippets.rb
@@ -29,12 +29,16 @@ module API
success Entities::Snippet
end
params do
+ optional :created_after, type: DateTime, desc: 'Return snippets created after the specified time'
+ optional :created_before, type: DateTime, desc: 'Return snippets created before the specified time'
+
use :pagination
end
get do
authenticate!
- present paginate(snippets_for_current_user), with: Entities::Snippet, current_user: current_user
+ filter_params = declared_params(include_missing: false).merge(author: current_user)
+ present paginate(SnippetsFinder.new(current_user, filter_params).execute), with: Entities::Snippet, current_user: current_user
end
desc 'List all public personal snippets current_user has access to' do
@@ -42,12 +46,16 @@ module API
success Entities::PersonalSnippet
end
params do
+ optional :created_after, type: DateTime, desc: 'Return snippets created after the specified time'
+ optional :created_before, type: DateTime, desc: 'Return snippets created before the specified time'
+
use :pagination
end
get 'public', urgency: :low do
authenticate!
- present paginate(public_snippets), with: Entities::PersonalSnippet, current_user: current_user
+ filter_params = declared_params(include_missing: false).merge(only_personal: true)
+ present paginate(SnippetsFinder.new(nil, filter_params).execute), with: Entities::PersonalSnippet, current_user: current_user
end
desc 'Get a single snippet' do
diff --git a/lib/gitlab/sidekiq_daemon/memory_killer.rb b/lib/gitlab/sidekiq_daemon/memory_killer.rb
index 113076a6a75..cb7d9c6f8a7 100644
--- a/lib/gitlab/sidekiq_daemon/memory_killer.rb
+++ b/lib/gitlab/sidekiq_daemon/memory_killer.rb
@@ -145,6 +145,8 @@ module Gitlab
sleep(CHECK_INTERVAL_SECONDS)
refresh_state(:above_soft_limit)
+
+ log_rss_out_of_range(false)
end
# There are two chances to break from loop:
@@ -153,28 +155,49 @@ module Gitlab
# When `above hard limit`, it immediately go to `stop_fetching_new_jobs`
# So ignore `above hard limit` and always set `above_soft_limit` here
refresh_state(:above_soft_limit)
- log_rss_out_of_range(@current_rss, @hard_limit_rss, @soft_limit_rss)
+ log_rss_out_of_range
false
end
- def log_rss_out_of_range(current_rss, hard_limit_rss, soft_limit_rss)
+ def log_rss_out_of_range(deadline_exceeded = true)
+ reason = out_of_range_description(@current_rss,
+ @hard_limit_rss,
+ @soft_limit_rss,
+ deadline_exceeded)
+
Sidekiq.logger.warn(
class: self.class.to_s,
pid: pid,
message: 'Sidekiq worker RSS out of range',
- current_rss: current_rss,
- hard_limit_rss: hard_limit_rss,
- soft_limit_rss: soft_limit_rss,
- reason: out_of_range_description(current_rss, hard_limit_rss, soft_limit_rss)
- )
+ current_rss: @current_rss,
+ soft_limit_rss: @soft_limit_rss,
+ hard_limit_rss: @hard_limit_rss,
+ reason: reason,
+ running_jobs: running_jobs)
end
- def out_of_range_description(rss, hard_limit, soft_limit)
+ def running_jobs
+ jobs = []
+ Gitlab::SidekiqDaemon::Monitor.instance.jobs_mutex.synchronize do
+ jobs = Gitlab::SidekiqDaemon::Monitor.instance.jobs.map do |jid, job|
+ {
+ jid: jid,
+ worker_class: job[:worker_class].name
+ }
+ end
+ end
+
+ jobs
+ end
+
+ def out_of_range_description(rss, hard_limit, soft_limit, deadline_exceeded)
if rss > hard_limit
"current_rss(#{rss}) > hard_limit_rss(#{hard_limit})"
- else
+ elsif deadline_exceeded
"current_rss(#{rss}) > soft_limit_rss(#{soft_limit}) longer than GRACE_BALLOON_SECONDS(#{GRACE_BALLOON_SECONDS})"
+ else
+ "current_rss(#{rss}) > soft_limit_rss(#{soft_limit})"
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index b5422614ca9..e2aaf645b0a 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -757,6 +757,9 @@ msgstr ""
msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
msgstr ""
+msgid "%{labelStart}URL:%{labelEnd} %{url}"
+msgstr ""
+
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr ""
@@ -4592,13 +4595,25 @@ msgstr ""
msgid "ApplicationSettings|Require admin approval for new sign-ups"
msgstr ""
+msgid "ApplicationSettings|Require lowercase letters"
+msgstr ""
+
+msgid "ApplicationSettings|Require numbers"
+msgstr ""
+
+msgid "ApplicationSettings|Require symbols"
+msgstr ""
+
+msgid "ApplicationSettings|Require uppercase letters"
+msgstr ""
+
msgid "ApplicationSettings|Restricts sign-ups for email addresses that match the given regex. %{linkStart}What is the supported syntax?%{linkEnd}"
msgstr ""
msgid "ApplicationSettings|Save changes"
msgstr ""
-msgid "ApplicationSettings|See GitLab's %{linkStart}Password Policy Guidelines%{linkEnd}."
+msgid "ApplicationSettings|See %{linkStart}password policy guidelines%{linkEnd}."
msgstr ""
msgid "ApplicationSettings|Send confirmation email on sign-up"
@@ -4625,6 +4640,18 @@ msgstr ""
msgid "ApplicationSettings|Users with e-mail addresses that match these domain(s) cannot sign up. Wildcards allowed. Use separate lines or commas for multiple entries."
msgstr ""
+msgid "ApplicationSettings|When enabled, new passwords must contain at least one lowercase letter (a-z)."
+msgstr ""
+
+msgid "ApplicationSettings|When enabled, new passwords must contain at least one number (0-9)."
+msgstr ""
+
+msgid "ApplicationSettings|When enabled, new passwords must contain at least one symbol."
+msgstr ""
+
+msgid "ApplicationSettings|When enabled, new passwords must contain at least one uppercase letter (A-Z)."
+msgstr ""
+
msgid "ApplicationSettings|domain.com"
msgstr ""
@@ -5337,12 +5364,18 @@ msgstr ""
msgid "AuditStreams|Destinations receive all audit event data"
msgstr ""
+msgid "AuditStreams|Edit %{link}"
+msgstr ""
+
msgid "AuditStreams|Header"
msgstr ""
msgid "AuditStreams|Maximum of %{number} HTTP headers has been reached."
msgstr ""
+msgid "AuditStreams|Save external stream destination"
+msgstr ""
+
msgid "AuditStreams|Setup streaming for audit events"
msgstr ""
diff --git a/spec/frontend/admin/signup_restrictions/mock_data.js b/spec/frontend/admin/signup_restrictions/mock_data.js
index 135fc8caae0..9e001e122a4 100644
--- a/spec/frontend/admin/signup_restrictions/mock_data.js
+++ b/spec/frontend/admin/signup_restrictions/mock_data.js
@@ -18,6 +18,10 @@ export const rawMockData = {
emailRestrictions: 'user1@domain.com, user2@domain.com',
afterSignUpText: 'Congratulations on your successful sign-up!',
pendingUserCount: '0',
+ passwordNumberRequired: 'true',
+ passwordLowercaseRequired: 'true',
+ passwordUppercaseRequired: 'true',
+ passwordSymbolRequired: 'true',
};
export const mockData = {
@@ -40,4 +44,8 @@ export const mockData = {
emailRestrictions: 'user1@domain.com, user2@domain.com',
afterSignUpText: 'Congratulations on your successful sign-up!',
pendingUserCount: '0',
+ passwordNumberRequired: true,
+ passwordLowercaseRequired: true,
+ passwordUppercaseRequired: true,
+ passwordSymbolRequired: true,
};
diff --git a/spec/frontend/admin/signup_restrictions/utils_spec.js b/spec/frontend/admin/signup_restrictions/utils_spec.js
index fd5c4c3317b..f07e14430f9 100644
--- a/spec/frontend/admin/signup_restrictions/utils_spec.js
+++ b/spec/frontend/admin/signup_restrictions/utils_spec.js
@@ -14,6 +14,10 @@ describe('utils', () => {
'domainDenylistEnabled',
'denylistTypeRawSelected',
'emailRestrictionsEnabled',
+ 'passwordNumberRequired',
+ 'passwordLowercaseRequired',
+ 'passwordUppercaseRequired',
+ 'passwordSymbolRequired',
],
}),
).toEqual(mockData);
diff --git a/spec/frontend/merge_request_tabs_spec.js b/spec/frontend/merge_request_tabs_spec.js
index 96ac655381b..2001bb5f95e 100644
--- a/spec/frontend/merge_request_tabs_spec.js
+++ b/spec/frontend/merge_request_tabs_spec.js
@@ -334,6 +334,8 @@ describe('MergeRequestTabs', () => {
${'diffs'} | ${true} | ${'hides'}
${'commits'} | ${true} | ${'hides'}
`('it $hidesText expand button on $tab tab', ({ tab, hides }) => {
+ window.gon = { features: { movedMrSidebar: true } };
+
const expandButton = document.createElement('div');
expandButton.classList.add('js-expand-sidebar');
@@ -347,7 +349,11 @@ describe('MergeRequestTabs', () => {
testContext.class = new MergeRequestTabs({ stubLocation });
testContext.class.tabShown(tab, 'foobar');
- expect(testContext.class.expandSidebar.classList.contains('gl-display-none!')).toBe(hides);
+ testContext.class.expandSidebar.forEach((el) => {
+ expect(el.classList.contains('gl-display-none!')).toBe(hides);
+ });
+
+ window.gon = {};
});
describe('when switching tabs', () => {
diff --git a/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb b/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb
index 4a952a2040a..01b7270d761 100644
--- a/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb
+++ b/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb
@@ -129,7 +129,7 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do
allow(Sidekiq).to receive(:options).and_return(timeout: 9)
end
- it 'return true when everything is within limit' do
+ it 'return true when everything is within limit', :aggregate_failures do
expect(memory_killer).to receive(:get_rss).and_return(100)
expect(memory_killer).to receive(:get_soft_limit_rss).and_return(200)
expect(memory_killer).to receive(:get_hard_limit_rss).and_return(300)
@@ -144,7 +144,7 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do
expect(subject).to be true
end
- it 'return false when rss exceeds hard_limit_rss' do
+ it 'return false when rss exceeds hard_limit_rss', :aggregate_failures do
expect(memory_killer).to receive(:get_rss).at_least(:once).and_return(400)
expect(memory_killer).to receive(:get_soft_limit_rss).at_least(:once).and_return(200)
expect(memory_killer).to receive(:get_hard_limit_rss).at_least(:once).and_return(300)
@@ -159,12 +159,12 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do
expect(Gitlab::Metrics::System).to receive(:monotonic_time).and_call_original
- expect(memory_killer).to receive(:log_rss_out_of_range).with(400, 300, 200)
+ expect(memory_killer).to receive(:out_of_range_description).with(400, 300, 200, true)
expect(subject).to be false
end
- it 'return false when rss exceed hard_limit_rss after a while' do
+ it 'return false when rss exceed hard_limit_rss after a while', :aggregate_failures do
expect(memory_killer).to receive(:get_rss).and_return(250, 400, 400)
expect(memory_killer).to receive(:get_soft_limit_rss).at_least(:once).and_return(200)
expect(memory_killer).to receive(:get_hard_limit_rss).at_least(:once).and_return(300)
@@ -180,12 +180,13 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do
expect(Gitlab::Metrics::System).to receive(:monotonic_time).twice.and_call_original
expect(memory_killer).to receive(:sleep).with(check_interval_seconds)
- expect(memory_killer).to receive(:log_rss_out_of_range).with(400, 300, 200)
+ expect(memory_killer).to receive(:out_of_range_description).with(400, 300, 200, false)
+ expect(memory_killer).to receive(:out_of_range_description).with(400, 300, 200, true)
expect(subject).to be false
end
- it 'return true when rss below soft_limit_rss after a while within GRACE_BALLOON_SECONDS' do
+ it 'return true when rss below soft_limit_rss after a while within GRACE_BALLOON_SECONDS', :aggregate_failures do
expect(memory_killer).to receive(:get_rss).and_return(250, 100)
expect(memory_killer).to receive(:get_soft_limit_rss).and_return(200, 200)
expect(memory_killer).to receive(:get_hard_limit_rss).and_return(300, 300)
@@ -201,15 +202,15 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do
expect(Gitlab::Metrics::System).to receive(:monotonic_time).twice.and_call_original
expect(memory_killer).to receive(:sleep).with(check_interval_seconds)
- expect(memory_killer).not_to receive(:log_rss_out_of_range)
+ expect(memory_killer).to receive(:out_of_range_description).with(100, 300, 200, false)
expect(subject).to be true
end
- context 'when exceeding GRACE_BALLOON_SECONDS' do
+ context 'when exceeds GRACE_BALLOON_SECONDS' do
let(:grace_balloon_seconds) { 0 }
- it 'return false when rss exceed soft_limit_rss' do
+ it 'return false when rss exceed soft_limit_rss', :aggregate_failures do
allow(memory_killer).to receive(:get_rss).and_return(250)
allow(memory_killer).to receive(:get_soft_limit_rss).and_return(200)
allow(memory_killer).to receive(:get_hard_limit_rss).and_return(300)
@@ -222,8 +223,7 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do
.with(:above_soft_limit)
.and_call_original
- expect(memory_killer).to receive(:log_rss_out_of_range)
- .with(250, 300, 200)
+ expect(memory_killer).to receive(:out_of_range_description).with(250, 300, 200, true)
expect(subject).to be false
end
@@ -318,7 +318,7 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do
subject { memory_killer.send(:signal_pgroup, signal, explanation) }
- it 'send signal to this proces if it is not group leader' do
+ it 'send signal to this process if it is not group leader' do
expect(Process).to receive(:getpgrp).and_return(pid + 1)
expect(Sidekiq.logger).to receive(:warn).once
@@ -351,12 +351,34 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do
let(:current_rss) { 100 }
let(:soft_limit_rss) { 200 }
let(:hard_limit_rss) { 300 }
+ let(:jid) { 1 }
let(:reason) { 'rss out of range reason description' }
+ let(:queue) { 'default' }
+ let(:running_jobs) { [{ jid: jid, worker_class: 'DummyWorker' }] }
+ let(:worker) do
+ Class.new do
+ def self.name
+ 'DummyWorker'
+ end
+
+ include ApplicationWorker
+ end
+ end
+
+ before do
+ stub_const("DummyWorker", worker)
+
+ allow(memory_killer).to receive(:get_rss).and_return(*current_rss)
+ allow(memory_killer).to receive(:get_soft_limit_rss).and_return(soft_limit_rss)
+ allow(memory_killer).to receive(:get_hard_limit_rss).and_return(hard_limit_rss)
+
+ memory_killer.send(:refresh_state, :running)
+ end
- subject { memory_killer.send(:log_rss_out_of_range, current_rss, hard_limit_rss, soft_limit_rss) }
+ subject { memory_killer.send(:log_rss_out_of_range) }
it 'invoke sidekiq logger warn' do
- expect(memory_killer).to receive(:out_of_range_description).with(current_rss, hard_limit_rss, soft_limit_rss).and_return(reason)
+ expect(memory_killer).to receive(:out_of_range_description).with(current_rss, hard_limit_rss, soft_limit_rss, true).and_return(reason)
expect(Sidekiq.logger).to receive(:warn)
.with(
class: described_class.to_s,
@@ -365,9 +387,12 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do
current_rss: current_rss,
hard_limit_rss: hard_limit_rss,
soft_limit_rss: soft_limit_rss,
- reason: reason)
+ reason: reason,
+ running_jobs: running_jobs)
- subject
+ Gitlab::SidekiqDaemon::Monitor.instance.within_job(DummyWorker, jid, queue) do
+ subject
+ end
end
end
@@ -375,8 +400,9 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do
let(:hard_limit) { 300 }
let(:soft_limit) { 200 }
let(:grace_balloon_seconds) { 12 }
+ let(:deadline_exceeded) { true }
- subject { memory_killer.send(:out_of_range_description, rss, hard_limit, soft_limit) }
+ subject { memory_killer.send(:out_of_range_description, rss, hard_limit, soft_limit, deadline_exceeded) }
context 'when rss > hard_limit' do
let(:rss) { 400 }
@@ -389,9 +415,20 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do
context 'when rss <= hard_limit' do
let(:rss) { 300 }
- it 'tells reason' do
- stub_const("#{described_class}::GRACE_BALLOON_SECONDS", grace_balloon_seconds)
- expect(subject).to eq("current_rss(#{rss}) > soft_limit_rss(#{soft_limit}) longer than GRACE_BALLOON_SECONDS(#{grace_balloon_seconds})")
+ context 'deadline exceeded' do
+ let(:deadline_exceeded) { true }
+
+ it 'tells reason' do
+ stub_const("#{described_class}::GRACE_BALLOON_SECONDS", grace_balloon_seconds)
+ expect(subject).to eq("current_rss(#{rss}) > soft_limit_rss(#{soft_limit}) longer than GRACE_BALLOON_SECONDS(#{grace_balloon_seconds})")
+ end
+ end
+ context 'deadline not exceeded' do
+ let(:deadline_exceeded) { false }
+
+ it 'tells reason' do
+ expect(subject).to eq("current_rss(#{rss}) > soft_limit_rss(#{soft_limit})")
+ end
end
end
end
diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb
index 13160519996..0ba1011684a 100644
--- a/spec/requests/api/snippets_spec.rb
+++ b/spec/requests/api/snippets_spec.rb
@@ -9,9 +9,9 @@ RSpec.describe API::Snippets, factory_default: :keep do
let_it_be(:user) { create(:user) }
let_it_be(:other_user) { create(:user) }
- let_it_be(:public_snippet) { create(:personal_snippet, :repository, :public, author: user) }
- let_it_be(:private_snippet) { create(:personal_snippet, :repository, :private, author: user) }
- let_it_be(:internal_snippet) { create(:personal_snippet, :repository, :internal, author: user) }
+ let_it_be(:public_snippet) { create(:personal_snippet, :repository, :public, author: user) }
+ let_it_be_with_refind(:private_snippet) { create(:personal_snippet, :repository, :private, author: user) }
+ let_it_be(:internal_snippet) { create(:personal_snippet, :repository, :internal, author: user) }
let_it_be(:user_token) { create(:personal_access_token, user: user) }
let_it_be(:other_user_token) { create(:personal_access_token, user: other_user) }
@@ -63,6 +63,23 @@ RSpec.describe API::Snippets, factory_default: :keep do
expect(snippet["id"]).not_to eq(public_snippet.id)
end
end
+
+ context 'filtering snippets by created_after/created_before' do
+ let_it_be(:private_snippet_before_time_range) { create(:personal_snippet, :repository, :private, author: user, created_at: Time.parse("2021-08-20T00:00:00Z")) }
+ let_it_be(:private_snippet_in_time_range1) { create(:personal_snippet, :repository, :private, author: user, created_at: Time.parse("2021-08-22T00:00:00Z")) }
+ let_it_be(:private_snippet_in_time_range2) { create(:personal_snippet, :repository, :private, author: user, created_at: Time.parse("2021-08-24T00:00:00Z")) }
+ let_it_be(:private_snippet_after_time_range) { create(:personal_snippet, :repository, :private, author: user, created_at: Time.parse("2021-08-26T00:00:00Z")) }
+
+ let(:path) { "/snippets?created_after=2021-08-21T00:00:00Z&created_before=2021-08-25T00:00:00Z" }
+
+ it 'returns snippets available for user in given time range' do
+ get api(path, personal_access_token: user_token)
+
+ expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly(
+ private_snippet_in_time_range1.id,
+ private_snippet_in_time_range2.id)
+ end
+ end
end
describe 'GET /snippets/public' do
@@ -98,6 +115,21 @@ RSpec.describe API::Snippets, factory_default: :keep do
expect(response).to have_gitlab_http_status(:unauthorized)
end
+
+ context 'filtering public snippets by created_after/created_before' do
+ let_it_be(:public_snippet_before_time_range) { create(:personal_snippet, :repository, :public, author: other_user, created_at: Time.parse("2021-08-20T00:00:00Z")) }
+ let_it_be(:public_snippet_in_time_range) { create(:personal_snippet, :repository, :public, author: other_user, created_at: Time.parse("2021-08-22T00:00:00Z")) }
+ let_it_be(:public_snippet_after_time_range) { create(:personal_snippet, :repository, :public, author: other_user, created_at: Time.parse("2021-08-24T00:00:00Z")) }
+
+ let(:path) { "/snippets/public?created_after=2021-08-21T00:00:00Z&created_before=2021-08-23T00:00:00Z" }
+
+ it 'returns public snippets available to user in given time range' do
+ get api(path, personal_access_token: user_token)
+
+ expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly(
+ public_snippet_in_time_range.id)
+ end
+ end
end
describe 'GET /snippets/:id/raw' do