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

jemalloc_stats_spec.rb « reports « memory « gitlab « lib « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 53fae48776bf6a1ecec00a82947b6857f1173a09 (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
117
118
119
120
121
122
123
124
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Gitlab::Memory::Reports::JemallocStats do
  let(:reports_dir) { '/empty-dir' }
  let(:jemalloc_stats) { described_class.new(reports_path: reports_dir) }

  describe '.run' do
    context 'when :report_jemalloc_stats ops FF is enabled' do
      let(:worker_id) { 'puma_1' }
      let(:report_name) { 'report.json' }
      let(:report_path) { File.join(reports_dir, report_name) }

      before do
        allow(Prometheus::PidProvider).to receive(:worker_id).and_return(worker_id)
      end

      it 'invokes Jemalloc.dump_stats and returns file path' do
        expect(Gitlab::Memory::Jemalloc)
          .to receive(:dump_stats).with(path: reports_dir, filename_label: worker_id).and_return(report_path)

        expect(jemalloc_stats.run).to eq(report_path)
      end

      describe 'reports cleanup' do
        let_it_be(:outdir) { Dir.mktmpdir }

        let(:jemalloc_stats) { described_class.new(reports_path: outdir) }

        before do
          stub_env('GITLAB_DIAGNOSTIC_REPORTS_JEMALLOC_MAX_REPORTS_STORED', 3)
          allow(Gitlab::Memory::Jemalloc).to receive(:dump_stats)
        end

        after do
          FileUtils.rm_f(outdir)
        end

        context 'when number of reports exceeds `max_reports_stored`' do
          let_it_be(:reports) do
            now = Time.current

            (1..5).map do |i|
              Tempfile.new("jemalloc_stats.#{i}.worker_#{i}.#{Time.current.to_i}.json", outdir).tap do |f|
                FileUtils.touch(f, mtime: (now + i.second).to_i)
              end
            end
          end

          after do
            reports.each do |f|
              f.close
              f.unlink
            rescue Errno::ENOENT
              # Some of the files are already unlinked by the code we test; Ignore
            end
          end

          it 'keeps only `max_reports_stored` total newest files' do
            expect { jemalloc_stats.run }
              .to change { Dir.entries(outdir).count { |e| e.match(/jemalloc_stats.*/) } }
                    .from(5).to(3)

            # Keeps only the newest reports
            expect(reports.last(3).all? { |r| File.exist?(r) }).to be true
          end
        end

        context 'when number of reports does not exceed `max_reports_stored`' do
          let_it_be(:reports) do
            now = Time.current

            (1..3).map do |i|
              Tempfile.new("jemalloc_stats.#{i}.worker_#{i}.#{Time.current.to_i}.json", outdir).tap do |f|
                FileUtils.touch(f, mtime: (now + i.second).to_i)
              end
            end
          end

          after do
            reports.each do |f|
              f.close
              f.unlink
            end
          end

          it 'does not remove any reports' do
            expect { jemalloc_stats.run }
              .not_to change { Dir.entries(outdir).count { |e| e.match(/jemalloc_stats.*/) } }
          end
        end
      end
    end

    context 'when :report_jemalloc_stats ops FF is disabled' do
      before do
        stub_feature_flags(report_jemalloc_stats: false)
      end

      it 'does not run the report and returns nil' do
        expect(Gitlab::Memory::Jemalloc).not_to receive(:dump_stats)

        expect(jemalloc_stats.run).to be_nil
      end
    end
  end

  describe '.active?' do
    subject(:active) { jemalloc_stats.active? }

    context 'when :report_jemalloc_stats ops FF is enabled' do
      it { is_expected.to be true }
    end

    context 'when :report_jemalloc_stats ops FF is disabled' do
      before do
        stub_feature_flags(report_jemalloc_stats: false)
      end

      it { is_expected.to be false }
    end
  end
end