diff --git a/Rakefile b/Rakefile index 38ec48a0d0c..3358c148a6b 100644 --- a/Rakefile +++ b/Rakefile @@ -121,7 +121,7 @@ end namespace :test do task all: [:main, :rails, - :sidekiq, :monkey] + :monkey] Rake::TestTask.new(:main) do |t| t.libs << %w[test lib] @@ -140,7 +140,6 @@ namespace :test do [ :grape, - :sidekiq, :sucker_punch ].each do |contrib| Rake::TestTask.new(contrib) do |t| @@ -199,7 +198,6 @@ task :ci do if RUBY_PLATFORM != 'java' # Contrib minitests sh 'bundle exec appraisal contrib-old rake test:monkey' - sh 'bundle exec appraisal contrib-old rake test:sidekiq' sh 'bundle exec appraisal contrib-old rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib-old rake spec:active_model_serializers' @@ -256,7 +254,6 @@ task :ci do if RUBY_PLATFORM != 'java' # Contrib minitests sh 'bundle exec appraisal contrib-old rake test:monkey' - sh 'bundle exec appraisal contrib-old rake test:sidekiq' sh 'bundle exec appraisal contrib-old rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib-old rake spec:active_model_serializers' @@ -320,7 +317,6 @@ task :ci do if RUBY_PLATFORM != 'java' # Contrib minitests sh 'bundle exec appraisal contrib rake test:grape' - sh 'bundle exec appraisal contrib rake test:sidekiq' sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' @@ -395,7 +391,6 @@ task :ci do if RUBY_PLATFORM != 'java' # Contrib minitests sh 'bundle exec appraisal contrib rake test:grape' - sh 'bundle exec appraisal contrib rake test:sidekiq' sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' @@ -475,7 +470,6 @@ task :ci do sh 'bundle exec rake benchmark' # Contrib minitests sh 'bundle exec appraisal contrib rake test:grape' - sh 'bundle exec appraisal contrib rake test:sidekiq' sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' @@ -540,7 +534,6 @@ task :ci do sh 'bundle exec rake benchmark' # Contrib minitests sh 'bundle exec appraisal contrib rake test:grape' - sh 'bundle exec appraisal contrib rake test:sidekiq' sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' @@ -615,7 +608,6 @@ task :ci do sh 'bundle exec rake benchmark' # Contrib minitests sh 'bundle exec appraisal contrib rake test:grape' - sh 'bundle exec appraisal contrib rake test:sidekiq' sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' @@ -689,7 +681,6 @@ task :ci do sh 'bundle exec rake benchmark' # Contrib minitests sh 'bundle exec appraisal contrib rake test:grape' - sh 'bundle exec appraisal contrib rake test:sidekiq' sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' diff --git a/spec/ddtrace/contrib/sidekiq/client_tracer_spec.rb b/spec/ddtrace/contrib/sidekiq/client_tracer_spec.rb new file mode 100644 index 00000000000..cfe88d79023 --- /dev/null +++ b/spec/ddtrace/contrib/sidekiq/client_tracer_spec.rb @@ -0,0 +1,70 @@ +require 'ddtrace/contrib/support/spec_helper' +require_relative 'support/helper' + +RSpec.describe 'ClientTracerTest' do + include_context 'Sidekiq testing' + + subject(:perform_async) { job_class.perform_async } + let(:job_class) { EmptyWorker } + + before do + Sidekiq.configure_client do |config| + config.client_middleware.clear + config.client_middleware do |chain| + chain.add(Datadog::Contrib::Sidekiq::ClientTracer) + end + end + + Sidekiq::Testing.server_middleware.clear + Sidekiq::Extensions.enable_delay! if Sidekiq::VERSION > '5.0.0' + end + + it 'traces job push' do + perform_async + + expect(span.service).to eq('sidekiq-client') + expect(span.resource).to eq('EmptyWorker') + expect(span.get_tag('sidekiq.job.queue')).to eq('default') + expect(span.status).to eq(0) + expect(span.parent).to be_nil + expect(span.get_metric('_dd.measured')).to be_nil + end + + context 'with nested trace' do + it 'traces job push' do + tracer.trace('parent.span', service: 'parent-service') do + perform_async + end + + expect(spans).to have(2).items + + parent_span, child_span = spans + + expect(parent_span.name).to eq('parent.span') + expect(parent_span.status).to eq(0) + expect(parent_span.parent).to be_nil + + expect(child_span.service).to eq('sidekiq-client') + expect(child_span.resource).to eq('EmptyWorker') + expect(child_span.get_tag('sidekiq.job.queue')).to eq('default') + expect(child_span.status).to eq(0) + expect(child_span.parent).to eq(parent_span) + expect(child_span.get_metric('_dd.measured')).to be_nil + end + end + + context 'with delayed extensions' do + subject(:do_work) { DelayableClass.delay.do_work } + + before do + stub_const('DelayableClass', Class.new do + def self.do_work; end + end) + end + + it 'traces with correct resource' do + do_work + expect(spans.first.resource).to eq('DelayableClass.do_work') + end + end +end diff --git a/spec/ddtrace/contrib/sidekiq/disabled_tracer_spec.rb b/spec/ddtrace/contrib/sidekiq/disabled_tracer_spec.rb new file mode 100644 index 00000000000..d8a972e4e39 --- /dev/null +++ b/spec/ddtrace/contrib/sidekiq/disabled_tracer_spec.rb @@ -0,0 +1,23 @@ +require 'ddtrace/contrib/support/spec_helper' +require_relative 'support/helper' + +RSpec.describe 'Disabled tracer' do + include_context 'Sidekiq testing' + + subject(:perform_async) { job_class.perform_async } + let(:job_class) { EmptyWorker } + + before do + Sidekiq::Testing.server_middleware.clear + Sidekiq::Testing.server_middleware do |chain| + Datadog.tracer.configure(enabled: false) + chain.add(Datadog::Contrib::Sidekiq::ServerTracer) + end + end + + it 'does not trace' do + perform_async + + expect(spans).to be_empty + end +end diff --git a/spec/ddtrace/contrib/sidekiq/server_tracer_spec.rb b/spec/ddtrace/contrib/sidekiq/server_tracer_spec.rb new file mode 100644 index 00000000000..cdeee073ac0 --- /dev/null +++ b/spec/ddtrace/contrib/sidekiq/server_tracer_spec.rb @@ -0,0 +1,119 @@ +require 'ddtrace/contrib/support/spec_helper' +require_relative 'support/helper' + +RSpec.describe 'Server tracer' do + include_context 'Sidekiq testing' + + subject(:perform_async) { job_class.perform_async } + let(:job_class) { EmptyWorker } + + before do + Sidekiq::Testing.server_middleware.clear + Sidekiq::Testing.server_middleware do |chain| + chain.add(Datadog::Contrib::Sidekiq::ServerTracer) + end + + Sidekiq::Extensions.enable_delay! if Sidekiq::VERSION > '5.0.0' + end + + it 'traces async job run' do + perform_async + + expect(spans).to have(2).items + + span, _push = spans + expect(span.service).to eq('sidekiq') + expect(span.resource).to eq('EmptyWorker') + expect(span.get_tag('sidekiq.job.queue')).to eq('default') + expect(span.get_tag('sidekiq.job.delay')).to_not be_nil + expect(span.status).to eq(0) + expect(span.parent).to be_nil + expect(span.get_tag('sidekiq.job.args')).to be_nil + expect(span.get_metric('_dd.measured')).to eq(1.0) + end + + context 'with job run failing' do + let(:job_class) { ErrorWorker } + + before do + stub_const('ErrorWorker', Class.new do + include Sidekiq::Worker + + def perform + raise ZeroDivisionError, 'job error' + end + end) + end + + it 'traces async job run' do + expect { perform_async }.to raise_error(ZeroDivisionError) + expect(spans).to have(2).items + + span, _push = spans + expect(span.service).to eq('sidekiq') + expect(span.resource).to eq('ErrorWorker') + expect(span.get_tag('sidekiq.job.queue')).to eq('default') + expect(span.get_tag('sidekiq.job.delay')).to_not be_nil + expect(span.status).to eq(1) + expect(span.get_tag(Datadog::Ext::Errors::MSG)).to eq('job error') + expect(span.get_tag(Datadog::Ext::Errors::TYPE)).to eq('ZeroDivisionError') + expect(span.parent).to be_nil + expect(span.get_tag('sidekiq.job.args')).to be_nil + expect(span.get_metric('_dd.measured')).to eq(1.0) + end + end + + context 'with custom job' do + before do + stub_const('CustomWorker', Class.new do + include Sidekiq::Worker + + def self.datadog_tracer_config + { service_name: 'sidekiq-slow', tag_args: true } + end + + def perform(_) end + end) + end + + it 'traces async job run' do + perform_async + CustomWorker.perform_async('random_id') + + expect(spans).to have(4).items + + custom, empty, _push, _push = spans + + expect(empty.service).to eq('sidekiq') + expect(empty.resource).to eq('EmptyWorker') + expect(empty.get_tag('sidekiq.job.queue')).to eq('default') + expect(empty.get_tag('sidekiq.job.delay')).to_not be_nil + expect(empty.status).to eq(0) + expect(empty.parent).to be_nil + expect(empty.get_metric('_dd.measured')).to eq(1.0) + + expect(custom.service).to eq('sidekiq-slow') + expect(custom.resource).to eq('CustomWorker') + expect(custom.get_tag('sidekiq.job.queue')).to eq('default') + expect(custom.status).to eq(0) + expect(custom.parent).to be_nil + expect(custom.get_tag('sidekiq.job.args')).to eq(['random_id'].to_s) + expect(custom.get_metric('_dd.measured')).to eq(1.0) + end + end + + context 'with delayed extensions' do + subject(:do_work) { DelayableClass.delay.do_work } + + before do + stub_const('DelayableClass', Class.new do + def self.do_work; end + end) + end + + it 'traces with correct resource' do + do_work + expect(spans.first.resource).to eq('DelayableClass.do_work') + end + end +end diff --git a/test/contrib/sidekiq/tracer_test_base.rb b/spec/ddtrace/contrib/sidekiq/support/helper.rb similarity index 54% rename from test/contrib/sidekiq/tracer_test_base.rb rename to spec/ddtrace/contrib/sidekiq/support/helper.rb index 73f795225a9..8635102d91c 100644 --- a/test/contrib/sidekiq/tracer_test_base.rb +++ b/spec/ddtrace/contrib/sidekiq/support/helper.rb @@ -1,22 +1,18 @@ - require 'sidekiq/testing' require 'ddtrace' require 'ddtrace/contrib/sidekiq/client_tracer' require 'ddtrace/contrib/sidekiq/server_tracer' -require 'helper' - -class TracerTestBase < Minitest::Test - include TestTracerHelper - REDIS_HOST = ENV.fetch('TEST_REDIS_HOST', '127.0.0.1').freeze - REDIS_PORT = ENV.fetch('TEST_REDIS_PORT', 6379) +RSpec.shared_context 'Sidekiq testing' do + let(:redis_host) { ENV.fetch('TEST_REDIS_HOST', '127.0.0.1') } + let(:redis_port) { ENV.fetch('TEST_REDIS_PORT', 6379) } - def configure + before do Datadog.configure do |c| c.use :sidekiq end - redis_url = "redis://#{REDIS_HOST}:#{REDIS_PORT}" + redis_url = "redis://#{redis_host}:#{redis_port}" Sidekiq.configure_client do |config| config.redis = { url: redis_url } @@ -29,7 +25,10 @@ def configure Sidekiq::Testing.inline! end - def writer - @tracer.writer + let!(:empty_worker) do + stub_const('EmptyWorker', Class.new do + include Sidekiq::Worker + def perform; end + end) end end diff --git a/spec/ddtrace/contrib/sidekiq/tracer_configure_spec.rb b/spec/ddtrace/contrib/sidekiq/tracer_configure_spec.rb new file mode 100644 index 00000000000..a237803764e --- /dev/null +++ b/spec/ddtrace/contrib/sidekiq/tracer_configure_spec.rb @@ -0,0 +1,29 @@ +require 'ddtrace/contrib/support/spec_helper' +require_relative 'support/helper' + +RSpec.describe 'Tracer configuration' do + include_context 'Sidekiq testing' + + subject(:perform_async) { job_class.perform_async } + let(:job_class) { EmptyWorker } + + context 'with custom middleware configuration' do + before do + Sidekiq::Testing.server_middleware do |chain| + chain.add( + Datadog::Contrib::Sidekiq::ServerTracer, + service_name: 'my-service' + ) + end + end + + it 'instruments with custom values' do + perform_async + + expect(spans).to have(2).items + + span, _push = spans + expect(span.service).to eq('my-service') + end + end +end diff --git a/test/contrib/sidekiq/client_tracer_test.rb b/test/contrib/sidekiq/client_tracer_test.rb deleted file mode 100644 index 7e41345193a..00000000000 --- a/test/contrib/sidekiq/client_tracer_test.rb +++ /dev/null @@ -1,68 +0,0 @@ -require 'contrib/sidekiq/tracer_test_base' - -class ClientTracerTest < TracerTestBase - class EmptyWorker - include Sidekiq::Worker - - def perform(); end - end - - class DelayableClass - def self.do_work; end - end - - def setup - super - - Sidekiq.configure_client do |config| - config.client_middleware.clear - - config.client_middleware do |chain| - chain.add(Datadog::Contrib::Sidekiq::ClientTracer, enabled: true) - end - end - - Sidekiq::Testing.server_middleware.clear - Sidekiq::Extensions.enable_delay! if Sidekiq::VERSION > '5.0.0' - end - - def test_empty - tracer.trace('parent.span', service: 'parent-service') do - EmptyWorker.perform_async - end - - assert_equal(2, spans.length) - - parent_span, child_span = spans - - assert_equal('parent.span', parent_span.name) - assert_equal(0, parent_span.status) - assert_nil(parent_span.parent) - - assert_equal('sidekiq-client', child_span.service) - assert_equal('ClientTracerTest::EmptyWorker', child_span.resource) - assert_equal('default', child_span.get_tag('sidekiq.job.queue')) - assert_equal(0, child_span.status) - assert_equal(parent_span, child_span.parent) - assert_nil(child_span.get_metric('_dd.measured')) - end - - def test_empty_parentless - EmptyWorker.perform_async - - assert_equal(1, spans.length) - - span = spans.first - assert_equal('sidekiq-client', span.service) - assert_equal('ClientTracerTest::EmptyWorker', span.resource) - assert_equal('default', span.get_tag('sidekiq.job.queue')) - assert_equal(0, span.status) - assert_nil(span.parent) - assert_nil(span.get_metric('_dd.measured')) - end - - def test_delayed_extensions - DelayableClass.delay.do_work - assert_equal('ClientTracerTest::DelayableClass.do_work', spans.first.resource) - end -end diff --git a/test/contrib/sidekiq/disabled_tracer_test.rb b/test/contrib/sidekiq/disabled_tracer_test.rb deleted file mode 100644 index 30c52269386..00000000000 --- a/test/contrib/sidekiq/disabled_tracer_test.rb +++ /dev/null @@ -1,25 +0,0 @@ - -require 'contrib/sidekiq/tracer_test_base' - -class DisabledTracerTest < TracerTestBase - class EmptyWorker - include Sidekiq::Worker - - def perform; end - end - - def setup - super - - Sidekiq::Testing.server_middleware do |chain| - Datadog.tracer.configure(enabled: false) - chain.add(Datadog::Contrib::Sidekiq::ServerTracer) - end - end - - def test_empty - EmptyWorker.perform_async() - - assert_equal(0, spans.length) - end -end diff --git a/test/contrib/sidekiq/server_tracer_test.rb b/test/contrib/sidekiq/server_tracer_test.rb deleted file mode 100644 index 5590ebedcf1..00000000000 --- a/test/contrib/sidekiq/server_tracer_test.rb +++ /dev/null @@ -1,110 +0,0 @@ -require 'contrib/sidekiq/tracer_test_base' - -class ServerTracerTest < TracerTestBase - class TestError < StandardError; end - - class EmptyWorker - include Sidekiq::Worker - - def perform(); end - end - - class ErrorWorker - include Sidekiq::Worker - - def perform - raise TestError, 'job error' - end - end - - class CustomWorker - include Sidekiq::Worker - - def self.datadog_tracer_config - { service_name: 'sidekiq-slow', tag_args: true } - end - - def perform(args); end - end - - class DelayableClass - def self.do_work; end - end - - def setup - super - - Sidekiq::Testing.server_middleware do |chain| - chain.add(Datadog::Contrib::Sidekiq::ServerTracer, enabled: true) - end - Sidekiq::Extensions.enable_delay! if Sidekiq::VERSION > '5.0.0' - end - - def test_empty - EmptyWorker.perform_async() - - assert_equal(2, spans.length) - - span, _push = spans - assert_equal('sidekiq', span.service) - assert_equal('ServerTracerTest::EmptyWorker', span.resource) - assert_equal('default', span.get_tag('sidekiq.job.queue')) - refute_nil(span.get_tag('sidekiq.job.delay')) - assert_equal(0, span.status) - assert_nil(span.parent) - assert_nil(span.get_tag('sidekiq.job.args')) - assert_equal(span.get_metric('_dd.measured'), 1.0) - end - - # rubocop:disable Lint/HandleExceptions - def test_error - begin - ErrorWorker.perform_async() - rescue TestError - end - - assert_equal(2, spans.length) - - span, _push = spans - assert_equal('sidekiq', span.service) - assert_equal('ServerTracerTest::ErrorWorker', span.resource) - assert_equal('default', span.get_tag('sidekiq.job.queue')) - refute_nil(span.get_tag('sidekiq.job.delay')) - assert_equal(1, span.status) - assert_equal('job error', span.get_tag(Datadog::Ext::Errors::MSG)) - assert_equal('ServerTracerTest::TestError', span.get_tag(Datadog::Ext::Errors::TYPE)) - assert_nil(span.parent) - assert_nil(span.get_tag('sidekiq.job.args')) - assert_equal(span.get_metric('_dd.measured'), 1.0) - end - - def test_custom - EmptyWorker.perform_async() - CustomWorker.perform_async('random_id') - - assert_equal(4, spans.length) - - custom, empty, _push, _push = spans - - assert_equal('sidekiq', empty.service) - assert_equal('ServerTracerTest::EmptyWorker', empty.resource) - assert_equal('default', empty.get_tag('sidekiq.job.queue')) - refute_nil(empty.get_tag('sidekiq.job.delay')) - assert_equal(0, empty.status) - assert_nil(empty.parent) - assert_equal(empty.get_metric('_dd.measured'), 1.0) - - assert_equal('sidekiq-slow', custom.service) - assert_equal('ServerTracerTest::CustomWorker', custom.resource) - assert_equal('default', custom.get_tag('sidekiq.job.queue')) - assert_equal(0, custom.status) - assert_nil(custom.parent) - assert_equal(['random_id'].to_s, custom.get_tag('sidekiq.job.args')) - assert_equal(custom.get_metric('_dd.measured'), 1.0) - end - - def test_delayed_extensions - DelayableClass.delay.do_work - assert_equal('ServerTracerTest::DelayableClass.do_work', spans.first.resource) - end -end diff --git a/test/contrib/sidekiq/tracer_configure_test.rb b/test/contrib/sidekiq/tracer_configure_test.rb deleted file mode 100644 index ca3b404d263..00000000000 --- a/test/contrib/sidekiq/tracer_configure_test.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'contrib/sidekiq/tracer_test_base' - -class TracerTest < TracerTestBase - class EmptyWorker - include Sidekiq::Worker - - def perform(); end - end - - def test_configuration_defaults - # it should configure the tracer with reasonable defaults - Sidekiq::Testing.server_middleware do |chain| - chain.add(Datadog::Contrib::Sidekiq::ServerTracer) - end - EmptyWorker.perform_async() - end - - def test_configuration_custom - # it should configure the tracer with users' settings - Datadog.tracer.configure(enabled: false) - Sidekiq::Testing.server_middleware do |chain| - chain.add( - Datadog::Contrib::Sidekiq::ServerTracer, - service_name: 'my-sidekiq' - ) - end - EmptyWorker.perform_async() - end -end