statsd-instrument 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +3 -3
- data/.rubocop.yml +3 -13
- data/CHANGELOG.md +6 -0
- data/Gemfile +8 -0
- data/README.md +2 -2
- data/Rakefile +1 -1
- data/bin/rake +29 -0
- data/bin/rubocop +29 -0
- data/lib/statsd/instrument.rb +4 -1
- data/lib/statsd/instrument/assertions.rb +200 -196
- data/lib/statsd/instrument/capture_sink.rb +23 -19
- data/lib/statsd/instrument/client.rb +414 -410
- data/lib/statsd/instrument/datagram.rb +69 -65
- data/lib/statsd/instrument/datagram_builder.rb +81 -77
- data/lib/statsd/instrument/dogstatsd_datagram.rb +76 -72
- data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +68 -64
- data/lib/statsd/instrument/environment.rb +80 -77
- data/lib/statsd/instrument/expectation.rb +96 -92
- data/lib/statsd/instrument/helpers.rb +11 -7
- data/lib/statsd/instrument/log_sink.rb +20 -16
- data/lib/statsd/instrument/matchers.rb +86 -70
- data/lib/statsd/instrument/null_sink.rb +12 -8
- data/lib/statsd/instrument/railtie.rb +11 -7
- data/lib/statsd/instrument/statsd_datagram_builder.rb +12 -8
- data/lib/statsd/instrument/udp_sink.rb +50 -46
- data/lib/statsd/instrument/version.rb +1 -1
- data/statsd-instrument.gemspec +2 -8
- data/test/assertions_test.rb +12 -12
- data/test/capture_sink_test.rb +8 -8
- data/test/client_test.rb +54 -54
- data/test/datagram_builder_test.rb +29 -29
- data/test/datagram_test.rb +1 -1
- data/test/dogstatsd_datagram_builder_test.rb +28 -28
- data/test/environment_test.rb +9 -9
- data/test/helpers/rubocop_helper.rb +9 -6
- data/test/helpers_test.rb +5 -5
- data/test/integration_test.rb +1 -1
- data/test/log_sink_test.rb +2 -2
- data/test/matchers_test.rb +36 -36
- data/test/null_sink_test.rb +2 -2
- data/test/rubocop/metric_return_value_test.rb +3 -3
- data/test/rubocop/positional_arguments_test.rb +10 -10
- data/test/statsd_instrumentation_test.rb +66 -66
- data/test/statsd_test.rb +44 -44
- data/test/test_helper.rb +6 -4
- data/test/udp_sink_test.rb +8 -8
- metadata +7 -103
- data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +0 -1027
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a26da2deac1a048fae156e2e8804ec5a423fde1e383ed1b3c446d34b0c553ec
|
4
|
+
data.tar.gz: edae81c0c408a10c4729d019930596e2a586abc17863b57642e3f2a0ff1b3084
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87037561be37e4fbf2cdee8e32564b35ae66b9d4c5a308e4784764d879171644ce2e0e5470fca8ac949b3e4ac3bff633e4bf95e83c37449dbbbe365543305bba
|
7
|
+
data.tar.gz: 9679d5832ffb8406ab800580bbab62ac3ba3d2b936ac9e841a755a90a9f09883ab62777f084a1ad6c979dbb4372f283cfed61e7e200dd32ee164da2673b82669
|
data/.github/workflows/ci.yml
CHANGED
@@ -11,7 +11,7 @@ jobs:
|
|
11
11
|
matrix:
|
12
12
|
# Windows on macOS builds started failing, so they are disabled for noew
|
13
13
|
|
14
|
-
ruby: [2.4, 2.5, 2.6]
|
14
|
+
ruby: [2.4, 2.5, 2.6, 2.7]
|
15
15
|
# platform: [windows-2019, macOS-10.14, ubuntu-18.04]
|
16
16
|
|
17
17
|
# exclude:
|
@@ -43,7 +43,7 @@ jobs:
|
|
43
43
|
run: gem install bundler && bundle install --jobs 4 --retry 3
|
44
44
|
|
45
45
|
- name: Run test suite
|
46
|
-
run:
|
46
|
+
run: rake test
|
47
47
|
|
48
48
|
- name: Run Rubocop
|
49
|
-
run:
|
49
|
+
run: bin/rubocop
|
data/.rubocop.yml
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
|
2
|
-
-
|
1
|
+
inherit_gem:
|
2
|
+
rubocop-shopify: rubocop.yml
|
3
3
|
|
4
4
|
require:
|
5
5
|
- ./lib/statsd/instrument/rubocop.rb
|
6
6
|
|
7
7
|
AllCops:
|
8
|
-
TargetRubyVersion: 2.
|
8
|
+
TargetRubyVersion: 2.4
|
9
9
|
UseCache: true
|
10
10
|
CacheRootDirectory: tmp/rubocop
|
11
11
|
Exclude:
|
@@ -16,16 +16,6 @@ Naming/FileName:
|
|
16
16
|
Exclude:
|
17
17
|
- lib/statsd-instrument.rb
|
18
18
|
|
19
|
-
Style/ClassAndModuleChildren:
|
20
|
-
Enabled: false # TODO: enable later
|
21
|
-
|
22
|
-
|
23
|
-
Style/MethodCallWithArgsParentheses:
|
24
|
-
Enabled: false # TODO: enable later
|
25
|
-
|
26
|
-
Lint/UnusedMethodArgument:
|
27
|
-
AllowUnusedKeywordArguments: true
|
28
|
-
|
29
19
|
# Enable our own cops on our own repo
|
30
20
|
|
31
21
|
StatsD/MetricReturnValue:
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,12 @@ section below.
|
|
8
8
|
|
9
9
|
_Nothing yet_
|
10
10
|
|
11
|
+
## Version 3.0.1
|
12
|
+
|
13
|
+
- Fix metaprograming methods to not print keyword argument warnings on
|
14
|
+
Ruby 2.7.
|
15
|
+
- Fix the gemspec to no longer register `rake` and `rubocop` as executables.
|
16
|
+
|
11
17
|
## Version 3.0.0
|
12
18
|
|
13
19
|
This version makes the new client that was added in version 2.6+ the default
|
data/Gemfile
CHANGED
@@ -3,5 +3,13 @@
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
gem 'rake'
|
7
|
+
gem 'minitest'
|
8
|
+
gem 'rspec'
|
9
|
+
gem 'mocha'
|
10
|
+
gem 'yard'
|
11
|
+
gem 'rubocop'
|
12
|
+
gem 'rubocop-shopify', require: false
|
13
|
+
|
6
14
|
# benchmark-ips save! method is not part of a released version yet.
|
7
15
|
gem 'benchmark-ips', git: 'https://github.com/evanphx/benchmark-ips', branch: 'master'
|
data/README.md
CHANGED
@@ -105,7 +105,7 @@ Because you are counting unique values, the results of using a sampling value le
|
|
105
105
|
Builds a histogram of numeric values.
|
106
106
|
``` ruby
|
107
107
|
|
108
|
-
StatsD.histogram('Order.value', order.value_in_usd.to_f tags: { source: 'POS' })
|
108
|
+
StatsD.histogram('Order.value', order.value_in_usd.to_f, tags: { source: 'POS' })
|
109
109
|
```
|
110
110
|
|
111
111
|
Because you are counting unique values, the results of using a sampling value less than 1.0 can lead to unexpected, hard to interpret results.
|
@@ -128,7 +128,7 @@ An event is a (title, text) tuple that can be used to correlate metrics with som
|
|
128
128
|
This is a good fit for instance to correlate response time variation with a deploy of the new code.
|
129
129
|
|
130
130
|
```ruby
|
131
|
-
StatsD.event('shipit.deploy', 'started'
|
131
|
+
StatsD.event('shipit.deploy', 'started')
|
132
132
|
```
|
133
133
|
|
134
134
|
*Note: This is only supported by the [datadog implementation](https://docs.datadoghq.com/guides/dogstatsd/#events).*
|
data/Rakefile
CHANGED
data/bin/rake
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rake' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load(Gem.bin_path("rake", "rake"))
|
data/bin/rubocop
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load(Gem.bin_path("rubocop", "rubocop"))
|
data/lib/statsd/instrument.rb
CHANGED
@@ -275,6 +275,9 @@ module StatsD
|
|
275
275
|
|
276
276
|
instrumentation_module.module_eval(&block)
|
277
277
|
instrumentation_module.send(method_scope, method)
|
278
|
+
if instrumentation_module.respond_to?(:ruby2_keywords, true)
|
279
|
+
instrumentation_module.send(:ruby2_keywords, method)
|
280
|
+
end
|
278
281
|
prepend(instrumentation_module) unless self < instrumentation_module
|
279
282
|
end
|
280
283
|
|
@@ -333,7 +336,7 @@ module StatsD
|
|
333
336
|
# @!method distribution(name, value = nil, sample_rate: nil, tags: nil, &block)
|
334
337
|
# (see StatsD::Instrument::Client#distribution)
|
335
338
|
#
|
336
|
-
# @!method event(title, text, tags: nil, hostname: nil, timestamp: nil, aggregation_key: nil, priority: nil, source_type_name: nil, alert_type: nil) # rubocop:disable
|
339
|
+
# @!method event(title, text, tags: nil, hostname: nil, timestamp: nil, aggregation_key: nil, priority: nil, source_type_name: nil, alert_type: nil) # rubocop:disable Layout/LineLength
|
337
340
|
# (see StatsD::Instrument::Client#event)
|
338
341
|
#
|
339
342
|
# @!method service_check(name, status, tags: nil, hostname: nil, timestamp: nil, message: nil)
|
@@ -1,219 +1,223 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# metric
|
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
|
-
assert(datagrams.empty?, "No StatsD calls for metric #{datagrams.map(&:name).join(', ')} expected.")
|
63
|
-
end
|
64
|
-
|
65
|
-
# Asserts that a given counter metric occurred inside the provided block.
|
66
|
-
#
|
67
|
-
# @param [String] metric_name The name of the metric that should occur.
|
68
|
-
# @param [Hash] options (see StatsD::Instrument::MetricExpectation.new)
|
69
|
-
# @yield A block in which the specified metric should occur. This block
|
70
|
-
# should not raise any exceptions.
|
71
|
-
# @return [void]
|
72
|
-
# @raise [Minitest::Assertion] If an exception occurs, or if the metric did
|
73
|
-
# not occur as specified during the execution the block.
|
74
|
-
def assert_statsd_increment(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
|
75
|
-
expectation = StatsD::Instrument::Expectation.increment(metric_name, value, **options)
|
76
|
-
assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
|
77
|
-
end
|
78
|
-
|
79
|
-
# Asserts that a given timing metric occurred inside the provided block.
|
80
|
-
#
|
81
|
-
# @param metric_name (see #assert_statsd_increment)
|
82
|
-
# @param options (see #assert_statsd_increment)
|
83
|
-
# @yield (see #assert_statsd_increment)
|
84
|
-
# @return [void]
|
85
|
-
# @raise (see #assert_statsd_increment)
|
86
|
-
def assert_statsd_measure(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
|
87
|
-
expectation = StatsD::Instrument::Expectation.measure(metric_name, value, **options)
|
88
|
-
assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
|
89
|
-
end
|
90
|
-
|
91
|
-
# Asserts that a given gauge metric occurred inside the provided block.
|
92
|
-
#
|
93
|
-
# @param metric_name (see #assert_statsd_increment)
|
94
|
-
# @param options (see #assert_statsd_increment)
|
95
|
-
# @yield (see #assert_statsd_increment)
|
96
|
-
# @return [void]
|
97
|
-
# @raise (see #assert_statsd_increment)
|
98
|
-
def assert_statsd_gauge(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
|
99
|
-
expectation = StatsD::Instrument::Expectation.gauge(metric_name, value, **options)
|
100
|
-
assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
|
101
|
-
end
|
3
|
+
module StatsD
|
4
|
+
module Instrument
|
5
|
+
# This module defines several assertion methods that can be used to verify that
|
6
|
+
# your application is emitting the right StatsD metrics.
|
7
|
+
#
|
8
|
+
# Every metric type has its own assertion method, like {#assert_statsd_increment}
|
9
|
+
# to assert `StatsD.increment` calls. You can also assert other properties of the
|
10
|
+
# metric that was emitted, like the sample rate or presence of tags.
|
11
|
+
# To check for the absence of metrics, use {#assert_no_statsd_calls}.
|
12
|
+
#
|
13
|
+
# @example Check for metric properties:
|
14
|
+
# assert_statsd_measure('foo', sample_rate: 0.1, tags: ["bar"]) do
|
15
|
+
# StatsD.measure('foo', sample_rate: 0.5, tags: ['bar','baz']) do
|
16
|
+
# some_code_to_measure
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# @example Check for multiple occurrences:
|
21
|
+
# assert_statsd_increment('foo', times: 2) do
|
22
|
+
# StatsD.increment('foo')
|
23
|
+
# StatsD.increment('foo')
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# @example Absence of metrics
|
27
|
+
# assert_no_statsd_calls do
|
28
|
+
# foo
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# @example Handling exceptions
|
32
|
+
# assert_statsd_increment('foo.error') do
|
33
|
+
# # If we expect exceptions to occur, we have to handle them inside
|
34
|
+
# # the block we pass to assert_statsd_increment.
|
35
|
+
# assert_raises(RuntimeError) do
|
36
|
+
# begin
|
37
|
+
# attempt_foo
|
38
|
+
# rescue
|
39
|
+
# StatsD.increment('foo.error')
|
40
|
+
# raise 'foo failed'
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
module Assertions
|
45
|
+
include StatsD::Instrument::Helpers
|
46
|
+
|
47
|
+
# Asserts no metric occurred during the execution of the provided block.
|
48
|
+
#
|
49
|
+
# @param [Array<String>] metric_names (default: []) The metric names that are not
|
50
|
+
# allowed to happen inside the block. If this is set to `[]`, the assertion
|
51
|
+
# will fail if any metric occurs.
|
52
|
+
# @yield A block in which the specified metric should not occur. This block
|
53
|
+
# should not raise any exceptions.
|
54
|
+
# @return [void]
|
55
|
+
# @raise [Minitest::Assertion] If an exception occurs, or if any metric (with the
|
56
|
+
# provided names, or any), occurred during the execution of the provided block.
|
57
|
+
def assert_no_statsd_calls(*metric_names, datagrams: nil, client: nil, &block)
|
58
|
+
if datagrams.nil?
|
59
|
+
raise LocalJumpError, "assert_no_statsd_calls requires a block" unless block_given?
|
60
|
+
datagrams = capture_statsd_datagrams_with_exception_handling(client: client, &block)
|
61
|
+
end
|
102
62
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
# @param options (see #assert_statsd_increment)
|
107
|
-
# @yield (see #assert_statsd_increment)
|
108
|
-
# @return [void]
|
109
|
-
# @raise (see #assert_statsd_increment)
|
110
|
-
def assert_statsd_histogram(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
|
111
|
-
expectation = StatsD::Instrument::Expectation.histogram(metric_name, value, **options)
|
112
|
-
assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
|
113
|
-
end
|
63
|
+
datagrams.select! { |metric| metric_names.include?(metric.name) } unless metric_names.empty?
|
64
|
+
assert(datagrams.empty?, "No StatsD calls for metric #{datagrams.map(&:name).join(', ')} expected.")
|
65
|
+
end
|
114
66
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
67
|
+
# Asserts that a given counter metric occurred inside the provided block.
|
68
|
+
#
|
69
|
+
# @param [String] metric_name The name of the metric that should occur.
|
70
|
+
# @param [Hash] options (see StatsD::Instrument::MetricExpectation.new)
|
71
|
+
# @yield A block in which the specified metric should occur. This block
|
72
|
+
# should not raise any exceptions.
|
73
|
+
# @return [void]
|
74
|
+
# @raise [Minitest::Assertion] If an exception occurs, or if the metric did
|
75
|
+
# not occur as specified during the execution the block.
|
76
|
+
def assert_statsd_increment(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
|
77
|
+
expectation = StatsD::Instrument::Expectation.increment(metric_name, value, **options)
|
78
|
+
assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
|
79
|
+
end
|
126
80
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
81
|
+
# Asserts that a given timing metric occurred inside the provided block.
|
82
|
+
#
|
83
|
+
# @param metric_name (see #assert_statsd_increment)
|
84
|
+
# @param options (see #assert_statsd_increment)
|
85
|
+
# @yield (see #assert_statsd_increment)
|
86
|
+
# @return [void]
|
87
|
+
# @raise (see #assert_statsd_increment)
|
88
|
+
def assert_statsd_measure(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
|
89
|
+
expectation = StatsD::Instrument::Expectation.measure(metric_name, value, **options)
|
90
|
+
assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
|
91
|
+
end
|
138
92
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
def assert_statsd_expectations(expectations, datagrams: nil, client: nil, &block)
|
151
|
-
if datagrams.nil?
|
152
|
-
raise LocalJumpError, "assert_statsd_expectations requires a block" unless block_given?
|
153
|
-
datagrams = capture_statsd_datagrams_with_exception_handling(client: client, &block)
|
154
|
-
end
|
93
|
+
# Asserts that a given gauge metric occurred inside the provided block.
|
94
|
+
#
|
95
|
+
# @param metric_name (see #assert_statsd_increment)
|
96
|
+
# @param options (see #assert_statsd_increment)
|
97
|
+
# @yield (see #assert_statsd_increment)
|
98
|
+
# @return [void]
|
99
|
+
# @raise (see #assert_statsd_increment)
|
100
|
+
def assert_statsd_gauge(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
|
101
|
+
expectation = StatsD::Instrument::Expectation.gauge(metric_name, value, **options)
|
102
|
+
assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
|
103
|
+
end
|
155
104
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
105
|
+
# Asserts that a given histogram metric occurred inside the provided block.
|
106
|
+
#
|
107
|
+
# @param metric_name (see #assert_statsd_increment)
|
108
|
+
# @param options (see #assert_statsd_increment)
|
109
|
+
# @yield (see #assert_statsd_increment)
|
110
|
+
# @return [void]
|
111
|
+
# @raise (see #assert_statsd_increment)
|
112
|
+
def assert_statsd_histogram(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
|
113
|
+
expectation = StatsD::Instrument::Expectation.histogram(metric_name, value, **options)
|
114
|
+
assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
|
115
|
+
end
|
162
116
|
|
163
|
-
|
164
|
-
|
117
|
+
# Asserts that a given distribution metric occurred inside the provided block.
|
118
|
+
#
|
119
|
+
# @param metric_name (see #assert_statsd_increment)
|
120
|
+
# @param options (see #assert_statsd_increment)
|
121
|
+
# @yield (see #assert_statsd_increment)
|
122
|
+
# @return [void]
|
123
|
+
# @raise (see #assert_statsd_increment)
|
124
|
+
def assert_statsd_distribution(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
|
125
|
+
expectation = StatsD::Instrument::Expectation.distribution(metric_name, value, **options)
|
126
|
+
assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
|
165
127
|
end
|
166
128
|
|
167
|
-
|
168
|
-
|
129
|
+
# Asserts that a given set metric occurred inside the provided block.
|
130
|
+
#
|
131
|
+
# @param metric_name (see #assert_statsd_increment)
|
132
|
+
# @param options (see #assert_statsd_increment)
|
133
|
+
# @yield (see #assert_statsd_increment)
|
134
|
+
# @return [void]
|
135
|
+
# @raise (see #assert_statsd_increment)
|
136
|
+
def assert_statsd_set(metric_name, value = nil, datagrams: nil, client: nil, **options, &block)
|
137
|
+
expectation = StatsD::Instrument::Expectation.set(metric_name, value, **options)
|
138
|
+
assert_statsd_expectation(expectation, datagrams: datagrams, client: client, &block)
|
139
|
+
end
|
169
140
|
|
170
|
-
|
171
|
-
|
172
|
-
|
141
|
+
# Asserts that the set of provided metric expectations came true.
|
142
|
+
#
|
143
|
+
# Generally, it's recommended to use more specific assertion methods, like
|
144
|
+
# {#assert_statsd_increment} and others.
|
145
|
+
#
|
146
|
+
# @private
|
147
|
+
# @param [Array<StatsD::Instrument::Expectation>] expectations The set of
|
148
|
+
# expectations to verify.
|
149
|
+
# @yield (see #assert_statsd_increment)
|
150
|
+
# @return [void]
|
151
|
+
# @raise (see #assert_statsd_increment)
|
152
|
+
def assert_statsd_expectations(expectations, datagrams: nil, client: nil, &block)
|
153
|
+
if datagrams.nil?
|
154
|
+
raise LocalJumpError, "assert_statsd_expectations requires a block" unless block_given?
|
155
|
+
datagrams = capture_statsd_datagrams_with_exception_handling(client: client, &block)
|
173
156
|
end
|
174
157
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
158
|
+
expectations = Array(expectations)
|
159
|
+
matched_expectations = []
|
160
|
+
expectations.each do |expectation|
|
161
|
+
expectation_times = expectation.times
|
162
|
+
expectation_times_remaining = expectation.times
|
163
|
+
filtered_datagrams = datagrams.select { |m| m.type == expectation.type && m.name == expectation.name }
|
164
|
+
|
165
|
+
if filtered_datagrams.empty?
|
166
|
+
flunk("No StatsD calls for metric #{expectation.name} of type #{expectation.type} were made.")
|
167
|
+
end
|
168
|
+
|
169
|
+
filtered_datagrams.each do |datagram|
|
170
|
+
next unless expectation.matches(datagram)
|
171
|
+
|
172
|
+
if expectation_times_remaining == 0
|
173
|
+
flunk("Unexpected StatsD call; number of times this metric " \
|
174
|
+
"was expected exceeded: #{expectation.inspect}")
|
175
|
+
end
|
176
|
+
|
177
|
+
expectation_times_remaining -= 1
|
178
|
+
datagrams.delete(datagram)
|
179
|
+
if expectation_times_remaining == 0
|
180
|
+
matched_expectations << expectation
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
next if expectation_times_remaining == 0
|
185
|
+
|
186
|
+
msg = +"Metric expected #{expectation_times} times but seen " \
|
187
|
+
"#{expectation_times - expectation_times_remaining} " \
|
188
|
+
"times: #{expectation.inspect}."
|
189
|
+
msg << "\nCaptured metrics with the same key: #{filtered_datagrams}" if filtered_datagrams.any?
|
190
|
+
flunk(msg)
|
179
191
|
end
|
180
|
-
|
192
|
+
expectations -= matched_expectations
|
181
193
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
"times: #{expectation.inspect}."
|
187
|
-
msg << "\nCaptured metrics with the same key: #{filtered_datagrams}" if filtered_datagrams.any?
|
188
|
-
flunk(msg)
|
189
|
-
end
|
190
|
-
expectations -= matched_expectations
|
191
|
-
|
192
|
-
unless expectations.empty?
|
193
|
-
flunk("Unexpected StatsD calls; the following metric expectations " \
|
194
|
-
"were not satisfied: #{expectations.inspect}")
|
195
|
-
end
|
194
|
+
unless expectations.empty?
|
195
|
+
flunk("Unexpected StatsD calls; the following metric expectations " \
|
196
|
+
"were not satisfied: #{expectations.inspect}")
|
197
|
+
end
|
196
198
|
|
197
|
-
|
198
|
-
|
199
|
+
pass
|
200
|
+
end
|
199
201
|
|
200
|
-
|
201
|
-
|
202
|
-
|
202
|
+
# For backwards compatibility
|
203
|
+
alias_method :assert_statsd_calls, :assert_statsd_expectations
|
204
|
+
alias_method :assert_statsd_expectation, :assert_statsd_expectations
|
203
205
|
|
204
|
-
|
206
|
+
private
|
205
207
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
208
|
+
def capture_statsd_datagrams_with_exception_handling(client:, &block)
|
209
|
+
capture_statsd_datagrams(client: client, &block)
|
210
|
+
rescue => exception
|
211
|
+
flunk(<<~MESSAGE)
|
212
|
+
An exception occurred in the block provided to the StatsD assertion.
|
211
213
|
|
212
|
-
|
213
|
-
|
214
|
+
#{exception.class.name}: #{exception.message}
|
215
|
+
\t#{(exception.backtrace || []).join("\n\t")}
|
214
216
|
|
215
|
-
|
216
|
-
|
217
|
-
|
217
|
+
If this exception is expected, make sure to handle it using `assert_raises`
|
218
|
+
inside the block provided to the StatsD assertion.
|
219
|
+
MESSAGE
|
220
|
+
end
|
221
|
+
end
|
218
222
|
end
|
219
223
|
end
|