statsd-instrument 2.8.0 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +16 -7
  3. data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +6 -6
  4. data/CHANGELOG.md +28 -6
  5. data/CONTRIBUTING.md +3 -3
  6. data/README.md +11 -11
  7. data/lib/statsd/instrument.rb +33 -18
  8. data/lib/statsd/instrument/assertions.rb +7 -7
  9. data/lib/statsd/instrument/backend.rb +1 -1
  10. data/lib/statsd/instrument/client.rb +11 -10
  11. data/lib/statsd/instrument/datagram.rb +1 -2
  12. data/lib/statsd/instrument/datagram_builder.rb +1 -1
  13. data/lib/statsd/instrument/dogstatsd_datagram.rb +88 -0
  14. data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +4 -0
  15. data/lib/statsd/instrument/expectation.rb +37 -1
  16. data/lib/statsd/instrument/legacy_client.rb +5 -5
  17. data/lib/statsd/instrument/metric.rb +2 -2
  18. data/lib/statsd/instrument/rubocop/metaprogramming_positional_arguments.rb +1 -1
  19. data/lib/statsd/instrument/rubocop/positional_arguments.rb +6 -6
  20. data/lib/statsd/instrument/rubocop/singleton_configuration.rb +1 -1
  21. data/lib/statsd/instrument/strict.rb +37 -17
  22. data/lib/statsd/instrument/version.rb +1 -1
  23. data/test/assertions_on_legacy_client_test.rb +1 -1
  24. data/test/assertions_test.rb +26 -1
  25. data/test/capture_sink_test.rb +1 -1
  26. data/test/client_test.rb +5 -5
  27. data/test/compatibility/dogstatsd_datagram_compatibility_test.rb +1 -1
  28. data/test/datagram_builder_test.rb +1 -1
  29. data/test/deprecations_test.rb +8 -1
  30. data/test/dogstatsd_datagram_builder_test.rb +41 -4
  31. data/test/environment_test.rb +1 -1
  32. data/test/integration_test.rb +1 -1
  33. data/test/log_sink_test.rb +1 -1
  34. data/test/null_sink_test.rb +1 -1
  35. data/test/rubocop/metric_prefix_argument_test.rb +1 -1
  36. data/test/rubocop/positional_arguments_test.rb +3 -3
  37. data/test/statsd_instrumentation_test.rb +11 -0
  38. data/test/statsd_test.rb +2 -9
  39. data/test/udp_backend_test.rb +3 -0
  40. data/test/udp_sink_test.rb +1 -1
  41. metadata +3 -2
@@ -333,7 +333,7 @@ class AssertionsOnLegacyClientTest < Minitest::Test
333
333
  end
334
334
 
335
335
  def test_assertion_block_with_other_assertion_failures
336
- # If another assertion failure happens inside the block, that failrue should have priority
336
+ # If another assertion failure happens inside the block, that failure should have priority
337
337
  assertion = assert_raises(Minitest::Assertion) do
338
338
  @test_case.assert_statsd_increment('counter') do
339
339
  @test_case.flunk('other assertion failure')
@@ -33,6 +33,31 @@ class AssertionsTest < Minitest::Test
33
33
  end
34
34
  assert_equal assertion.message, "No StatsD calls for metric counter expected."
35
35
 
36
+ @test_case.assert_no_statsd_calls('counter1', 'counter2') do
37
+ # noop
38
+ end
39
+
40
+ @test_case.assert_no_statsd_calls('counter1', 'counter2') do
41
+ StatsD.increment('counter')
42
+ end
43
+
44
+ assertion = assert_raises(Minitest::Assertion) do
45
+ @test_case.assert_no_statsd_calls('counter1', 'counter2') do
46
+ StatsD.increment('counter0')
47
+ StatsD.increment('counter1')
48
+ StatsD.increment('counter2')
49
+ StatsD.increment('counter3')
50
+ end
51
+ end
52
+ assert_equal assertion.message, "No StatsD calls for metric counter1, counter2 expected."
53
+
54
+ assertion = assert_raises(Minitest::Assertion) do
55
+ @test_case.assert_no_statsd_calls('counter0', 'counter1', 'counter2') do
56
+ StatsD.increment('counter1')
57
+ end
58
+ end
59
+ assert_equal assertion.message, "No StatsD calls for metric counter1 expected."
60
+
36
61
  assertion = assert_raises(Minitest::Assertion) do
37
62
  @test_case.assert_no_statsd_calls do
38
63
  StatsD.increment('other')
@@ -363,7 +388,7 @@ class AssertionsTest < Minitest::Test
363
388
  end
364
389
 
365
390
  def test_assertion_block_with_other_assertion_failures
366
- # If another assertion failure happens inside the block, that failrue should have priority
391
+ # If another assertion failure happens inside the block, that failure should have priority
367
392
  assertion = assert_raises(Minitest::Assertion) do
368
393
  @test_case.assert_statsd_increment('counter') do
369
394
  @test_case.flunk('other assertion failure')
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'test_helper'
4
4
 
5
- class CaptureSinktest < Minitest::Test
5
+ class CaptureSinkTest < Minitest::Test
6
6
  def test_capture_sink_captures_datagram_instances
7
7
  capture_sink = StatsD::Instrument::CaptureSink.new(parent: [])
8
8
  capture_sink << 'foo:1|c'
@@ -75,11 +75,11 @@ class ClientTest < Minitest::Test
75
75
  assert_equal ['baz'], inner_datagrams.map(&:name)
76
76
  end
77
77
 
78
- def test_metric_methods_return_nil
79
- assert_nil @client.increment('foo')
80
- assert_nil @client.measure('bar', 122.54)
81
- assert_nil @client.set('baz', 123)
82
- assert_nil @client.gauge('baz', 12.3)
78
+ def test_metric_methods_return_truish_void
79
+ assert @client.increment('foo')
80
+ assert @client.measure('bar', 122.54)
81
+ assert @client.set('baz', 123)
82
+ assert @client.gauge('baz', 12.3)
83
83
  end
84
84
 
85
85
  def test_increment_with_default_value
@@ -101,7 +101,7 @@ module Compatibility
101
101
  assert_equal_datagrams { |client| client.event('foo', "bar\nbaz") }
102
102
  assert_equal_datagrams { |client| client.event('foo', "bar\nbaz", no_prefix: true) }
103
103
  assert_equal_datagrams do |client|
104
- client.event('Something happend', "And it's not good", timestamp: Time.parse('2019-09-09T04:22:17Z'),
104
+ client.event('Something happened', "And it's not good", timestamp: Time.parse('2019-09-09T04:22:17Z'),
105
105
  hostname: 'localhost', tags: ['foo'], alert_type: 'warning', priority: 'low',
106
106
  aggregation_key: 'foo', source_type_name: 'logs')
107
107
  end
@@ -18,7 +18,7 @@ class DatagramBuilderTest < Minitest::Test
18
18
  assert_equal ['ign#ored'], @datagram_builder.send(:normalize_tags, ['ign#o|re,d'])
19
19
  # Note: how this is interpreted by the backend is undefined.
20
20
  # We rely on the user to not do stuff like this if they don't want to be surprised.
21
- # We do not want to take the performance hit of normaling this.
21
+ # We do not want to take the performance hit of normalizing this.
22
22
  assert_equal ['lol::class:omg::lol'], @datagram_builder.send(:normalize_tags, "lol::class" => "omg::lol")
23
23
  end
24
24
 
@@ -74,7 +74,7 @@ class DeprecationsTest < Minitest::Test
74
74
  # rubocop:enable StatsD/MetricValueKeywordArgument
75
75
 
76
76
  # rubocop:disable StatsD/MetricReturnValue
77
- def test__deprecated__statsd_increment_retuns_metric_instance
77
+ def test__deprecated__statsd_increment_returns_metric_instance
78
78
  metric = StatsD.increment('key')
79
79
  assert_kind_of StatsD::Instrument::Metric, metric
80
80
  assert_equal 'key', metric.name
@@ -122,6 +122,13 @@ class DeprecationsTest < Minitest::Test
122
122
  end
123
123
  # rubocop:enable StatsD/MetricPrefixArgument
124
124
 
125
+ def test__deprecated__statsd_key_value
126
+ metric = capture_statsd_call { StatsD.key_value('values.foobar', 42) }
127
+ assert_equal :kv, metric.type
128
+ assert_equal 'values.foobar', metric.name
129
+ assert_equal 42, metric.value
130
+ end
131
+
125
132
  protected
126
133
 
127
134
  def capture_statsd_call(&block)
@@ -11,20 +11,57 @@ class DogStatsDDatagramBuilderTest < Minitest::Test
11
11
  assert_raises(NotImplementedError) { @datagram_builder.kv('foo', 10, nil, nil) }
12
12
  end
13
13
 
14
- def test_service_check
15
- assert_equal '_sc|service|0', @datagram_builder._sc('service', :ok)
14
+ def test_simple_service_check
15
+ datagram = @datagram_builder._sc('service', :ok)
16
+ assert_equal '_sc|service|0', datagram
17
+ parsed_datagram = StatsD::Instrument::DogStatsDDatagramBuilder.datagram_class.new(datagram)
18
+ assert_equal :_sc, parsed_datagram.type
19
+ assert_equal 'service', parsed_datagram.name
20
+ assert_equal 0, parsed_datagram.value
21
+ end
22
+
23
+ def test_complex_service_check
16
24
  datagram = @datagram_builder._sc('service', :warning, timestamp: Time.parse('2019-09-30T04:22:12Z'),
17
25
  hostname: 'localhost', tags: { foo: 'bar|baz' }, message: 'blah')
18
26
  assert_equal "_sc|service|1|h:localhost|d:1569817332|#foo:barbaz|m:blah", datagram
27
+
28
+ parsed_datagram = StatsD::Instrument::DogStatsDDatagramBuilder.datagram_class.new(datagram)
29
+ assert_equal :_sc, parsed_datagram.type
30
+ assert_equal 'service', parsed_datagram.name
31
+ assert_equal 1, parsed_datagram.value
32
+ assert_equal 'localhost', parsed_datagram.hostname
33
+ assert_equal Time.parse('2019-09-30T04:22:12Z'), parsed_datagram.timestamp
34
+ assert_equal ["foo:barbaz"], parsed_datagram.tags
35
+ assert_equal 'blah', parsed_datagram.message
19
36
  end
20
37
 
21
- def test_event
22
- assert_equal '_e{5,5}:hello|world', @datagram_builder._e('hello', "world")
38
+ def test_simple_event
39
+ datagram = @datagram_builder._e('hello', "world")
40
+ assert_equal '_e{5,5}:hello|world', datagram
23
41
 
42
+ parsed_datagram = StatsD::Instrument::DogStatsDDatagramBuilder.datagram_class.new(datagram)
43
+ assert_equal :_e, parsed_datagram.type
44
+ assert_equal 'hello', parsed_datagram.name
45
+ assert_equal 'world', parsed_datagram.value
46
+ end
47
+
48
+ def test_complex_event
24
49
  datagram = @datagram_builder._e("testing", "with\nnewline", timestamp: Time.parse('2019-09-30T04:22:12Z'),
25
50
  hostname: 'localhost', aggregation_key: 'my-key', priority: 'low', source_type_name: 'source',
26
51
  alert_type: 'success', tags: { foo: 'bar|baz' })
27
52
  assert_equal '_e{7,13}:testing|with\\nnewline|h:localhost|d:1569817332|k:my-key|' \
28
53
  'p:low|s:source|t:success|#foo:barbaz', datagram
54
+
55
+ parsed_datagram = StatsD::Instrument::DogStatsDDatagramBuilder.datagram_class.new(datagram)
56
+ assert_equal :_e, parsed_datagram.type
57
+ assert_equal 'testing', parsed_datagram.name
58
+ assert_equal "with\nnewline", parsed_datagram.value
59
+ assert_equal 'localhost', parsed_datagram.hostname
60
+ assert_equal Time.parse('2019-09-30T04:22:12Z'), parsed_datagram.timestamp
61
+ assert_equal ["foo:barbaz"], parsed_datagram.tags
62
+ assert_equal "my-key", parsed_datagram.aggregation_key
63
+ assert_equal "low", parsed_datagram.priority
64
+ assert_equal "source", parsed_datagram.source_type_name
65
+ assert_equal "success", parsed_datagram.alert_type
29
66
  end
30
67
  end
@@ -67,7 +67,7 @@ class EnvironmentTest < Minitest::Test
67
67
  assert_kind_of StatsD::Instrument::LegacyClient, env.client
68
68
  end
69
69
 
70
- def test_client_returns_new_client_if_envcironment_asks_for_it
70
+ def test_client_returns_new_client_if_environment_asks_for_it
71
71
  env = StatsD::Instrument::Environment.new('STATSD_USE_NEW_CLIENT' => '1')
72
72
  assert_kind_of StatsD::Instrument::Client, env.client
73
73
  end
@@ -35,7 +35,7 @@ class IntegrationTest < Minitest::Test
35
35
  Process.kill('TERM', pid)
36
36
  _, exit_status = Process.waitpid2(pid)
37
37
 
38
- assert_equal 0, exit_status, "The foked process did not exit cleanly"
38
+ assert_equal 0, exit_status, "The forked process did not exit cleanly"
39
39
  assert_equal "exiting:1|c", @server.recvfrom_nonblock(100).first
40
40
 
41
41
  rescue NotImplementedError
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'test_helper'
4
4
 
5
- class LogSinktest < Minitest::Test
5
+ class LogSinkTest < Minitest::Test
6
6
  def test_log_sink
7
7
  logger = Logger.new(log = StringIO.new)
8
8
  logger.formatter = proc do |severity, _datetime, _progname, msg|
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'test_helper'
4
4
 
5
- class NullSinktest < Minitest::Test
5
+ class NullSinkTest < Minitest::Test
6
6
  def test_null_sink
7
7
  null_sink = StatsD::Instrument::NullSink.new
8
8
  null_sink << 'foo:1|c' << 'bar:1|c'
@@ -19,7 +19,7 @@ module Rubocop
19
19
 
20
20
  def test_ok_for_metaprogramming_method_without_prefix_argument
21
21
  assert_no_offenses("statsd_measure(:method, 'metric_name')")
22
- assert_no_offenses("statsd_count(:method, 'metric_name', sample_rate: 1, no_pefix: true)")
22
+ assert_no_offenses("statsd_count(:method, 'metric_name', sample_rate: 1, no_prefix: true)")
23
23
  assert_no_offenses("statsd_count_if(:method, 'metric_name', sample_rate: 1) {}")
24
24
  end
25
25
 
@@ -21,7 +21,7 @@ module Rubocop
21
21
  assert_no_offenses("StatsD.gauge('foo', 2, **kwargs)")
22
22
  end
23
23
 
24
- def test_no_offense_for_now_when_using_value_keyword_argumenr
24
+ def test_no_offense_for_now_when_using_value_keyword_argument
25
25
  assert_no_offenses("StatsD.increment 'foo', value: 3")
26
26
  assert_no_offenses("StatsD.increment 'foo', value: 3, sample_rate: 0.5")
27
27
  assert_no_offenses("StatsD.increment('foo', value: 3, tags: ['foo']) { foo }")
@@ -29,7 +29,7 @@ module Rubocop
29
29
 
30
30
  def test_offense_when_using_method_or_constant
31
31
  assert_offense("StatsD.gauge('foo', 2, SAMPLE_RATE_CONSTANT)")
32
- assert_offense("StatsD.gauge('foo', 2, method_ruturning_a_hash)")
32
+ assert_offense("StatsD.gauge('foo', 2, method_returning_a_hash)")
33
33
  end
34
34
 
35
35
  def test_offense_when_using_local_variable
@@ -46,7 +46,7 @@ module Rubocop
46
46
 
47
47
  def test_no_autocorrect_when_using_method_or_constant
48
48
  assert_no_autocorrect("StatsD.gauge('foo', 2, SAMPLE_RATE_CONSTANT)")
49
- assert_no_autocorrect("StatsD.gauge('foo', 2, method_ruturning_a_hash)")
49
+ assert_no_autocorrect("StatsD.gauge('foo', 2, method_returning_a_hash)")
50
50
  end
51
51
 
52
52
  def test_autocorrect_only_sample_rate
@@ -443,6 +443,17 @@ class StatsDInstrumentationTest < Minitest::Test
443
443
  StatsD.singleton_client = old_client
444
444
  end
445
445
 
446
+ def test_statsd_count_with_injected_client
447
+ client = StatsD::Instrument::Client.new(prefix: 'prefix')
448
+
449
+ ActiveMerchant::Gateway.statsd_count(:ssl_post, 'ActiveMerchant.Gateway.ssl_post', client: client)
450
+ assert_statsd_increment('prefix.ActiveMerchant.Gateway.ssl_post', client: client) do
451
+ ActiveMerchant::Gateway.new.purchase(true)
452
+ end
453
+ ensure
454
+ ActiveMerchant::Gateway.statsd_remove_count :ssl_post, 'ActiveMerchant.Gateway.ssl_post'
455
+ end
456
+
446
457
  private
447
458
 
448
459
  def assert_scope(klass, method, expected_scope)
@@ -189,19 +189,12 @@ class StatsDTest < Minitest::Test
189
189
  assert_nil return_value
190
190
  end
191
191
 
192
- def test_statsd_key_value
193
- metric = capture_statsd_call { StatsD.key_value('values.foobar', 42) }
194
- assert_equal :kv, metric.type
195
- assert_equal 'values.foobar', metric.name
196
- assert_equal 42, metric.value
197
- end
198
-
199
- def test_statsd_durarion_returns_time_in_seconds
192
+ def test_statsd_duration_returns_time_in_seconds
200
193
  duration = StatsD::Instrument.duration {}
201
194
  assert_kind_of Float, duration
202
195
  end
203
196
 
204
- def test_statsd_durarion_does_not_swallow_exceptions
197
+ def test_statsd_duration_does_not_swallow_exceptions
205
198
  assert_raises(RuntimeError) do
206
199
  StatsD::Instrument.duration { raise "Foo" }
207
200
  end
@@ -160,6 +160,7 @@ class UDPBackendTest < Minitest::Test
160
160
  end
161
161
 
162
162
  def test_supports_key_value_syntax_on_statsite
163
+ skip if StatsD::Instrument.strict_mode_enabled?
163
164
  @backend.implementation = :statsite
164
165
  @backend.expects(:write_packet).with("fooy:42|kv\n")
165
166
  StatsD.key_value('fooy', 42)
@@ -173,6 +174,7 @@ class UDPBackendTest < Minitest::Test
173
174
 
174
175
  # rubocop:disable StatsD/PositionalArguments
175
176
  def test_supports_key_value_with_timestamp_on_statsite
177
+ skip if StatsD::Instrument.strict_mode_enabled?
176
178
  @backend.implementation = :statsite
177
179
  @backend.expects(:write_packet).with("fooy:42|kv|@123456\n")
178
180
  StatsD.key_value('fooy', 42, 123456)
@@ -180,6 +182,7 @@ class UDPBackendTest < Minitest::Test
180
182
  # rubocop:enable StatsD/PositionalArguments
181
183
 
182
184
  def test_warn_when_using_key_value_and_not_on_statsite
185
+ skip if StatsD::Instrument.strict_mode_enabled?
183
186
  @backend.implementation = :other
184
187
  @backend.expects(:write_packet).never
185
188
  @logger.expects(:warn)
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'test_helper'
4
4
 
5
- class UDPSinktest < Minitest::Test
5
+ class UDPSinkTest < Minitest::Test
6
6
  def setup
7
7
  @receiver = UDPSocket.new
8
8
  @receiver.bind('localhost', 0)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statsd-instrument
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.0
4
+ version: 2.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jesse Storimer
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-10-21 00:00:00.000000000 Z
13
+ date: 2019-10-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -148,6 +148,7 @@ files:
148
148
  - lib/statsd/instrument/client.rb
149
149
  - lib/statsd/instrument/datagram.rb
150
150
  - lib/statsd/instrument/datagram_builder.rb
151
+ - lib/statsd/instrument/dogstatsd_datagram.rb
151
152
  - lib/statsd/instrument/dogstatsd_datagram_builder.rb
152
153
  - lib/statsd/instrument/environment.rb
153
154
  - lib/statsd/instrument/expectation.rb