statsd-instrument 2.3.2 → 2.6.0

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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/workflows/benchmark.yml +32 -0
  4. data/.github/workflows/ci.yml +47 -0
  5. data/.gitignore +1 -0
  6. data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +1027 -0
  7. data/.rubocop.yml +50 -0
  8. data/.yardopts +5 -0
  9. data/CHANGELOG.md +288 -2
  10. data/CONTRIBUTING.md +28 -6
  11. data/Gemfile +5 -0
  12. data/README.md +54 -46
  13. data/Rakefile +4 -2
  14. data/benchmark/README.md +29 -0
  15. data/benchmark/datagram-client +41 -0
  16. data/benchmark/send-metrics-to-dev-null-log +47 -0
  17. data/benchmark/send-metrics-to-local-udp-receiver +57 -0
  18. data/lib/statsd/instrument/assertions.rb +179 -30
  19. data/lib/statsd/instrument/backend.rb +3 -2
  20. data/lib/statsd/instrument/backends/capture_backend.rb +4 -1
  21. data/lib/statsd/instrument/backends/logger_backend.rb +3 -3
  22. data/lib/statsd/instrument/backends/null_backend.rb +2 -0
  23. data/lib/statsd/instrument/backends/udp_backend.rb +39 -45
  24. data/lib/statsd/instrument/capture_sink.rb +27 -0
  25. data/lib/statsd/instrument/client.rb +313 -0
  26. data/lib/statsd/instrument/datagram.rb +75 -0
  27. data/lib/statsd/instrument/datagram_builder.rb +101 -0
  28. data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +71 -0
  29. data/lib/statsd/instrument/environment.rb +108 -29
  30. data/lib/statsd/instrument/helpers.rb +16 -8
  31. data/lib/statsd/instrument/log_sink.rb +24 -0
  32. data/lib/statsd/instrument/matchers.rb +14 -11
  33. data/lib/statsd/instrument/metric.rb +72 -45
  34. data/lib/statsd/instrument/metric_expectation.rb +32 -18
  35. data/lib/statsd/instrument/null_sink.rb +13 -0
  36. data/lib/statsd/instrument/railtie.rb +2 -1
  37. data/lib/statsd/instrument/rubocop/measure_as_dist_argument.rb +39 -0
  38. data/lib/statsd/instrument/rubocop/metaprogramming_positional_arguments.rb +42 -0
  39. data/lib/statsd/instrument/rubocop/metric_prefix_argument.rb +37 -0
  40. data/lib/statsd/instrument/rubocop/metric_return_value.rb +32 -0
  41. data/lib/statsd/instrument/rubocop/metric_value_keyword_argument.rb +36 -0
  42. data/lib/statsd/instrument/rubocop/positional_arguments.rb +99 -0
  43. data/lib/statsd/instrument/rubocop/splat_arguments.rb +31 -0
  44. data/lib/statsd/instrument/rubocop.rb +64 -0
  45. data/lib/statsd/instrument/statsd_datagram_builder.rb +14 -0
  46. data/lib/statsd/instrument/strict.rb +235 -0
  47. data/lib/statsd/instrument/udp_sink.rb +62 -0
  48. data/lib/statsd/instrument/version.rb +3 -1
  49. data/lib/statsd/instrument.rb +340 -163
  50. data/lib/statsd-instrument.rb +2 -0
  51. data/statsd-instrument.gemspec +13 -10
  52. data/test/assertions_test.rb +167 -156
  53. data/test/benchmark/clock_gettime.rb +27 -0
  54. data/test/benchmark/default_tags.rb +47 -0
  55. data/test/benchmark/metrics.rb +9 -8
  56. data/test/benchmark/tags.rb +5 -3
  57. data/test/capture_backend_test.rb +4 -2
  58. data/test/capture_sink_test.rb +44 -0
  59. data/test/client_test.rb +164 -0
  60. data/test/compatibility/dogstatsd_datagram_compatibility_test.rb +162 -0
  61. data/test/datagram_builder_test.rb +120 -0
  62. data/test/deprecations_test.rb +132 -0
  63. data/test/dogstatsd_datagram_builder_test.rb +32 -0
  64. data/test/environment_test.rb +75 -8
  65. data/test/helpers/rubocop_helper.rb +47 -0
  66. data/test/helpers_test.rb +2 -1
  67. data/test/integration_test.rb +31 -7
  68. data/test/log_sink_test.rb +37 -0
  69. data/test/logger_backend_test.rb +10 -8
  70. data/test/matchers_test.rb +42 -28
  71. data/test/metric_test.rb +18 -22
  72. data/test/null_sink_test.rb +13 -0
  73. data/test/rubocop/measure_as_dist_argument_test.rb +44 -0
  74. data/test/rubocop/metaprogramming_positional_arguments_test.rb +58 -0
  75. data/test/rubocop/metric_prefix_argument_test.rb +38 -0
  76. data/test/rubocop/metric_return_value_test.rb +78 -0
  77. data/test/rubocop/metric_value_keyword_argument_test.rb +39 -0
  78. data/test/rubocop/positional_arguments_test.rb +110 -0
  79. data/test/rubocop/splat_arguments_test.rb +27 -0
  80. data/test/statsd_datagram_builder_test.rb +22 -0
  81. data/test/statsd_instrumentation_test.rb +109 -100
  82. data/test/statsd_test.rb +113 -79
  83. data/test/test_helper.rb +12 -1
  84. data/test/udp_backend_test.rb +38 -36
  85. data/test/udp_sink_test.rb +85 -0
  86. metadata +85 -5
  87. data/.travis.yml +0 -12
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'statsd/instrument'
@@ -1,21 +1,23 @@
1
+ # frozen-string-literal: true
1
2
  # encoding: utf-8
3
+
2
4
  lib = File.expand_path('../lib', __FILE__)
3
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
6
  require 'statsd/instrument/version'
5
7
 
6
8
  Gem::Specification.new do |spec|
7
- spec.name = "statsd-instrument"
8
- spec.version = StatsD::Instrument::VERSION
9
- spec.authors = ["Jesse Storimer", "Tobias Lutke", "Willem van Bergen"]
10
- spec.email = ["jesse@shopify.com"]
11
- spec.homepage = "https://github.com/Shopify/statsd-instrument"
12
- spec.summary = %q{A StatsD client for Ruby apps}
9
+ spec.name = "statsd-instrument"
10
+ spec.version = StatsD::Instrument::VERSION
11
+ spec.authors = ["Jesse Storimer", "Tobias Lutke", "Willem van Bergen"]
12
+ spec.email = ["jesse@shopify.com"]
13
+ spec.homepage = "https://github.com/Shopify/statsd-instrument"
14
+ spec.summary = %q{A StatsD client for Ruby apps}
13
15
  spec.description = %q{A StatsD client for Ruby apps. Provides metaprogramming methods to inject StatsD instrumentation into your code.}
14
- spec.license = "MIT"
16
+ spec.license = "MIT"
15
17
 
16
- spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
21
  spec.require_paths = ["lib"]
20
22
 
21
23
  spec.add_development_dependency 'rake'
@@ -23,5 +25,6 @@ Gem::Specification.new do |spec|
23
25
  spec.add_development_dependency 'rspec'
24
26
  spec.add_development_dependency 'mocha'
25
27
  spec.add_development_dependency 'yard'
28
+ spec.add_development_dependency 'rubocop'
26
29
  spec.add_development_dependency 'benchmark-ips'
27
30
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class AssertionsTest < Minitest::Test
@@ -8,141 +10,120 @@ class AssertionsTest < Minitest::Test
8
10
  end
9
11
 
10
12
  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
13
+ @test_case.assert_no_statsd_calls('counter') do
14
+ # noop
15
15
  end
16
16
 
17
- assert_no_assertion_triggered do
18
- @test_case.assert_no_statsd_calls('counter') do
19
- StatsD.increment('other')
20
- end
17
+ @test_case.assert_no_statsd_calls('counter') do
18
+ StatsD.increment('other')
21
19
  end
22
20
 
23
- assert_assertion_triggered("No StatsD calls for metric counter expected.") do
21
+ assertion = assert_raises(Minitest::Assertion) do
24
22
  @test_case.assert_no_statsd_calls('counter') do
25
23
  StatsD.increment('counter')
26
24
  end
27
25
  end
26
+ assert_equal assertion.message, "No StatsD calls for metric counter expected."
28
27
 
29
- assert_assertion_triggered("No StatsD calls for metric other expected.") do
28
+ assertion = assert_raises(Minitest::Assertion) do
30
29
  @test_case.assert_no_statsd_calls do
31
30
  StatsD.increment('other')
32
31
  end
33
32
  end
33
+ assert_equal assertion.message, "No StatsD calls for metric other expected."
34
34
 
35
- assert_assertion_triggered("No StatsD calls for metric other, another expected.") do
35
+ assertion = assert_raises(Minitest::Assertion) do
36
36
  @test_case.assert_no_statsd_calls do
37
37
  StatsD.increment('other')
38
38
  StatsD.increment('another')
39
39
  end
40
40
  end
41
+ assert_equal assertion.message, "No StatsD calls for metric other, another expected."
41
42
  end
42
43
 
43
44
  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
45
+ @test_case.assert_statsd_increment('counter') do
46
+ StatsD.increment('counter')
48
47
  end
49
48
 
50
- assert_no_assertion_triggered do
51
- @test_case.assert_statsd_increment('counter') do
52
- StatsD.increment('counter')
53
- StatsD.increment('other')
54
- end
49
+ @test_case.assert_statsd_increment('counter') do
50
+ StatsD.increment('counter')
51
+ StatsD.increment('other')
55
52
  end
56
53
 
57
- assert_assertion_triggered do
54
+ assert_raises(Minitest::Assertion) do
58
55
  @test_case.assert_statsd_increment('counter') do
59
56
  StatsD.increment('other')
60
57
  end
61
58
  end
62
59
 
63
- assert_assertion_triggered do
60
+ assert_raises(Minitest::Assertion) do
64
61
  @test_case.assert_statsd_increment('counter') do
65
62
  StatsD.gauge('counter', 42)
66
63
  end
67
64
  end
68
65
 
69
- assert_assertion_triggered do
66
+ assert_raises(Minitest::Assertion) do
70
67
  @test_case.assert_statsd_increment('counter') do
71
68
  StatsD.increment('counter')
72
69
  StatsD.increment('counter')
73
70
  end
74
71
  end
75
72
 
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
73
+ @test_case.assert_statsd_increment('counter', times: 2) do
74
+ StatsD.increment('counter')
75
+ StatsD.increment('counter')
81
76
  end
82
77
 
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
78
+ @test_case.assert_statsd_increment('counter', times: 2, tags: ['foo:1']) do
79
+ StatsD.increment('counter', tags: { foo: 1 })
80
+ StatsD.increment('counter', tags: { foo: 1 })
88
81
  end
89
82
 
90
- assert_assertion_triggered do
83
+ assert_raises(Minitest::Assertion) do
91
84
  @test_case.assert_statsd_increment('counter', times: 2, tags: ['foo:1']) do
92
85
  StatsD.increment('counter', tags: { foo: 1 })
93
86
  StatsD.increment('counter', tags: { foo: 2 })
94
87
  end
95
88
  end
96
89
 
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
90
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a', 'b']) do
91
+ StatsD.increment('counter', sample_rate: 0.5, tags: ['a', 'b'])
101
92
  end
102
93
 
103
- assert_assertion_triggered do
94
+ assert_raises(Minitest::Assertion) do
104
95
  @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a', 'b'], ignore_tags: ['b']) do
105
96
  StatsD.increment('counter', sample_rate: 0.5, tags: ['a'])
106
97
  end
107
98
  end
108
99
 
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
100
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a'], ignore_tags: ['b']) do
101
+ StatsD.increment('counter', sample_rate: 0.5, tags: ['a', 'b'])
113
102
  end
114
103
 
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
104
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a'], ignore_tags: ['b']) do
105
+ StatsD.increment('counter', sample_rate: 0.5, tags: ['a'])
119
106
  end
120
107
 
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
108
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1 }, ignore_tags: { b: 2 }) do
109
+ StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2 })
125
110
  end
126
111
 
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
112
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1 }, ignore_tags: { b: 2 }) do
113
+ StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 3 })
131
114
  end
132
115
 
133
- assert_assertion_triggered do
116
+ assert_raises(Minitest::Assertion) do
134
117
  @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1, b: 3 }, ignore_tags: ['b']) do
135
118
  StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2 })
136
119
  end
137
120
  end
138
121
 
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
122
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1 }, ignore_tags: ['b']) do
123
+ StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2 })
143
124
  end
144
125
 
145
- assert_assertion_triggered do
126
+ assert_raises(Minitest::Assertion) do
146
127
  @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a', 'b']) do
147
128
  StatsD.increment('counter', sample_rate: 0.2, tags: ['c'])
148
129
  end
@@ -150,71 +131,70 @@ class AssertionsTest < Minitest::Test
150
131
  end
151
132
 
152
133
  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
134
+ @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1 }) do
135
+ StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2 })
157
136
  end
158
137
 
159
- assert_assertion_triggered do
138
+ assert_raises(Minitest::Assertion) do
160
139
  @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1, b: 3 }) do
161
140
  StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2, c: 4 })
162
141
  end
163
142
  end
164
143
  end
165
144
 
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 })
145
+ def test_tags_friendly_error
146
+ assertion = assert_raises(Minitest::Assertion) do
147
+ @test_case.assert_statsd_increment('counter', tags: { class: "AnotherJob" }) do
148
+ StatsD.increment('counter', tags: { class: "MyJob" })
173
149
  end
174
150
  end
175
151
 
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
152
+ assert_includes assertion.message, "Captured metrics with the same key"
153
+ assert_includes assertion.message, "MyJob"
154
+ end
155
+
156
+ def test_multiple_metrics_are_not_order_dependent
157
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:1'])
158
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
159
+ @test_case.assert_statsd_calls([foo_1_metric, foo_2_metric]) do
160
+ StatsD.increment('counter', tags: { foo: 1 })
161
+ StatsD.increment('counter', tags: { foo: 2 })
183
162
  end
184
163
 
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
164
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:1'])
165
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
166
+ @test_case.assert_statsd_calls([foo_2_metric, foo_1_metric]) do
167
+ StatsD.increment('counter', tags: { foo: 1 })
168
+ StatsD.increment('counter', tags: { foo: 2 })
193
169
  end
194
170
 
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
171
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
172
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
173
+ @test_case.assert_statsd_calls([foo_1_metric, foo_2_metric]) do
174
+ StatsD.increment('counter', tags: { foo: 1 })
175
+ StatsD.increment('counter', tags: { foo: 1 })
176
+ StatsD.increment('counter', tags: { foo: 2 })
203
177
  end
204
178
 
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
179
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
180
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
181
+ @test_case.assert_statsd_calls([foo_2_metric, foo_1_metric]) do
182
+ StatsD.increment('counter', tags: { foo: 1 })
183
+ StatsD.increment('counter', tags: { foo: 1 })
184
+ StatsD.increment('counter', tags: { foo: 2 })
185
+ end
186
+
187
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
188
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
189
+ @test_case.assert_statsd_calls([foo_2_metric, foo_1_metric]) do
190
+ StatsD.increment('counter', tags: { foo: 1 })
191
+ StatsD.increment('counter', tags: { foo: 2 })
192
+ StatsD.increment('counter', tags: { foo: 1 })
213
193
  end
214
194
  end
215
195
 
216
196
  def test_assert_multiple_statsd_calls
217
- assert_assertion_triggered do
197
+ assert_raises(Minitest::Assertion) do
218
198
  foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
219
199
  foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
220
200
  @test_case.assert_statsd_calls([foo_1_metric, foo_2_metric]) do
@@ -223,7 +203,7 @@ class AssertionsTest < Minitest::Test
223
203
  end
224
204
  end
225
205
 
226
- assert_assertion_triggered do
206
+ assert_raises(Minitest::Assertion) do
227
207
  foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
228
208
  foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
229
209
  @test_case.assert_statsd_calls([foo_1_metric, foo_2_metric]) do
@@ -234,59 +214,52 @@ class AssertionsTest < Minitest::Test
234
214
  end
235
215
  end
236
216
 
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
217
+ foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 2, tags: ['foo:1'])
218
+ foo_2_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:2'])
219
+ @test_case.assert_statsd_calls([foo_1_metric, foo_2_metric]) do
220
+ StatsD.increment('counter', tags: { foo: 1 })
221
+ StatsD.increment('counter', tags: { foo: 1 })
222
+ StatsD.increment('counter', tags: { foo: 2 })
245
223
  end
246
224
  end
247
225
 
248
226
  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
227
+ @test_case.assert_statsd_increment('counter', tags: ['a:b', 'c:d']) do
228
+ StatsD.increment('counter', tags: { a: 'b', c: 'd' })
253
229
  end
254
230
 
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
231
+ @test_case.assert_statsd_increment('counter', tags: { a: 'b', c: 'd' }) do
232
+ StatsD.increment('counter', tags: ['a:b', 'c:d'])
259
233
  end
260
234
  end
261
235
 
262
236
  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
237
+ skip("In Strict mode, the StatsD.increment call will raise") if StatsD::Instrument.strict_mode_enabled?
238
+
239
+ assertion = assert_raises(Minitest::Assertion) do
264
240
  @test_case.assert_statsd_increment('counter', tags: ['a', 'b']) do
265
- StatsD.increment('counter', sample_rate: 'abc', tags: ['a', 'b'])
241
+ StatsD.increment('counter', sample_rate: 'abc', tags: ['a', 'b'])
266
242
  end
267
243
  end
244
+ assert_equal "Unexpected sample rate type for metric counter, must be numeric", assertion.message
268
245
  end
269
246
 
270
247
  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
248
+ @test_case.assert_statsd_increment('counter1') do
249
+ @test_case.assert_statsd_increment('counter2') do
250
+ StatsD.increment('counter1')
251
+ StatsD.increment('counter2')
277
252
  end
278
253
  end
279
254
 
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
255
+ @test_case.assert_statsd_increment('counter1') do
256
+ StatsD.increment('counter1')
257
+ @test_case.assert_statsd_increment('counter2') do
258
+ StatsD.increment('counter2')
286
259
  end
287
260
  end
288
261
 
289
- assert_assertion_triggered do
262
+ assert_raises(Minitest::Assertion) do
290
263
  @test_case.assert_statsd_increment('counter1') do
291
264
  @test_case.assert_statsd_increment('counter2') do
292
265
  StatsD.increment('counter2')
@@ -294,7 +267,7 @@ class AssertionsTest < Minitest::Test
294
267
  end
295
268
  end
296
269
 
297
- assert_assertion_triggered do
270
+ assert_raises(Minitest::Assertion) do
298
271
  @test_case.assert_statsd_increment('counter1') do
299
272
  @test_case.assert_statsd_increment('counter2') do
300
273
  StatsD.increment('counter1')
@@ -304,26 +277,64 @@ class AssertionsTest < Minitest::Test
304
277
  end
305
278
  end
306
279
 
307
- private
280
+ def test_assertion_block_with_expected_exceptions
281
+ @test_case.assert_statsd_increment('expected_happened') do
282
+ @test_case.assert_raises(RuntimeError) do
283
+ begin
284
+ raise "expected"
285
+ rescue
286
+ StatsD.increment('expected_happened')
287
+ raise
288
+ end
289
+ end
290
+ end
291
+
292
+ assertion = assert_raises(Minitest::Assertion) do
293
+ @test_case.assert_statsd_increment('counter') do
294
+ @test_case.assert_raises(RuntimeError) do
295
+ raise "expected"
296
+ end
297
+ end
298
+ end
299
+ assert_includes assertion.message, "No StatsD calls for metric counter of type c were made"
300
+ end
301
+
302
+ def test_assertion_block_with_unexpected_exceptions
303
+ assertion = assert_raises(Minitest::Assertion) do
304
+ @test_case.assert_statsd_increment('counter') do
305
+ StatsD.increment('counter')
306
+ raise "unexpected"
307
+ end
308
+ end
309
+ assert_includes assertion.message, "An exception occurred in the block provided to the StatsD assertion"
310
+
311
+ assertion = assert_raises(Minitest::Assertion) do
312
+ @test_case.assert_raises(RuntimeError) do
313
+ @test_case.assert_statsd_increment('counter') do
314
+ StatsD.increment('counter')
315
+ raise "unexpected"
316
+ end
317
+ end
318
+ end
319
+ assert_includes assertion.message, "An exception occurred in the block provided to the StatsD assertion"
308
320
 
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
321
+ assertion = assert_raises(Minitest::Assertion) do
322
+ @test_case.assert_raises(RuntimeError) do
323
+ @test_case.assert_no_statsd_calls do
324
+ raise "unexpected"
325
+ end
326
+ end
327
+ end
328
+ assert_includes assertion.message, "An exception occurred in the block provided to the StatsD assertion"
315
329
  end
316
330
 
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."
331
+ def test_assertion_block_with_other_assertion_failures
332
+ # If another assertion failure happens inside the block, that failrue should have priority
333
+ assertion = assert_raises(Minitest::Assertion) do
334
+ @test_case.assert_statsd_increment('counter') do
335
+ @test_case.flunk('other assertion failure')
336
+ end
337
+ end
338
+ assert_equal "other assertion failure", assertion.message
328
339
  end
329
340
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'benchmark/ips'
4
+
5
+ Benchmark.ips do |bench|
6
+ bench.report("Process.clock_gettime in milliseconds (int)") do
7
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
8
+ end
9
+
10
+ bench.report("Process.clock_gettime in milliseconds (float)") do
11
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
12
+ end
13
+
14
+ bench.report("Process.clock_gettime in seconds (float), multiplied by 1000") do
15
+ 1000 * Process.clock_gettime(Process::CLOCK_MONOTONIC)
16
+ end
17
+
18
+ bench.report("Process.clock_gettime in seconds (float), multiplied by 1000.0") do
19
+ 1000.0 * Process.clock_gettime(Process::CLOCK_MONOTONIC)
20
+ end
21
+
22
+ bench.report("Time.now, multiplied by 1000") do
23
+ 1000 * Time.now.to_f
24
+ end
25
+
26
+ bench.compare!
27
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'statsd-instrument'
4
+ require 'benchmark/ips'
5
+
6
+ StatsD.logger = Logger.new(File::NULL)
7
+
8
+ class Suite
9
+ def warming(*args)
10
+ StatsD.default_tags = if args[0] == "with default tags"
11
+ { first_tag: 'first_value', second_tag: 'second_value' }
12
+ end
13
+ puts "warming with default tags: #{StatsD.default_tags}"
14
+ end
15
+
16
+ def running(*args)
17
+ StatsD.default_tags = if args[0] == "with default tags"
18
+ { first_tag: 'first_value', second_tag: 'second_value' }
19
+ end
20
+ puts "running with default tags: #{StatsD.default_tags}"
21
+ end
22
+
23
+ def warmup_stats(*)
24
+ end
25
+
26
+ def add_report(*)
27
+ end
28
+ end
29
+
30
+ suite = Suite.new
31
+
32
+ Benchmark.ips do |bench|
33
+ bench.config(suite: suite)
34
+ bench.report("without default tags") do
35
+ StatsD.increment('GoogleBase.insert', tags: {
36
+ first_tag: 'first_value',
37
+ second_tag: 'second_value',
38
+ third_tag: 'third_value',
39
+ })
40
+ end
41
+
42
+ bench.report("with default tags") do
43
+ StatsD.increment('GoogleBase.insert', tags: { third_tag: 'third_value' })
44
+ end
45
+
46
+ bench.compare!
47
+ end
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'statsd-instrument'
2
4
  require 'benchmark/ips'
3
5
 
4
- def helperFunction()
5
- a = 10
6
- a += a
7
- a -= a
8
- a *= a
6
+ def helper_function
7
+ a = 10
8
+ a += a
9
+ a -= a
10
+ a * a
9
11
  end
10
12
 
11
13
  Benchmark.ips do |bench|
@@ -14,8 +16,8 @@ Benchmark.ips do |bench|
14
16
  end
15
17
 
16
18
  bench.report("measure metric benchmark") do
17
- StatsD.measure('helperFunction') do
18
- helperFunction()
19
+ StatsD.measure('helper_function') do
20
+ helper_function
19
21
  end
20
22
  end
21
23
 
@@ -34,5 +36,4 @@ Benchmark.ips do |bench|
34
36
  bench.report("service check metric benchmark") do
35
37
  StatsD.service_check('shipit.redis_connection', 'ok')
36
38
  end
37
-
38
39
  end