-
Notifications
You must be signed in to change notification settings - Fork 137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rewrite specs using rspec #135
Conversation
878b808
to
179f9e6
Compare
e3eb299
to
7c1e15d
Compare
@@ -28,6 +28,9 @@ def send_message(message) | |||
socket.sendmsg_nonblock(message) | |||
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ENOENT => e | |||
@socket = nil | |||
# TODO: FIXME: This error should be considered as a retryable error in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found this bug, it was not caught by the previous tests: If we catch a connection refused or reset, we don't try to reconnect to the UDS socket. For the missing socket, it seems relevant, it means that the socket was never found, but for other cases, I think we should retry.
30907e1
to
9603e9f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it could be worth keeping some of the old tests that were more like integration/high level? Aren't we reducing the coverage?
spec/matchers/telemetry_matcher.rb
Outdated
RSpec::Matchers.define :eq_with_telemetry do |expected, telemetry_options| | ||
telemetry_options ||= {} | ||
|
||
def text_with_telemetry(text, metrics: 1, events: 0, service_checks: 0, bytes_sent: 0, bytes_dropped:0, packets_sent: 0, packets_dropped: 0, transport: 'udp') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def text_with_telemetry(text, metrics: 1, events: 0, service_checks: 0, bytes_sent: 0, bytes_dropped:0, packets_sent: 0, packets_dropped: 0, transport: 'udp') | |
# Appends the telemetry metrics to the metrics string passed as 'text' | |
def add_telemetry(text, metrics: 1, events: 0, service_checks: 0, bytes_sent: 0, bytes_dropped:0, packets_sent: 0, packets_dropped: 0, transport: 'udp') |
Better function name (I think).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is!
spec/matchers/telemetry_matcher.rb
Outdated
end | ||
|
||
match do |actual| | ||
actual == text_with_telemetry(expected, **telemetry_options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actual == text_with_telemetry(expected, **telemetry_options) | |
actual == add_telemetry(expected, **telemetry_options) |
spec/statsd/version_spec.rb
Outdated
describe Datadog::Statsd do | ||
describe 'VERSION' do | ||
it 'has a version' do | ||
expect(Datadog::Statsd::VERSION).to eq '4.6.0' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will need to update this for every version. Isn't it better to use a regex like before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this part to be explicit everytime we release but I can change it to a regexp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's properly update the release documentation then, let me know if you need the link to the document I'm mentioning
spec/integrations/allocation_spec.rb
Outdated
end | ||
|
||
let(:expected_allocations) do | ||
if RUBY_VERSION >= '2.3.0' && RUBY_VERSION < '2.4.0' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if RUBY_VERSION >= '2.3.0' && RUBY_VERSION < '2.4.0' | |
if RUBY_VERSION < '2.4.0' |
Otherwise, older rubies would fall in the else
case, which isn't what this code wants to express.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is what I wanted :). Older rubies make 8 allocations in this case.
spec/integrations/allocation_spec.rb
Outdated
end | ||
|
||
let(:expected_allocations) do | ||
if RUBY_VERSION >= '2.3.0' && RUBY_VERSION < '2.4.0' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if RUBY_VERSION >= '2.3.0' && RUBY_VERSION < '2.4.0' | |
if RUBY_VERSION < '2.4.0' |
idem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is what I wanted :). Older rubies make 8 allocations in this case.
9603e9f
to
4cbbd8e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did my best to review this carefully but I won't lie, I may have been a bit fast on some of the tests.
In all cases, great update and it'll definitely be helpful to have solid unit testing on this lib. Thanks 🙇
lib/datadog/statsd/version.rb
Outdated
|
||
module Datadog | ||
class Statsd | ||
VERSION = '4.6.0' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: it's most likely 4.7.0
now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll fix it :)
spec/statsd/version_spec.rb
Outdated
describe Datadog::Statsd do | ||
describe 'VERSION' do | ||
it 'has a version' do | ||
expect(Datadog::Statsd::VERSION).to eq '4.6.0' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's properly update the release documentation then, let me know if you need the link to the document I'm mentioning
context 'because of an unknown error' do | ||
before do | ||
allow(fake_socket_retry) | ||
.to receive(:send) | ||
.and_raise(RuntimeError, 'yolo') | ||
end | ||
|
||
it 'ignores the connection failure' do | ||
expect do | ||
subject.write('foobar') | ||
end.not_to raise_error | ||
end | ||
|
||
it 'logs the error message' do | ||
subject.write('foobar') | ||
expect(log.string).to match 'Statsd: RuntimeError yolo' | ||
end | ||
end | ||
|
||
context 'because of a SocketError' do | ||
before do | ||
allow(fake_socket_retry) | ||
.to receive(:send) | ||
.and_raise(SocketError, 'yolo') | ||
end | ||
|
||
it 'ignores the connection failure' do | ||
expect do | ||
subject.write('foobar') | ||
end.not_to raise_error | ||
end | ||
|
||
it 'logs the error message' do | ||
subject.write('foobar') | ||
expect(log.string).to match 'Statsd: SocketError yolo' | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't they testing the same thing? I'm may miss a subtlety here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, just to be sure that we don't handle socketerrors differently.
statsd = Datadog::Statsd.new(host, port) | ||
statsd.increment('foobar') | ||
message = socket.recvfrom(64).first | ||
expect(message).to eq 'foobar:1|c' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we test more than just a counter? Probably not has you improved the test coverage on everything but if that's like 2, 4 more lines, could be helpful someday.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could make a big test for that. I'll add it.
let(:sample_rate) { nil } | ||
let(:socket) { FakeUDPSocket.new } | ||
let(:tags) { %w[abc def] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it doesn't harm, let's use tags just slightly more realistic: for instance abc:def host:myhost12-11
, WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually you did it right after, nvm.
4cbbd8e
to
3d6e252
Compare
We discovered that there is a bug with which strategy each error has to have. Connection refused or connection reset are not retried on UDS Connections.
3d6e252
to
f698c8d
Compare
What does this PR?
It rewrites the tests using RSpec and mocking in the idea of refactoring the project to have more SOLID code. Some tests are still breaking encapsulation and fixing them implies to modify the code to make it more testable and uncoupled.
Motivation
Clarify the project, use more recent testing techniques and allowing people to contribute easily + making grounds to refactor the project.
Notes
Found a bug, notified it in comment.