Skip to content
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
2 changes: 1 addition & 1 deletion test/multiverse/lib/multiverse/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def execute_suites(filter, opts)

# these need services running in github actions, so they are separated
'services_1' => %w[mongo bunny],
'services_2' => %w[redis sidekiq sidekiq_delay_extensions memcache],
'services_2' => %w[redis sidekiq sidekiq_delay_extensions sidekiq_ignore_retry_errors_enabled memcache],
'services_kafka' => %w[rdkafka ruby_kafka],
'services_elasticsearch' => %w[elasticsearch],
'services_mysql_pg' => %w[active_record active_record_pg],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

require_relative 'sidekiq_test_helpers'

# On startup, Sidekiq instrumentation registers error and death handlers
# based on the value of the 'sidekiq.ignore_retry_errors'. Because of this,
# we need to have separate enabled/disabled test suites to test both cases.
class SidekiqIgnoreRetryErrorsTest < Minitest::Test
include SidekiqTestHelpers

Expand Down Expand Up @@ -50,58 +53,6 @@ def test_error_handlers_registered_when_sidekiq_ignore_retry_errors_is_false
'Expected NewRelic error_handler to be registered when sidekiq.ignore_retry_errors is false'
end

def test_error_handlers_not_registered_when_sidekiq_ignore_retry_errors_is_true
with_config(:'sidekiq.ignore_retry_errors' => true) do
# TODO: MAJOR VERSION - remove this when Sidekiq v5 is no longer supported
skip 'Test requires Sidekiq v6+' unless Sidekiq::VERSION.split('.').first.to_i >= 6

config = if Sidekiq::VERSION.split('.').first.to_i >= 7
Sidekiq.default_configuration
else
Sidekiq
end

error_handlers = if config.respond_to?(:error_handlers)
config.error_handlers
else
config[:error_handlers] || []
end

nr_error_handler_found = error_handlers.any? do |handler|
handler.is_a?(Proc) && handler.source_location&.first&.include?('newrelic')
end

refute nr_error_handler_found,
'Expected NewRelic error_handler to NOT be registered when sidekiq.ignore_retry_errors is true'
end
end

def test_death_handlers_registered_when_sidekiq_ignore_retry_errors_is_true
with_config(:'sidekiq.ignore_retry_errors' => true) do
# TODO: MAJOR VERSION - remove this when Sidekiq v5 is no longer supported
skip 'Test requires Sidekiq v6+' unless Sidekiq::VERSION.split('.').first.to_i >= 6

config = if Sidekiq::VERSION.split('.').first.to_i >= 7
Sidekiq.default_configuration
else
Sidekiq
end

death_handlers = if config.respond_to?(:death_handlers)
config.death_handlers
else
config[:death_handlers] || []
end

nr_death_handler_found = death_handlers.any? do |handler|
handler.is_a?(Proc) && handler.source_location&.first&.include?('newrelic')
end

assert nr_death_handler_found,
'Expected NewRelic death_handler to be registered when sidekiq.ignore_retry_errors is true'
end
end

def test_death_handlers_not_registered_when_sidekiq_ignore_retry_errors_is_false
# TODO: MAJOR VERSION - remove this when Sidekiq v5 is no longer supported
skip 'Test requires Sidekiq v6+' unless Sidekiq::VERSION.split('.').first.to_i >= 6
Expand All @@ -125,14 +76,4 @@ def test_death_handlers_not_registered_when_sidekiq_ignore_retry_errors_is_false
refute nr_death_handler_found,
'Expected NewRelic death_handler to NOT be registered when sidekiq.ignore_retry_errors is false'
end

def test_basic_job_execution_still_works
with_config(:'sidekiq.ignore_retry_errors' => true) do
segment = run_job

assert_predicate segment, :finished?
assert_predicate segment, :record_metrics?
assert segment.duration.is_a?(Float)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
# frozen_string_literal: true

# require_relative 'sidekiq_test_helpers'

# # On startup, Sidekiq instrumentation registers error and death handlers
# # based on the value of the 'sidekiq.ignore_retry_errors'. Because of this,
# # we need to have separate enabled/disabled test suites to test both cases.
# class SidekiqIgnoreRetryErrorEnabledTest < Minitest::Test
# include SidekiqTestHelpers

# def setup
# @config = {:'sidekiq.ignore_retry_errors' => true}
# NewRelic::Agent.config.add_config_for_testing(@config)
# end

# def teardown
# NewRelic::Agent.config.reset_to_defaults
# end

# def test_error_handlers_not_registered_when_sidekiq_ignore_retry_errors_is_true
# # TODO: MAJOR VERSION - remove this when Sidekiq v5 is no longer supported
# skip 'Test requires Sidekiq v6+' unless Sidekiq::VERSION.split('.').first.to_i >= 6

# config = if Sidekiq::VERSION.split('.').first.to_i >= 7
# Sidekiq.default_configuration
# else
# Sidekiq
# end

# error_handlers = if config.respond_to?(:error_handlers)
# config.error_handlers
# else
# config[:error_handlers] || []
# end

# nr_error_handler_found = error_handlers.any? do |handler|
# handler.is_a?(Proc) && handler.source_location&.first&.include?('newrelic')
# end

# refute nr_error_handler_found,
# 'Expected NewRelic error_handler to NOT be registered when sidekiq.ignore_retry_errors is true'
# end

# def test_death_handlers_registered_when_sidekiq_ignore_retry_errors_is_true
# # TODO: MAJOR VERSION - remove this when Sidekiq v5 is no longer supported
# skip 'Test requires Sidekiq v6+' unless Sidekiq::VERSION.split('.').first.to_i >= 6

# config = if Sidekiq::VERSION.split('.').first.to_i >= 7
# Sidekiq.default_configuration
# else
# Sidekiq
# end

# death_handlers = if config.respond_to?(:death_handlers)
# config.death_handlers
# else
# config[:death_handlers] || []
# end

# nr_death_handler_found = death_handlers.any? do |handler|
# handler.is_a?(Proc) && handler.source_location&.first&.include?('newrelic')
# end

# assert nr_death_handler_found,
# 'Expected NewRelic death_handler to be registered when sidekiq.ignore_retry_errors is true'
# end

# def test_basic_job_execution_still_works
# segment = run_job

# assert_predicate segment, :finished?
# assert_predicate segment, :record_metrics?
# assert_kind_of Float, segment.duration
# end
# end
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
# frozen_string_literal: true

SIDEKIQ_VERSIONS = [
[nil, 3.2],
['7.3.9', 2.7],
['6.4.0', 2.5],
['5.0.3', 2.4, 2.5]
]

def gem_list(sidekiq_version = nil)
<<-RB
gem 'sidekiq'#{sidekiq_version}
gem 'newrelic_rpm', :require => false, :path => File.expand_path('../../../../')
RB
end

create_gemfiles(SIDEKIQ_VERSIONS)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
development:
error_collector:
enabled: true
apdex_t: 0.5
monitor_mode: true
license_key: bootstrap_newrelic_admin_license_key_000
app_name: test
ca_bundle_path: ../../../config/test.cert.crt
app_name: test
host: localhost
api_host: localhost
port: <%= $collector && $collector.port %>
transaction_tracer:
record_sql: obfuscated
enabled: true
stack_trace_threshold: 0.5
transaction_threshold: 1.0
capture_params: false
log_file_path: log
sidekiq.ignore_retry_errors: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
# frozen_string_literal: true

require_relative 'sidekiq_test_helpers'

# On startup, Sidekiq instrumentation registers error and death handlers
# based on the value of the 'sidekiq.ignore_retry_errors'. Because of this,
# we need to have separate enabled/disabled test suites to test both cases.
class SidekiqIgnoreRetryErrorEnabledTest < Minitest::Test
include SidekiqTestHelpers

def test_error_handlers_not_registered_when_sidekiq_ignore_retry_errors_is_true
# TODO: MAJOR VERSION - remove this when Sidekiq v5 is no longer supported
skip 'Test requires Sidekiq v6+' unless Sidekiq::VERSION.split('.').first.to_i >= 6

config = if Sidekiq::VERSION.split('.').first.to_i >= 7
Sidekiq.default_configuration
else
Sidekiq
end

error_handlers = if config.respond_to?(:error_handlers)
config.error_handlers
else
config[:error_handlers] || []
end

nr_error_handler_found = error_handlers.any? do |handler|
handler.is_a?(Proc) && handler.source_location&.first&.include?('newrelic')
end

refute nr_error_handler_found,
'Expected NewRelic error_handler to NOT be registered when sidekiq.ignore_retry_errors is true'
end

def test_death_handlers_registered_when_sidekiq_ignore_retry_errors_is_true
# TODO: MAJOR VERSION - remove this when Sidekiq v5 is no longer supported
skip 'Test requires Sidekiq v6+' unless Sidekiq::VERSION.split('.').first.to_i >= 6

config = if Sidekiq::VERSION.split('.').first.to_i >= 7
Sidekiq.default_configuration
else
Sidekiq
end

death_handlers = if config.respond_to?(:death_handlers)
config.death_handlers
else
config[:death_handlers] || []
end

nr_death_handler_found = death_handlers.any? do |handler|
handler.is_a?(Proc) && handler.source_location&.first&.include?('newrelic')
end

assert nr_death_handler_found,
'Expected NewRelic death_handler to be registered when sidekiq.ignore_retry_errors is true'
end

def test_basic_job_execution_still_works
segment = run_job

assert_predicate segment, :finished?
assert_predicate segment, :record_metrics?
assert_kind_of Float, segment.duration
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
# frozen_string_literal: true

require 'sidekiq'
require 'sidekiq/cli'
require 'newrelic_rpm'

class NRDeadEndJob
# TODO: MAJOR VERSION - remove this when Sidekiq v5 is no longer supported
if Sidekiq::VERSION.split('.').first.to_i >= 6
include Sidekiq::Job
else
include Sidekiq::Worker
end

sidekiq_options retry: 5

COMPLETION_VAR = :@@nr_job_complete
ERROR_MESSAGE = 'kaboom'

def perform(*args)
raise ERROR_MESSAGE if args.first.is_a?(Hash) && args.first['raise_error']
ensure
self.class.class_variable_set(COMPLETION_VAR, true)
end
end

module SidekiqTestHelpers
def run_job(*args)
segments = nil
in_transaction do |txn|
NRDeadEndJob.perform_async(*args)
process_queued_jobs
segments = txn.segments.select { |s| s.name.eql?('Nested/OtherTransaction/SidekiqJob/NRDeadEndJob/perform') }
end

assert_equal 1, segments.size, "Expected to find a single Sidekiq job segment, found #{segments.size}"
segments.first
end

def run_job_and_get_attributes(*args)
run_job(*args).attributes.agent_attributes_for(NewRelic::Agent::AttributeFilter::DST_TRANSACTION_TRACER)
end

def process_queued_jobs
NRDeadEndJob.class_variable_set(NRDeadEndJob::COMPLETION_VAR, false)
config = cli.instance_variable_defined?(:@config) ? cli.instance_variable_get(:@config) : Sidekiq.options

# TODO: MAJOR VERSION - remove this when Sidekiq v5 is no longer supported
require 'sidekiq/launcher' if Sidekiq::VERSION.split('.').first.to_i < 6

launcher = Sidekiq::Launcher.new(config)
launcher.run
Timeout.timeout(5) do
sleep 0.01 until NRDeadEndJob.class_variable_get(NRDeadEndJob::COMPLETION_VAR)
end

# TODO: MAJOR VERSION - Sidekiq v7 is fine with launcher.stop, but v5 and v6
# need the Manager#quiet call
if launcher.instance_variable_defined?(:@manager)
launcher.instance_variable_get(:@manager).quiet
else
launcher.stop
end
end

def cli
@@cli ||= begin
cli = Sidekiq::CLI.instance
cli.parse(['--require', File.absolute_path(__FILE__), '--queue', 'default,1'])
cli.logger.instance_variable_get(:@logdev).instance_variable_set(:@dev, File.new('/dev/null', 'w'))
ensure_sidekiq_config(cli)
cli
end
end

def ensure_sidekiq_config(cli)
return unless Sidekiq::VERSION.split('.').first.to_i >= 7
return unless cli.respond_to?(:config)
return unless cli.config.nil?

require 'sidekiq/config'
cli.instance_variable_set(:@config, ::Sidekiq::Config.new)
end

def flatten(object)
NewRelic::Agent::AttributeProcessing.flatten_and_coerce(object, 'job.sidekiq.args')
end
end
Loading