summaryrefslogtreecommitdiff
path: root/spec/initializers/memory_watchdog_spec.rb
blob: 56f995b5cd353373e7f299791589012c7df69e63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# frozen_string_literal: true

require 'fast_spec_helper'

RSpec.describe 'memory watchdog' do
  subject(:run_initializer) do
    load Rails.root.join('config/initializers/memory_watchdog.rb')
  end

  context 'when GITLAB_MEMORY_WATCHDOG_ENABLED is truthy' do
    let(:env_switch) { 'true' }

    before do
      stub_env('GITLAB_MEMORY_WATCHDOG_ENABLED', env_switch)
    end

    context 'when runtime is an application' do
      let(:watchdog) { instance_double(Gitlab::Memory::Watchdog) }
      let(:background_task) { instance_double(Gitlab::BackgroundTask) }

      before do
        allow(Gitlab::Runtime).to receive(:application?).and_return(true)
      end

      it 'registers a life-cycle hook' do
        expect(Gitlab::Cluster::LifecycleEvents).to receive(:on_worker_start)

        run_initializer
      end

      shared_examples 'starts watchdog with handler' do |handler_class|
        it "uses the #{handler_class} and starts the watchdog" do
          expect(Gitlab::Memory::Watchdog).to receive(:new).with(
            handler: an_instance_of(handler_class),
            logger: Gitlab::AppLogger).and_return(watchdog)
          expect(Gitlab::BackgroundTask).to receive(:new).with(watchdog).and_return(background_task)
          expect(background_task).to receive(:start)
          expect(Gitlab::Cluster::LifecycleEvents).to receive(:on_worker_start).and_yield

          run_initializer
        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 watchdog with handler', Gitlab::Memory::Watchdog::PumaHandler
      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 watchdog with handler', Gitlab::Memory::Watchdog::TermProcessHandler
      end

      context 'when other runtime' do
        it_behaves_like 'starts watchdog with handler', Gitlab::Memory::Watchdog::NullHandler
      end
    end

    context 'when runtime is unsupported' do
      it 'does not register life-cycle hook' do
        expect(Gitlab::Cluster::LifecycleEvents).not_to receive(:on_worker_start)

        run_initializer
      end
    end
  end

  context 'when GITLAB_MEMORY_WATCHDOG_ENABLED is false' do
    let(:env_switch) { 'false' }

    before do
      stub_env('GITLAB_MEMORY_WATCHDOG_ENABLED', env_switch)
      # To rule out we return early due to this being false.
      allow(Gitlab::Runtime).to receive(:application?).and_return(true)
    end

    it 'does not register life-cycle hook' do
      expect(Gitlab::Cluster::LifecycleEvents).not_to receive(:on_worker_start)

      run_initializer
    end
  end

  context 'when GITLAB_MEMORY_WATCHDOG_ENABLED is not set' do
    before do
      # To rule out we return early due to this being false.
      allow(Gitlab::Runtime).to receive(:application?).and_return(true)
    end

    it 'does not register life-cycle hook' do
      expect(Gitlab::Cluster::LifecycleEvents).not_to receive(:on_worker_start)

      run_initializer
    end
  end
end