qubole-statsd-instrument 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
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