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

jemalloc_spec.rb « memory « gitlab « lib « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8847516b52c9c686bef5eb88603ef5a5de613417 (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
# frozen_string_literal: true

require 'fast_spec_helper'

RSpec.describe Gitlab::Memory::Jemalloc do
  let(:outdir) { Dir.mktmpdir }

  after do
    FileUtils.rm_f(outdir)
  end

  context 'when jemalloc is loaded' do
    let(:fiddle_func) { instance_double(::Fiddle::Function) }

    context 'with JSON format' do
      let(:format) { :json }
      let(:output) { '{"a": 24}' }

      before do
        stub_stats_call(output, 'J')
      end

      describe '.stats' do
        it 'returns stats JSON' do
          expect(described_class.stats(format: format)).to eq(output)
        end
      end

      describe '.dump_stats' do
        it 'writes stats JSON file' do
          described_class.dump_stats(path: outdir, format: format)

          file = Dir.entries(outdir).find { |e| e.match(/jemalloc_stats\.#{$$}\.\d+\.json$/) }
          expect(file).not_to be_nil
          expect(File.read(File.join(outdir, file))).to eq(output)
        end
      end
    end

    context 'with text format' do
      let(:format) { :text }
      let(:output) { 'stats' }

      before do
        stub_stats_call(output)
      end

      describe '.stats' do
        it 'returns a text report' do
          expect(described_class.stats(format: format)).to eq(output)
        end
      end

      describe '.dump_stats' do
        it 'writes stats text file' do
          described_class.dump_stats(path: outdir, format: format)

          file = Dir.entries(outdir).find { |e| e.match(/jemalloc_stats\.#{$$}\.\d+\.txt$/) }
          expect(file).not_to be_nil
          expect(File.read(File.join(outdir, file))).to eq(output)
        end
      end
    end

    context 'with unsupported format' do
      let(:format) { 'unsupported' }

      describe '.stats' do
        it 'raises an error' do
          expect do
            described_class.stats(format: format)
          end.to raise_error(/format must be one of/)
        end
      end

      describe '.dump_stats' do
        it 'raises an error' do
          expect do
            described_class.dump_stats(path: outdir, format: format)
          end.to raise_error(/format must be one of/)
        end
      end
    end
  end

  context 'when jemalloc is not loaded' do
    before do
      expect(::Fiddle::Handle).to receive(:sym).and_raise(Fiddle::DLError)
    end

    describe '.stats' do
      it 'returns nil' do
        expect(described_class.stats).to be_nil
      end
    end

    describe '.dump_stats' do
      it 'does nothing' do
        stub_env('LD_PRELOAD', nil)

        described_class.dump_stats(path: outdir)

        expect(Dir.empty?(outdir)).to be(true)
      end
    end
  end

  def stub_stats_call(output, expected_options = '')
    # Stub function pointer to stats call.
    func_pointer = Fiddle::Pointer.new(0xd34db33f)
    expect(::Fiddle::Handle).to receive(:sym).with('malloc_stats_print').and_return(func_pointer)

    # Stub actual function call.
    expect(::Fiddle::Function).to receive(:new)
      .with(func_pointer, anything, anything)
      .and_return(fiddle_func)
    expect(fiddle_func).to receive(:call).with(anything, nil, expected_options) do |callback, _, options|
      callback.call(nil, output)
    end
  end
end