qubole-statsd-instrument 2.1.4

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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.travis.yml +12 -0
  4. data/CHANGELOG.md +89 -0
  5. data/CONTRIBUTING.md +34 -0
  6. data/Gemfile +2 -0
  7. data/LICENSE +20 -0
  8. data/README.md +319 -0
  9. data/Rakefile +10 -0
  10. data/lib/statsd/instrument/assertions.rb +88 -0
  11. data/lib/statsd/instrument/backend.rb +17 -0
  12. data/lib/statsd/instrument/backends/capture_backend.rb +29 -0
  13. data/lib/statsd/instrument/backends/logger_backend.rb +20 -0
  14. data/lib/statsd/instrument/backends/null_backend.rb +7 -0
  15. data/lib/statsd/instrument/backends/udp_backend.rb +106 -0
  16. data/lib/statsd/instrument/environment.rb +54 -0
  17. data/lib/statsd/instrument/helpers.rb +14 -0
  18. data/lib/statsd/instrument/matchers.rb +96 -0
  19. data/lib/statsd/instrument/metric.rb +117 -0
  20. data/lib/statsd/instrument/metric_expectation.rb +67 -0
  21. data/lib/statsd/instrument/railtie.rb +14 -0
  22. data/lib/statsd/instrument/version.rb +5 -0
  23. data/lib/statsd/instrument.rb +407 -0
  24. data/lib/statsd-instrument.rb +1 -0
  25. data/shipit.rubygems.yml +1 -0
  26. data/statsd-instrument.gemspec +27 -0
  27. data/test/assertions_test.rb +329 -0
  28. data/test/benchmark/tags.rb +34 -0
  29. data/test/capture_backend_test.rb +24 -0
  30. data/test/environment_test.rb +46 -0
  31. data/test/helpers_test.rb +24 -0
  32. data/test/integration_test.rb +20 -0
  33. data/test/logger_backend_test.rb +20 -0
  34. data/test/matchers_test.rb +102 -0
  35. data/test/metric_test.rb +45 -0
  36. data/test/statsd_instrumentation_test.rb +328 -0
  37. data/test/statsd_test.rb +136 -0
  38. data/test/test_helper.rb +10 -0
  39. data/test/udp_backend_test.rb +167 -0
  40. metadata +182 -0
@@ -0,0 +1,329 @@
1
+ require 'test_helper'
2
+
3
+ class AssertionsTest < Minitest::Test
4
+ def setup
5
+ test_class = Class.new(Minitest::Test)
6
+ test_class.send(:include, StatsD::Instrument::Assertions)
7
+ @test_case = test_class.new('fake')
8
+ end
9
+
10
+ def test_assert_no_statsd_calls
11
+ assert_no_assertion_triggered do
12
+ @test_case.assert_no_statsd_calls('counter') do
13
+ # noop
14
+ end
15
+ end
16
+
17
+ assert_no_assertion_triggered do
18
+ @test_case.assert_no_statsd_calls('counter') do
19
+ StatsD.increment('other')
20
+ end
21
+ end
22
+
23
+ assert_assertion_triggered("No StatsD calls for metric counter expected.") do
24
+ @test_case.assert_no_statsd_calls('counter') do
25
+ StatsD.increment('counter')
26
+ end
27
+ end
28
+
29
+ assert_assertion_triggered("No StatsD calls for metric other expected.") do
30
+ @test_case.assert_no_statsd_calls do
31
+ StatsD.increment('other')
32
+ end
33
+ end
34
+
35
+ assert_assertion_triggered("No StatsD calls for metric other, another expected.") do
36
+ @test_case.assert_no_statsd_calls do
37
+ StatsD.increment('other')
38
+ StatsD.increment('another')
39
+ end
40
+ end
41
+ end
42
+
43
+ def test_assert_statsd_call
44
+ assert_no_assertion_triggered do
45
+ @test_case.assert_statsd_increment('counter') do
46
+ StatsD.increment('counter')
47
+ end
48
+ end
49
+
50
+ assert_no_assertion_triggered do
51
+ @test_case.assert_statsd_increment('counter') do
52
+ StatsD.increment('counter')
53
+ StatsD.increment('other')
54
+ end
55
+ end
56
+
57
+ assert_assertion_triggered do
58
+ @test_case.assert_statsd_increment('counter') do
59
+ StatsD.increment('other')
60
+ end
61
+ end
62
+
63
+ assert_assertion_triggered do
64
+ @test_case.assert_statsd_increment('counter') do
65
+ StatsD.gauge('counter', 42)
66
+ end
67
+ end
68
+
69
+ assert_assertion_triggered do
70
+ @test_case.assert_statsd_increment('counter') do
71
+ StatsD.increment('counter')
72
+ StatsD.increment('counter')
73
+ end
74
+ end
75
+
76
+ assert_no_assertion_triggered do
77
+ @test_case.assert_statsd_increment('counter', times: 2) do
78
+ StatsD.increment('counter')
79
+ StatsD.increment('counter')
80
+ end
81
+ end
82
+
83
+ assert_no_assertion_triggered do
84
+ @test_case.assert_statsd_increment('counter', times: 2, tags: ['foo:1']) do
85
+ StatsD.increment('counter', tags: { foo: 1 })
86
+ StatsD.increment('counter', tags: { foo: 1 })
87
+ end
88
+ end
89
+
90
+ assert_assertion_triggered do
91
+ @test_case.assert_statsd_increment('counter', times: 2, tags: ['foo:1']) do
92
+ StatsD.increment('counter', tags: { foo: 1 })
93
+ StatsD.increment('counter', tags: { foo: 2 })
94
+ end
95
+ end
96
+
97
+ assert_no_assertion_triggered do
98
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a', 'b']) do
99
+ StatsD.increment('counter', sample_rate: 0.5, tags: ['a', 'b'])
100
+ end
101
+ end
102
+
103
+ assert_assertion_triggered do
104
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a', 'b'], ignore_tags: ['b']) do
105
+ StatsD.increment('counter', sample_rate: 0.5, tags: ['a'])
106
+ end
107
+ end
108
+
109
+ assert_no_assertion_triggered do
110
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a'], ignore_tags: ['b']) do
111
+ StatsD.increment('counter', sample_rate: 0.5, tags: ['a', 'b'])
112
+ end
113
+ end
114
+
115
+ assert_no_assertion_triggered do
116
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a'], ignore_tags: ['b']) do
117
+ StatsD.increment('counter', sample_rate: 0.5, tags: ['a'])
118
+ end
119
+ end
120
+
121
+ assert_no_assertion_triggered do
122
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1 }, ignore_tags: { b: 2 }) do
123
+ StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2 })
124
+ end
125
+ end
126
+
127
+ assert_no_assertion_triggered do
128
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1 }, ignore_tags: { b: 2 }) do
129
+ StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 3 })
130
+ end
131
+ end
132
+
133
+ assert_assertion_triggered do
134
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1, b: 3 }, ignore_tags: ['b']) do
135
+ StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2 })
136
+ end
137
+ end
138
+
139
+ assert_no_assertion_triggered do
140
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1 }, ignore_tags: ['b']) do
141
+ StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2 })
142
+ end
143
+ end
144
+
145
+ assert_assertion_triggered do
146
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a', 'b']) do
147
+ StatsD.increment('counter', sample_rate: 0.2, tags: ['c'])
148
+ end
149
+ end
150
+ end
151
+
152
+ def test_tags_will_match_subsets
153
+ assert_no_assertion_triggered do
154
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1 }) do
155
+ StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2 })
156
+ end
157
+ end
158
+
159
+ assert_assertion_triggered do
160
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1, b: 3 }) do
161
+ StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2, c: 4 })
162
+ end
163
+ end
164
+ end
165
+
166
+ def test_multiple_metrics_are_not_order_dependent
167
+ assert_no_assertion_triggered do
168
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:1'])
169
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
170
+ @test_case.assert_statsd_calls([foo_1_metric, foo_2_metric]) do
171
+ StatsD.increment('counter', tags: { foo: 1 })
172
+ StatsD.increment('counter', tags: { foo: 2 })
173
+ end
174
+ end
175
+
176
+ assert_no_assertion_triggered do
177
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:1'])
178
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
179
+ @test_case.assert_statsd_calls([foo_2_metric, foo_1_metric]) do
180
+ StatsD.increment('counter', tags: { foo: 1 })
181
+ StatsD.increment('counter', tags: { foo: 2 })
182
+ end
183
+ end
184
+
185
+ assert_no_assertion_triggered do
186
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
187
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
188
+ @test_case.assert_statsd_calls([foo_1_metric, foo_2_metric]) do
189
+ StatsD.increment('counter', tags: { foo: 1 })
190
+ StatsD.increment('counter', tags: { foo: 1 })
191
+ StatsD.increment('counter', tags: { foo: 2 })
192
+ end
193
+ end
194
+
195
+ assert_no_assertion_triggered do
196
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
197
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
198
+ @test_case.assert_statsd_calls([foo_2_metric, foo_1_metric]) do
199
+ StatsD.increment('counter', tags: { foo: 1 })
200
+ StatsD.increment('counter', tags: { foo: 1 })
201
+ StatsD.increment('counter', tags: { foo: 2 })
202
+ end
203
+ end
204
+
205
+ assert_no_assertion_triggered do
206
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
207
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
208
+ @test_case.assert_statsd_calls([foo_2_metric, foo_1_metric]) do
209
+ StatsD.increment('counter', tags: { foo: 1 })
210
+ StatsD.increment('counter', tags: { foo: 2 })
211
+ StatsD.increment('counter', tags: { foo: 1 })
212
+ end
213
+ end
214
+ end
215
+
216
+ def test_assert_multiple_statsd_calls
217
+ assert_assertion_triggered do
218
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
219
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
220
+ @test_case.assert_statsd_calls([foo_1_metric, foo_2_metric]) do
221
+ StatsD.increment('counter', tags: { foo: 1 })
222
+ StatsD.increment('counter', tags: { foo: 2 })
223
+ end
224
+ end
225
+
226
+ assert_assertion_triggered do
227
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
228
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
229
+ @test_case.assert_statsd_calls([foo_1_metric, foo_2_metric]) do
230
+ StatsD.increment('counter', tags: { foo: 1 })
231
+ StatsD.increment('counter', tags: { foo: 1 })
232
+ StatsD.increment('counter', tags: { foo: 2 })
233
+ StatsD.increment('counter', tags: { foo: 2 })
234
+ end
235
+ end
236
+
237
+ assert_no_assertion_triggered do
238
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
239
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
240
+ @test_case.assert_statsd_calls([foo_1_metric, foo_2_metric]) do
241
+ StatsD.increment('counter', tags: { foo: 1 })
242
+ StatsD.increment('counter', tags: { foo: 1 })
243
+ StatsD.increment('counter', tags: { foo: 2 })
244
+ end
245
+ end
246
+ end
247
+
248
+ def test_assert_statsd_call_with_tags
249
+ assert_no_assertion_triggered do
250
+ @test_case.assert_statsd_increment('counter', tags: ['a:b', 'c:d']) do
251
+ StatsD.increment('counter', tags: { a: 'b', c: 'd' })
252
+ end
253
+ end
254
+
255
+ assert_no_assertion_triggered do
256
+ @test_case.assert_statsd_increment('counter', tags: { a: 'b', c: 'd' }) do
257
+ StatsD.increment('counter', tags: ['a:b', 'c:d'])
258
+ end
259
+ end
260
+ end
261
+
262
+ def test_assert_statsd_call_with_wrong_sample_rate_type
263
+ assert_assertion_triggered "Unexpected sample rate type for metric counter, must be numeric" do
264
+ @test_case.assert_statsd_increment('counter', tags: ['a', 'b']) do
265
+ StatsD.increment('counter', sample_rate: 'abc', tags: ['a', 'b'])
266
+ end
267
+ end
268
+ end
269
+
270
+ def test_nested_assertions
271
+ assert_no_assertion_triggered do
272
+ @test_case.assert_statsd_increment('counter1') do
273
+ @test_case.assert_statsd_increment('counter2') do
274
+ StatsD.increment('counter1')
275
+ StatsD.increment('counter2')
276
+ end
277
+ end
278
+ end
279
+
280
+ assert_no_assertion_triggered do
281
+ @test_case.assert_statsd_increment('counter1') do
282
+ StatsD.increment('counter1')
283
+ @test_case.assert_statsd_increment('counter2') do
284
+ StatsD.increment('counter2')
285
+ end
286
+ end
287
+ end
288
+
289
+ assert_assertion_triggered do
290
+ @test_case.assert_statsd_increment('counter1') do
291
+ @test_case.assert_statsd_increment('counter2') do
292
+ StatsD.increment('counter2')
293
+ end
294
+ end
295
+ end
296
+
297
+ assert_assertion_triggered do
298
+ @test_case.assert_statsd_increment('counter1') do
299
+ @test_case.assert_statsd_increment('counter2') do
300
+ StatsD.increment('counter1')
301
+ end
302
+ StatsD.increment('counter2')
303
+ end
304
+ end
305
+ end
306
+
307
+ private
308
+
309
+ def assert_no_assertion_triggered(&block)
310
+ block.call
311
+ rescue MiniTest::Assertion => assertion
312
+ flunk "No assertion trigger expected, but one was triggered with message #{assertion.message}."
313
+ else
314
+ pass
315
+ end
316
+
317
+ def assert_assertion_triggered(message = nil, &block)
318
+ block.call
319
+ rescue MiniTest::Assertion => assertion
320
+ if message
321
+ assert_equal message, assertion.message, "Assertion triggered, but message was not what was expected."
322
+ else
323
+ pass
324
+ end
325
+ assertion
326
+ else
327
+ flunk "No assertion was triggered, but one was expected."
328
+ end
329
+ end
@@ -0,0 +1,34 @@
1
+ require 'statsd-instrument'
2
+ require 'benchmark/ips'
3
+
4
+ Benchmark.ips do |bench|
5
+ bench.report("normalized tags with simple hash") do
6
+ StatsD::Instrument::Metric.normalize_tags(:tag => 'value')
7
+ end
8
+
9
+ bench.report("normalized tags with simple array") do
10
+ StatsD::Instrument::Metric.normalize_tags(['test:test'])
11
+ end
12
+
13
+ bench.report("normalized tags with large hash") do
14
+ StatsD::Instrument::Metric.normalize_tags({
15
+ mobile: true,
16
+ pod: "1",
17
+ protocol: "https",
18
+ country: "Langbortistan",
19
+ complete: true,
20
+ shop: "omg shop that has a longer name",
21
+ })
22
+ end
23
+
24
+ bench.report("normalized tags with large array") do
25
+ StatsD::Instrument::Metric.normalize_tags([
26
+ "mobile:true",
27
+ "pod:1",
28
+ "protocol:https",
29
+ "country:Langbortistan",
30
+ "complete:true",
31
+ "shop:omg_shop_that_has_a_longer_name",
32
+ ])
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ class CaptureBackendTest < Minitest::Test
4
+ def setup
5
+ @backend = StatsD::Instrument::Backends::CaptureBackend.new
6
+ @metric1 = StatsD::Instrument::Metric::new(type: :c, name: 'mock.counter')
7
+ @metric2 = StatsD::Instrument::Metric::new(type: :ms, name: 'mock.measure', value: 123)
8
+ end
9
+
10
+ def test_collecting_metric
11
+ assert @backend.collected_metrics.empty?
12
+ @backend.collect_metric(@metric1)
13
+ @backend.collect_metric(@metric2)
14
+ assert_equal [@metric1, @metric2], @backend.collected_metrics
15
+ end
16
+
17
+ def test_reset
18
+ @backend.collect_metric(@metric1)
19
+ @backend.reset
20
+ assert @backend.collected_metrics.empty?
21
+ @backend.collect_metric(@metric2)
22
+ assert_equal [@metric2], @backend.collected_metrics
23
+ end
24
+ end
@@ -0,0 +1,46 @@
1
+ require 'test_helper'
2
+
3
+ module Rails; end
4
+
5
+ class EnvironmentTest < Minitest::Test
6
+
7
+ def setup
8
+ ENV['STATSD_ADDR'] = nil
9
+ ENV['IMPLEMENTATION'] = nil
10
+ end
11
+
12
+ def test_uses_logger_in_development_environment
13
+ StatsD::Instrument::Environment.stubs(:environment).returns('development')
14
+ assert_instance_of StatsD::Instrument::Backends::LoggerBackend, StatsD::Instrument::Environment.default_backend
15
+ end
16
+
17
+ def test_uses_null_backend_in_test_environment
18
+ StatsD::Instrument::Environment.stubs(:environment).returns('test')
19
+ assert_instance_of StatsD::Instrument::Backends::NullBackend, StatsD::Instrument::Environment.default_backend
20
+ end
21
+
22
+ def test_uses_udp_backend_in_production_environment
23
+ StatsD::Instrument::Environment.stubs(:environment).returns('production')
24
+ assert_instance_of StatsD::Instrument::Backends::UDPBackend, StatsD::Instrument::Environment.default_backend
25
+ end
26
+
27
+ def test_uses_environment_variables_in_production_environment
28
+ StatsD::Instrument::Environment.stubs(:environment).returns('production')
29
+ ENV['STATSD_ADDR'] = '127.0.0.1:1234'
30
+ ENV['STATSD_IMPLEMENTATION'] = 'datadog'
31
+
32
+ backend = StatsD::Instrument::Environment.default_backend
33
+ assert_equal '127.0.0.1', backend.host
34
+ assert_equal 1234, backend.port
35
+ assert_equal :datadog, backend.implementation
36
+ end
37
+
38
+ def test_uses_env_when_rails_does_not_respond_to_env
39
+ assert_equal ENV['ENV'], StatsD::Instrument::Environment.environment
40
+ end
41
+
42
+ def test_uses_rails_env_when_rails_is_available
43
+ Rails.stubs(:env).returns('production')
44
+ assert_equal 'production', StatsD::Instrument::Environment.environment
45
+ end
46
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ class HelpersTest < Minitest::Test
4
+ def setup
5
+ test_class = Class.new(Minitest::Test)
6
+ test_class.send(:include, StatsD::Instrument::Helpers)
7
+ @test_case = test_class.new('fake')
8
+ end
9
+
10
+ def test_capture_metrics_inside_block_only
11
+ StatsD.increment('counter')
12
+ metrics = @test_case.capture_statsd_calls do
13
+ StatsD.increment('counter')
14
+ StatsD.gauge('gauge', 12)
15
+ end
16
+ StatsD.gauge('gauge', 15)
17
+
18
+ assert_equal 2, metrics.length
19
+ assert_equal 'counter', metrics[0].name
20
+ assert_equal 'gauge', metrics[1].name
21
+ assert_equal 12, metrics[1].value
22
+ end
23
+ end
24
+
@@ -0,0 +1,20 @@
1
+ require 'test_helper'
2
+
3
+ class IntegrationTest < Minitest::Test
4
+
5
+ def setup
6
+ @old_backend, StatsD.backend = StatsD.backend, StatsD::Instrument::Backends::UDPBackend.new("localhost:31798")
7
+ end
8
+
9
+ def teardown
10
+ StatsD.backend = @old_backend
11
+ end
12
+
13
+ def test_live_local_udp_socket
14
+ server = UDPSocket.new
15
+ server.bind('localhost', 31798)
16
+
17
+ StatsD.increment('counter')
18
+ assert_equal "counter:1|c", server.recvfrom(100).first
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require 'test_helper'
2
+
3
+ class LoggerBackendTest < Minitest::Test
4
+ def setup
5
+ logger = Logger.new(@io = StringIO.new)
6
+ logger.formatter = lambda { |_,_,_, msg| "#{msg}\n" }
7
+ @backend = StatsD::Instrument::Backends::LoggerBackend.new(logger)
8
+ @metric1 = StatsD::Instrument::Metric::new(type: :c, name: 'mock.counter', tags: { a: 'b', c: 'd'})
9
+ @metric2 = StatsD::Instrument::Metric::new(type: :ms, name: 'mock.measure', value: 123, sample_rate: 0.3)
10
+ end
11
+
12
+ def test_logs_metrics
13
+ @backend.collect_metric(@metric1)
14
+ assert_equal @io.string, "[StatsD] increment mock.counter:1 #a:b #c:d\n"
15
+ @io.string = ""
16
+
17
+ @backend.collect_metric(@metric2)
18
+ assert_equal @io.string, "[StatsD] measure mock.measure:123 @0.3\n"
19
+ end
20
+ end
@@ -0,0 +1,102 @@
1
+ require 'test_helper'
2
+ require 'statsd/instrument/matchers'
3
+
4
+ class MatchersTest < Minitest::Test
5
+ def test_statsd_increment_matched
6
+ assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', {}).matches? lambda { StatsD.increment('counter') }
7
+ end
8
+
9
+ def test_statsd_increment_not_matched
10
+ refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', {}).matches? lambda { StatsD.increment('not_counter') }
11
+ end
12
+
13
+ def test_statsd_increment_compound_matched
14
+ matcher_1 = StatsD::Instrument::Matchers::Increment.new(:c, 'counter', tags: ['a'])
15
+ matcher_2 = StatsD::Instrument::Matchers::Increment.new(:c, 'counter', tags: ['b'])
16
+
17
+ assert RSpec::Matchers::BuiltIn::Compound::And.new(matcher_1, matcher_2).matches? lambda {
18
+ StatsD.increment('counter', tags: ['a'])
19
+ StatsD.increment('counter', tags: ['b'])
20
+ }
21
+ end
22
+
23
+ def test_statsd_increment_compound_not_matched
24
+ matcher_1 = StatsD::Instrument::Matchers::Increment.new(:c, 'counter', tags: ['a'])
25
+ matcher_2 = StatsD::Instrument::Matchers::Increment.new(:c, 'counter', tags: ['b'])
26
+
27
+ refute RSpec::Matchers::BuiltIn::Compound::And.new(matcher_1, matcher_2).matches? lambda {
28
+ StatsD.increment('counter', tags: ['a'])
29
+ StatsD.increment('counter', tags: ['a'])
30
+ }
31
+ end
32
+
33
+ def test_statsd_increment_with_times_matched
34
+ assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 1).matches? lambda { StatsD.increment('counter') }
35
+ end
36
+
37
+ def test_statsd_increment_with_times_not_matched
38
+ refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 2).matches? lambda { StatsD.increment('counter', times: 3) }
39
+ end
40
+
41
+ def test_statsd_increment_with_sample_rate_matched
42
+ assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: 0.5).matches? lambda { StatsD.increment('counter', sample_rate: 0.5) }
43
+ end
44
+
45
+ def test_statsd_increment_with_sample_rate_not_matched
46
+ refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: 0.5).matches? lambda { StatsD.increment('counter', sample_rate: 0.7) }
47
+ end
48
+
49
+ def test_statsd_increment_with_value_matched
50
+ assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 1).matches? lambda { StatsD.increment('counter') }
51
+ end
52
+
53
+ def test_statsd_increment_with_value_matched_when_multiple_metrics
54
+ assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 1).matches? lambda {
55
+ StatsD.increment('counter', value: 2)
56
+ StatsD.increment('counter', value: 1)
57
+ }
58
+ end
59
+
60
+ def test_statsd_increment_with_value_not_matched_when_multiple_metrics
61
+ refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 1).matches? lambda {
62
+ StatsD.increment('counter', value: 2)
63
+ StatsD.increment('counter', value: 3)
64
+ }
65
+ end
66
+
67
+ def test_statsd_increment_with_value_not_matched
68
+ refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 3).matches? lambda { StatsD.increment('counter') }
69
+ end
70
+
71
+ def test_statsd_increment_with_tags_matched
72
+ assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', tags: ['a', 'b']).matches? lambda { StatsD.increment('counter', tags: ['a', 'b']) }
73
+ end
74
+
75
+ def test_statsd_increment_with_tags_not_matched
76
+ refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', tags: ['a', 'b']).matches? lambda { StatsD.increment('counter', tags: ['c']) }
77
+ end
78
+
79
+ def test_statsd_increment_with_times_and_value_matched
80
+ assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 2, value: 1).matches? lambda {
81
+ StatsD.increment('counter', value: 1)
82
+ StatsD.increment('counter', value: 1)
83
+ }
84
+ end
85
+
86
+ def test_statsd_increment_with_times_and_value_not_matched
87
+ refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 2, value: 1).matches? lambda {
88
+ StatsD.increment('counter', value: 1)
89
+ StatsD.increment('counter', value: 2)
90
+ }
91
+ end
92
+
93
+ def test_statsd_increment_with_sample_rate_and_argument_matcher_matched
94
+ between_matcher = RSpec::Matchers::BuiltIn::BeBetween.new(0.4, 0.6).inclusive
95
+ assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: between_matcher).matches? lambda { StatsD.increment('counter', sample_rate: 0.5) }
96
+ end
97
+
98
+ def test_statsd_increment_with_sample_rate_and_argument_matcher_not_matched
99
+ between_matcher = RSpec::Matchers::BuiltIn::BeBetween.new(0.4, 0.6).inclusive
100
+ refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: between_matcher).matches? lambda { StatsD.increment('counter', sample_rate: 0.7) }
101
+ end
102
+ end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ class MetricTest < Minitest::Test
4
+
5
+ def test_required_arguments
6
+ assert_raises(ArgumentError) { StatsD::Instrument::Metric.new(type: :c) }
7
+ assert_raises(ArgumentError) { StatsD::Instrument::Metric.new(name: 'test') }
8
+ assert_raises(ArgumentError) { StatsD::Instrument::Metric.new(type: :ms, name: 'test') }
9
+ end
10
+
11
+ def test_default_values
12
+ m = StatsD::Instrument::Metric.new(type: :c, name: 'counter')
13
+ assert_equal 1, m.value
14
+ assert_equal StatsD.default_sample_rate, m.sample_rate
15
+ assert m.tags.nil?
16
+ end
17
+
18
+ def test_name_prefix
19
+ StatsD.stubs(:prefix).returns('prefix')
20
+ m = StatsD::Instrument::Metric.new(type: :c, name: 'counter')
21
+ assert_equal 'prefix.counter', m.name
22
+
23
+ m = StatsD::Instrument::Metric.new(type: :c, name: 'counter', no_prefix: true)
24
+ assert_equal 'counter', m.name
25
+ end
26
+
27
+ def test_bad_metric_name
28
+ m = StatsD::Instrument::Metric.new(type: :c, name: 'my:metric', no_prefix: true)
29
+ assert_equal 'my_metric', m.name
30
+ m = StatsD::Instrument::Metric.new(type: :c, name: 'my|metric', no_prefix: true)
31
+ assert_equal 'my_metric', m.name
32
+ m = StatsD::Instrument::Metric.new(type: :c, name: 'my@metric', no_prefix: true)
33
+ assert_equal 'my_metric', m.name
34
+ end
35
+
36
+ def test_handle_bad_tags
37
+ assert_equal ['ignored'], StatsD::Instrument::Metric.normalize_tags(['igno|red'])
38
+ assert_equal ['lol::class:omg::lol'], StatsD::Instrument::Metric.normalize_tags({ :"lol::class" => "omg::lol" })
39
+ end
40
+
41
+ def test_rewrite_tags_provided_as_hash
42
+ assert_equal ['tag:value'], StatsD::Instrument::Metric.normalize_tags(:tag => 'value')
43
+ assert_equal ['tag:value', 'tag2:value2'], StatsD::Instrument::Metric.normalize_tags(:tag => 'value', :tag2 => 'value2')
44
+ end
45
+ end