Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-11-07 18:11:00 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-11-07 18:11:00 +0300
commitfa4473a48706d074217f4ffc8d183cf630af1833 (patch)
tree6e2ae917c1351d24d0b5b65a86fd9da3cddb8bab /spec
parent1dab074ef1740798bcba5f8468b09e5f378fe0f4 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/components/pajamas/spinner_component_spec.rb4
-rw-r--r--spec/components/previews/pajamas/spinner_component_preview.rb18
-rw-r--r--spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js37
-rw-r--r--spec/helpers/icons_helper_spec.rb2
-rw-r--r--spec/initializers/memory_watchdog_spec.rb73
-rw-r--r--spec/initializers/rails_yaml_safe_load_spec.rb43
-rw-r--r--spec/lib/gitlab/ci/build/rules/rule/clause/exists_spec.rb52
-rw-r--r--spec/lib/gitlab/memory/watchdog/configuration_spec.rb61
-rw-r--r--spec/lib/gitlab/memory/watchdog/configurator_spec.rb187
-rw-r--r--spec/lib/gitlab/memory/watchdog/monitor/rss_memory_limit_spec.rb39
-rw-r--r--spec/lib/gitlab/memory/watchdog_spec.rb6
-rw-r--r--spec/mailers/emails/releases_spec.rb1
12 files changed, 414 insertions, 109 deletions
diff --git a/spec/components/pajamas/spinner_component_spec.rb b/spec/components/pajamas/spinner_component_spec.rb
index 9aac9a0085c..f03d8c9561b 100644
--- a/spec/components/pajamas/spinner_component_spec.rb
+++ b/spec/components/pajamas/spinner_component_spec.rb
@@ -35,7 +35,7 @@ RSpec.describe Pajamas::SpinnerComponent, type: :component do
describe 'inline' do
context 'by default' do
it 'renders a div' do
- expect(page).to have_css 'div.gl-spinner'
+ expect(page).to have_css 'div.gl-spinner-container'
end
end
@@ -43,7 +43,7 @@ RSpec.describe Pajamas::SpinnerComponent, type: :component do
let(:options) { { inline: true } }
it 'renders a span' do
- expect(page).to have_css 'span.gl-spinner'
+ expect(page).to have_css 'span.gl-spinner-container'
end
end
end
diff --git a/spec/components/previews/pajamas/spinner_component_preview.rb b/spec/components/previews/pajamas/spinner_component_preview.rb
index 149bfddcfc2..3ff87786768 100644
--- a/spec/components/previews/pajamas/spinner_component_preview.rb
+++ b/spec/components/previews/pajamas/spinner_component_preview.rb
@@ -9,14 +9,28 @@ module Pajamas
# @param label text
# @param size select [[small, sm], [medium, md], [large, lg], [extra large, xl]]
def default(inline: false, label: "Loading", size: :md)
- render(Pajamas::SpinnerComponent.new(inline: inline, label: label, size: size))
+ render Pajamas::SpinnerComponent.new(
+ inline: inline,
+ label: label,
+ size: size
+ )
end
- # Use a light spinner on dark backgrounds
+ # Use a light spinner on dark backgrounds.
#
# @display bg_color "#222"
def light
render(Pajamas::SpinnerComponent.new(color: :light))
end
+
+ # Any extra HTML attributes like `class`, `data` or `id` get automatically applied to the spinner container element.
+ #
+ def extra_attributes
+ render Pajamas::SpinnerComponent.new(
+ class: "js-do-something",
+ data: { foo: "bar" },
+ id: "my-special-spinner"
+ )
+ end
end
end
diff --git a/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js b/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js
index 59b3b4c02df..055d57d6ada 100644
--- a/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js
+++ b/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js
@@ -1,4 +1,9 @@
-import { getDateWithUTC, newDateAsLocaleTime } from '~/lib/utils/datetime/date_calculation_utility';
+import {
+ getDateWithUTC,
+ newDateAsLocaleTime,
+ nSecondsAfter,
+ nSecondsBefore,
+} from '~/lib/utils/datetime/date_calculation_utility';
describe('newDateAsLocaleTime', () => {
it.each`
@@ -31,3 +36,33 @@ describe('getDateWithUTC', () => {
expect(getDateWithUTC(date)).toEqual(expected);
});
});
+
+describe('nSecondsAfter', () => {
+ const start = new Date('2022-03-22T01:23:45.678Z');
+ it.each`
+ date | seconds | expected
+ ${start} | ${0} | ${start}
+ ${start} | ${1} | ${new Date('2022-03-22T01:23:46.678Z')}
+ ${start} | ${5} | ${new Date('2022-03-22T01:23:50.678Z')}
+ ${start} | ${60} | ${new Date('2022-03-22T01:24:45.678Z')}
+ ${start} | ${3600} | ${new Date('2022-03-22T02:23:45.678Z')}
+ ${start} | ${86400} | ${new Date('2022-03-23T01:23:45.678Z')}
+ `('returns $expected given $string', ({ date, seconds, expected }) => {
+ expect(nSecondsAfter(date, seconds)).toEqual(expected);
+ });
+});
+
+describe('nSecondsBefore', () => {
+ const start = new Date('2022-03-22T01:23:45.678Z');
+ it.each`
+ date | seconds | expected
+ ${start} | ${0} | ${start}
+ ${start} | ${1} | ${new Date('2022-03-22T01:23:44.678Z')}
+ ${start} | ${5} | ${new Date('2022-03-22T01:23:40.678Z')}
+ ${start} | ${60} | ${new Date('2022-03-22T01:22:45.678Z')}
+ ${start} | ${3600} | ${new Date('2022-03-22T00:23:45.678Z')}
+ ${start} | ${86400} | ${new Date('2022-03-21T01:23:45.678Z')}
+ `('returns $expected given $string', ({ date, seconds, expected }) => {
+ expect(nSecondsBefore(date, seconds)).toEqual(expected);
+ });
+});
diff --git a/spec/helpers/icons_helper_spec.rb b/spec/helpers/icons_helper_spec.rb
index 139e8be33d5..2f1682e9194 100644
--- a/spec/helpers/icons_helper_spec.rb
+++ b/spec/helpers/icons_helper_spec.rb
@@ -234,7 +234,7 @@ RSpec.describe IconsHelper do
describe 'gl_loading_icon' do
it 'returns the default spinner markup' do
expect(gl_loading_icon.to_s)
- .to eq '<div class="gl-spinner-container" role="status"><span class="gl-spinner gl-spinner-dark gl-spinner-sm gl-vertical-align-text-bottom!" aria-label="Loading"></span></div>'
+ .to eq '<div class="gl-spinner-container" role="status"><span aria-label="Loading" class="gl-spinner gl-spinner-sm gl-spinner-dark gl-vertical-align-text-bottom!"></span></div>'
end
context 'when css_class is provided' do
diff --git a/spec/initializers/memory_watchdog_spec.rb b/spec/initializers/memory_watchdog_spec.rb
index 36f96131c3d..5c3d020016a 100644
--- a/spec/initializers/memory_watchdog_spec.rb
+++ b/spec/initializers/memory_watchdog_spec.rb
@@ -29,28 +29,10 @@ RSpec.describe 'memory watchdog' do
run_initializer
end
- shared_examples 'starts configured watchdog' do |handler_class|
- let(:configuration) { Gitlab::Memory::Watchdog::Configuration.new }
- let(:watchdog_monitors_params) do
- {
- Gitlab::Memory::Watchdog::Monitor::HeapFragmentation => {
- max_heap_fragmentation: max_heap_fragmentation,
- max_strikes: max_strikes
- },
- Gitlab::Memory::Watchdog::Monitor::UniqueMemoryGrowth => {
- max_mem_growth: max_mem_growth,
- max_strikes: max_strikes
- }
- }
- end
-
+ shared_examples 'starts configured watchdog' do |configure_monitor_method|
shared_examples 'configures and starts watchdog' do
it "correctly configures and starts watchdog", :aggregate_failures do
- expect(watchdog).to receive(:configure).and_yield(configuration)
-
- watchdog_monitors_params.each do |monitor_class, params|
- expect(configuration.monitors).to receive(:use).with(monitor_class, **params)
- end
+ expect(Gitlab::Memory::Watchdog::Configurator).to receive(configure_monitor_method)
expect(Gitlab::Memory::Watchdog).to receive(:new).and_return(watchdog)
expect(Gitlab::BackgroundTask).to receive(:new).with(watchdog).and_return(background_task)
@@ -58,71 +40,24 @@ RSpec.describe 'memory watchdog' do
expect(Gitlab::Cluster::LifecycleEvents).to receive(:on_worker_start).and_yield
run_initializer
-
- expect(configuration.handler).to be_an_instance_of(handler_class)
- expect(configuration.logger).to eq(logger)
- expect(configuration.sleep_time_seconds).to eq(sleep_time_seconds)
end
end
-
- context 'when settings are not passed through the environment' do
- let(:max_strikes) { 5 }
- let(:max_heap_fragmentation) { 0.5 }
- let(:max_mem_growth) { 3.0 }
- let(:sleep_time_seconds) { 60 }
-
- include_examples 'configures and starts watchdog'
- end
-
- context 'when settings are passed through the environment' do
- let(:max_strikes) { 6 }
- let(:max_heap_fragmentation) { 0.4 }
- let(:max_mem_growth) { 2.0 }
- let(:sleep_time_seconds) { 50 }
-
- before do
- stub_env('GITLAB_MEMWD_MAX_STRIKES', 6)
- stub_env('GITLAB_MEMWD_SLEEP_TIME_SEC', 50)
- stub_env('GITLAB_MEMWD_MAX_MEM_GROWTH', 2.0)
- stub_env('GITLAB_MEMWD_MAX_HEAP_FRAG', 0.4)
- end
-
- include_examples 'configures and starts watchdog'
- end
end
- # In tests, the Puma constant does not exist so we cannot use a verified double.
- # rubocop: disable RSpec/VerifiedDoubles
context 'when puma' do
- let(:puma) do
- Class.new do
- def self.cli_config
- Struct.new(:options).new
- end
- end
- end
-
before do
- stub_const('Puma', puma)
- stub_const('Puma::Cluster::WorkerHandle', double.as_null_object)
-
allow(Gitlab::Runtime).to receive(:puma?).and_return(true)
end
- it_behaves_like 'starts configured watchdog', Gitlab::Memory::Watchdog::PumaHandler
+ it_behaves_like 'starts configured watchdog', :configure_for_puma
end
- # rubocop: enable RSpec/VerifiedDoubles
context 'when sidekiq' do
before do
allow(Gitlab::Runtime).to receive(:sidekiq?).and_return(true)
end
- it_behaves_like 'starts configured watchdog', Gitlab::Memory::Watchdog::TermProcessHandler
- end
-
- context 'when other runtime' do
- it_behaves_like 'starts configured watchdog', Gitlab::Memory::Watchdog::NullHandler
+ it_behaves_like 'starts configured watchdog', :configure_for_sidekiq
end
end
diff --git a/spec/initializers/rails_yaml_safe_load_spec.rb b/spec/initializers/rails_yaml_safe_load_spec.rb
new file mode 100644
index 00000000000..8cf6a3676e0
--- /dev/null
+++ b/spec/initializers/rails_yaml_safe_load_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Rails YAML safe load' do
+ let(:unsafe_load) { false }
+
+ let(:klass) do
+ Class.new(ActiveRecord::Base) do
+ self.table_name = 'issues'
+
+ serialize :description
+ end
+ end
+
+ let(:instance) { klass.new(description: data) }
+
+ context 'with default permitted classes' do
+ let(:data) do
+ {
+ 'time' => Time.now,
+ 'date' => Date.today,
+ 'number' => 1,
+ 'hashie-array' => Hashie::Array.new([1, 2]),
+ 'array' => [5, 6]
+ }
+ end
+
+ it 'deserializes data' do
+ instance.save!
+
+ expect(klass.find(instance.id).description).to eq(data)
+ end
+
+ context 'with unpermitted classes' do
+ let(:data) { { 'test' => create(:user) } }
+
+ it 'throws an exception' do
+ expect { instance.save! }.to raise_error(Psych::DisallowedClass)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/build/rules/rule/clause/exists_spec.rb b/spec/lib/gitlab/ci/build/rules/rule/clause/exists_spec.rb
index f9ebab149a5..c31d1c1fbf4 100644
--- a/spec/lib/gitlab/ci/build/rules/rule/clause/exists_spec.rb
+++ b/spec/lib/gitlab/ci/build/rules/rule/clause/exists_spec.rb
@@ -4,11 +4,47 @@ require 'spec_helper'
RSpec.describe Gitlab::Ci::Build::Rules::Rule::Clause::Exists do
describe '#satisfied_by?' do
- shared_examples 'an exists rule with a context' do
+ subject(:satisfied_by?) { described_class.new(globs).satisfied_by?(nil, context) }
+
+ shared_examples 'a rules:exists with a context' do
it_behaves_like 'a glob matching rule' do
let(:project) { create(:project, :custom_repo, files: files) }
end
+ context 'when the rules:exists has a variable' do
+ let_it_be(:project) { create(:project, :custom_repo, files: { 'helm/helm_file.txt' => '' }) }
+
+ let(:globs) { ['$HELM_DIR/**/*'] }
+
+ let(:variables_hash) do
+ { 'HELM_DIR' => 'helm' }
+ end
+
+ before do
+ allow(context).to receive(:variables_hash).and_return(variables_hash)
+ end
+
+ context 'when the ci_variables_rules_exists FF is disabled' do
+ before do
+ stub_feature_flags(ci_variable_expansion_in_rules_exists: false)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when the ci_variables_rules_exists FF is enabled' do
+ context 'when the context has the specified variables' do
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when variable expansion does not match' do
+ let(:variables_hash) { {} }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+ end
+
context 'after pattern comparision limit is reached' do
let(:globs) { ['*definitely_not_a_matching_glob*'] }
let(:project) { create(:project, :repository) }
@@ -22,26 +58,24 @@ RSpec.describe Gitlab::Ci::Build::Rules::Rule::Clause::Exists do
end
end
- subject(:satisfied_by?) { described_class.new(globs).satisfied_by?(nil, context) }
-
- context 'when context is Build::Context::Build' do
- it_behaves_like 'an exists rule with a context' do
+ context 'when the rules are being evaluated at job level' do
+ it_behaves_like 'a rules:exists with a context' do
let(:pipeline) { build(:ci_pipeline, project: project, sha: project.repository.commit.sha) }
let(:context) { Gitlab::Ci::Build::Context::Build.new(pipeline, sha: project.repository.commit.sha) }
end
end
- context 'when context is Build::Context::Global' do
- it_behaves_like 'an exists rule with a context' do
+ context 'when the rules are being evaluated for an entire pipeline' do
+ it_behaves_like 'a rules:exists with a context' do
let(:pipeline) { build(:ci_pipeline, project: project, sha: project.repository.commit.sha) }
let(:context) { Gitlab::Ci::Build::Context::Global.new(pipeline, yaml_variables: {}) }
end
end
- context 'when context is Config::External::Context' do
+ context 'when rules are being evaluated with `include`' do
let(:context) { Gitlab::Ci::Config::External::Context.new(project: project, sha: sha) }
- it_behaves_like 'an exists rule with a context' do
+ it_behaves_like 'a rules:exists with a context' do
let(:sha) { project.repository.commit.sha }
end
diff --git a/spec/lib/gitlab/memory/watchdog/configuration_spec.rb b/spec/lib/gitlab/memory/watchdog/configuration_spec.rb
index 892a4b06ad0..38a39f6a33a 100644
--- a/spec/lib/gitlab/memory/watchdog/configuration_spec.rb
+++ b/spec/lib/gitlab/memory/watchdog/configuration_spec.rb
@@ -78,36 +78,53 @@ RSpec.describe Gitlab::Memory::Watchdog::Configuration do
end
end
- context 'when two monitors are configured to be used' do
- before do
- configuration.monitors.use monitor_class_1, false, { message: 'monitor_1_text' }, max_strikes: 5
- configuration.monitors.use monitor_class_2, true, { message: 'monitor_2_text' }, max_strikes: 0
+ context 'when two different monitor class are configured' do
+ shared_examples 'executes monitors and returns correct results' do
+ it 'calls each monitor and returns correct results', :aggregate_failures do
+ payloads = []
+ thresholds = []
+ strikes = []
+ monitor_names = []
+
+ configuration.monitors.call_each do |result|
+ payloads << result.payload
+ thresholds << result.threshold_violated?
+ strikes << result.strikes_exceeded?
+ monitor_names << result.monitor_name
+ end
+
+ expect(payloads).to eq([payload1, payload2])
+ expect(thresholds).to eq([false, true])
+ expect(strikes).to eq([false, true])
+ expect(monitor_names).to eq([:monitor1, :monitor2])
+ end
+ end
+
+ context 'when monitors are configured inline' do
+ before do
+ configuration.monitors.push monitor_class_1, false, { message: 'monitor_1_text' }, max_strikes: 5
+ configuration.monitors.push monitor_class_2, true, { message: 'monitor_2_text' }, max_strikes: 0
+ end
+
+ include_examples 'executes monitors and returns correct results'
end
- it 'calls each monitor and returns correct results', :aggregate_failures do
- payloads = []
- thresholds = []
- strikes = []
- monitor_names = []
-
- configuration.monitors.call_each do |result|
- payloads << result.payload
- thresholds << result.threshold_violated?
- strikes << result.strikes_exceeded?
- monitor_names << result.monitor_name
+ context 'when monitors are configured in a block' do
+ before do
+ configuration.monitors do |stack|
+ stack.push monitor_class_1, false, { message: 'monitor_1_text' }, max_strikes: 5
+ stack.push monitor_class_2, true, { message: 'monitor_2_text' }, max_strikes: 0
+ end
end
- expect(payloads).to eq([payload1, payload2])
- expect(thresholds).to eq([false, true])
- expect(strikes).to eq([false, true])
- expect(monitor_names).to eq([:monitor1, :monitor2])
+ include_examples 'executes monitors and returns correct results'
end
end
- context 'when same monitor class is configured to be used twice' do
+ context 'when same monitor class is configured twice' do
before do
- configuration.monitors.use monitor_class_1, max_strikes: 1
- configuration.monitors.use monitor_class_1, max_strikes: 1
+ configuration.monitors.push monitor_class_1, max_strikes: 1
+ configuration.monitors.push monitor_class_1, max_strikes: 1
end
it 'calls same monitor only once' do
diff --git a/spec/lib/gitlab/memory/watchdog/configurator_spec.rb b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb
new file mode 100644
index 00000000000..2c5fae5736d
--- /dev/null
+++ b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb
@@ -0,0 +1,187 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'prometheus/client'
+require_dependency 'gitlab/cluster/lifecycle_events'
+
+RSpec.describe Gitlab::Memory::Watchdog::Configurator do
+ shared_examples 'as configurator' do |handler_class, sleep_time_env, sleep_time|
+ it 'configures the correct handler' do
+ configurator.call(configuration)
+
+ expect(configuration.handler).to be_an_instance_of(handler_class)
+ end
+
+ it 'configures the correct logger' do
+ configurator.call(configuration)
+
+ expect(configuration.logger).to eq(logger)
+ end
+
+ context 'when sleep_time_seconds is not passed through the environment' do
+ let(:sleep_time_seconds) { sleep_time }
+
+ it 'configures the correct sleep time' do
+ configurator.call(configuration)
+
+ expect(configuration.sleep_time_seconds).to eq(sleep_time_seconds)
+ end
+ end
+
+ context 'when sleep_time_seconds is passed through the environment' do
+ let(:sleep_time_seconds) { sleep_time - 1 }
+
+ before do
+ stub_env(sleep_time_env, sleep_time - 1)
+ end
+
+ it 'configures the correct sleep time' do
+ configurator.call(configuration)
+
+ expect(configuration.sleep_time_seconds).to eq(sleep_time_seconds)
+ end
+ end
+ end
+
+ shared_examples 'as monitor configurator' do
+ it 'executes monitors and returns correct results' do
+ configurator.call(configuration)
+
+ payloads = {}
+ configuration.monitors.call_each do |result|
+ payloads[result.monitor_name] = result.payload
+ end
+
+ expect(payloads).to eq(expected_payloads)
+ end
+ end
+
+ let(:configuration) { Gitlab::Memory::Watchdog::Configuration.new }
+
+ # In tests, the Puma constant does not exist so we cannot use a verified double.
+ # rubocop: disable RSpec/VerifiedDoubles
+ describe '.configure_for_puma' do
+ let(:logger) { Gitlab::AppLogger }
+ let(:puma) do
+ Class.new do
+ def self.cli_config
+ Struct.new(:options).new
+ end
+ end
+ end
+
+ subject(:configurator) { described_class.configure_for_puma }
+
+ def stub_prometheus_metrics
+ gauge = instance_double(::Prometheus::Client::Gauge)
+ allow(Gitlab::Metrics).to receive(:gauge).and_return(gauge)
+ allow(gauge).to receive(:set)
+ end
+
+ before do
+ stub_const('Puma', puma)
+ stub_const('Puma::Cluster::WorkerHandle', double.as_null_object)
+ stub_prometheus_metrics
+ end
+
+ it_behaves_like 'as configurator',
+ Gitlab::Memory::Watchdog::PumaHandler,
+ 'GITLAB_MEMWD_SLEEP_TIME_SEC',
+ 60
+
+ context 'with DISABLE_PUMA_WORKER_KILLER set to true' do
+ let(:primary_memory) { 2048 }
+ let(:worker_memory) { max_mem_growth * primary_memory + 1 }
+ let(:expected_payloads) do
+ {
+ heap_fragmentation: {
+ message: 'heap fragmentation limit exceeded',
+ memwd_cur_heap_frag: max_heap_fragmentation + 0.1,
+ memwd_max_heap_frag: max_heap_fragmentation,
+ memwd_max_strikes: max_strikes,
+ memwd_cur_strikes: 1
+
+ },
+ unique_memory_growth: {
+ message: 'memory limit exceeded',
+ memwd_uss_bytes: worker_memory,
+ memwd_ref_uss_bytes: primary_memory,
+ memwd_max_uss_bytes: max_mem_growth * primary_memory,
+ memwd_max_strikes: max_strikes,
+ memwd_cur_strikes: 1
+ }
+ }
+ end
+
+ before do
+ stub_env('DISABLE_PUMA_WORKER_KILLER', true)
+ allow(Gitlab::Metrics::Memory).to receive(:gc_heap_fragmentation).and_return(max_heap_fragmentation + 0.1)
+ allow(Gitlab::Metrics::System).to receive(:memory_usage_uss_pss).and_return({ uss: worker_memory })
+ allow(Gitlab::Metrics::System).to receive(:memory_usage_uss_pss).with(
+ pid: Gitlab::Cluster::PRIMARY_PID
+ ).and_return({ uss: primary_memory })
+ end
+
+ context 'when settings are set via environment variables' do
+ let(:max_heap_fragmentation) { 0.4 }
+ let(:max_mem_growth) { 4.0 }
+ let(:max_strikes) { 4 }
+
+ before do
+ stub_env('GITLAB_MEMWD_MAX_HEAP_FRAG', 0.4)
+ stub_env('GITLAB_MEMWD_MAX_MEM_GROWTH', 4.0)
+ stub_env('GITLAB_MEMWD_MAX_STRIKES', 4)
+ end
+
+ it_behaves_like 'as monitor configurator'
+ end
+
+ context 'when settings are not set via environment variables' do
+ let(:max_heap_fragmentation) { 0.5 }
+ let(:max_mem_growth) { 3.0 }
+ let(:max_strikes) { 5 }
+
+ it_behaves_like 'as monitor configurator'
+ end
+ end
+
+ context 'with DISABLE_PUMA_WORKER_KILLER set to false' do
+ let(:expected_payloads) do
+ {
+ rss_memory_limit: {
+ message: 'rss memory limit exceeded',
+ memwd_rss_bytes: memory_limit + 1,
+ memwd_max_rss_bytes: memory_limit,
+ memwd_max_strikes: max_strikes,
+ memwd_cur_strikes: 1
+ }
+ }
+ end
+
+ before do
+ stub_env('DISABLE_PUMA_WORKER_KILLER', false)
+ allow(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return({ total: memory_limit + 1 })
+ end
+
+ context 'when settings are set via environment variables' do
+ let(:memory_limit) { 1300 }
+ let(:max_strikes) { 4 }
+
+ before do
+ stub_env('PUMA_WORKER_MAX_MEMORY', 1300)
+ stub_env('GITLAB_MEMWD_MAX_STRIKES', 4)
+ end
+
+ it_behaves_like 'as monitor configurator'
+ end
+
+ context 'when settings are not set via environment variables' do
+ let(:memory_limit) { 1200 }
+ let(:max_strikes) { 5 }
+
+ it_behaves_like 'as monitor configurator'
+ end
+ end
+ end
+ # rubocop: enable RSpec/VerifiedDoubles
+end
diff --git a/spec/lib/gitlab/memory/watchdog/monitor/rss_memory_limit_spec.rb b/spec/lib/gitlab/memory/watchdog/monitor/rss_memory_limit_spec.rb
new file mode 100644
index 00000000000..9e25cfda782
--- /dev/null
+++ b/spec/lib/gitlab/memory/watchdog/monitor/rss_memory_limit_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'support/shared_examples/lib/gitlab/memory/watchdog/monitor_result_shared_examples'
+
+RSpec.describe Gitlab::Memory::Watchdog::Monitor::RssMemoryLimit do
+ let(:memory_limit) { 2048 }
+ let(:worker_memory) { 1024 }
+
+ subject(:monitor) do
+ described_class.new(memory_limit: memory_limit)
+ end
+
+ before do
+ allow(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return({ total: worker_memory })
+ end
+
+ describe '#call' do
+ context 'when process exceeds threshold' do
+ let(:worker_memory) { memory_limit + 1 }
+ let(:payload) do
+ {
+ message: 'rss memory limit exceeded',
+ memwd_rss_bytes: worker_memory,
+ memwd_max_rss_bytes: memory_limit
+ }
+ end
+
+ include_examples 'returns Watchdog Monitor result', threshold_violated: true
+ end
+
+ context 'when process does not exceed threshold' do
+ let(:worker_memory) { memory_limit - 1 }
+ let(:payload) { {} }
+
+ include_examples 'returns Watchdog Monitor result', threshold_violated: false
+ end
+ end
+end
diff --git a/spec/lib/gitlab/memory/watchdog_spec.rb b/spec/lib/gitlab/memory/watchdog_spec.rb
index 9c5f01a4bb2..5d9599d6eab 100644
--- a/spec/lib/gitlab/memory/watchdog_spec.rb
+++ b/spec/lib/gitlab/memory/watchdog_spec.rb
@@ -69,7 +69,7 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures do
config.handler = handler
config.logger = logger
config.sleep_time_seconds = sleep_time_seconds
- config.monitors.use monitor_class, threshold_violated, payload, max_strikes: max_strikes
+ config.monitors.push monitor_class, threshold_violated, payload, max_strikes: max_strikes
end
allow(handler).to receive(:call).and_return(true)
@@ -205,8 +205,8 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures do
config.handler = handler
config.logger = logger
config.sleep_time_seconds = sleep_time_seconds
- config.monitors.use monitor_class, threshold_violated, payload, max_strikes: max_strikes
- config.monitors.use monitor_class, threshold_violated, payload, max_strikes: max_strikes
+ config.monitors.push monitor_class, threshold_violated, payload, max_strikes: max_strikes
+ config.monitors.push monitor_class, threshold_violated, payload, max_strikes: max_strikes
end
end
diff --git a/spec/mailers/emails/releases_spec.rb b/spec/mailers/emails/releases_spec.rb
index d1d7f5e6d6a..e8ca9533256 100644
--- a/spec/mailers/emails/releases_spec.rb
+++ b/spec/mailers/emails/releases_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe Emails::Releases do
subject { Notify.new_release_email(user.id, release) }
it_behaves_like 'an email sent from GitLab'
+ it_behaves_like 'an email with X-GitLab headers containing project details'
context 'when the release has a name' do
it 'shows the correct subject' do