Skip to content
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

Add Datadog::DeprecatedPin for phasing out Datadog::Pin usage #692

Merged
merged 1 commit into from
Feb 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions lib/ddtrace/pin.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'ddtrace/patcher'

# \Datadog global namespace that includes all tracing functionality for Tracer and Span classes.
module Datadog
# A \Pin (a.k.a Patch INfo) is a small class which is used to
Expand Down Expand Up @@ -67,4 +69,48 @@ def to_s
"Pin(service:#{service},app:#{app},app_type:#{app_type},name:#{name})"
end
end

# Modification to Pin which logs deprecation warnings if accessed.
# Will be used by integrations which are phasing out the direct use of #datadog_pin.
module DeprecatedPin
include Datadog::Patcher

DEPRECATION_WARNING = %(
Use of Datadog::Pin is DEPRECATED.
Upgrade to the configuration API using the migration guide here:
https://github.com/DataDog/dd-trace-rb/releases/tag/v0.11.0).freeze

# Raise a deprecation warning when #datadog_pin or #datadog_pin= is accessed.
def onto(obj)
obj.instance_exec(self) do |pin|
@datadog_deprecated_pin = pin

unless respond_to? :datadog_pin=
def datadog_pin=(pin)
@datadog_deprecated_pin.log_deprecation_warning('#datadog_pin=')
@datadog_pin = pin
end
end

unless respond_to? :datadog_pin
def datadog_pin
@datadog_deprecated_pin.log_deprecation_warning('#datadog_pin')
@datadog_pin
end
end

# Set instance variable to avoid deprecation warnings
@datadog_pin = @datadog_deprecated_pin
end

self
end

def log_deprecation_warning(method_name)
# Only log each deprecation warning once (safeguard against log spam)
do_once(method_name) do
Datadog::Tracer.log.warn("#{method_name}:#{DEPRECATION_WARNING}")
end
end
end
end
56 changes: 56 additions & 0 deletions spec/ddtrace/pin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,59 @@ def datadog_pin=(pin)
end
end
end

RSpec.describe Datadog::DeprecatedPin do
include_context 'tracer logging'

subject(:pin) { pin_class.new(service_name) }
let(:pin_class) { Class.new(Datadog::Pin) { include Datadog::DeprecatedPin } }
let(:service_name) { 'my_service' }

describe '#onto' do
before(:each) { pin.onto(object) }
let(:object) { Object.new }

let(:deprecation_warnings) do
[
/.*#datadog_pin.*/,
/.*Use of Datadog::Pin is DEPRECATED.*/
]
end

it 'does not generate deprecation warnings' do
expect(log_buffer.length).to eq(0)
expect(log_buffer).to_not contain_line_with(*deprecation_warnings)
expect(log_buffer).to_not contain_line_with(*deprecation_warnings)
end

context 'when invoked then followed by' do
describe 'Datadog::Pin.get_from' do
before(:each) { Datadog::Pin.get_from(object) }
it { expect(log_buffer).to contain_line_with(*deprecation_warnings).once }

context 'twice' do
it { expect(log_buffer).to contain_line_with(*deprecation_warnings).once }
end
end

describe '#datadog_pin' do
before(:each) { object.datadog_pin }
it { expect(log_buffer).to contain_line_with(*deprecation_warnings).once }

context 'twice' do
it { expect(log_buffer).to contain_line_with(*deprecation_warnings).once }
end
end

describe '#datadog_pin=' do
before(:each) { object.datadog_pin = new_pin }
let(:new_pin) { Datadog::Pin.new('new_service') }
it { expect(log_buffer).to contain_line_with(*deprecation_warnings).once }

context 'twice' do
it { expect(log_buffer).to contain_line_with(*deprecation_warnings).once }
end
end
end
end
end
74 changes: 74 additions & 0 deletions spec/support/log_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,78 @@ def without_errors
Datadog::Tracer.log.level = level
end
end

shared_context 'tracer logging' do
let(:log_buffer) { StringIO.new }

before(:each) do
@default_logger = Datadog::Tracer.log
Datadog::Tracer.log = Datadog::Logger.new(log_buffer)
Datadog::Tracer.log.level = ::Logger::WARN
end

after(:each) do
Datadog::Tracer.log = @default_logger
end

# Checks buffer to see if it contains lines that match all patterns.
# Limited to only checking for one kind of message.
RSpec::Matchers.define :contain_line_with do |*patterns|
attr_accessor \
:comparison,
:repetitions

match do |buffer|
repetitions ||= 1

# Creates a Hash that counts number of matches per pattern e.g. 'a' => 0, 'b' => 0
pattern_matches = Hash[patterns.zip(Array.new(patterns.length) { 0 })]

# Test below iterates on lines, this is required for Ruby 1.9 backward compatibility.
# Scans each pattern against each line, increments count if it matches.
lines = buffer.string.lines
lines.each do |line|
pattern_matches.keys.each do |pattern|
pattern_matches[pattern] += 1 if line.match(pattern)
end
end

# If all patterns were matched for required number of repetitions: success.
patterns_match_expectations = pattern_matches.values.all? do |value|
case comparison
when :gte
value >= repetitions
when :lte
value <= repetitions
else
value == repetitions
end
end

expect(patterns_match_expectations).to be true
end

chain :at_least do |count|
@repetitions = count
@comparison = :gte
end

chain :no_more_than do |count|
@repetitions = count
@comparison = :lte
end

chain :exactly do |count|
@repetitions = count
end

chain :times do
# Do nothing
end

chain :once do
@repetitions = 1
end
end
end
end