File: mmaped_file_spec.rb

package info (click to toggle)
ruby-prometheus-client-mmap 1.2.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 700 kB
  • sloc: ruby: 3,149; sh: 54; makefile: 21
file content (113 lines) | stat: -rw-r--r-- 3,805 bytes parent folder | download
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
require 'spec_helper'
require 'prometheus/client/helper/mmaped_file'
require 'prometheus/client/page_size'

describe Prometheus::Client::Helper::MmapedFile do
  let(:filename) { Dir::Tmpname.create('mmaped_file_') {} }

  after do
    File.delete(filename) if File.exist?(filename)
  end

  describe '.open' do
    it 'initialize PRIVATE mmaped file read only' do
      expect(described_class).to receive(:new).with(filename).and_call_original

      expect(described_class.open(filename)).to be_instance_of(described_class)
    end
  end

  context 'file does not exist' do
    let (:subject) { described_class.open(filename) }
    it 'creates and initializes file correctly' do
      expect(File.exist?(filename)).to be_falsey

      subject

      expect(File.exist?(filename)).to be_truthy
    end

    it 'creates a file with minimum initial size' do
      expect(File.size(subject.filepath)).to eq(subject.send(:initial_mmap_file_size))
    end

    context 'when initial mmap size is larger' do
      let(:page_size) { Prometheus::Client::PageSize.page_size }
      let (:initial_mmap_file_size) { page_size + 1024 }

      before do
        allow_any_instance_of(described_class).to receive(:initial_mmap_file_size).and_return(initial_mmap_file_size)
      end

      it 'creates a file with increased minimum initial size' do
        expect(File.size(subject.filepath)).to eq(page_size * 2);
      end
    end
  end

  describe '.ensure_exclusive_file' do
    let(:tmpdir) { Dir.mktmpdir('mmaped_file') }
    let(:pid) { 'pid' }

    before do
      allow(Prometheus::Client.configuration).to receive(:multiprocess_files_dir).and_return(tmpdir)
      allow(Prometheus::Client.configuration).to receive(:pid_provider).and_return(pid.method(:to_s))
    end

    context 'when no files are already locked' do
      it 'provides first possible filename' do
        expect(described_class.ensure_exclusive_file('mmaped_file'))
          .to match(/.*mmaped_file_pid-0\.db/)
      end

      it 'provides first and second possible filenames for two invocations' do
        expect(described_class.ensure_exclusive_file('mmaped_file'))
          .to match(/.*mmaped_file_pid-0\.db/)

        expect(described_class.ensure_exclusive_file('mmaped_file'))
          .to match(/.*mmaped_file_pid-1\.db/)
      end
    end

    context 'when first possible file exists for current file ID' do
      let(:first_mmaped_file) { described_class.ensure_exclusive_file('mmaped_file') }
      before do
        first_mmaped_file
      end

      context 'first file is unlocked' do
        before do
          Prometheus::Client::Helper::FileLocker.unlock(first_mmaped_file)
        end

        it 'provides first possible filename discarding the lock' do
          expect(described_class.ensure_exclusive_file('mmaped_file'))
            .to match(/.*mmaped_file_pid-0\.db/)
        end

        it 'provides second possible filename for second invocation' do
          expect(described_class.ensure_exclusive_file('mmaped_file'))
            .to match(/.*mmaped_file_pid-0\.db/)

          expect(described_class.ensure_exclusive_file('mmaped_file'))
            .to match(/.*mmaped_file_pid-1\.db/)
        end
      end

      context 'first file is not unlocked' do
        it 'provides second possible filename' do
          expect(described_class.ensure_exclusive_file('mmaped_file'))
            .to match(/.*mmaped_file_pid-1\.db/)
        end

        it 'provides second and third possible filename for two invocations' do
          expect(described_class.ensure_exclusive_file('mmaped_file'))
            .to match(/.*mmaped_file_pid-1\.db/)

          expect(described_class.ensure_exclusive_file('mmaped_file'))
            .to match(/.*mmaped_file_pid-2\.db/)
        end
      end
    end
  end
end