diff --git a/Rakefile b/Rakefile index ee1945dc64..6ffb6c9ef2 100644 --- a/Rakefile +++ b/Rakefile @@ -142,7 +142,6 @@ namespace :test do end [ - :sucker_punch ].each do |contrib| Rake::TestTask.new(contrib) do |t| t.libs << %w[test lib] @@ -200,7 +199,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:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib-old rake spec:active_model_serializers' sh 'bundle exec appraisal contrib-old rake spec:active_record' @@ -257,7 +255,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:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib-old rake spec:active_model_serializers' sh 'bundle exec appraisal contrib-old rake spec:active_record' @@ -320,7 +317,6 @@ task :ci do if RUBY_PLATFORM != 'java' # Contrib minitests - sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' sh 'bundle exec appraisal contrib rake spec:action_view' @@ -395,7 +391,6 @@ task :ci do if RUBY_PLATFORM != 'java' # Contrib minitests - sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' sh 'bundle exec appraisal contrib rake spec:action_view' @@ -475,7 +470,6 @@ task :ci do # Benchmarks sh 'bundle exec rake benchmark' # Contrib minitests - sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' sh 'bundle exec appraisal contrib rake spec:action_view' @@ -537,7 +531,6 @@ task :ci do sh 'bundle exec rake spec:benchmark' if RUBY_PLATFORM != 'java' # Too slow due to repeated JVM instantiation sh 'bundle exec rake benchmark' # Contrib minitests - sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' sh 'bundle exec appraisal contrib rake spec:action_view' @@ -611,7 +604,6 @@ task :ci do # Benchmarks sh 'bundle exec rake benchmark' # Contrib minitests - sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' sh 'bundle exec appraisal contrib rake spec:action_view' @@ -685,7 +677,6 @@ task :ci do # Benchmarks sh 'bundle exec rake benchmark' # Contrib minitests - sh 'bundle exec appraisal contrib rake test:sucker_punch' # Contrib specs sh 'bundle exec appraisal contrib rake spec:action_pack' sh 'bundle exec appraisal contrib rake spec:action_view' diff --git a/spec/ddtrace/contrib/sucker_punch/patcher_spec.rb b/spec/ddtrace/contrib/sucker_punch/patcher_spec.rb new file mode 100644 index 0000000000..01626ee390 --- /dev/null +++ b/spec/ddtrace/contrib/sucker_punch/patcher_spec.rb @@ -0,0 +1,128 @@ +require 'ddtrace/contrib/support/spec_helper' +require 'ddtrace/contrib/analytics_examples' +require 'sucker_punch' +require 'ddtrace' + +RSpec.describe 'sucker_punch instrumentation' do + before do + Datadog.configure do |c| + c.use :sucker_punch + end + + SuckerPunch::Queue.clear + SuckerPunch::RUNNING.make_true + end + + after do + SuckerPunch::Queue.clear + end + + around do |example| + # Reset before and after each example; don't allow global state to linger. + Datadog.registry[:sucker_punch].reset_configuration! + example.run + Datadog.registry[:sucker_punch].reset_configuration! + end + + let(:worker_class) do + Class.new do + include SuckerPunch::Job + + def perform(action = :none) + 1 / 0 if action == :fail + end + end + end + + context 'successful job' do + subject(:dummy_worker_success) { worker_class.perform_async } + let(:job_span) { spans.find { |s| s.resource[/PROCESS/] } } + let(:enqueue_span) { spans.find { |s| s.resource[/ENQUEUE/] } } + let(:span) { spans.first } + + it_behaves_like 'measured span for integration', true do + before do + dummy_worker_success + try_wait_until { fetch_spans.any? } + end + end + + it 'should generate two spans, one for pushing to enqueue and one for the job itself' do + is_expected.to be true + try_wait_until { fetch_spans.length == 2 } + expect(spans.length).to eq(2) + end + + it 'should instrument successful job' do + is_expected.to be true + try_wait_until { fetch_spans.length == 2 } + + expect(job_span.service).to eq('sucker_punch') + expect(job_span.name).to eq('sucker_punch.perform') + expect(job_span.resource).to eq("PROCESS #{worker_class}") + expect(job_span.get_tag('sucker_punch.queue')).to eq(worker_class.to_s) + expect(job_span.status).not_to eq(Datadog::Ext::Errors::STATUS) + end + + it 'should instrument successful enqueuing' do + is_expected.to be true + try_wait_until { fetch_spans.any? } + + expect(enqueue_span.service).to eq('sucker_punch') + expect(enqueue_span.name).to eq('sucker_punch.perform_async') + expect(enqueue_span.resource).to eq("ENQUEUE #{worker_class}") + expect(enqueue_span.get_tag('sucker_punch.queue')).to eq(worker_class.to_s) + expect(enqueue_span.get_metric('_dd.measured')).to eq(1.0) + end + end + + context 'failed job' do + subject(:dummy_worker_fail) { worker_class.perform_async(:fail) } + let(:job_span) { spans.find { |s| s.resource[/PROCESS/] } } + let(:span) { spans.first } + + it_behaves_like 'measured span for integration', true do + before do + dummy_worker_fail + try_wait_until { fetch_spans.any? } + end + end + + it 'should instrument a failed job' do + is_expected.to be true + try_wait_until { fetch_spans.length == 2 } + + expect(job_span.service).to eq('sucker_punch') + expect(job_span.name).to eq('sucker_punch.perform') + expect(job_span.resource).to eq("PROCESS #{worker_class}") + expect(job_span.get_tag('sucker_punch.queue')).to eq(worker_class.to_s) + expect(job_span).to have_error + expect(job_span).to have_error_type('ZeroDivisionError') + expect(job_span).to have_error_message('divided by 0') + end + end + + context 'delayed job' do + subject(:dummy_worker_delay) { worker_class.perform_in(0) } + let(:enqueue_span) { spans.find { |s| s.resource[/ENQUEUE/] } } + let(:span) { spans.first } + + it_behaves_like 'measured span for integration', true do + before do + dummy_worker_delay + try_wait_until { fetch_spans.any? } + end + end + + it 'should instrument enqueuing for a delayed job' do + is_expected.to be true + try_wait_until { fetch_spans.any? } + + expect(enqueue_span.service).to eq('sucker_punch') + expect(enqueue_span.name).to eq('sucker_punch.perform_in') + expect(enqueue_span.resource).to eq("ENQUEUE #{worker_class}") + expect(enqueue_span.get_tag('sucker_punch.queue')).to eq(worker_class.to_s) + expect(enqueue_span.get_tag('sucker_punch.perform_in')).to eq(0) + end + end +end diff --git a/test/contrib/sucker_punch/dummy_worker.rb b/test/contrib/sucker_punch/dummy_worker.rb deleted file mode 100644 index 980b077bf7..0000000000 --- a/test/contrib/sucker_punch/dummy_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'sucker_punch' - -class DummyWorker - include ::SuckerPunch::Job - - def perform(action = :none) - 1 / 0 if action == :fail - end -end diff --git a/test/contrib/sucker_punch/patcher_test.rb b/test/contrib/sucker_punch/patcher_test.rb deleted file mode 100644 index c627e1877a..0000000000 --- a/test/contrib/sucker_punch/patcher_test.rb +++ /dev/null @@ -1,97 +0,0 @@ -require 'helper' -require 'sucker_punch' -require 'ddtrace' -require_relative 'dummy_worker' - -module Datadog - module Contrib - module SuckerPunch - class PatcherTest < Minitest::Test - include TestTracerHelper - def integration_name - :sucker_punch - end - - def teardown - ::SuckerPunch::Queue.shutdown_all - end - - def configure - Datadog.configure do |c| - c.use :sucker_punch - end - - ::SuckerPunch::Queue.clear - ::SuckerPunch::RUNNING.make_true - end - - def test_two_spans_per_job - # One span when pushing to the queue - # One span for the job execution itself - ::DummyWorker.perform_async - try_wait_until { fetch_spans.length == 2 } - assert_equal(2, spans.length) - end - - def test_successful_job - ::DummyWorker.perform_async - try_wait_until { fetch_spans.length == 2 } - - span = spans.find { |s| s.resource[/PROCESS/] } - assert_equal('sucker_punch', span.service) - assert_equal('sucker_punch.perform', span.name) - assert_equal('PROCESS DummyWorker', span.resource) - assert_equal('DummyWorker', span.get_tag('sucker_punch.queue')) - refute_equal(Datadog::Ext::Errors::STATUS, span.status) - assert_equal(span.get_metric('_dd.measured'), 1.0) - end - - def test_failed_job - ::DummyWorker.perform_async(:fail) - try_wait_until { fetch_spans.length == 2 } - - span = spans.find { |s| s.resource[/PROCESS/] } - assert_equal('sucker_punch', span.service) - assert_equal('sucker_punch.perform', span.name) - assert_equal('PROCESS DummyWorker', span.resource) - assert_equal('DummyWorker', span.get_tag('sucker_punch.queue')) - assert_equal(Datadog::Ext::Errors::STATUS, span.status) - assert_equal('ZeroDivisionError', span.get_tag(Datadog::Ext::Errors::TYPE)) - assert_equal('divided by 0', span.get_tag(Datadog::Ext::Errors::MSG)) - assert_equal(span.get_metric('_dd.measured'), 1.0) - end - - def test_async_enqueueing - ::DummyWorker.perform_async - try_wait_until { fetch_spans.any? } - - span = spans.find { |s| s.resource[/ENQUEUE/] } - assert_equal('sucker_punch', span.service) - assert_equal('sucker_punch.perform_async', span.name) - assert_equal('ENQUEUE DummyWorker', span.resource) - assert_equal('DummyWorker', span.get_tag('sucker_punch.queue')) - assert_equal(span.get_metric('_dd.measured'), 1.0) - end - - def test_delayed_enqueueing - ::DummyWorker.perform_in(0) - try_wait_until { fetch_spans.any? } - - span = spans.find { |s| s.resource[/ENQUEUE/] } - assert_equal('sucker_punch', span.service) - assert_equal('sucker_punch.perform_in', span.name) - assert_equal('ENQUEUE DummyWorker', span.resource) - assert_equal('DummyWorker', span.get_tag('sucker_punch.queue')) - assert_equal(0, span.get_tag('sucker_punch.perform_in')) - assert_equal(span.get_metric('_dd.measured'), 1.0) - end - - private - - def pin - ::SuckerPunch.datadog_pin - end - end - end - end -end