sampler_spec.rb 3.62 KB
Newer Older
1 2 3 4 5
require 'spec_helper'

describe Gitlab::Metrics::Sampler do
  let(:sampler) { described_class.new(5) }

6 7 8 9
  after do
    Allocations.stop if Gitlab::Metrics.mri?
  end

10 11
  describe '#start' do
    it 'gathers a sample at a given interval' do
12
      expect(sampler).to receive(:sleep).with(a_kind_of(Numeric))
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
      expect(sampler).to receive(:sample)
      expect(sampler).to receive(:loop).and_yield

      sampler.start.join
    end
  end

  describe '#sample' do
    it 'samples various statistics' do
      expect(sampler).to receive(:sample_memory_usage)
      expect(sampler).to receive(:sample_file_descriptors)
      expect(sampler).to receive(:sample_objects)
      expect(sampler).to receive(:sample_gc)
      expect(sampler).to receive(:flush)

      sampler.sample
    end

    it 'clears any GC profiles' do
      expect(sampler).to receive(:flush)
      expect(GC::Profiler).to receive(:clear)

      sampler.sample
    end
  end

  describe '#flush' do
    it 'schedules the metrics using Sidekiq' do
41
      expect(Gitlab::Metrics).to receive(:submit_metrics).
42 43 44 45 46 47 48 49 50 51 52 53
        with([an_instance_of(Hash)])

      sampler.sample_memory_usage
      sampler.flush
    end
  end

  describe '#sample_memory_usage' do
    it 'adds a metric containing the memory usage' do
      expect(Gitlab::Metrics::System).to receive(:memory_usage).
        and_return(9000)

54 55
      expect(sampler).to receive(:add_metric).
        with(/memory_usage/, value: 9000).
56 57 58 59 60 61 62 63 64 65 66
        and_call_original

      sampler.sample_memory_usage
    end
  end

  describe '#sample_file_descriptors' do
    it 'adds a metric containing the amount of open file descriptors' do
      expect(Gitlab::Metrics::System).to receive(:file_descriptor_count).
        and_return(4)

67 68
      expect(sampler).to receive(:add_metric).
        with(/file_descriptors/, value: 4).
69 70 71 72 73 74 75 76
        and_call_original

      sampler.sample_file_descriptors
    end
  end

  describe '#sample_objects' do
    it 'adds a metric containing the amount of allocated objects' do
77 78
      expect(sampler).to receive(:add_metric).
        with(/object_counts/, an_instance_of(Hash), an_instance_of(Hash)).
79
        at_least(:once).
80 81 82 83 84 85 86 87 88 89
        and_call_original

      sampler.sample_objects
    end
  end

  describe '#sample_gc' do
    it 'adds a metric containing garbage collection statistics' do
      expect(GC::Profiler).to receive(:total_time).and_return(0.24)

90 91
      expect(sampler).to receive(:add_metric).
        with(/gc_statistics/, an_instance_of(Hash)).
92 93 94 95 96
        and_call_original

      sampler.sample_gc
    end
  end
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118

  describe '#add_metric' do
    it 'prefixes the series name for a Rails process' do
      expect(sampler).to receive(:sidekiq?).and_return(false)

      expect(Gitlab::Metrics::Metric).to receive(:new).
        with('rails_cats', { value: 10 }, {}).
        and_call_original

      sampler.add_metric('cats', value: 10)
    end

    it 'prefixes the series name for a Sidekiq process' do
      expect(sampler).to receive(:sidekiq?).and_return(true)

      expect(Gitlab::Metrics::Metric).to receive(:new).
        with('sidekiq_cats', { value: 10 }, {}).
        and_call_original

      sampler.add_metric('cats', value: 10)
    end
  end
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138

  describe '#sleep_interval' do
    it 'returns a Numeric' do
      expect(sampler.sleep_interval).to be_a_kind_of(Numeric)
    end

    # Testing random behaviour is very hard, so treat this test as a basic smoke
    # test instead of a very accurate behaviour/unit test.
    it 'does not return the same interval twice in a row' do
      last = nil

      100.times do
        interval = sampler.sleep_interval

        expect(interval).to_not eq(last)

        last = interval
      end
    end
  end
139
end