statsd-instrument 2.3.2 → 2.6.0

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