Skip to content

Commit

Permalink
Merge pull request #692 from DataDog/refactor/add_deprecated_pin
Browse files Browse the repository at this point in the history
Add Datadog::DeprecatedPin for phasing out Datadog::Pin usage
  • Loading branch information
delner authored Feb 19, 2019
2 parents ff0bad4 + 973da4a commit fe4ed1a
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 0 deletions.
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

0 comments on commit fe4ed1a

Please sign in to comment.