1
0
Fork 0
mirror of https://github.com/mperham/sidekiq.git synced 2022-11-09 13:52:34 -05:00

Cleanup CLI (#4026)

* Refactor CLI test

Extracted 3 main parts:
- parse
- run
- signal handling

* Move demonization and pid write from parse to run phase

* Move queues default from validate to setup options phase

* Add pry-byebug gem

* Drop Sidekiq::Test

* Require launcher in CLI

* Remove TODOs
This commit is contained in:
Andrew Babichev 2018-12-03 22:24:37 +01:00 committed by Mike Perham
parent 78f3b6854b
commit ddb0c8b3a8
35 changed files with 354 additions and 456 deletions

1
.gitignore vendored
View file

@ -11,3 +11,4 @@ vendor/
.sass-cache/ .sass-cache/
tmp/ tmp/
pkg/*.gem pkg/*.gem
.byebug_history

View file

@ -8,6 +8,7 @@ gemspec
group :test do group :test do
gem 'rails', '>= 5.0.1' gem 'rails', '>= 5.0.1'
gem 'minitest' gem 'minitest'
gem 'pry-byebug', platforms: :mri
gem 'rake' gem 'rake'
gem 'redis-namespace' gem 'redis-namespace'
gem 'simplecov' gem 'simplecov'

View file

@ -1,4 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'sidekiq/version' require 'sidekiq/version'
fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.2.2." if RUBY_PLATFORM != 'java' && Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2') fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.2.2." if RUBY_PLATFORM != 'java' && Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2')
@ -56,6 +57,7 @@ module Sidekiq
def self.options def self.options
@options ||= DEFAULTS.dup @options ||= DEFAULTS.dup
end end
def self.options=(opts) def self.options=(opts)
@options = opts @options = opts
end end

View file

@ -9,6 +9,7 @@ require 'fileutils'
require 'sidekiq' require 'sidekiq'
require 'sidekiq/util' require 'sidekiq/util'
require 'sidekiq/launcher'
module Sidekiq module Sidekiq
class CLI class CLI
@ -24,22 +25,13 @@ module Sidekiq
] ]
# Used for CLI testing # Used for CLI testing
attr_accessor :code
attr_accessor :launcher attr_accessor :launcher
attr_accessor :environment attr_accessor :environment
def initialize
@code = nil
end
def parse(args=ARGV) def parse(args=ARGV)
@code = nil
setup_options(args) setup_options(args)
initialize_logger initialize_logger
validate! validate!
daemonize
write_pid
end end
def jruby? def jruby?
@ -50,6 +42,8 @@ module Sidekiq
# global process state irreversibly. PRs which improve the # global process state irreversibly. PRs which improve the
# test coverage of Sidekiq::CLI are welcomed. # test coverage of Sidekiq::CLI are welcomed.
def run def run
daemonize if options[:daemon]
write_pid
boot_system boot_system
print_banner print_banner
@ -103,7 +97,6 @@ module Sidekiq
logger.info 'Starting processing, hit Ctrl-C to stop' logger.info 'Starting processing, hit Ctrl-C to stop'
end end
require 'sidekiq/launcher'
@launcher = Sidekiq::Launcher.new(options) @launcher = Sidekiq::Launcher.new(options)
begin begin
@ -194,8 +187,6 @@ module Sidekiq
end end
def daemonize def daemonize
return unless options[:daemon]
raise ArgumentError, "You really should set a logfile if you're going to daemonize" unless options[:logfile] raise ArgumentError, "You really should set a logfile if you're going to daemonize" unless options[:logfile]
files_to_reopen = [] files_to_reopen = []
ObjectSpace.each_object(File) do |file| ObjectSpace.each_object(File) do |file|
@ -242,6 +233,8 @@ module Sidekiq
opts = parse_options(args) opts = parse_options(args)
set_environment opts[:environment] set_environment opts[:environment]
options[:queues] << 'default' if options[:queues].empty?
cfile = opts[:config_file] cfile = opts[:config_file]
opts = parse_config(cfile).merge(opts) if cfile opts = parse_config(cfile).merge(opts) if cfile
@ -298,8 +291,6 @@ module Sidekiq
end end
def validate! def validate!
options[:queues] << 'default' if options[:queues].empty?
if !File.exist?(options[:require]) || if !File.exist?(options[:require]) ||
(File.directory?(options[:require]) && !File.exist?("#{options[:require]}/config/application.rb")) (File.directory?(options[:require]) && !File.exist?("#{options[:require]}/config/application.rb"))
logger.info "==================================================================" logger.info "=================================================================="

1
test/config_empty.yml Normal file
View file

@ -0,0 +1 @@
---

View file

@ -1,11 +1,12 @@
--- ---
:pidfile: /tmp/sidekiq-config-test.pid :pidfile: /tmp/sidekiq-config-test.pid
:concurrency: 50 :concurrency: 50
staging: staging:
:verbose: false :verbose: false
:require: ./test/fake_env.rb :require: ./test/fake_env.rb
:logfile: /tmp/sidekiq.log :logfile: /tmp/sidekiq.log
:concurrency: 5 :concurrency: 50
:queues: :queues:
- [<%="very_"%>often, 2] - [<%="very_"%>often, 2]
- [seldom, 1] - [seldom, 1]

View file

@ -1,4 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
require "bundler/setup"
Bundler.require
$TESTING = true $TESTING = true
# disable minitest/parallel threads # disable minitest/parallel threads
ENV["N"] = "0" ENV["N"] = "0"
@ -10,6 +14,7 @@ if ENV["COVERAGE"]
add_filter "/myapp/" add_filter "/myapp/"
end end
end end
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = 'test' ENV['RACK_ENV'] = ENV['RAILS_ENV'] = 'test'
trap 'TSTP' do trap 'TSTP' do
@ -29,20 +34,10 @@ trap 'TSTP' do
puts "=" * 80 puts "=" * 80
end end
begin
require 'pry-byebug'
rescue LoadError
end
require 'minitest/autorun' require 'minitest/autorun'
require 'sidekiq'
require 'sidekiq/util'
Sidekiq.logger.level = Logger::ERROR Sidekiq.logger.level = Logger::ERROR
Sidekiq::Test = Minitest::Test
require 'sidekiq/redis_connection'
REDIS_URL = ENV['REDIS_URL'] || 'redis://localhost/15' REDIS_URL = ENV['REDIS_URL'] || 'redis://localhost/15'
REDIS = Sidekiq::RedisConnection.create(:url => REDIS_URL) REDIS = Sidekiq::RedisConnection.create(:url => REDIS_URL)

View file

@ -5,7 +5,7 @@ require 'sidekiq/fetch'
require 'sidekiq/scheduled' require 'sidekiq/scheduled'
require 'sidekiq/processor' require 'sidekiq/processor'
class TestActors < Sidekiq::Test class TestActors < Minitest::Test
class JoeWorker class JoeWorker
include Sidekiq::Worker include Sidekiq::Worker
def perform(slp) def perform(slp)

View file

@ -4,7 +4,7 @@ require 'sidekiq/api'
require 'active_job' require 'active_job'
require 'action_mailer' require 'action_mailer'
class TestApi < Sidekiq::Test class TestApi < Minitest::Test
describe 'api' do describe 'api' do
before do before do
Sidekiq.redis {|c| c.flushdb } Sidekiq.redis {|c| c.flushdb }

View file

@ -1,441 +1,344 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative 'helper' require_relative 'helper'
require 'sidekiq/cli' require 'sidekiq/cli'
require 'tempfile' require 'tempfile'
class Sidekiq::CLI class TestCLI < Minitest::Test
def die(code) describe '#parse' do
@code = code
end
def valid?
!@code
end
end
class TestCli < Sidekiq::Test
describe 'CLI#parse' do
before do before do
@cli = Sidekiq::CLI.new @cli = Sidekiq::CLI.new
@opts = Sidekiq.options.dup Sidekiq.options = Sidekiq::DEFAULTS.dup
@logger = Sidekiq.logger
@logdev = StringIO.new
Sidekiq.logger = Logger.new(@logdev)
end end
after do after do
Sidekiq.options = @opts Sidekiq.logger = @logger
end
describe 'options' do
describe 'require' do
it 'accepts with -r' do
@cli.parse(%w[sidekiq -r ./test/fake_env.rb])
assert_equal './test/fake_env.rb', Sidekiq.options[:require]
end
end
describe 'concurrency' do
it 'accepts with -c' do
@cli.parse(%w[sidekiq -c 60 -r ./test/fake_env.rb])
assert_equal 60, Sidekiq.options[:concurrency]
end
describe 'when concurrency is empty and RAILS_MAX_THREADS env var is set' do
before do
ENV['RAILS_MAX_THREADS'] = '9'
end
after do
ENV.delete('RAILS_MAX_THREADS')
end
it 'sets concurrency from RAILS_MAX_THREADS env var' do
@cli.parse(%w[sidekiq -r ./test/fake_env.rb])
assert_equal 9, Sidekiq.options[:concurrency]
end
it 'option overrides RAILS_MAX_THREADS env var' do
@cli.parse(%w[sidekiq -c 60 -r ./test/fake_env.rb])
assert_equal 60, Sidekiq.options[:concurrency]
end
end
end
describe 'queues' do
it 'accepts with -q' do
@cli.parse(%w[sidekiq -q foo -r ./test/fake_env.rb])
assert_equal ['foo'], Sidekiq.options[:queues]
end
describe 'when weights are not present' do
it 'accepts queues without weights' do
@cli.parse(%w[sidekiq -q foo -q bar -r ./test/fake_env.rb])
assert_equal ['foo', 'bar'], Sidekiq.options[:queues]
end
it 'sets strictly ordered queues' do
@cli.parse(%w[sidekiq -q foo -q bar -r ./test/fake_env.rb])
assert_equal true, !!Sidekiq.options[:strict]
end
end
describe 'when weights are present' do
it 'accepts queues with weights' do
@cli.parse(%w[sidekiq -q foo,3 -q bar -r ./test/fake_env.rb])
assert_equal ['foo', 'foo', 'foo', 'bar'], Sidekiq.options[:queues]
end
it 'does not set strictly ordered queues' do
@cli.parse(%w[sidekiq -q foo,3 -q bar -r ./test/fake_env.rb])
assert_equal false, !!Sidekiq.options[:strict]
end
end
it 'accepts queues with multi-word names' do
@cli.parse(%w[sidekiq -q queue_one -q queue-two -r ./test/fake_env.rb])
assert_equal ['queue_one', 'queue-two'], Sidekiq.options[:queues]
end
it 'accepts queues with dots in the name' do
@cli.parse(%w[sidekiq -q foo.bar -r ./test/fake_env.rb])
assert_equal ['foo.bar'], Sidekiq.options[:queues]
end
describe 'when duplicate queue names' do
it 'raises an argument error' do
assert_raises(ArgumentError) { @cli.parse(%w[sidekiq -q foo -q foo -r ./test/fake_env.rb]) }
assert_raises(ArgumentError) { @cli.parse(%w[sidekiq -q foo,3 -q foo,1 -r ./test/fake_env.rb]) }
end
end
describe 'when queues are empty' do
it "sets 'default' queue" do
@cli.parse(%w[sidekiq -r ./test/fake_env.rb])
assert_equal ['default'], Sidekiq.options[:queues]
end
end
end
describe 'process index' do
it 'accepts with -i' do
@cli.parse(%w[sidekiq -i 7 -r ./test/fake_env.rb])
assert_equal 7, Sidekiq.options[:index]
end
it 'accepts stringy value' do
@cli.parse(%w[sidekiq -i worker.7 -r ./test/fake_env.rb])
assert_equal 7, Sidekiq.options[:index]
end
end
describe 'timeout' do
it 'accepts with -t' do
@cli.parse(%w[sidekiq -t 30 -r ./test/fake_env.rb])
assert_equal 30, Sidekiq.options[:timeout]
end
end
describe 'logfile' do
it 'accepts wiht -L' do
@cli.parse(%w[sidekiq -L /tmp/sidekiq.log -r ./test/fake_env.rb])
assert_equal '/tmp/sidekiq.log', Sidekiq.options[:logfile]
end
end
describe 'verbose' do
it 'accepts with -v' do
@cli.parse(%w[sidekiq -v -r ./test/fake_env.rb])
assert_equal Logger::DEBUG, Sidekiq.logger.level
end
end
describe 'pidfile' do
it 'accepts with -P' do
@cli.parse(%w[sidekiq -P /tmp/sidekiq.pid -r ./test/fake_env.rb])
assert_equal '/tmp/sidekiq.pid', Sidekiq.options[:pidfile]
end
end
describe 'config file' do
it 'accepts with -C' do
@cli.parse(%w[sidekiq -C ./test/config.yml])
assert_equal './test/config.yml', Sidekiq.options[:config_file]
refute Sidekiq.options[:verbose]
assert_equal './test/fake_env.rb', Sidekiq.options[:require]
assert_nil Sidekiq.options[:environment]
assert_equal 50, Sidekiq.options[:concurrency]
assert_equal '/tmp/sidekiq-config-test.pid', Sidekiq.options[:pidfile]
assert_equal '/tmp/sidekiq.log', Sidekiq.options[:logfile]
assert_equal 2, Sidekiq.options[:queues].count { |q| q == 'very_often' }
assert_equal 1, Sidekiq.options[:queues].count { |q| q == 'seldom' }
end
it 'accepts stringy keys' do
@cli.parse(%w[sidekiq -C ./test/config_string.yml])
assert_equal './test/config_string.yml', Sidekiq.options[:config_file]
refute Sidekiq.options[:verbose]
assert_equal './test/fake_env.rb', Sidekiq.options[:require]
assert_nil Sidekiq.options[:environment]
assert_equal 50, Sidekiq.options[:concurrency]
assert_equal '/tmp/sidekiq-config-test.pid', Sidekiq.options[:pidfile]
assert_equal '/tmp/sidekiq.log', Sidekiq.options[:logfile]
assert_equal 2, Sidekiq.options[:queues].count { |q| q == 'very_often' }
assert_equal 1, Sidekiq.options[:queues].count { |q| q == 'seldom' }
end
it 'accepts environment specific config' do
@cli.parse(%w[sidekiq -e staging -C ./test/config_environment.yml])
assert_equal './test/config_environment.yml', Sidekiq.options[:config_file]
refute Sidekiq.options[:verbose]
assert_equal './test/fake_env.rb', Sidekiq.options[:require]
assert_equal 'staging', Sidekiq.options[:environment]
assert_equal 50, Sidekiq.options[:concurrency]
assert_equal '/tmp/sidekiq-config-test.pid', Sidekiq.options[:pidfile]
assert_equal '/tmp/sidekiq.log', Sidekiq.options[:logfile]
assert_equal 2, Sidekiq.options[:queues].count { |q| q == 'very_often' }
assert_equal 1, Sidekiq.options[:queues].count { |q| q == 'seldom' }
end
describe 'when config file is empty' do
it 'sets default options' do
@cli.parse(%w[sidekiq -C ./test/config_empty.yml -r ./test/fake_env.rb])
assert_equal './test/config_empty.yml', Sidekiq.options[:config_file]
refute Sidekiq.options[:verbose]
assert_equal './test/fake_env.rb', Sidekiq.options[:require]
assert_nil Sidekiq.options[:environment]
assert_equal 10, Sidekiq.options[:concurrency]
assert_nil Sidekiq.options[:pidfile]
assert_nil Sidekiq.options[:logfile]
assert_equal ['default'], Sidekiq.options[:queues]
end
end
describe 'when config file and flags' do
it 'merges options' do
@cli.parse(%w[sidekiq -C ./test/config.yml
-e snoop
-c 100
-r ./test/fake_env.rb
-P /tmp/sidekiq.pid
-q often,7
-q seldom,3])
assert_equal './test/config.yml', Sidekiq.options[:config_file]
refute Sidekiq.options[:verbose]
assert_equal './test/fake_env.rb', Sidekiq.options[:require]
assert_equal 'snoop', Sidekiq.options[:environment]
assert_equal 100, Sidekiq.options[:concurrency]
assert_equal '/tmp/sidekiq.pid', Sidekiq.options[:pidfile]
assert_equal '/tmp/sidekiq.log', Sidekiq.options[:logfile]
assert_equal 7, Sidekiq.options[:queues].count { |q| q == 'often' }
assert_equal 3, Sidekiq.options[:queues].count { |q| q == 'seldom' }
end
end
end
end
describe 'validation' do
describe 'when required application path does not exist' do
it 'exits with status 1' do
exit = assert_raises(SystemExit) { @cli.parse(%w[sidekiq -r /non/existent/path]) }
assert_equal 1, exit.status
end
end
describe 'when required path is a directory without config/application.rb' do
it 'exits with status 1' do
exit = assert_raises(SystemExit) { @cli.parse(%w[sidekiq -r ./test/fixtures]) }
assert_equal 1, exit.status
end
end
end end
it 'does not require the specified Ruby code' do it 'does not require the specified Ruby code' do
@cli.parse(['sidekiq', '-r', './test/fake_env.rb']) @cli.parse(%w[sidekiq -r ./test/fake_env.rb])
refute($LOADED_FEATURES.any? { |x| x =~ /fake_env/ }) refute($LOADED_FEATURES.any? { |x| x =~ /fake_env/ })
assert @cli.valid?
end end
it 'does not boot rails' do it 'does not boot rails' do
refute defined?(::Rails::Application) refute defined?(::Rails::Application)
@cli.parse(['sidekiq', '-r', './myapp'])
@cli.parse(%w[sidekiq -r ./myapp])
refute defined?(::Rails::Application) refute defined?(::Rails::Application)
end end
it 'changes concurrency' do
@cli.parse(['sidekiq', '-c', '60', '-r', './test/fake_env.rb'])
assert_equal 60, Sidekiq.options[:concurrency]
end
it 'changes concurrency with ENV' do
begin
ENV['RAILS_MAX_THREADS'] = '9'
@cli.parse(['sidekiq', '-c', '60', '-r', './test/fake_env.rb'])
assert_equal 60, Sidekiq.options[:concurrency]
@cli.parse(['sidekiq', '-r', './test/fake_env.rb'])
assert_equal 9, Sidekiq.options[:concurrency]
ensure
ENV.delete('RAILS_MAX_THREADS')
end
end
it 'changes queues' do
@cli.parse(['sidekiq', '-q', 'foo', '-r', './test/fake_env.rb'])
assert_equal ['foo'], Sidekiq.options[:queues]
end
it 'accepts a process index' do
@cli.parse(['sidekiq', '-i', '7', '-r', './test/fake_env.rb'])
assert_equal 7, Sidekiq.options[:index]
end
it 'accepts a stringy process index' do
@cli.parse(['sidekiq', '-i', 'worker.7', '-r', './test/fake_env.rb'])
assert_equal 7, Sidekiq.options[:index]
end
it 'sets strictly ordered queues if weights are not present' do
@cli.parse(['sidekiq', '-q', 'foo', '-q', 'bar', '-r', './test/fake_env.rb'])
assert_equal true, !!Sidekiq.options[:strict]
end
it 'does not set strictly ordered queues if weights are present' do
@cli.parse(['sidekiq', '-q', 'foo,3', '-r', './test/fake_env.rb'])
assert_equal false, !!Sidekiq.options[:strict]
end
it 'does not set strictly ordered queues if weights are present with multiple queues' do
@cli.parse(['sidekiq', '-q', 'foo,3', '-q', 'bar', '-r', './test/fake_env.rb'])
assert_equal false, !!Sidekiq.options[:strict]
end
it 'changes timeout' do
@cli.parse(['sidekiq', '-t', '30', '-r', './test/fake_env.rb'])
assert_equal 30, Sidekiq.options[:timeout]
end
it 'handles multiple queues with weights' do
@cli.parse(['sidekiq', '-q', 'foo,3', '-q', 'bar', '-r', './test/fake_env.rb'])
assert_equal %w(foo foo foo bar), Sidekiq.options[:queues]
end
it 'handles queues with multi-word names' do
@cli.parse(['sidekiq', '-q', 'queue_one', '-q', 'queue-two', '-r', './test/fake_env.rb'])
assert_equal %w(queue_one queue-two), Sidekiq.options[:queues]
end
it 'handles queues with dots in the name' do
@cli.parse(['sidekiq', '-q', 'foo.bar', '-r', './test/fake_env.rb'])
assert_equal ['foo.bar'], Sidekiq.options[:queues]
end
it 'raises an error for duplicate queue names' do
assert_raises(ArgumentError) { @cli.parse(['sidekiq', '-q', 'foo', '-q', 'foo', '-r', './test/fake_env.rb']) }
assert_raises(ArgumentError) { @cli.parse(['sidekiq', '-q', 'foo,3', '-q', 'foo,1', '-r', './test/fake_env.rb']) }
end
it 'sets verbose' do
old = Sidekiq.logger.level
@cli.parse(['sidekiq', '-v', '-r', './test/fake_env.rb'])
assert_equal Logger::DEBUG, Sidekiq.logger.level
# If we leave the logger at DEBUG it'll add a lot of noise to the test output
Sidekiq.options.delete(:verbose)
Sidekiq.logger.level = old
end
describe 'with logfile' do
before do
@old_logger = Sidekiq.logger
@tmp_log_path = '/tmp/sidekiq.log'
end
after do
Sidekiq.logger = @old_logger
Sidekiq.options.delete(:logfile)
File.unlink @tmp_log_path if File.exist?(@tmp_log_path)
end
it 'sets the logfile path' do
@cli.parse(['sidekiq', '-L', @tmp_log_path, '-r', './test/fake_env.rb'])
assert_equal @tmp_log_path, Sidekiq.options[:logfile]
end
it 'creates and writes to a logfile' do
@cli.parse(['sidekiq', '-L', @tmp_log_path, '-r', './test/fake_env.rb'])
Sidekiq.logger.info('test message')
assert_match(/test message/, File.read(@tmp_log_path), "didn't include the log message")
end
it 'appends messages to a logfile' do
File.open(@tmp_log_path, 'w') do |f|
f.puts 'already existent log message'
end
@cli.parse(['sidekiq', '-L', @tmp_log_path, '-r', './test/fake_env.rb'])
Sidekiq.logger.info('test message')
log_file_content = File.read(@tmp_log_path)
assert_match(/already existent/, log_file_content, "didn't include the old message")
assert_match(/test message/, log_file_content, "didn't include the new message")
end
end
describe 'with pidfile' do
before do
@tmp_file = Tempfile.new('sidekiq-test')
@tmp_path = @tmp_file.path
@tmp_file.close!
@cli.parse(['sidekiq', '-P', @tmp_path, '-r', './test/fake_env.rb'])
end
after do
File.unlink @tmp_path if File.exist? @tmp_path
end
it 'sets pidfile path' do
assert_equal @tmp_path, Sidekiq.options[:pidfile]
end
it 'writes pidfile' do
assert_equal File.read(@tmp_path).strip.to_i, Process.pid
end
end
describe 'with config file' do
before do
@cli.parse(['sidekiq', '-C', './test/config.yml'])
end
it 'parses as expected' do
assert_equal './test/config.yml', Sidekiq.options[:config_file]
refute Sidekiq.options[:verbose]
assert_equal './test/fake_env.rb', Sidekiq.options[:require]
assert_nil Sidekiq.options[:environment]
assert_equal 50, Sidekiq.options[:concurrency]
assert_equal '/tmp/sidekiq-config-test.pid', Sidekiq.options[:pidfile]
assert_equal '/tmp/sidekiq.log', Sidekiq.options[:logfile]
assert_equal 2, Sidekiq.options[:queues].count { |q| q == 'very_often' }
assert_equal 1, Sidekiq.options[:queues].count { |q| q == 'seldom' }
end
end
describe 'with config file using string keys' do
before do
@cli.parse(['sidekiq', '-C', './test/string_config.yml'])
end
it 'parses as expected' do
assert_equal './test/string_config.yml', Sidekiq.options[:config_file]
refute Sidekiq.options[:verbose]
assert_equal './test/fake_env.rb', Sidekiq.options[:require]
assert_nil Sidekiq.options[:environment]
assert_equal 50, Sidekiq.options[:concurrency]
assert_equal '/tmp/sidekiq-config-test.pid', Sidekiq.options[:pidfile]
assert_equal '/tmp/sidekiq.log', Sidekiq.options[:logfile]
assert_equal 2, Sidekiq.options[:queues].count { |q| q == 'very_often' }
assert_equal 1, Sidekiq.options[:queues].count { |q| q == 'seldom' }
end
end
describe 'with env based config file' do
before do
@cli.parse(['sidekiq', '-e', 'staging', '-C', './test/env_based_config.yml'])
end
it 'parses as expected' do
assert_equal './test/env_based_config.yml', Sidekiq.options[:config_file]
refute Sidekiq.options[:verbose]
assert_equal './test/fake_env.rb', Sidekiq.options[:require]
assert_equal 'staging', Sidekiq.options[:environment]
assert_equal 5, Sidekiq.options[:concurrency]
assert_equal '/tmp/sidekiq-config-test.pid', Sidekiq.options[:pidfile]
assert_equal '/tmp/sidekiq.log', Sidekiq.options[:logfile]
assert_equal 2, Sidekiq.options[:queues].count { |q| q == 'very_often' }
assert_equal 1, Sidekiq.options[:queues].count { |q| q == 'seldom' }
end
end
describe 'with an empty config file' do
before do
@tmp_file = Tempfile.new('sidekiq-test')
@tmp_path = @tmp_file.path
@tmp_file.close!
end
after do
File.unlink @tmp_path if File.exist? @tmp_path
end
it 'takes a path' do
@cli.parse(['sidekiq', '-C', @tmp_path])
assert_equal @tmp_path, Sidekiq.options[:config_file]
end
it 'should have an identical options hash, except for config_file' do
@cli.parse(['sidekiq'])
old_options = Sidekiq.options.clone
@cli.parse(['sidekiq', '-C', @tmp_path])
new_options = Sidekiq.options.clone
refute_equal old_options, new_options
new_options.delete(:config_file)
assert_equal old_options, new_options
end
end
describe 'with config file and flags' do
before do
# We need an actual file here.
@tmp_lib_path = '/tmp/require-me.rb'
File.open(@tmp_lib_path, 'w') do |f|
f.puts "# do work"
end
@tmp_file = Tempfile.new('sidekiqr')
@tmp_path = @tmp_file.path
@tmp_file.close!
@cli.parse(['sidekiq',
'-C', './test/config.yml',
'-e', 'snoop',
'-c', '100',
'-r', @tmp_lib_path,
'-P', @tmp_path,
'-q', 'often,7',
'-q', 'seldom,3'])
end
after do
File.unlink @tmp_lib_path if File.exist? @tmp_lib_path
File.unlink @tmp_path if File.exist? @tmp_path
end
it 'gives the expected options' do
assert_equal 100, Sidekiq.options[:concurrency]
assert_equal @tmp_lib_path, Sidekiq.options[:require]
assert_equal 'snoop', Sidekiq.options[:environment]
assert_equal @tmp_path, Sidekiq.options[:pidfile]
assert_equal 7, Sidekiq.options[:queues].count { |q| q == 'often' }
assert_equal 3, Sidekiq.options[:queues].count { |q| q == 'seldom' }
end
end
describe 'Sidekiq::CLI#parse_queues' do
describe 'when weight is present' do
it 'concatenates queues by factor of weight and sets strict to false' do
opts = { strict: true }
@cli.__send__ :parse_queues, opts, [['often', 7], ['repeatedly', 3]]
@cli.__send__ :parse_queues, opts, [['once']]
assert_equal (%w[often] * 7 + %w[repeatedly] * 3 + %w[once]), opts[:queues]
assert !opts[:strict]
end
end
describe 'when weight is not present' do
it 'returns queues and sets strict' do
opts = { strict: true }
@cli.__send__ :parse_queues, opts, [['once'], ['one_time']]
@cli.__send__ :parse_queues, opts, [['einmal']]
assert_equal %w[once one_time einmal], opts[:queues]
assert opts[:strict]
end
end
end
describe 'Sidekiq::CLI#parse_queue' do
describe 'when weight is present' do
it 'concatenates queue to opts[:queues] weight number of times and sets strict to false' do
opts = { strict: true }
@cli.__send__ :parse_queue, opts, 'often', 7
assert_equal %w[often] * 7, opts[:queues]
assert !opts[:strict]
end
end
describe 'when weight is not present' do
it 'concatenates queue to opts[:queues] once and leaves strict true' do
opts = { strict: true }
@cli.__send__ :parse_queue, opts, 'once', nil
assert_equal %w[once], opts[:queues]
assert opts[:strict]
end
end
end
end end
describe 'misc' do describe 'signal handling' do
before do before do
@cli = Sidekiq::CLI.new @cli = Sidekiq::CLI.new
Sidekiq.options = Sidekiq::DEFAULTS.dup
@logger = Sidekiq.logger
@logdev = StringIO.new
Sidekiq.logger = Logger.new(@logdev)
end end
it 'handles interrupts' do after do
assert_raises Interrupt do Sidekiq.logger = @logger
@cli.handle_signal('INT')
end
assert_raises Interrupt do
@cli.handle_signal('TERM')
end
end end
describe 'handles TSTP and USR2' do %w(INT TERM).each do |sig|
before do describe sig do
@tmp_log_path = '/tmp/sidekiq.log' it 'raises interrupt error' do
@cli.parse(['sidekiq', '-L', @tmp_log_path, '-r', './test/fake_env.rb']) assert_raises Interrupt do
end @cli.handle_signal(sig)
after do
File.unlink @tmp_log_path if File.exist? @tmp_log_path
end
it 'shuts down the worker' do
count = 0
Sidekiq.options[:lifecycle_events][:quiet] = [proc {
count += 1
}]
@cli.launcher = Sidekiq::Launcher.new(Sidekiq.options)
@cli.handle_signal('TSTP')
assert_equal 1, count
end
it 'reopens logs' do
mock = MiniTest::Mock.new
# reopen_logs returns number of files reopened so mock that
mock.expect(:call, 1)
Sidekiq::Logging.stub(:reopen_logs, mock) do
@cli.handle_signal('USR2')
end
mock.verify
end
end
describe 'handles TTIN' do
before do
@tmp_log_path = '/tmp/sidekiq.log'
@cli.parse(['sidekiq', '-L', @tmp_log_path, '-r', './test/fake_env.rb'])
@mock_thread = MiniTest::Mock.new
@mock_thread.expect(:[], 'interrupt_test', ['sidekiq_label'])
end
after do
File.unlink @tmp_log_path if File.exist? @tmp_log_path
end
describe 'with backtrace' do
it 'logs backtrace' do
2.times { @mock_thread.expect(:backtrace, ['something went wrong']) }
Thread.stub(:list, [@mock_thread]) do
@cli.handle_signal('TTIN')
assert_match(/something went wrong/, File.read(@tmp_log_path), "didn't include the log message")
end
end
end
describe 'without backtrace' do
it 'logs no backtrace available' do
@mock_thread.expect(:backtrace, nil)
Thread.stub(:list, [@mock_thread]) do
@cli.handle_signal('TTIN')
assert_match(/no backtrace available/, File.read(@tmp_log_path), "didn't include the log message")
end end
end end
end end
end end
%w(TSTP USR1).each do |sig|
describe sig do
it 'quites with a corresponding event' do
quiet = false
it 'can fire events' do Sidekiq.on(:quiet) do
count = 0 quiet = true
Sidekiq.options[:lifecycle_events][:startup] = [proc { end
count += 1
}] @cli.parse(%w[sidekiq -r ./test/fake_env.rb])
cli = Sidekiq::CLI.new @cli.launcher = Sidekiq::Launcher.new(Sidekiq.options)
cli.fire_event(:startup) @cli.handle_signal(sig)
assert_equal 1, count
assert_match(/Got #{sig} signal/, @logdev.string)
assert_equal true, quiet
end
end
end
describe 'TTIN' do
it 'prints backtraces for all threads in the process to the logfile' do
@cli.parse(%w[sidekiq -r ./test/fake_env.rb])
@cli.handle_signal('TTIN')
assert_match(/Got TTIN signal/, @logdev.string)
assert_match(/\bbacktrace\b/, @logdev.string)
end
end
describe 'UNKNOWN' do
it 'logs about' do
@cli.parse(%w[sidekiq -r ./test/fake_env.rb])
@cli.handle_signal('UNKNOWN')
assert_match(/Got UNKNOWN signal/, @logdev.string)
assert_match(/No signal handler for UNKNOWN/, @logdev.string)
end
end end
end end
end end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative 'helper' require_relative 'helper'
class TestClient < Sidekiq::Test class TestClient < Minitest::Test
describe 'errors' do describe 'errors' do
it 'raises ArgumentError with invalid params' do it 'raises ArgumentError with invalid params' do
assert_raises ArgumentError do assert_raises ArgumentError do

View file

@ -2,7 +2,7 @@
require_relative 'helper' require_relative 'helper'
require 'sidekiq/api' require 'sidekiq/api'
class TestDeadSet < Sidekiq::Test class TestDeadSet < Minitest::Test
describe 'dead_set' do describe 'dead_set' do
describe 'zomg' do describe 'zomg' do
def dead_set def dead_set

View file

@ -17,7 +17,7 @@ class Component
end end
end end
class TestExceptionHandler < Sidekiq::Test class TestExceptionHandler < Minitest::Test
describe "with mock logger" do describe "with mock logger" do
before do before do
@old_logger = Sidekiq.logger @old_logger = Sidekiq.logger

View file

@ -5,7 +5,7 @@ require 'active_record'
require 'action_mailer' require 'action_mailer'
Sidekiq::Extensions.enable_delay! Sidekiq::Extensions.enable_delay!
class TestExtensions < Sidekiq::Test class TestExtensions < Minitest::Test
describe 'sidekiq extensions' do describe 'sidekiq extensions' do
before do before do
Sidekiq.redis = REDIS Sidekiq.redis = REDIS

View file

@ -2,7 +2,7 @@
require_relative 'helper' require_relative 'helper'
require 'sidekiq/fetch' require 'sidekiq/fetch'
class TestFetcher < Sidekiq::Test class TestFetcher < Minitest::Test
describe 'fetcher' do describe 'fetcher' do
before do before do
Sidekiq.redis = { :url => REDIS_URL } Sidekiq.redis = { :url => REDIS_URL }

View file

@ -2,7 +2,7 @@
require_relative 'helper' require_relative 'helper'
require 'sidekiq/launcher' require 'sidekiq/launcher'
class TestLauncher < Sidekiq::Test class TestLauncher < Minitest::Test
describe 'launcher' do describe 'launcher' do
before do before do

View file

@ -2,7 +2,7 @@
require_relative 'helper' require_relative 'helper'
require 'sidekiq/logging' require 'sidekiq/logging'
class TestLogging < Sidekiq::Test class TestLogging < Minitest::Test
describe Sidekiq::Logging do describe Sidekiq::Logging do
describe "#with_context" do describe "#with_context" do
def ctx def ctx

View file

@ -2,7 +2,7 @@
require_relative 'helper' require_relative 'helper'
require 'sidekiq/manager' require 'sidekiq/manager'
class TestManager < Sidekiq::Test class TestManager < Minitest::Test
describe 'manager' do describe 'manager' do
before do before do

View file

@ -3,7 +3,7 @@ require_relative 'helper'
require 'sidekiq/middleware/chain' require 'sidekiq/middleware/chain'
require 'sidekiq/processor' require 'sidekiq/processor'
class TestMiddleware < Sidekiq::Test class TestMiddleware < Minitest::Test
describe 'middleware chain' do describe 'middleware chain' do
before do before do
$errors = [] $errors = []

View file

@ -4,7 +4,7 @@ require 'sidekiq/fetch'
require 'sidekiq/cli' require 'sidekiq/cli'
require 'sidekiq/processor' require 'sidekiq/processor'
class TestProcessor < Sidekiq::Test class TestProcessor < Minitest::Test
TestException = Class.new(StandardError) TestException = Class.new(StandardError)
TEST_EXCEPTION = TestException.new("kerboom!") TEST_EXCEPTION = TestException.new("kerboom!")

View file

@ -8,7 +8,7 @@ rescue LoadError
$HAS_AJ = false $HAS_AJ = false
end end
class TestRails < Sidekiq::Test class TestRails < Minitest::Test
describe 'ActiveJob' do describe 'ActiveJob' do
it 'does not allow Sidekiq::Worker in AJ::Base classes' do it 'does not allow Sidekiq::Worker in AJ::Base classes' do

View file

@ -1,9 +1,12 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative 'helper' require_relative 'helper'
class TestRedisConnection < Sidekiq::Test class TestRedisConnection < Minitest::Test
describe ".create" do describe ".create" do
before do
Sidekiq.options = Sidekiq::DEFAULTS.dup
end
# To support both redis-rb 3.3.x #client and 4.0.x #_client # To support both redis-rb 3.3.x #client and 4.0.x #_client
def client_for(redis) def client_for(redis)

View file

@ -4,7 +4,7 @@ require_relative 'helper'
require 'sidekiq/scheduled' require 'sidekiq/scheduled'
require 'sidekiq/job_retry' require 'sidekiq/job_retry'
class TestRetry < Sidekiq::Test class TestRetry < Minitest::Test
describe 'middleware' do describe 'middleware' do
class SomeWorker class SomeWorker
include Sidekiq::Worker include Sidekiq::Worker

View file

@ -2,7 +2,7 @@
require_relative 'helper' require_relative 'helper'
require 'sidekiq/job_retry' require 'sidekiq/job_retry'
class TestRetryExhausted < Sidekiq::Test class TestRetryExhausted < Minitest::Test
describe 'sidekiq_retries_exhausted' do describe 'sidekiq_retries_exhausted' do
class NewWorker class NewWorker
include Sidekiq::Worker include Sidekiq::Worker

View file

@ -2,7 +2,7 @@
require_relative 'helper' require_relative 'helper'
require 'sidekiq/scheduled' require 'sidekiq/scheduled'
class TestScheduled < Sidekiq::Test class TestScheduled < Minitest::Test
class ScheduledWorker class ScheduledWorker
include Sidekiq::Worker include Sidekiq::Worker
def perform(x) def perform(x)

View file

@ -2,7 +2,7 @@
require_relative 'helper' require_relative 'helper'
require 'sidekiq/scheduled' require 'sidekiq/scheduled'
class TestScheduling < Sidekiq::Test class TestScheduling < Minitest::Test
describe 'middleware' do describe 'middleware' do
class ScheduledWorker class ScheduledWorker
include Sidekiq::Worker include Sidekiq::Worker

View file

@ -2,7 +2,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative 'helper' require_relative 'helper'
class TestSidekiq < Sidekiq::Test class TestSidekiq < Minitest::Test
describe 'json processing' do describe 'json processing' do
it 'handles json' do it 'handles json' do
assert_equal({"foo" => "bar"}, Sidekiq.load_json("{\"foo\":\"bar\"}")) assert_equal({"foo" => "bar"}, Sidekiq.load_json("{\"foo\":\"bar\"}"))

View file

@ -20,7 +20,7 @@ def output(section = 'all')
end end
end end
class TestSidekiqctl < Sidekiq::Test class TestSidekiqctl < Minitest::Test
describe 'sidekiqctl status' do describe 'sidekiqctl status' do
describe 'version' do describe 'version' do
it 'displays the current Sidekiq version' do it 'displays the current Sidekiq version' do

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative 'helper' require_relative 'helper'
class TestTesting < Sidekiq::Test class TestTesting < Minitest::Test
describe 'sidekiq testing' do describe 'sidekiq testing' do
describe 'require/load sidekiq/testing.rb' do describe 'require/load sidekiq/testing.rb' do
before do before do

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative 'helper' require_relative 'helper'
class TestFake < Sidekiq::Test class TestFake < Minitest::Test
describe 'sidekiq testing' do describe 'sidekiq testing' do
class PerformError < RuntimeError; end class PerformError < RuntimeError; end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative 'helper' require_relative 'helper'
class TestInline < Sidekiq::Test class TestInline < Minitest::Test
describe 'sidekiq inline testing' do describe 'sidekiq inline testing' do
class InlineError < RuntimeError; end class InlineError < RuntimeError; end
class ParameterIsNotString < RuntimeError; end class ParameterIsNotString < RuntimeError; end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative 'helper' require_relative 'helper'
class TestUtil < Sidekiq::Test class TestUtil < Minitest::Test
class Helpers class Helpers
include Sidekiq::Util include Sidekiq::Util

View file

@ -4,7 +4,7 @@ require_relative 'helper'
require 'sidekiq/web' require 'sidekiq/web'
require 'rack/test' require 'rack/test'
class TestWeb < Sidekiq::Test class TestWeb < Minitest::Test
describe 'sidekiq web' do describe 'sidekiq web' do
include Rack::Test::Methods include Rack::Test::Methods

View file

@ -2,7 +2,7 @@
require_relative 'helper' require_relative 'helper'
require 'sidekiq/web' require 'sidekiq/web'
class TestWebHelpers < Sidekiq::Test class TestWebHelpers < Minitest::Test
class Helpers class Helpers
include Sidekiq::WebHelpers include Sidekiq::WebHelpers