Module: StatsD::Instrument::Assertions

Includes:
Helpers
Defined in:
lib/statsd/instrument/assertions.rb

Overview

This module defines several assertion methods that can be used to verify that your application is emitting the right StatsD metrics.

Every metric type has its own assertion method, like #assert_statsd_increment to assert StatsD.increment calls. You can also assert other properties of the metric that was emitted, like the sample rate or presence of tags. To check for the absence of metrics, use #assert_no_statsd_calls.

Examples:

Check for metric properties:

assert_statsd_measure('foo', sample_rate: 0.1, tags: ["bar"]) do
  StatsD.measure('foo', sample_rate: 0.5, tags: ['bar','baz']) do
    some_code_to_measure
  end
end

Check for multiple occurrences:

assert_statsd_increment('foo', times: 2) do
  StatsD.increment('foo')
  StatsD.increment('foo')
end

Absence of metrics

assert_no_statsd_calls do
  foo
end

Handling exceptions

assert_statsd_increment('foo.error') do
  # If we expect exceptions to occur, we have to handle them inside
  # the block we pass to assert_statsd_increment.
  assert_raises(RuntimeError) do
    begin
      attempt_foo
    rescue
      StatsD.increment('foo.error')
      raise 'foo failed'
    end
  end
end

Instance Method Summary collapse

Methods included from Helpers

#capture_statsd_datagrams

Instance Method Details

#assert_no_statsd_calls(*metric_names, datagrams: nil, client: nil) { ... } ⇒ void

This method returns an undefined value.

Asserts no metric occurred during the execution of the provided block.

Parameters:

  • metric_names (Array<String>)

    (default: []) The metric names that are not allowed to happen inside the block. If this is set to [], the assertion will fail if any metric occurs.

Yields:

  • A block in which the specified metric should not occur. This block should not raise any exceptions.

Raises:

  • (Minitest::Assertion)

    If an exception occurs, or if any metric (with the provided names, or any), occurred during the execution of the provided block.



57
58
59
60
61
62
63
64
65
# File 'lib/statsd/instrument/assertions.rb', line 57

def assert_no_statsd_calls(*metric_names, datagrams: nil, client: nil, &block)
  if datagrams.nil?
    raise LocalJumpError, "assert_no_statsd_calls requires a block" unless block_given?
    datagrams = capture_statsd_datagrams_with_exception_handling(client: client, &block)
  end

  datagrams.select! { |metric| metric_names.include?(metric.name) } unless metric_names.empty?
  assert(datagrams.empty?, "No StatsD calls for metric #{datagrams.map(&:name).join(', ')} expected.")
end

#assert_statsd_distribution(metric_name, value = nil, datagrams: nil, client: nil, **options) { ... } ⇒ void

This method returns an undefined value.

Asserts that a given distribution metric occurred inside the provided block.

Parameters:

  • metric_name (String)

    The name of the metric that should occur.

  • options (Hash)

    (see StatsD::Instrument::MetricExpectation.new)

Yields:

  • A block in which the specified metric should occur. This block should not raise any exceptions.

Raises:

  • (Minitest::Assertion)

    If an exception occurs, or if the metric did not occur as specified during the execution the block.



124
125
126
127
# File 'lib/statsd/instrument/assertions.rb', line 124

def assert_statsd_distribution(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
  expectation = StatsD::Instrument::Expectation.distribution(metric_name, value, **options)
  assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
end

#assert_statsd_expectations(expectations, datagrams: nil, client: nil) { ... } ⇒ void Also known as: assert_statsd_calls, assert_statsd_expectation

This method returns an undefined value.

Asserts that the set of provided metric expectations came true.

Generally, it's recommended to use more specific assertion methods, like #assert_statsd_increment and others.

Parameters:

Yields:

  • A block in which the specified metric should occur. This block should not raise any exceptions.

Raises:

  • (Minitest::Assertion)

    If an exception occurs, or if the metric did not occur as specified during the execution the block.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/statsd/instrument/assertions.rb', line 152

def assert_statsd_expectations(expectations, datagrams: nil, client: nil, &block)
  if datagrams.nil?
    raise LocalJumpError, "assert_statsd_expectations requires a block" unless block_given?
    datagrams = capture_statsd_datagrams_with_exception_handling(client: client, &block)
  end

  expectations = Array(expectations)
  matched_expectations = []
  expectations.each do |expectation|
    expectation_times = expectation.times
    expectation_times_remaining = expectation.times
    filtered_datagrams = datagrams.select { |m| m.type == expectation.type && m.name == expectation.name }

    if filtered_datagrams.empty?
      flunk("No StatsD calls for metric #{expectation.name} of type #{expectation.type} were made.")
    end

    filtered_datagrams.each do |datagram|
      next unless expectation.matches(datagram)

      if expectation_times_remaining == 0
        flunk("Unexpected StatsD call; number of times this metric " \
          "was expected exceeded: #{expectation.inspect}")
      end

      expectation_times_remaining -= 1
      datagrams.delete(datagram)
      if expectation_times_remaining == 0
        matched_expectations << expectation
      end
    end

    next if expectation_times_remaining == 0

    msg = +"Metric expected #{expectation_times} times but seen " \
      "#{expectation_times - expectation_times_remaining} " \
      "times: #{expectation.inspect}."
    msg << "\nCaptured metrics with the same key: #{filtered_datagrams}" if filtered_datagrams.any?
    flunk(msg)
  end
  expectations -= matched_expectations

  unless expectations.empty?
    flunk("Unexpected StatsD calls; the following metric expectations " \
      "were not satisfied: #{expectations.inspect}")
  end

  pass
end

#assert_statsd_gauge(metric_name, value = nil, datagrams: nil, client: nil, **options) { ... } ⇒ void

This method returns an undefined value.

Asserts that a given gauge metric occurred inside the provided block.

Parameters:

  • metric_name (String)

    The name of the metric that should occur.

  • options (Hash)

    (see StatsD::Instrument::MetricExpectation.new)

Yields:

  • A block in which the specified metric should occur. This block should not raise any exceptions.

Raises:

  • (Minitest::Assertion)

    If an exception occurs, or if the metric did not occur as specified during the execution the block.



100
101
102
103
# File 'lib/statsd/instrument/assertions.rb', line 100

def assert_statsd_gauge(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
  expectation = StatsD::Instrument::Expectation.gauge(metric_name, value, **options)
  assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
end

#assert_statsd_histogram(metric_name, value = nil, datagrams: nil, client: nil, **options) { ... } ⇒ void

This method returns an undefined value.

Asserts that a given histogram metric occurred inside the provided block.

Parameters:

  • metric_name (String)

    The name of the metric that should occur.

  • options (Hash)

    (see StatsD::Instrument::MetricExpectation.new)

Yields:

  • A block in which the specified metric should occur. This block should not raise any exceptions.

Raises:

  • (Minitest::Assertion)

    If an exception occurs, or if the metric did not occur as specified during the execution the block.



112
113
114
115
# File 'lib/statsd/instrument/assertions.rb', line 112

def assert_statsd_histogram(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
  expectation = StatsD::Instrument::Expectation.histogram(metric_name, value, **options)
  assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
end

#assert_statsd_increment(metric_name, value = nil, datagrams: nil, client: nil, **options) { ... } ⇒ void

This method returns an undefined value.

Asserts that a given counter metric occurred inside the provided block.

Parameters:

  • metric_name (String)

    The name of the metric that should occur.

  • options (Hash)

    (see StatsD::Instrument::MetricExpectation.new)

Yields:

  • A block in which the specified metric should occur. This block should not raise any exceptions.

Raises:

  • (Minitest::Assertion)

    If an exception occurs, or if the metric did not occur as specified during the execution the block.



76
77
78
79
# File 'lib/statsd/instrument/assertions.rb', line 76

def assert_statsd_increment(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
  expectation = StatsD::Instrument::Expectation.increment(metric_name, value, **options)
  assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
end

#assert_statsd_measure(metric_name, value = nil, datagrams: nil, client: nil, **options) { ... } ⇒ void

This method returns an undefined value.

Asserts that a given timing metric occurred inside the provided block.

Parameters:

  • metric_name (String)

    The name of the metric that should occur.

  • options (Hash)

    (see StatsD::Instrument::MetricExpectation.new)

Yields:

  • A block in which the specified metric should occur. This block should not raise any exceptions.

Raises:

  • (Minitest::Assertion)

    If an exception occurs, or if the metric did not occur as specified during the execution the block.



88
89
90
91
# File 'lib/statsd/instrument/assertions.rb', line 88

def assert_statsd_measure(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
  expectation = StatsD::Instrument::Expectation.measure(metric_name, value, **options)
  assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
end

#assert_statsd_set(metric_name, value = nil, datagrams: nil, client: nil, **options) { ... } ⇒ void

This method returns an undefined value.

Asserts that a given set metric occurred inside the provided block.

Parameters:

  • metric_name (String)

    The name of the metric that should occur.

  • options (Hash)

    (see StatsD::Instrument::MetricExpectation.new)

Yields:

  • A block in which the specified metric should occur. This block should not raise any exceptions.

Raises:

  • (Minitest::Assertion)

    If an exception occurs, or if the metric did not occur as specified during the execution the block.



136
137
138
139
# File 'lib/statsd/instrument/assertions.rb', line 136

def assert_statsd_set(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
  expectation = StatsD::Instrument::Expectation.set(metric_name, value, **options)
  assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
end