statsd-instrument 3.0.0.pre1 → 3.1.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.
- checksums.yaml +4 -4
- data/.github/workflows/lint.yml +22 -0
- data/.github/workflows/tests.yml +31 -0
- data/.rubocop.yml +3 -13
- data/CHANGELOG.md +50 -0
- data/Gemfile +8 -2
- data/README.md +6 -3
- data/Rakefile +7 -7
- data/benchmark/send-metrics-to-dev-null-log +12 -11
- data/benchmark/send-metrics-to-local-udp-receiver +16 -15
- data/bin/rake +29 -0
- data/bin/rubocop +29 -0
- data/lib/statsd-instrument.rb +1 -1
- data/lib/statsd/instrument.rb +112 -145
- data/lib/statsd/instrument/assertions.rb +200 -208
- data/lib/statsd/instrument/batched_udp_sink.rb +154 -0
- data/lib/statsd/instrument/capture_sink.rb +23 -19
- data/lib/statsd/instrument/client.rb +410 -306
- data/lib/statsd/instrument/datagram.rb +69 -65
- data/lib/statsd/instrument/datagram_builder.rb +81 -77
- data/lib/statsd/instrument/dogstatsd_datagram.rb +76 -72
- data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +68 -64
- data/lib/statsd/instrument/environment.rb +88 -77
- data/lib/statsd/instrument/expectation.rb +96 -96
- data/lib/statsd/instrument/helpers.rb +11 -7
- data/lib/statsd/instrument/log_sink.rb +20 -16
- data/lib/statsd/instrument/matchers.rb +93 -74
- data/lib/statsd/instrument/null_sink.rb +12 -8
- data/lib/statsd/instrument/railtie.rb +11 -7
- data/lib/statsd/instrument/rubocop.rb +8 -8
- data/lib/statsd/instrument/rubocop/measure_as_dist_argument.rb +1 -1
- data/lib/statsd/instrument/rubocop/metaprogramming_positional_arguments.rb +2 -2
- data/lib/statsd/instrument/rubocop/metric_prefix_argument.rb +1 -1
- data/lib/statsd/instrument/rubocop/metric_return_value.rb +2 -2
- data/lib/statsd/instrument/rubocop/metric_value_keyword_argument.rb +1 -1
- data/lib/statsd/instrument/rubocop/positional_arguments.rb +4 -4
- data/lib/statsd/instrument/rubocop/singleton_configuration.rb +1 -1
- data/lib/statsd/instrument/rubocop/splat_arguments.rb +2 -2
- data/lib/statsd/instrument/statsd_datagram_builder.rb +12 -8
- data/lib/statsd/instrument/strict.rb +1 -6
- data/lib/statsd/instrument/udp_sink.rb +49 -47
- data/lib/statsd/instrument/version.rb +1 -1
- data/statsd-instrument.gemspec +4 -8
- data/test/assertions_test.rb +205 -161
- data/test/benchmark/clock_gettime.rb +1 -1
- data/test/benchmark/default_tags.rb +9 -9
- data/test/benchmark/metrics.rb +8 -8
- data/test/benchmark/tags.rb +4 -4
- data/test/capture_sink_test.rb +14 -14
- data/test/client_test.rb +96 -96
- data/test/datagram_builder_test.rb +55 -55
- data/test/datagram_test.rb +5 -5
- data/test/dogstatsd_datagram_builder_test.rb +37 -37
- data/test/environment_test.rb +30 -21
- data/test/helpers/rubocop_helper.rb +12 -9
- data/test/helpers_test.rb +15 -15
- data/test/integration_test.rb +7 -7
- data/test/log_sink_test.rb +4 -4
- data/test/matchers_test.rb +54 -54
- data/test/null_sink_test.rb +4 -4
- data/test/rubocop/measure_as_dist_argument_test.rb +2 -2
- data/test/rubocop/metaprogramming_positional_arguments_test.rb +2 -2
- data/test/rubocop/metric_prefix_argument_test.rb +2 -2
- data/test/rubocop/metric_return_value_test.rb +6 -6
- data/test/rubocop/metric_value_keyword_argument_test.rb +3 -3
- data/test/rubocop/positional_arguments_test.rb +12 -12
- data/test/rubocop/singleton_configuration_test.rb +8 -8
- data/test/rubocop/splat_arguments_test.rb +2 -2
- data/test/statsd_datagram_builder_test.rb +6 -6
- data/test/statsd_instrumentation_test.rb +122 -122
- data/test/statsd_test.rb +69 -67
- data/test/test_helper.rb +19 -10
- data/test/udp_sink_test.rb +122 -50
- metadata +12 -92
- data/.github/workflows/ci.yml +0 -56
- data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +0 -1027
data/test/statsd_test.rb
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "test_helper"
|
4
4
|
|
5
5
|
class StatsDTest < Minitest::Test
|
6
6
|
include StatsD::Instrument::Assertions
|
7
7
|
|
8
8
|
def test_statsd_measure_with_explicit_value
|
9
|
-
metric = capture_statsd_call { StatsD.measure(
|
10
|
-
assert_equal
|
11
|
-
assert_equal
|
12
|
-
assert_equal
|
9
|
+
metric = capture_statsd_call { StatsD.measure("values.foobar", 42) }
|
10
|
+
assert_equal("values.foobar", metric.name)
|
11
|
+
assert_equal(42, metric.value)
|
12
|
+
assert_equal(:ms, metric.type)
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_statsd_measure_with_explicit_value_and_sample_rate
|
16
|
-
metric = capture_statsd_call { StatsD.measure(
|
17
|
-
assert_equal
|
16
|
+
metric = capture_statsd_call { StatsD.measure("values.foobar", 42, sample_rate: 0.1) }
|
17
|
+
assert_equal(0.1, metric.sample_rate)
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_statsd_measure_with_benchmarked_block_duration
|
21
21
|
Process.stubs(:clock_gettime).returns(5.0, 5.0 + 1.12)
|
22
22
|
metric = capture_statsd_call do
|
23
|
-
StatsD.measure(
|
23
|
+
StatsD.measure("values.foobar") { "foo" }
|
24
24
|
end
|
25
|
-
assert_equal
|
25
|
+
assert_equal(1120.0, metric.value)
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_statsd_measure_returns_return_value_of_block
|
29
|
-
return_value = StatsD.measure(
|
30
|
-
assert_equal
|
29
|
+
return_value = StatsD.measure("values.foobar") { "sarah" }
|
30
|
+
assert_equal("sarah", return_value)
|
31
31
|
end
|
32
32
|
|
33
33
|
def test_statsd_measure_with_return_in_block_still_captures
|
@@ -35,14 +35,14 @@ class StatsDTest < Minitest::Test
|
|
35
35
|
result = nil
|
36
36
|
metric = capture_statsd_call do
|
37
37
|
lambda = -> do
|
38
|
-
StatsD.measure(
|
38
|
+
StatsD.measure("values.foobar") { return "from lambda" }
|
39
39
|
end
|
40
40
|
|
41
41
|
result = lambda.call
|
42
42
|
end
|
43
43
|
|
44
|
-
assert_equal
|
45
|
-
assert_equal
|
44
|
+
assert_equal("from lambda", result)
|
45
|
+
assert_equal(1120.0, metric.value)
|
46
46
|
end
|
47
47
|
|
48
48
|
def test_statsd_measure_with_exception_in_block_still_captures
|
@@ -50,73 +50,74 @@ class StatsDTest < Minitest::Test
|
|
50
50
|
result = nil
|
51
51
|
metric = capture_statsd_call do
|
52
52
|
lambda = -> do
|
53
|
-
StatsD.measure(
|
53
|
+
StatsD.measure("values.foobar") { raise "from lambda" }
|
54
54
|
end
|
55
55
|
|
56
56
|
begin
|
57
57
|
result = lambda.call
|
58
|
-
rescue
|
58
|
+
rescue
|
59
|
+
# noop
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
62
|
-
assert_nil
|
63
|
-
assert_equal
|
63
|
+
assert_nil(result)
|
64
|
+
assert_equal(1120.0, metric.value)
|
64
65
|
end
|
65
66
|
|
66
67
|
def test_statsd_increment
|
67
|
-
metric = capture_statsd_call { StatsD.increment(
|
68
|
-
assert_equal
|
69
|
-
assert_equal
|
70
|
-
assert_equal
|
68
|
+
metric = capture_statsd_call { StatsD.increment("values.foobar", 3) }
|
69
|
+
assert_equal(:c, metric.type)
|
70
|
+
assert_equal("values.foobar", metric.name)
|
71
|
+
assert_equal(3, metric.value)
|
71
72
|
end
|
72
73
|
|
73
74
|
def test_statsd_increment_with_hash_argument
|
74
|
-
metric = capture_statsd_call { StatsD.increment(
|
75
|
-
assert_equal
|
76
|
-
assert_equal
|
77
|
-
assert_equal
|
75
|
+
metric = capture_statsd_call { StatsD.increment("values.foobar", tags: ["test"]) }
|
76
|
+
assert_equal(StatsD.singleton_client.default_sample_rate, metric.sample_rate)
|
77
|
+
assert_equal(["test"], metric.tags)
|
78
|
+
assert_equal(1, metric.value)
|
78
79
|
end
|
79
80
|
|
80
81
|
def test_statsd_gauge
|
81
|
-
metric = capture_statsd_call { StatsD.gauge(
|
82
|
-
assert_equal
|
83
|
-
assert_equal
|
84
|
-
assert_equal
|
82
|
+
metric = capture_statsd_call { StatsD.gauge("values.foobar", 12) }
|
83
|
+
assert_equal(:g, metric.type)
|
84
|
+
assert_equal("values.foobar", metric.name)
|
85
|
+
assert_equal(12, metric.value)
|
85
86
|
end
|
86
87
|
|
87
88
|
def test_statsd_gauge_without_value
|
88
|
-
assert_raises(ArgumentError) { StatsD.gauge(
|
89
|
+
assert_raises(ArgumentError) { StatsD.gauge("values.foobar") }
|
89
90
|
end
|
90
91
|
|
91
92
|
def test_statsd_set
|
92
|
-
metric = capture_statsd_call { StatsD.set(
|
93
|
-
assert_equal
|
94
|
-
assert_equal
|
95
|
-
assert_equal
|
93
|
+
metric = capture_statsd_call { StatsD.set("values.foobar", "unique_identifier") }
|
94
|
+
assert_equal(:s, metric.type)
|
95
|
+
assert_equal("values.foobar", metric.name)
|
96
|
+
assert_equal("unique_identifier", metric.value)
|
96
97
|
end
|
97
98
|
|
98
99
|
def test_statsd_histogram
|
99
|
-
metric = capture_statsd_call { StatsD.histogram(
|
100
|
-
assert_equal
|
101
|
-
assert_equal
|
102
|
-
assert_equal
|
100
|
+
metric = capture_statsd_call { StatsD.histogram("values.foobar", 42) }
|
101
|
+
assert_equal(:h, metric.type)
|
102
|
+
assert_equal("values.foobar", metric.name)
|
103
|
+
assert_equal(42, metric.value)
|
103
104
|
end
|
104
105
|
|
105
106
|
def test_statsd_distribution
|
106
|
-
metric = capture_statsd_call { StatsD.distribution(
|
107
|
-
assert_equal
|
108
|
-
assert_equal
|
109
|
-
assert_equal
|
107
|
+
metric = capture_statsd_call { StatsD.distribution("values.foobar", 42) }
|
108
|
+
assert_equal(:d, metric.type)
|
109
|
+
assert_equal("values.foobar", metric.name)
|
110
|
+
assert_equal(42, metric.value)
|
110
111
|
end
|
111
112
|
|
112
113
|
def test_statsd_distribution_with_benchmarked_block_duration
|
113
114
|
Process.stubs(:clock_gettime).returns(5.0, 5.0 + 1.12)
|
114
115
|
metric = capture_statsd_call do
|
115
|
-
result = StatsD.distribution(
|
116
|
-
assert_equal
|
116
|
+
result = StatsD.distribution("values.foobar") { "foo" }
|
117
|
+
assert_equal("foo", result)
|
117
118
|
end
|
118
|
-
assert_equal
|
119
|
-
assert_equal
|
119
|
+
assert_equal(:d, metric.type)
|
120
|
+
assert_equal(1120.0, metric.value)
|
120
121
|
end
|
121
122
|
|
122
123
|
def test_statsd_distribution_with_return_in_block_still_captures
|
@@ -124,16 +125,16 @@ class StatsDTest < Minitest::Test
|
|
124
125
|
result = nil
|
125
126
|
metric = capture_statsd_call do
|
126
127
|
lambda = -> do
|
127
|
-
StatsD.distribution(
|
128
|
+
StatsD.distribution("values.foobar") { return "from lambda" }
|
128
129
|
flunk("This code should not be reached")
|
129
130
|
end
|
130
131
|
|
131
132
|
result = lambda.call
|
132
133
|
end
|
133
134
|
|
134
|
-
assert_equal
|
135
|
-
assert_equal
|
136
|
-
assert_equal
|
135
|
+
assert_equal("from lambda", result)
|
136
|
+
assert_equal(:d, metric.type)
|
137
|
+
assert_equal(1120.0, metric.value)
|
137
138
|
end
|
138
139
|
|
139
140
|
def test_statsd_distribution_with_exception_in_block_still_captures
|
@@ -141,44 +142,45 @@ class StatsDTest < Minitest::Test
|
|
141
142
|
result = nil
|
142
143
|
metric = capture_statsd_call do
|
143
144
|
lambda = -> do
|
144
|
-
StatsD.distribution(
|
145
|
+
StatsD.distribution("values.foobar") { raise "from lambda" }
|
145
146
|
end
|
146
147
|
|
147
148
|
begin
|
148
149
|
result = lambda.call
|
149
|
-
rescue
|
150
|
+
rescue
|
151
|
+
# noop
|
150
152
|
end
|
151
153
|
end
|
152
154
|
|
153
|
-
assert_nil
|
154
|
-
assert_equal
|
155
|
-
assert_equal
|
155
|
+
assert_nil(result)
|
156
|
+
assert_equal(:d, metric.type)
|
157
|
+
assert_equal(1120.0, metric.value)
|
156
158
|
end
|
157
159
|
|
158
160
|
def test_statsd_distribution_with_block_and_options
|
159
161
|
Process.stubs(:clock_gettime).returns(5.0, 5.0 + 1.12)
|
160
162
|
metric = capture_statsd_call do
|
161
|
-
StatsD.distribution(
|
163
|
+
StatsD.distribution("values.foobar", tags: ["test"], sample_rate: 0.9) { "foo" }
|
162
164
|
end
|
163
|
-
assert_equal
|
164
|
-
assert_equal
|
165
|
-
assert_equal
|
166
|
-
assert_equal
|
165
|
+
assert_equal(1120.0, metric.value)
|
166
|
+
assert_equal("values.foobar", metric.name)
|
167
|
+
assert_equal(0.9, metric.sample_rate)
|
168
|
+
assert_equal(["test"], metric.tags)
|
167
169
|
end
|
168
170
|
|
169
171
|
def test_statsd_distribution_returns_return_value_of_block
|
170
|
-
return_value = StatsD.distribution(
|
171
|
-
assert_equal
|
172
|
+
return_value = StatsD.distribution("values.foobar") { "sarah" }
|
173
|
+
assert_equal("sarah", return_value)
|
172
174
|
end
|
173
175
|
|
174
176
|
def test_statsd_measure_returns_return_value_of_block_even_if_nil
|
175
|
-
return_value = StatsD.distribution(
|
176
|
-
assert_nil
|
177
|
+
return_value = StatsD.distribution("values.foobar") { nil }
|
178
|
+
assert_nil(return_value)
|
177
179
|
end
|
178
180
|
|
179
181
|
def test_statsd_duration_returns_time_in_seconds
|
180
182
|
duration = StatsD::Instrument.duration {}
|
181
|
-
assert_kind_of
|
183
|
+
assert_kind_of(Float, duration)
|
182
184
|
end
|
183
185
|
|
184
186
|
def test_statsd_duration_does_not_swallow_exceptions
|
@@ -191,7 +193,7 @@ class StatsDTest < Minitest::Test
|
|
191
193
|
|
192
194
|
def capture_statsd_call(&block)
|
193
195
|
metrics = capture_statsd_calls(&block)
|
194
|
-
assert_equal
|
196
|
+
assert_equal(1, metrics.length)
|
195
197
|
metrics.first
|
196
198
|
end
|
197
199
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,19 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
if Warning.respond_to?(:[]=)
|
4
|
+
Warning[:deprecated] = true
|
5
|
+
end
|
6
|
+
|
7
|
+
ENV["ENV"] = "test"
|
4
8
|
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
+
require "minitest/autorun"
|
10
|
+
require "minitest/pride"
|
11
|
+
require "mocha/minitest"
|
12
|
+
require "statsd-instrument"
|
9
13
|
|
10
|
-
require_relative
|
14
|
+
require_relative "helpers/rubocop_helper"
|
11
15
|
|
12
|
-
module StatsD
|
13
|
-
|
14
|
-
|
15
|
-
StatsD.
|
16
|
+
module StatsD
|
17
|
+
module Instrument
|
18
|
+
def self.strict_mode_enabled?
|
19
|
+
StatsD::Instrument.const_defined?(:Strict) &&
|
20
|
+
StatsD.singleton_class.ancestors.include?(StatsD::Instrument::Strict)
|
21
|
+
end
|
16
22
|
end
|
17
23
|
end
|
18
24
|
|
19
25
|
StatsD.logger = Logger.new(File::NULL)
|
26
|
+
|
27
|
+
Thread.abort_on_exception = true
|
28
|
+
Thread.report_on_exception = true
|
data/test/udp_sink_test.rb
CHANGED
@@ -1,83 +1,155 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
|
5
|
-
class UDPSinkTest < Minitest::Test
|
6
|
-
def setup
|
7
|
-
@receiver = UDPSocket.new
|
8
|
-
@receiver.bind('localhost', 0)
|
9
|
-
@host = @receiver.addr[2]
|
10
|
-
@port = @receiver.addr[1]
|
11
|
-
end
|
12
|
-
|
13
|
-
def teardown
|
14
|
-
@receiver.close
|
15
|
-
end
|
3
|
+
require "test_helper"
|
16
4
|
|
5
|
+
module UDPSinkTests
|
17
6
|
def test_udp_sink_sends_data_over_udp
|
18
|
-
udp_sink =
|
19
|
-
udp_sink <<
|
7
|
+
udp_sink = build_sink(@host, @port)
|
8
|
+
udp_sink << "foo:1|c"
|
20
9
|
|
21
10
|
datagram, _source = @receiver.recvfrom(100)
|
22
|
-
assert_equal
|
11
|
+
assert_equal("foo:1|c", datagram)
|
12
|
+
end
|
13
|
+
|
14
|
+
def large_datagram
|
15
|
+
datagram = "#{"a" * 1000}:1|c"
|
16
|
+
udp_sink = build_sink(@host, @port)
|
17
|
+
udp_sink << datagram
|
18
|
+
|
19
|
+
datagram, _source = @receiver.recvfrom(1500)
|
20
|
+
assert_equal(datagram, datagram)
|
23
21
|
end
|
24
22
|
|
25
23
|
def test_sample?
|
26
|
-
udp_sink =
|
27
|
-
assert
|
28
|
-
refute
|
24
|
+
udp_sink = build_sink(@host, @port)
|
25
|
+
assert(udp_sink.sample?(1))
|
26
|
+
refute(udp_sink.sample?(0))
|
29
27
|
|
30
28
|
udp_sink.stubs(:rand).returns(0.3)
|
31
|
-
assert
|
29
|
+
assert(udp_sink.sample?(0.5))
|
32
30
|
|
33
31
|
udp_sink.stubs(:rand).returns(0.7)
|
34
|
-
refute
|
32
|
+
refute(udp_sink.sample?(0.5))
|
35
33
|
end
|
36
34
|
|
37
35
|
def test_parallelism
|
38
|
-
udp_sink =
|
39
|
-
50.times { |i| Thread.new { udp_sink << "foo:#{i}|c" << "bar:#{i}|c" } }
|
36
|
+
udp_sink = build_sink(@host, @port)
|
37
|
+
50.times.map { |i| Thread.new { udp_sink << "foo:#{i}|c" << "bar:#{i}|c" } }
|
40
38
|
datagrams = []
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
|
40
|
+
while @receiver.wait_readable(2)
|
41
|
+
datagram, _source = @receiver.recvfrom(4000)
|
42
|
+
datagrams += datagram.split("\n")
|
44
43
|
end
|
45
44
|
|
46
|
-
assert_equal
|
45
|
+
assert_equal(100, datagrams.size)
|
47
46
|
end
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
socket.expects(:connect).with('localhost', 8125).in_sequence(seq)
|
54
|
-
socket.expects(:send).raises(Errno::EDESTADDRREQ).in_sequence(seq)
|
55
|
-
socket.expects(:connect).with('localhost', 8125).in_sequence(seq)
|
56
|
-
socket.expects(:send).returns(1).in_sequence(seq)
|
57
|
-
|
58
|
-
udp_sink = StatsD::Instrument::UDPSink.new('localhost', 8125)
|
59
|
-
udp_sink << 'foo:1|c'
|
60
|
-
udp_sink << 'bar:1|c'
|
48
|
+
class SimpleFormatter < ::Logger::Formatter
|
49
|
+
def call(_severity, _timestamp, _progname, msg)
|
50
|
+
"#{String === msg ? msg : msg.inspect}\n"
|
51
|
+
end
|
61
52
|
end
|
62
53
|
|
63
54
|
def test_sends_datagram_in_signal_handler
|
64
|
-
udp_sink =
|
55
|
+
udp_sink = build_sink(@host, @port)
|
56
|
+
Signal.trap("USR1") { udp_sink << "exiting:1|c" }
|
57
|
+
|
65
58
|
pid = fork do
|
66
|
-
|
67
|
-
|
68
|
-
|
59
|
+
sleep(5)
|
60
|
+
end
|
61
|
+
|
62
|
+
Signal.trap("USR1", "DEFAULT")
|
63
|
+
|
64
|
+
Process.kill("USR1", pid)
|
65
|
+
@receiver.wait_readable(1)
|
66
|
+
assert_equal("exiting:1|c", @receiver.recvfrom_nonblock(100).first)
|
67
|
+
Process.kill("KILL", pid)
|
68
|
+
rescue NotImplementedError
|
69
|
+
pass("Fork is not implemented on #{RUBY_PLATFORM}")
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def build_sink(host = @host, port = @port)
|
75
|
+
@sink_class.new(host, port)
|
76
|
+
end
|
77
|
+
|
78
|
+
class UDPSinkTest < Minitest::Test
|
79
|
+
include UDPSinkTests
|
80
|
+
|
81
|
+
def setup
|
82
|
+
@receiver = UDPSocket.new
|
83
|
+
@receiver.bind("localhost", 0)
|
84
|
+
@host = @receiver.addr[2]
|
85
|
+
@port = @receiver.addr[1]
|
86
|
+
@sink_class = StatsD::Instrument::UDPSink
|
87
|
+
end
|
88
|
+
|
89
|
+
def teardown
|
90
|
+
@receiver.close
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_socket_error_should_invalidate_socket
|
94
|
+
previous_logger = StatsD.logger
|
95
|
+
begin
|
96
|
+
logs = StringIO.new
|
97
|
+
StatsD.logger = Logger.new(logs)
|
98
|
+
StatsD.logger.formatter = SimpleFormatter.new
|
99
|
+
UDPSocket.stubs(:new).returns(socket = mock("socket"))
|
100
|
+
|
101
|
+
seq = sequence("connect_fail_connect_succeed")
|
102
|
+
socket.expects(:connect).with("localhost", 8125).in_sequence(seq)
|
103
|
+
socket.expects(:send).raises(Errno::EDESTADDRREQ).in_sequence(seq)
|
104
|
+
socket.expects(:connect).with("localhost", 8125).in_sequence(seq)
|
105
|
+
socket.expects(:send).returns(1).in_sequence(seq)
|
106
|
+
|
107
|
+
udp_sink = build_sink("localhost", 8125)
|
108
|
+
udp_sink << "foo:1|c"
|
109
|
+
udp_sink << "bar:1|c"
|
110
|
+
|
111
|
+
assert_equal(
|
112
|
+
"[#{@sink_class}] Resetting connection because of " \
|
113
|
+
"Errno::EDESTADDRREQ: Destination address required\n",
|
114
|
+
logs.string,
|
115
|
+
)
|
116
|
+
ensure
|
117
|
+
StatsD.logger = previous_logger
|
69
118
|
end
|
119
|
+
end
|
120
|
+
end
|
70
121
|
|
71
|
-
|
122
|
+
class BatchedUDPSinkTest < Minitest::Test
|
123
|
+
include UDPSinkTests
|
124
|
+
|
125
|
+
def setup
|
126
|
+
@receiver = UDPSocket.new
|
127
|
+
@receiver.bind("localhost", 0)
|
128
|
+
@host = @receiver.addr[2]
|
129
|
+
@port = @receiver.addr[1]
|
130
|
+
@sink_class = StatsD::Instrument::BatchedUDPSink
|
72
131
|
end
|
73
132
|
|
74
|
-
|
75
|
-
|
133
|
+
def teardown
|
134
|
+
@receiver.close
|
135
|
+
end
|
76
136
|
|
77
|
-
|
78
|
-
|
137
|
+
def test_parallelism_buffering
|
138
|
+
udp_sink = build_sink(@host, @port)
|
139
|
+
50.times.map do |i|
|
140
|
+
Thread.new do
|
141
|
+
udp_sink << "foo:#{i}|c" << "bar:#{i}|c" << "baz:#{i}|c" << "plop:#{i}|c"
|
142
|
+
end
|
143
|
+
end
|
79
144
|
|
80
|
-
|
81
|
-
|
145
|
+
datagrams = []
|
146
|
+
|
147
|
+
while @receiver.wait_readable(2)
|
148
|
+
datagram, _source = @receiver.recvfrom(1000)
|
149
|
+
datagrams += datagram.split("\n")
|
150
|
+
end
|
151
|
+
|
152
|
+
assert_equal(200, datagrams.size)
|
153
|
+
end
|
82
154
|
end
|
83
155
|
end
|