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.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +1 -0
- data/.github/workflows/benchmark.yml +32 -0
- data/.github/workflows/ci.yml +47 -0
- data/.gitignore +1 -0
- data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +1027 -0
- data/.rubocop.yml +50 -0
- data/.yardopts +5 -0
- data/CHANGELOG.md +288 -2
- data/CONTRIBUTING.md +28 -6
- data/Gemfile +5 -0
- data/README.md +54 -46
- data/Rakefile +4 -2
- data/benchmark/README.md +29 -0
- data/benchmark/datagram-client +41 -0
- data/benchmark/send-metrics-to-dev-null-log +47 -0
- data/benchmark/send-metrics-to-local-udp-receiver +57 -0
- data/lib/statsd/instrument/assertions.rb +179 -30
- data/lib/statsd/instrument/backend.rb +3 -2
- data/lib/statsd/instrument/backends/capture_backend.rb +4 -1
- data/lib/statsd/instrument/backends/logger_backend.rb +3 -3
- data/lib/statsd/instrument/backends/null_backend.rb +2 -0
- data/lib/statsd/instrument/backends/udp_backend.rb +39 -45
- data/lib/statsd/instrument/capture_sink.rb +27 -0
- data/lib/statsd/instrument/client.rb +313 -0
- data/lib/statsd/instrument/datagram.rb +75 -0
- data/lib/statsd/instrument/datagram_builder.rb +101 -0
- data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +71 -0
- data/lib/statsd/instrument/environment.rb +108 -29
- data/lib/statsd/instrument/helpers.rb +16 -8
- data/lib/statsd/instrument/log_sink.rb +24 -0
- data/lib/statsd/instrument/matchers.rb +14 -11
- data/lib/statsd/instrument/metric.rb +72 -45
- data/lib/statsd/instrument/metric_expectation.rb +32 -18
- data/lib/statsd/instrument/null_sink.rb +13 -0
- data/lib/statsd/instrument/railtie.rb +2 -1
- data/lib/statsd/instrument/rubocop/measure_as_dist_argument.rb +39 -0
- data/lib/statsd/instrument/rubocop/metaprogramming_positional_arguments.rb +42 -0
- data/lib/statsd/instrument/rubocop/metric_prefix_argument.rb +37 -0
- data/lib/statsd/instrument/rubocop/metric_return_value.rb +32 -0
- data/lib/statsd/instrument/rubocop/metric_value_keyword_argument.rb +36 -0
- data/lib/statsd/instrument/rubocop/positional_arguments.rb +99 -0
- data/lib/statsd/instrument/rubocop/splat_arguments.rb +31 -0
- data/lib/statsd/instrument/rubocop.rb +64 -0
- data/lib/statsd/instrument/statsd_datagram_builder.rb +14 -0
- data/lib/statsd/instrument/strict.rb +235 -0
- data/lib/statsd/instrument/udp_sink.rb +62 -0
- data/lib/statsd/instrument/version.rb +3 -1
- data/lib/statsd/instrument.rb +340 -163
- data/lib/statsd-instrument.rb +2 -0
- data/statsd-instrument.gemspec +13 -10
- data/test/assertions_test.rb +167 -156
- data/test/benchmark/clock_gettime.rb +27 -0
- data/test/benchmark/default_tags.rb +47 -0
- data/test/benchmark/metrics.rb +9 -8
- data/test/benchmark/tags.rb +5 -3
- data/test/capture_backend_test.rb +4 -2
- data/test/capture_sink_test.rb +44 -0
- data/test/client_test.rb +164 -0
- data/test/compatibility/dogstatsd_datagram_compatibility_test.rb +162 -0
- data/test/datagram_builder_test.rb +120 -0
- data/test/deprecations_test.rb +132 -0
- data/test/dogstatsd_datagram_builder_test.rb +32 -0
- data/test/environment_test.rb +75 -8
- data/test/helpers/rubocop_helper.rb +47 -0
- data/test/helpers_test.rb +2 -1
- data/test/integration_test.rb +31 -7
- data/test/log_sink_test.rb +37 -0
- data/test/logger_backend_test.rb +10 -8
- data/test/matchers_test.rb +42 -28
- data/test/metric_test.rb +18 -22
- data/test/null_sink_test.rb +13 -0
- data/test/rubocop/measure_as_dist_argument_test.rb +44 -0
- data/test/rubocop/metaprogramming_positional_arguments_test.rb +58 -0
- data/test/rubocop/metric_prefix_argument_test.rb +38 -0
- data/test/rubocop/metric_return_value_test.rb +78 -0
- data/test/rubocop/metric_value_keyword_argument_test.rb +39 -0
- data/test/rubocop/positional_arguments_test.rb +110 -0
- data/test/rubocop/splat_arguments_test.rb +27 -0
- data/test/statsd_datagram_builder_test.rb +22 -0
- data/test/statsd_instrumentation_test.rb +109 -100
- data/test/statsd_test.rb +113 -79
- data/test/test_helper.rb +12 -1
- data/test/udp_backend_test.rb +38 -36
- data/test/udp_sink_test.rb +85 -0
- metadata +85 -5
- data/.travis.yml +0 -12
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'statsd/instrument/client'
|
6
|
+
|
7
|
+
class DogStatsDDatagramBuilderTest < Minitest::Test
|
8
|
+
def setup
|
9
|
+
@datagram_builder = StatsD::Instrument::DogStatsDDatagramBuilder.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_raises_on_unsupported_metrics
|
13
|
+
assert_raises(NotImplementedError) { @datagram_builder.kv('foo', 10, nil, nil) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_service_check
|
17
|
+
assert_equal '_sc|service|0', @datagram_builder._sc('service', :ok)
|
18
|
+
datagram = @datagram_builder._sc('service', :warning, timestamp: Time.parse('2019-09-30T04:22:12Z'),
|
19
|
+
hostname: 'localhost', tags: { foo: 'bar|baz' }, message: 'blah')
|
20
|
+
assert_equal "_sc|service|1|h:localhost|d:1569817332|#foo:barbaz|m:blah", datagram
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_event
|
24
|
+
assert_equal '_e{5,5}:hello|world', @datagram_builder._e('hello', "world")
|
25
|
+
|
26
|
+
datagram = @datagram_builder._e("testing", "with\nnewline", timestamp: Time.parse('2019-09-30T04:22:12Z'),
|
27
|
+
hostname: 'localhost', aggregation_key: 'my-key', priority: 'low', source_type_name: 'source',
|
28
|
+
alert_type: 'success', tags: { foo: 'bar|baz' })
|
29
|
+
assert_equal '_e{7,13}:testing|with\\nnewline|h:localhost|d:1569817332|k:my-key|' \
|
30
|
+
'p:low|s:source|t:success|#foo:barbaz', datagram
|
31
|
+
end
|
32
|
+
end
|
data/test/environment_test.rb
CHANGED
@@ -1,30 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
module Rails; end
|
4
6
|
|
5
7
|
class EnvironmentTest < Minitest::Test
|
6
|
-
|
7
8
|
def setup
|
8
9
|
ENV['STATSD_ADDR'] = nil
|
9
10
|
ENV['IMPLEMENTATION'] = nil
|
10
11
|
end
|
11
12
|
|
12
|
-
def
|
13
|
+
def test_default_backend_uses_logger_in_development_environment
|
13
14
|
StatsD::Instrument::Environment.stubs(:environment).returns('development')
|
14
15
|
assert_instance_of StatsD::Instrument::Backends::LoggerBackend, StatsD::Instrument::Environment.default_backend
|
15
16
|
end
|
16
17
|
|
17
|
-
def
|
18
|
+
def test_default_backend_uses_null_backend_in_test_environment
|
18
19
|
StatsD::Instrument::Environment.stubs(:environment).returns('test')
|
19
20
|
assert_instance_of StatsD::Instrument::Backends::NullBackend, StatsD::Instrument::Environment.default_backend
|
20
21
|
end
|
21
22
|
|
22
|
-
def
|
23
|
+
def test_default_backend_uses_udp_backend_in_production_environment
|
23
24
|
StatsD::Instrument::Environment.stubs(:environment).returns('production')
|
24
25
|
assert_instance_of StatsD::Instrument::Backends::UDPBackend, StatsD::Instrument::Environment.default_backend
|
25
26
|
end
|
26
27
|
|
27
|
-
def
|
28
|
+
def test_default_backend_uses_environment_variables_in_production_environment
|
28
29
|
StatsD::Instrument::Environment.stubs(:environment).returns('production')
|
29
30
|
ENV['STATSD_ADDR'] = '127.0.0.1:1234'
|
30
31
|
ENV['STATSD_IMPLEMENTATION'] = 'datadog'
|
@@ -35,12 +36,78 @@ class EnvironmentTest < Minitest::Test
|
|
35
36
|
assert_equal :datadog, backend.implementation
|
36
37
|
end
|
37
38
|
|
38
|
-
def
|
39
|
-
|
39
|
+
def test_environment_prefers_statsd_env_if_available
|
40
|
+
env = StatsD::Instrument::Environment.new(
|
41
|
+
'STATSD_ENV' => 'set_from_STATSD_ENV',
|
42
|
+
'RACK_ENV' => 'set_from_RACK_ENV',
|
43
|
+
'ENV' => 'set_from_ENV',
|
44
|
+
)
|
45
|
+
assert_equal 'set_from_STATSD_ENV', env.environment
|
40
46
|
end
|
41
47
|
|
42
|
-
def
|
48
|
+
def test_environment_uses_env_when_rails_does_not_respond_to_env_and_statsd_env_is_not_set
|
49
|
+
env = StatsD::Instrument::Environment.new(
|
50
|
+
'ENV' => 'set_from_ENV',
|
51
|
+
)
|
52
|
+
assert_equal 'set_from_ENV', env.environment
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_environment_uses_rails_env_when_rails_is_available
|
43
56
|
Rails.stubs(:env).returns('production')
|
44
57
|
assert_equal 'production', StatsD::Instrument::Environment.environment
|
45
58
|
end
|
59
|
+
|
60
|
+
def test_environment_defaults_to_development
|
61
|
+
env = StatsD::Instrument::Environment.new({})
|
62
|
+
assert_equal 'development', env.environment
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_default_client_uses_log_sink_in_development_environment
|
66
|
+
env = StatsD::Instrument::Environment.new('STATSD_ENV' => 'development')
|
67
|
+
assert_kind_of StatsD::Instrument::LogSink, env.default_client.sink
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_default_client_uses_null_sink_in_test_environment
|
71
|
+
env = StatsD::Instrument::Environment.new('STATSD_ENV' => 'test')
|
72
|
+
assert_kind_of StatsD::Instrument::NullSink, env.default_client.sink
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_default_client_uses_udp_sink_in_staging_environment
|
76
|
+
env = StatsD::Instrument::Environment.new('STATSD_ENV' => 'staging')
|
77
|
+
assert_kind_of StatsD::Instrument::UDPSink, env.default_client.sink
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_default_client_uses_udp_sink_in_production_environment
|
81
|
+
env = StatsD::Instrument::Environment.new('STATSD_ENV' => 'production')
|
82
|
+
assert_kind_of StatsD::Instrument::UDPSink, env.default_client.sink
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_default_client_respects_statsd_environment_variables
|
86
|
+
env = StatsD::Instrument::Environment.new(
|
87
|
+
'STATSD_ENV' => 'production',
|
88
|
+
'STATSD_IMPLEMENTATION' => 'datadog',
|
89
|
+
'STATSD_ADDR' => 'foo:8125',
|
90
|
+
'STATSD_SAMPLE_RATE' => "0.1",
|
91
|
+
'STATSD_PREFIX' => "foo",
|
92
|
+
'STATSD_DEFAULT_TAGS' => "foo,bar:baz",
|
93
|
+
)
|
94
|
+
|
95
|
+
assert_equal StatsD::Instrument::DogStatsDDatagramBuilder, env.default_client.datagram_builder_class
|
96
|
+
assert_equal 'foo', env.default_client.sink.host
|
97
|
+
assert_equal 8125, env.default_client.sink.port
|
98
|
+
assert_equal 0.1, env.default_client.default_sample_rate
|
99
|
+
assert_equal "foo", env.default_client.prefix
|
100
|
+
assert_equal ["foo", "bar:baz"], env.default_client.default_tags
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_default_client_has_sensible_defaults
|
104
|
+
env = StatsD::Instrument::Environment.new('STATSD_ENV' => 'production')
|
105
|
+
|
106
|
+
assert_equal StatsD::Instrument::StatsDDatagramBuilder, env.default_client.datagram_builder_class
|
107
|
+
assert_equal 'localhost', env.default_client.sink.host
|
108
|
+
assert_equal 8125, env.default_client.sink.port
|
109
|
+
assert_equal 1.0, env.default_client.default_sample_rate
|
110
|
+
assert_nil env.default_client.prefix
|
111
|
+
assert_nil env.default_client.default_tags
|
112
|
+
end
|
46
113
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubocop'
|
4
|
+
|
5
|
+
module RubocopHelper
|
6
|
+
attr_accessor :cop
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def assert_no_offenses(source)
|
11
|
+
investigate(RuboCop::ProcessedSource.new(source, 2.3, nil))
|
12
|
+
assert_predicate cop.offenses, :empty?, "Did not expect Rubocop to find offenses"
|
13
|
+
end
|
14
|
+
|
15
|
+
def assert_offense(source)
|
16
|
+
investigate(RuboCop::ProcessedSource.new(source, 2.3, nil))
|
17
|
+
refute_predicate cop.offenses, :empty?, "Expected Rubocop to find offenses"
|
18
|
+
end
|
19
|
+
|
20
|
+
def assert_no_autocorrect(source)
|
21
|
+
corrected = autocorrect_source(source)
|
22
|
+
assert_equal source, corrected
|
23
|
+
end
|
24
|
+
|
25
|
+
def autocorrect_source(source)
|
26
|
+
RuboCop::Formatter::DisabledConfigFormatter.config_to_allow_offenses = {}
|
27
|
+
RuboCop::Formatter::DisabledConfigFormatter.detected_styles = {}
|
28
|
+
cop.instance_variable_get(:@options)[:auto_correct] = true
|
29
|
+
|
30
|
+
processed_source = RuboCop::ProcessedSource.new(source, 2.3, nil)
|
31
|
+
investigate(processed_source)
|
32
|
+
|
33
|
+
corrector = RuboCop::Cop::Corrector.new(processed_source.buffer, cop.corrections)
|
34
|
+
corrector.rewrite
|
35
|
+
end
|
36
|
+
|
37
|
+
def investigate(processed_source)
|
38
|
+
forces = RuboCop::Cop::Force.all.each_with_object([]) do |klass, instances|
|
39
|
+
next unless cop.join_force?(klass)
|
40
|
+
instances << klass.new([cop])
|
41
|
+
end
|
42
|
+
|
43
|
+
commissioner = RuboCop::Cop::Commissioner.new([cop], forces, raise_error: true)
|
44
|
+
commissioner.investigate(processed_source)
|
45
|
+
commissioner
|
46
|
+
end
|
47
|
+
end
|
data/test/helpers_test.rb
CHANGED
data/test/integration_test.rb
CHANGED
@@ -1,20 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
class IntegrationTest < Minitest::Test
|
4
|
-
|
5
6
|
def setup
|
6
|
-
@
|
7
|
+
@server = UDPSocket.new
|
8
|
+
@server.bind('localhost', 0)
|
9
|
+
port = @server.addr[1]
|
10
|
+
|
11
|
+
@old_backend = StatsD.backend
|
12
|
+
StatsD.backend = StatsD::Instrument::Backends::UDPBackend.new("localhost:#{port}")
|
7
13
|
end
|
8
|
-
|
14
|
+
|
9
15
|
def teardown
|
16
|
+
@server.close
|
10
17
|
StatsD.backend = @old_backend
|
11
18
|
end
|
12
19
|
|
13
20
|
def test_live_local_udp_socket
|
14
|
-
server = UDPSocket.new
|
15
|
-
server.bind('localhost', 31798)
|
16
|
-
|
17
21
|
StatsD.increment('counter')
|
18
|
-
assert_equal "counter:1|c", server.recvfrom(100).first
|
22
|
+
assert_equal "counter:1|c", @server.recvfrom(100).first
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_synchronize_in_exit_handler_handles_thread_error_and_exits_cleanly
|
26
|
+
pid = fork do
|
27
|
+
Signal.trap('TERM') do
|
28
|
+
StatsD.increment('exiting')
|
29
|
+
Process.exit!(0)
|
30
|
+
end
|
31
|
+
|
32
|
+
sleep 100
|
33
|
+
end
|
34
|
+
|
35
|
+
Process.kill('TERM', pid)
|
36
|
+
_, exit_status = Process.waitpid2(pid)
|
37
|
+
|
38
|
+
assert_equal 0, exit_status, "The foked process did not exit cleanly"
|
39
|
+
assert_equal "exiting:1|c", @server.recvfrom_nonblock(100).first
|
40
|
+
|
41
|
+
rescue NotImplementedError
|
42
|
+
pass("Fork is not implemented on #{RUBY_PLATFORM}")
|
19
43
|
end
|
20
44
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'statsd/instrument/client'
|
6
|
+
|
7
|
+
class LogSinktest < Minitest::Test
|
8
|
+
def test_log_sink
|
9
|
+
logger = Logger.new(log = StringIO.new)
|
10
|
+
logger.formatter = proc do |severity, _datetime, _progname, msg|
|
11
|
+
"#{severity}: #{msg}\n"
|
12
|
+
end
|
13
|
+
|
14
|
+
log_sink = StatsD::Instrument::LogSink.new(logger)
|
15
|
+
log_sink << 'foo:1|c' << 'bar:1|c'
|
16
|
+
|
17
|
+
assert_equal <<~LOG, log.string
|
18
|
+
DEBUG: [StatsD] foo:1|c
|
19
|
+
DEBUG: [StatsD] bar:1|c
|
20
|
+
LOG
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_log_sink_chomps_trailing_newlines
|
24
|
+
logger = Logger.new(log = StringIO.new)
|
25
|
+
logger.formatter = proc do |severity, _datetime, _progname, msg|
|
26
|
+
"#{severity}: #{msg}\n"
|
27
|
+
end
|
28
|
+
|
29
|
+
log_sink = StatsD::Instrument::LogSink.new(logger)
|
30
|
+
log_sink << "foo:1|c\n" << "bar:1|c\n"
|
31
|
+
|
32
|
+
assert_equal <<~LOG, log.string
|
33
|
+
DEBUG: [StatsD] foo:1|c
|
34
|
+
DEBUG: [StatsD] bar:1|c
|
35
|
+
LOG
|
36
|
+
end
|
37
|
+
end
|
data/test/logger_backend_test.rb
CHANGED
@@ -1,20 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
class LoggerBackendTest < Minitest::Test
|
4
6
|
def setup
|
5
7
|
logger = Logger.new(@io = StringIO.new)
|
6
|
-
logger.formatter = lambda { |_,_,_, msg| "#{msg}\n" }
|
8
|
+
logger.formatter = lambda { |_, _, _, msg| "#{msg}\n" }
|
7
9
|
@backend = StatsD::Instrument::Backends::LoggerBackend.new(logger)
|
8
|
-
@metric1 = StatsD::Instrument::Metric
|
9
|
-
@metric2 = StatsD::Instrument::Metric
|
10
|
+
@metric1 = StatsD::Instrument::Metric.new(type: :c, name: 'mock.counter', tags: { a: 'b', c: 'd' })
|
11
|
+
@metric2 = StatsD::Instrument::Metric.new(type: :ms, name: 'mock.measure', value: 123, sample_rate: 0.3)
|
10
12
|
end
|
11
13
|
|
12
14
|
def test_logs_metrics
|
13
15
|
@backend.collect_metric(@metric1)
|
14
|
-
assert_equal @io.string, "[StatsD] increment mock.counter:1 #a:b #c:d\n"
|
15
|
-
@io.string = ""
|
16
|
-
|
17
16
|
@backend.collect_metric(@metric2)
|
18
|
-
assert_equal @io.string
|
17
|
+
assert_equal <<~LOG, @io.string
|
18
|
+
[StatsD] increment mock.counter:1 #a:b #c:d
|
19
|
+
[StatsD] measure mock.measure:123 @0.3
|
20
|
+
LOG
|
19
21
|
end
|
20
|
-
end
|
22
|
+
end
|
data/test/matchers_test.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
require 'statsd/instrument/matchers'
|
3
5
|
|
4
6
|
class MatchersTest < Minitest::Test
|
5
7
|
def test_statsd_increment_matched
|
6
|
-
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', {})
|
8
|
+
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', {})
|
9
|
+
.matches?(lambda { StatsD.increment('counter') })
|
7
10
|
end
|
8
11
|
|
9
12
|
def test_statsd_increment_not_matched
|
10
|
-
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', {})
|
13
|
+
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', {})
|
14
|
+
.matches?(lambda { StatsD.increment('not_counter') })
|
11
15
|
end
|
12
16
|
|
13
17
|
def test_statsd_increment_compound_matched
|
@@ -31,72 +35,82 @@ class MatchersTest < Minitest::Test
|
|
31
35
|
end
|
32
36
|
|
33
37
|
def test_statsd_increment_with_times_matched
|
34
|
-
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 1)
|
38
|
+
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 1)
|
39
|
+
.matches?(lambda { StatsD.increment('counter') })
|
35
40
|
end
|
36
41
|
|
37
42
|
def test_statsd_increment_with_times_not_matched
|
38
|
-
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 2)
|
43
|
+
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 2)
|
44
|
+
.matches? lambda { 3.times { StatsD.increment('counter') } }
|
39
45
|
end
|
40
46
|
|
41
47
|
def test_statsd_increment_with_sample_rate_matched
|
42
|
-
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: 0.5)
|
48
|
+
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: 0.5)
|
49
|
+
.matches?(lambda { StatsD.increment('counter', sample_rate: 0.5) })
|
43
50
|
end
|
44
51
|
|
45
52
|
def test_statsd_increment_with_sample_rate_not_matched
|
46
|
-
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: 0.5)
|
53
|
+
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: 0.5)
|
54
|
+
.matches?(lambda { StatsD.increment('counter', sample_rate: 0.7) })
|
47
55
|
end
|
48
56
|
|
49
57
|
def test_statsd_increment_with_value_matched
|
50
|
-
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 1)
|
58
|
+
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 1)
|
59
|
+
.matches?(lambda { StatsD.increment('counter') })
|
51
60
|
end
|
52
61
|
|
53
62
|
def test_statsd_increment_with_value_matched_when_multiple_metrics
|
54
|
-
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 1).matches?
|
55
|
-
StatsD.increment('counter',
|
56
|
-
StatsD.increment('counter',
|
57
|
-
}
|
63
|
+
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 1).matches?(lambda {
|
64
|
+
StatsD.increment('counter', 2)
|
65
|
+
StatsD.increment('counter', 1)
|
66
|
+
})
|
58
67
|
end
|
59
68
|
|
60
69
|
def test_statsd_increment_with_value_not_matched_when_multiple_metrics
|
61
|
-
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 1).matches?
|
62
|
-
StatsD.increment('counter',
|
63
|
-
StatsD.increment('counter',
|
64
|
-
}
|
70
|
+
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 1).matches?(lambda {
|
71
|
+
StatsD.increment('counter', 2)
|
72
|
+
StatsD.increment('counter', 3)
|
73
|
+
})
|
65
74
|
end
|
66
75
|
|
67
76
|
def test_statsd_increment_with_value_not_matched
|
68
|
-
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 3)
|
77
|
+
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', value: 3)
|
78
|
+
.matches?(lambda { StatsD.increment('counter') })
|
69
79
|
end
|
70
80
|
|
71
81
|
def test_statsd_increment_with_tags_matched
|
72
|
-
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', tags: ['a', 'b'])
|
82
|
+
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', tags: ['a', 'b'])
|
83
|
+
.matches?(lambda { StatsD.increment('counter', tags: ['a', 'b']) })
|
73
84
|
end
|
74
85
|
|
75
86
|
def test_statsd_increment_with_tags_not_matched
|
76
|
-
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', tags: ['a', 'b'])
|
87
|
+
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', tags: ['a', 'b'])
|
88
|
+
.matches?(lambda { StatsD.increment('counter', tags: ['c']) })
|
77
89
|
end
|
78
90
|
|
79
91
|
def test_statsd_increment_with_times_and_value_matched
|
80
|
-
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 2, value: 1).matches?
|
81
|
-
StatsD.increment('counter',
|
82
|
-
StatsD.increment('counter',
|
83
|
-
}
|
92
|
+
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 2, value: 1).matches?(lambda {
|
93
|
+
StatsD.increment('counter', 1)
|
94
|
+
StatsD.increment('counter', 1)
|
95
|
+
})
|
84
96
|
end
|
85
97
|
|
86
98
|
def test_statsd_increment_with_times_and_value_not_matched
|
87
|
-
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 2, value: 1).matches?
|
88
|
-
StatsD.increment('counter',
|
89
|
-
StatsD.increment('counter',
|
90
|
-
}
|
99
|
+
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', times: 2, value: 1).matches?(lambda {
|
100
|
+
StatsD.increment('counter', 1)
|
101
|
+
StatsD.increment('counter', 2)
|
102
|
+
})
|
91
103
|
end
|
92
104
|
|
93
105
|
def test_statsd_increment_with_sample_rate_and_argument_matcher_matched
|
94
106
|
between_matcher = RSpec::Matchers::BuiltIn::BeBetween.new(0.4, 0.6).inclusive
|
95
|
-
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: between_matcher)
|
107
|
+
assert StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: between_matcher)
|
108
|
+
.matches?(lambda { StatsD.increment('counter', sample_rate: 0.5) })
|
96
109
|
end
|
97
110
|
|
98
111
|
def test_statsd_increment_with_sample_rate_and_argument_matcher_not_matched
|
99
112
|
between_matcher = RSpec::Matchers::BuiltIn::BeBetween.new(0.4, 0.6).inclusive
|
100
|
-
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: between_matcher)
|
113
|
+
refute StatsD::Instrument::Matchers::Increment.new(:c, 'counter', sample_rate: between_matcher)
|
114
|
+
.matches?(lambda { StatsD.increment('counter', sample_rate: 0.7) })
|
101
115
|
end
|
102
116
|
end
|
data/test/metric_test.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
class MetricTest < Minitest::Test
|
4
|
-
|
5
6
|
def test_required_arguments
|
6
7
|
assert_raises(ArgumentError) { StatsD::Instrument::Metric.new(type: :c) }
|
7
8
|
assert_raises(ArgumentError) { StatsD::Instrument::Metric.new(name: 'test') }
|
@@ -15,37 +16,32 @@ class MetricTest < Minitest::Test
|
|
15
16
|
assert m.tags.nil?
|
16
17
|
end
|
17
18
|
|
18
|
-
def test_name_prefix
|
19
|
-
StatsD.stubs(:prefix).returns('prefix')
|
20
|
-
m = StatsD::Instrument::Metric.new(type: :c, name: 'counter')
|
21
|
-
assert_equal 'prefix.counter', m.name
|
22
|
-
|
23
|
-
m = StatsD::Instrument::Metric.new(type: :c, name: 'counter', no_prefix: true)
|
24
|
-
assert_equal 'counter', m.name
|
25
|
-
|
26
|
-
m = StatsD::Instrument::Metric.new(type: :c, name: 'counter', prefix: "foobar")
|
27
|
-
assert_equal 'foobar.counter', m.name
|
28
|
-
|
29
|
-
m = StatsD::Instrument::Metric.new(type: :c, name: 'counter', prefix: "foobar", no_prefix: true)
|
30
|
-
assert_equal 'counter', m.name
|
31
|
-
end
|
32
|
-
|
33
19
|
def test_bad_metric_name
|
34
|
-
m = StatsD::Instrument::Metric.new(type: :c, name: 'my:metric'
|
20
|
+
m = StatsD::Instrument::Metric.new(type: :c, name: 'my:metric')
|
35
21
|
assert_equal 'my_metric', m.name
|
36
|
-
m = StatsD::Instrument::Metric.new(type: :c, name: 'my|metric'
|
22
|
+
m = StatsD::Instrument::Metric.new(type: :c, name: 'my|metric')
|
37
23
|
assert_equal 'my_metric', m.name
|
38
|
-
m = StatsD::Instrument::Metric.new(type: :c, name: 'my@metric'
|
24
|
+
m = StatsD::Instrument::Metric.new(type: :c, name: 'my@metric')
|
39
25
|
assert_equal 'my_metric', m.name
|
40
26
|
end
|
41
27
|
|
42
28
|
def test_handle_bad_tags
|
43
29
|
assert_equal ['ignored'], StatsD::Instrument::Metric.normalize_tags(['igno|red'])
|
44
|
-
assert_equal ['lol::class:omg::lol'], StatsD::Instrument::Metric.normalize_tags(
|
30
|
+
assert_equal ['lol::class:omg::lol'], StatsD::Instrument::Metric.normalize_tags("lol::class" => "omg::lol")
|
45
31
|
end
|
46
32
|
|
47
33
|
def test_rewrite_tags_provided_as_hash
|
48
|
-
assert_equal ['tag:value'], StatsD::Instrument::Metric.normalize_tags(:
|
49
|
-
assert_equal ['
|
34
|
+
assert_equal ['tag:value'], StatsD::Instrument::Metric.normalize_tags(tag: 'value')
|
35
|
+
assert_equal ['tag1:v1', 'tag2:v2'], StatsD::Instrument::Metric.normalize_tags(tag1: 'v1', tag2: 'v2')
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_default_tags
|
39
|
+
StatsD.stubs(:default_tags).returns(['default_tag:default_value'])
|
40
|
+
m = StatsD::Instrument::Metric.new(type: :c, name: 'counter', tags: { tag: 'value' })
|
41
|
+
assert_equal ['tag:value', 'default_tag:default_value'], m.tags
|
42
|
+
|
43
|
+
StatsD.stubs(:default_tags).returns(['tag:value'])
|
44
|
+
m = StatsD::Instrument::Metric.new(type: :c, name: 'counter', tags: { tag: 'value' })
|
45
|
+
assert_equal ['tag:value', 'tag:value'], m.tags # we don't care about duplicates
|
50
46
|
end
|
51
47
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'statsd/instrument/client'
|
6
|
+
|
7
|
+
class NullSinktest < Minitest::Test
|
8
|
+
def test_null_sink
|
9
|
+
null_sink = StatsD::Instrument::NullSink.new
|
10
|
+
null_sink << 'foo:1|c' << 'bar:1|c'
|
11
|
+
pass # We don't have anything to assert, except that no exception was raised
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'statsd/instrument/rubocop'
|
5
|
+
|
6
|
+
module Rubocop
|
7
|
+
class MeasureAsDistArgumentTest < Minitest::Test
|
8
|
+
include RubocopHelper
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@cop = RuboCop::Cop::StatsD::MeasureAsDistArgument.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_ok_for_metric_method_without_as_dist_argument
|
15
|
+
assert_no_offenses("StatsD.measure('foo', 123)")
|
16
|
+
assert_no_offenses("StatsD.measure('foo', 123, sample_rate: 3)")
|
17
|
+
assert_no_offenses("StatsD.measure('foo') {}")
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_ok_for_other_metric_methods
|
21
|
+
assert_no_offenses("StatsD.increment('foo', as_dist: true)")
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_ok_for_metaprogramming_method_without_as_dist_argument
|
25
|
+
assert_no_offenses("statsd_measure(:method, 'metric_name', sample_rate: 1) {}")
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_ok_for_other_metaprogramming_methods
|
29
|
+
assert_no_offenses("statsd_distribution(:method, 'metric_name', as_dist: true) {}")
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_offense_when_using_as_dist_with_measure_metric_method
|
33
|
+
assert_offense("StatsD.measure('foo', 123, sample_rate: 1, as_dist: true, tags: ['foo'])")
|
34
|
+
assert_offense("StatsD.measure('foo', 123, as_dist: false)")
|
35
|
+
assert_offense("StatsD.measure('foo', as_dist: true, &block)")
|
36
|
+
assert_offense("StatsD.measure('foo', as_dist: true) { } ")
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_offense_when_using_as_dist_with_measure_metaprogramming_method
|
40
|
+
assert_offense("statsd_measure(:method, 'foo', as_dist: true, &block)")
|
41
|
+
assert_offense("statsd_measure(:method, 'foo', as_dist: false) { } ")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'statsd/instrument/rubocop'
|
5
|
+
|
6
|
+
module Rubocop
|
7
|
+
class MetaprogrammingPositionalArgumentsTest < Minitest::Test
|
8
|
+
include RubocopHelper
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@cop = RuboCop::Cop::StatsD::MetaprogrammingPositionalArguments.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_ok_with_two_arguments
|
15
|
+
assert_no_offenses("ClassName.statsd_count_if(:method, 'metric') { foo }")
|
16
|
+
assert_no_offenses("ClassName.statsd_measure :method, 'metric'")
|
17
|
+
assert_no_offenses(<<~RUBY)
|
18
|
+
class Foo
|
19
|
+
statsd_count :method, 'metric'
|
20
|
+
end
|
21
|
+
RUBY
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_ok_with_keyword_arguments_and_blocks
|
25
|
+
assert_no_offenses("ClassName.statsd_measure :method, 'metric', foo: 'bar'")
|
26
|
+
assert_no_offenses("ClassName.statsd_count_success(:method, 'metric', **kwargs)")
|
27
|
+
assert_no_offenses("ClassName.statsd_measure(:method, 'metric', foo: 'bar', &block)")
|
28
|
+
assert_no_offenses(<<~RUBY)
|
29
|
+
class Foo
|
30
|
+
statsd_count_if(:method, 'metric', foo: 'bar', baz: 'quc') do |result|
|
31
|
+
result == 'ok'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
RUBY
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_offense_with_positional_arguments
|
38
|
+
assert_offense("ClassName.statsd_measure(:method, 'metric', 1)")
|
39
|
+
assert_offense("ClassName.statsd_measure(:method, 'metric', 1, ['tag'])")
|
40
|
+
assert_offense("ClassName.statsd_measure(:method, 'metric', 1, tag: 'value')")
|
41
|
+
assert_offense(<<~RUBY)
|
42
|
+
class Foo
|
43
|
+
extend StatsD::Instrument
|
44
|
+
statsd_measure(:method, 'metric', 1)
|
45
|
+
end
|
46
|
+
RUBY
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_offense_with_splat
|
50
|
+
assert_offense("ClassName.statsd_measure(:method, 'metric', *options)")
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_offense_with_constant_or_method_as_third_argument
|
54
|
+
assert_offense("ClassName.statsd_measure(:method, 'metric', SAMPLE_RATE_CONSTANT)")
|
55
|
+
assert_offense("ClassName.statsd_measure(:method, 'metric', method_returning_a_hash)")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|