diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f93daa345..98bf21aa0 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -8,6 +8,25 @@ on: branches: - "*" jobs: + lint: + name: Rubocop + timeout-minutes: 30 + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v2 + - name: Set up Ruby + uses: actions/setup-ruby@v1 + with: + ruby-version: "2.4" + - name: Set up Gems + run: | + gem update --system --no-document + gem install bundler --no-document + bundle install --jobs 4 --retry 3 --path=.bundle + - name: Lint + run: bundle exec rubocop + main: name: Main timeout-minutes: 30 diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 000000000..45ae5858b --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,114 @@ +AllCops: + TargetRubyVersion: 2.3 + +Layout/LineLength: + Max: 120 + Exclude: + - 'test/**/*' + +Layout/CaseIndentation: + EnforcedStyle: end + +Lint/RescueException: + Enabled: false + +Lint/SuppressedException: + Enabled: false + +Lint/AssignmentInCondition: + Enabled: false + +Lint/UnifiedInteger: + Enabled: false + +Metrics/ClassLength: + Enabled: false + +Metrics/CyclomaticComplexity: + Enabled: false + +Metrics/AbcSize: + Enabled: false + +Metrics/BlockLength: + Enabled: false + +Metrics/MethodLength: + Enabled: false + +Metrics/ModuleLength: + Enabled: false + +Metrics/ParameterLists: + Enabled: false + +Metrics/PerceivedComplexity: + Enabled: false + +Style/PercentLiteralDelimiters: + Enabled: false + +Style/ParallelAssignment: + Enabled: false + +Style/NumericPredicate: + Enabled: false + +Style/SignalException: + Exclude: + - 'lib/redis/connection/synchrony.rb' + +Style/MethodMissingSuper: + Enabled: false + +Style/StringLiterals: + Enabled: false + +Style/DoubleNegation: + Enabled: false + +Style/MultipleComparison: + Enabled: false + +Style/GuardClause: + Enabled: false + +Style/Semicolon: + Enabled: false + +Style/Documentation: + Enabled: false + +Style/FormatStringToken: + Enabled: false + +Style/FormatString: + Enabled: false + +Style/RescueStandardError: + Enabled: false + +Style/WordArray: + Enabled: false + +Lint/NonLocalExitFromIterator: + Enabled: false + +Lint/EndAlignment: + EnforcedStyleAlignWith: variable + +Layout/ElseAlignment: + Enabled: false + +Naming/HeredocDelimiterNaming: + Enabled: false + +Naming/FileName: + Enabled: false + +Naming/RescuedExceptionsVariableName: + Enabled: false + +Naming/AccessorMethodName: + Exclude: + - lib/redis/connection/ruby.rb \ No newline at end of file diff --git a/Gemfile b/Gemfile index dafdf4da5..f8199a67f 100644 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,12 @@ # frozen_string_literal: true + source 'https://rubygems.org' gemspec -gem 'rake' gem 'minitest' +gem 'rake' +gem 'rubocop', '0.81' # Using jruby-openssl 0.10.0, we get NPEs in jruby tests: https://github.com/redis/redis-rb/issues/756 platform :jruby do diff --git a/Rakefile b/Rakefile index 85ab1dec3..268b1568d 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'bundler/gem_tasks' require 'rake/testtask' Rake::TestTask.new :test do |t| diff --git a/benchmarking/cluster.rb b/benchmarking/cluster.rb index 468f6709f..8a5b9ff5e 100644 --- a/benchmarking/cluster.rb +++ b/benchmarking/cluster.rb @@ -12,7 +12,7 @@ HOST = '127.0.0.1' STANDALONE_PORT = 6381 CLUSTER_PORT = 7000 -N = (ARGV.first || 100000).to_i +N = (ARGV.first || 100_000).to_i rn = Redis.new(host: HOST, port: STANDALONE_PORT) rc = Redis.new(host: HOST, port: CLUSTER_PORT) diff --git a/benchmarking/cluster_slot.rb b/benchmarking/cluster_slot.rb index 208881c0f..a374aff86 100644 --- a/benchmarking/cluster_slot.rb +++ b/benchmarking/cluster_slot.rb @@ -3,15 +3,15 @@ require 'redis' require 'benchmark' -N = (ARGV.first || 100000).to_i +N = (ARGV.first || 100_000).to_i available_slots = { "127.0.0.1:7000" => [0..5460], "127.0.0.1:7003" => [0..5460], - "127.0.0.1:7001" => [5461..10922], - "127.0.0.1:7004" => [5461..10922], - "127.0.0.1:7002" => [10923..16383], - "127.0.0.1:7005" => [10923..16383] + "127.0.0.1:7001" => [5461..10_922], + "127.0.0.1:7004" => [5461..10_922], + "127.0.0.1:7002" => [10_923..16_383], + "127.0.0.1:7005" => [10_923..16_383] } node_flags = { @@ -33,4 +33,4 @@ puts GC.stat(:total_allocated_objects) - allocs end -end \ No newline at end of file +end diff --git a/benchmarking/logging.rb b/benchmarking/logging.rb index 828708629..7b09a4609 100644 --- a/benchmarking/logging.rb +++ b/benchmarking/logging.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # Run with # # $ ruby -Ilib benchmarking/logging.rb @@ -7,7 +8,7 @@ begin require "bench" rescue LoadError - $stderr.puts "`gem install bench` and try again." + warn "`gem install bench` and try again." exit 1 end @@ -35,19 +36,20 @@ def stress(redis) default = Redis.new logging_redises = [ - Redis.new(:logger => log(:DEBUG)), - Redis.new(:logger => log(:INFO)), + Redis.new(logger: log(:DEBUG)), + Redis.new(logger: log(:INFO)) ] begin require "log4r" logging_redises += [ - Redis.new(:logger => log(:DEBUG, Log4r)), - Redis.new(:logger => log(:INFO, Log4r)), + Redis.new(logger: log(:DEBUG, Log4r)), + Redis.new(logger: log(:INFO, Log4r)) ] rescue LoadError - $stderr.puts "Log4r not installed. `gem install log4r` if you want to compare it against Ruby's Logger (spoiler: it's much faster)." + warn "Log4r not installed. `gem install log4r` if you want to compare it against Ruby's " \ + "Logger (spoiler: it's much faster)." end benchmark "Default options (no logger)" do diff --git a/benchmarking/pipeline.rb b/benchmarking/pipeline.rb index f7efacaba..84b20dcc7 100644 --- a/benchmarking/pipeline.rb +++ b/benchmarking/pipeline.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true + require "benchmark" -$:.push File.join(File.dirname(__FILE__), 'lib') +$LOAD_PATH.push File.join(File.dirname(__FILE__), 'lib') require 'redis' -ITERATIONS = 10000 +ITERATIONS = 10_000 @r = Redis.new diff --git a/benchmarking/speed.rb b/benchmarking/speed.rb index 1bd07bd90..f8ab15879 100644 --- a/benchmarking/speed.rb +++ b/benchmarking/speed.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # Run with # # $ ruby -Ilib benchmarking/speed.rb @@ -8,7 +9,7 @@ require "redis" r = Redis.new -n = (ARGV.shift || 20000).to_i +n = (ARGV.shift || 20_000).to_i elapsed = Benchmark.realtime do # n sets, n gets diff --git a/benchmarking/suite.rb b/benchmarking/suite.rb index 87a23a2a7..de7dfe0ef 100644 --- a/benchmarking/suite.rb +++ b/benchmarking/suite.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'fileutils' def run_in_background(command) @@ -7,17 +8,17 @@ def run_in_background(command) def with_all_segments(&block) 0.upto(9) do |segment_number| - block_size = 100000 + block_size = 100_000 start_index = segment_number * block_size end_index = start_index + block_size - 1 block.call(start_index, end_index) end end -#with_all_segments do |start_index, end_index| +# with_all_segments do |start_index, end_index| # puts "Initializing keys from #{start_index} to #{end_index}" # system "ruby worker.rb initialize #{start_index} #{end_index} 0" -#end +# end with_all_segments do |start_index, end_index| run_in_background "ruby worker.rb write #{start_index} #{end_index} 10" diff --git a/benchmarking/worker.rb b/benchmarking/worker.rb index 422f0317d..15c6e5ac1 100644 --- a/benchmarking/worker.rb +++ b/benchmarking/worker.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true + BENCHMARK_ROOT = File.dirname(__FILE__) REDIS_ROOT = File.join(BENCHMARK_ROOT, "..", "lib") -$: << REDIS_ROOT +$LOAD_PATH << REDIS_ROOT require 'redis' require 'benchmark' @@ -16,7 +17,7 @@ def shift_from_argv value = ARGV.shift unless value show_usage - exit -1 + exit(-1) end value end @@ -25,48 +26,48 @@ def shift_from_argv start_index = shift_from_argv.to_i end_index = shift_from_argv.to_i sleep_msec = shift_from_argv.to_i -sleep_duration = sleep_msec/1000.0 +sleep_duration = sleep_msec / 1000.0 redis = Redis.new case operation - when :initialize +when :initialize - start_index.upto(end_index) do |i| - redis[i] = 0 - end + start_index.upto(end_index) do |i| + redis[i] = 0 + end - when :clear +when :clear - start_index.upto(end_index) do |i| - redis.delete(i) - end + start_index.upto(end_index) do |i| + redis.delete(i) + end - when :read, :write +when :read, :write - puts "Starting to #{operation} at segment #{end_index + 1}" + puts "Starting to #{operation} at segment #{end_index + 1}" - loop do - t1 = Time.now - start_index.upto(end_index) do |i| - case operation - when :read - redis.get(i) - when :write - redis.incr(i) - else - raise "Unknown operation: #{operation}" - end - sleep sleep_duration + loop do + t1 = Time.now + start_index.upto(end_index) do |i| + case operation + when :read + redis.get(i) + when :write + redis.incr(i) + else + raise "Unknown operation: #{operation}" end - t2 = Time.now - - requests_processed = end_index - start_index - time = t2 - t1 - puts "#{t2.strftime("%H:%M")} [segment #{end_index + 1}] : Processed #{requests_processed} requests in #{time} seconds - #{(requests_processed/time).round} requests/sec" + sleep sleep_duration end + t2 = Time.now + + requests_processed = end_index - start_index + time = t2 - t1 + puts "#{t2.strftime('%H:%M')} [segment #{end_index + 1}] : Processed #{requests_processed} requests " \ + "in #{time} seconds - #{(requests_processed / time).round} requests/sec" + end else - raise "Unknown operation: #{operation}" + raise "Unknown operation: #{operation}" end - diff --git a/bin/build b/bin/build index bfb27e6a5..7f2c788ab 100755 --- a/bin/build +++ b/bin/build @@ -69,9 +69,7 @@ class Builder def command!(*args) puts "$ #{args.join(' ')}" - unless system(*args) - raise "Command failed with status #{$?.exitstatus}" - end + raise "Command failed with status #{$CHILD_STATUS.exitstatus}" unless system(*args) end end diff --git a/bin/console b/bin/console index c2057a112..d4220d089 100755 --- a/bin/console +++ b/bin/console @@ -1,7 +1,7 @@ #!/usr/bin/env ruby # frozen_string_literal: true -$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__)) +$LOAD_PATH.unshift(File.expand_path('../lib', __dir__)) require 'redis' require 'irb' diff --git a/examples/basic.rb b/examples/basic.rb index d97384e88..4c8906bba 100644 --- a/examples/basic.rb +++ b/examples/basic.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'redis' r = Redis.new @@ -7,7 +8,7 @@ puts -p'set foo to "bar"' +p 'set foo to "bar"' r['foo'] = 'bar' puts diff --git a/examples/consistency.rb b/examples/consistency.rb index 73fefc4a3..f1445421d 100644 --- a/examples/consistency.rb +++ b/examples/consistency.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # This file implements a simple consistency test for Redis-rb (or any other # Redis environment if you pass a different client object) where a client # writes to the database using INCR in order to increment keys, but actively @@ -17,10 +18,10 @@ # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: -# +# # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -32,84 +33,83 @@ require 'redis' class ConsistencyTester - def initialize(redis) - @r = redis - @working_set = 10000 - @keyspace = 100000 - @writes = 0 - @reads = 0 - @failed_writes = 0 - @failed_reads = 0 - @lost_writes = 0 - @not_ack_writes = 0 - @delay = 0 - @cached = {} # We take our view of data stored in the DB. - @prefix = [Process.pid.to_s,Time.now.usec,@r.object_id,""].join("|") - @errtime = {} - end + def initialize(redis) + @r = redis + @working_set = 10_000 + @keyspace = 100_000 + @writes = 0 + @reads = 0 + @failed_writes = 0 + @failed_reads = 0 + @lost_writes = 0 + @not_ack_writes = 0 + @delay = 0 + @cached = {} # We take our view of data stored in the DB. + @prefix = [Process.pid.to_s, Time.now.usec, @r.object_id, ""].join("|") + @errtime = {} + end - def genkey - # Write more often to a small subset of keys - ks = rand() > 0.5 ? @keyspace : @working_set - @prefix+"key_"+rand(ks).to_s - end + def genkey + # Write more often to a small subset of keys + ks = rand > 0.5 ? @keyspace : @working_set + @prefix + "key_" + rand(ks).to_s + end - def check_consistency(key,value) - expected = @cached[key] - return if !expected # We lack info about previous state. - if expected > value - @lost_writes += expected-value - elsif expected < value - @not_ack_writes += value-expected - end - end + def check_consistency(key, value) + expected = @cached[key] + return unless expected # We lack info about previous state. - def puterr(msg) - if !@errtime[msg] || Time.now.to_i != @errtime[msg] - puts msg - end - @errtime[msg] = Time.now.to_i + if expected > value + @lost_writes += expected - value + elsif expected < value + @not_ack_writes += value - expected end + end + + def puterr(msg) + puts msg if !@errtime[msg] || Time.now.to_i != @errtime[msg] + @errtime[msg] = Time.now.to_i + end + + def test + last_report = Time.now.to_i + loop do + # Read + key = genkey + begin + val = @r.get(key) + check_consistency(key, val.to_i) + @reads += 1 + rescue => e + puterr "Reading: #{e.class}: #{e.message} (#{e.backtrace.first})" + @failed_reads += 1 + end - def test - last_report = Time.now.to_i - while true - # Read - key = genkey - begin - val = @r.get(key) - check_consistency(key,val.to_i) - @reads += 1 - rescue => e - puterr "Reading: #{e.class}: #{e.message} (#{e.backtrace.first})" - @failed_reads += 1 - end + # Write + begin + @cached[key] = @r.incr(key).to_i + @writes += 1 + rescue => e + puterr "Writing: #{e.class}: #{e.message} (#{e.backtrace.first})" + @failed_writes += 1 + end - # Write - begin - @cached[key] = @r.incr(key).to_i - @writes += 1 - rescue => e - puterr "Writing: #{e.class}: #{e.message} (#{e.backtrace.first})" - @failed_writes += 1 - end + # Report + sleep @delay + next unless Time.now.to_i != last_report - # Report - sleep @delay - if Time.now.to_i != last_report - report = "#{@reads} R (#{@failed_reads} err) | " + - "#{@writes} W (#{@failed_writes} err) | " - report += "#{@lost_writes} lost | " if @lost_writes > 0 - report += "#{@not_ack_writes} noack | " if @not_ack_writes > 0 - last_report = Time.now.to_i - puts report - end - end + report = "#{@reads} R (#{@failed_reads} err) | " \ + "#{@writes} W (#{@failed_writes} err) | " + report += "#{@lost_writes} lost | " if @lost_writes > 0 + report += "#{@not_ack_writes} noack | " if @not_ack_writes > 0 + last_report = Time.now.to_i + puts report end + end end -Sentinels = [{:host => "127.0.0.1", :port => 26379}, - {:host => "127.0.0.1", :port => 26380}] -r = Redis.new(:url => "redis://master1", :sentinels => Sentinels, :role => :master) +SENTINELS = [{ host: "127.0.0.1", port: 26_379 }, + { host: "127.0.0.1", port: 26_380 }].freeze +r = Redis.new(url: "redis://master1", sentinels: SENTINELS, role: :master) tester = ConsistencyTester.new(r) tester.test diff --git a/examples/dist_redis.rb b/examples/dist_redis.rb index 4366918a4..6a8878420 100644 --- a/examples/dist_redis.rb +++ b/examples/dist_redis.rb @@ -1,8 +1,14 @@ # frozen_string_literal: true + require "redis" require "redis/distributed" -r = Redis::Distributed.new %w[redis://localhost:6379 redis://localhost:6380 redis://localhost:6381 redis://localhost:6382] +r = Redis::Distributed.new %w[ + redis://localhost:6379 + redis://localhost:6380 + redis://localhost:6381 + redis://localhost:6382 +] r.flushdb diff --git a/examples/incr-decr.rb b/examples/incr-decr.rb index 498aedc5f..d226f3dfe 100644 --- a/examples/incr-decr.rb +++ b/examples/incr-decr.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'redis' r = Redis.new diff --git a/examples/list.rb b/examples/list.rb index 82b3901aa..06e460c40 100644 --- a/examples/list.rb +++ b/examples/list.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'rubygems' require 'redis' diff --git a/examples/pubsub.rb b/examples/pubsub.rb index bb57b4f70..8b9d09712 100644 --- a/examples/pubsub.rb +++ b/examples/pubsub.rb @@ -1,14 +1,15 @@ # frozen_string_literal: true + require "redis" -puts <<-EOS -To play with this example use redis-cli from another terminal, like this: +puts <<~EOS + To play with this example use redis-cli from another terminal, like this: - $ redis-cli publish one hello + $ redis-cli publish one hello -Finally force the example to exit sending the 'exit' message with: + Finally force the example to exit sending the 'exit' message with: - $ redis-cli publish two exit + $ redis-cli publish two exit EOS diff --git a/examples/sentinel.rb b/examples/sentinel.rb index 545d81649..884b77b96 100644 --- a/examples/sentinel.rb +++ b/examples/sentinel.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'redis' # This example creates a master-slave setup with a sentinel, then connects to @@ -14,29 +15,29 @@ at_exit do begin - Process.kill(:INT, $redises) + Process.kill(:INT, @redises) rescue Errno::ESRCH end Process.waitall end -$redises = spawn("examples/sentinel/start") +@redises = spawn("examples/sentinel/start") -Sentinels = [{:host => "127.0.0.1", :port => 26379}, - {:host => "127.0.0.1", :port => 26380}] -r = Redis.new(:url => "redis://master1", :sentinels => Sentinels, :role => :master) +SENTINELS = [{ host: "127.0.0.1", port: 26_379 }, + { host: "127.0.0.1", port: 26_380 }].freeze +r = Redis.new(url: "redis://master1", sentinels: SENTINELS, role: :master) # Set keys into a loop. # # The example traps errors so that you can actually try to failover while # running the script to see redis-rb reconfiguring. -(0..1000000).each{|i| - begin - r.set(i,i) - $stdout.write("SET (#{i} times)\n") if i % 100 == 0 - rescue => e - $stdout.write("E") - end - sleep(0.01) -} +(0..1_000_000).each do |i| + begin + r.set(i, i) + $stdout.write("SET (#{i} times)\n") if i % 100 == 0 + rescue + $stdout.write("E") + end + sleep(0.01) +end diff --git a/examples/sentinel/start b/examples/sentinel/start index 4a1fd1981..2ffbfa307 100755 --- a/examples/sentinel/start +++ b/examples/sentinel/start @@ -9,10 +9,10 @@ require "fileutils" -$pids = [] +pids = [] at_exit do - $pids.each do |pid| + pids.each do |pid| begin Process.kill(:INT, pid) rescue Errno::ESRCH @@ -22,29 +22,29 @@ at_exit do Process.waitall end -base = File.expand_path(File.dirname(__FILE__)) +base = __dir__ # Masters -$pids << spawn("redis-server --port 6380 --loglevel warning") -$pids << spawn("redis-server --port 6381 --loglevel warning") +pids << spawn("redis-server --port 6380 --loglevel warning") +pids << spawn("redis-server --port 6381 --loglevel warning") # Slaves of Master 1 -$pids << spawn("redis-server --port 63800 --slaveof 127.0.0.1 6380 --loglevel warning") -$pids << spawn("redis-server --port 63801 --slaveof 127.0.0.1 6380 --loglevel warning") +pids << spawn("redis-server --port 63800 --slaveof 127.0.0.1 6380 --loglevel warning") +pids << spawn("redis-server --port 63801 --slaveof 127.0.0.1 6380 --loglevel warning") # Slaves of Master 2 -$pids << spawn("redis-server --port 63810 --slaveof 127.0.0.1 6381 --loglevel warning") -$pids << spawn("redis-server --port 63811 --slaveof 127.0.0.1 6381 --loglevel warning") +pids << spawn("redis-server --port 63810 --slaveof 127.0.0.1 6381 --loglevel warning") +pids << spawn("redis-server --port 63811 --slaveof 127.0.0.1 6381 --loglevel warning") FileUtils.cp(File.join(base, "sentinel.conf"), "tmp/sentinel1.conf") FileUtils.cp(File.join(base, "sentinel.conf"), "tmp/sentinel2.conf") # Sentinels -$pids << spawn("redis-server tmp/sentinel1.conf --sentinel --port 26379") -$pids << spawn("redis-server tmp/sentinel2.conf --sentinel --port 26380") +pids << spawn("redis-server tmp/sentinel1.conf --sentinel --port 26379") +pids << spawn("redis-server tmp/sentinel2.conf --sentinel --port 26380") sleep 30 -Process.kill(:KILL, $pids[0]) +Process.kill(:KILL, pids[0]) Process.waitall diff --git a/examples/sets.rb b/examples/sets.rb index 902cd9d09..8446a51db 100644 --- a/examples/sets.rb +++ b/examples/sets.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'rubygems' require 'redis' diff --git a/examples/unicorn/config.ru b/examples/unicorn/config.ru index 31d0dd54c..81e5a523d 100644 --- a/examples/unicorn/config.ru +++ b/examples/unicorn/config.ru @@ -1,4 +1,5 @@ # frozen_string_literal: true -run lambda { |env| - [200, {"Content-Type" => "text/plain"}, [Redis.current.randomkey]] + +run lambda { |_env| + [200, { "Content-Type" => "text/plain" }, [Redis.current.randomkey]] } diff --git a/examples/unicorn/unicorn.rb b/examples/unicorn/unicorn.rb index 1c276d554..939e0e6dc 100644 --- a/examples/unicorn/unicorn.rb +++ b/examples/unicorn/unicorn.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "redis" worker_processes 3 @@ -16,6 +17,6 @@ # Thus we need to connect to Redis after forking the # worker processes. -after_fork do |server, worker| +after_fork do |_server, _worker| Redis.current.disconnect! end diff --git a/lib/redis.rb b/lib/redis.rb index 6ba0829f1..53ccaf465 100644 --- a/lib/redis.rb +++ b/lib/redis.rb @@ -12,8 +12,8 @@ def self.current @current ||= Redis.new end - def self.current=(redis) - @current = redis + class << self + attr_writer :current end include MonitorMixin @@ -21,7 +21,9 @@ def self.current=(redis) # Create a new client instance # # @param [Hash] options - # @option options [String] :url (value of the environment variable REDIS_URL) a Redis URL, for a TCP connection: `redis://:[password]@[hostname]:[port]/[db]` (password, port and database are optional), for a unix socket connection: `unix://[path to Redis socket]`. This overrides all other options. + # @option options [String] :url (value of the environment variable REDIS_URL) a Redis URL, for a TCP connection: + # `redis://:[password]@[hostname]:[port]/[db]` (password, port and database are optional), for a unix socket + # connection: `unix://[path to Redis socket]`. This overrides all other options. # @option options [String] :host ("127.0.0.1") server hostname # @option options [Integer] :port (6379) server port # @option options [String] :path path to server socket (overrides host and port) @@ -30,8 +32,10 @@ def self.current=(redis) # @option options [String] :password Password to authenticate against server # @option options [Integer] :db (0) Database to select after initial connect # @option options [Symbol] :driver Driver to use, currently supported: `:ruby`, `:hiredis`, `:synchrony` - # @option options [String] :id ID for the client connection, assigns name to current connection by sending `CLIENT SETNAME` - # @option options [Hash, Integer] :tcp_keepalive Keepalive values, if Integer `intvl` and `probe` are calculated based on the value, if Hash `time`, `intvl` and `probes` can be specified as a Integer + # @option options [String] :id ID for the client connection, assigns name to current connection by sending + # `CLIENT SETNAME` + # @option options [Hash, Integer] :tcp_keepalive Keepalive values, if Integer `intvl` and `probe` are calculated + # based on the value, if Hash `time`, `intvl` and `probes` can be specified as a Integer # @option options [Integer] :reconnect_attempts Number of attempts trying to connect # @option options [Boolean] :inherit_socket (false) Whether to use socket in forked process or not # @option options [Array] :sentinels List of sentinels to contact @@ -56,7 +60,7 @@ def synchronize end # Run code with the client reconnecting - def with_reconnect(val=true, &blk) + def with_reconnect(val = true, &blk) synchronize do |client| client.with_reconnect(val, &blk) end @@ -209,7 +213,7 @@ def bgsave def config(action, *args) synchronize do |client| client.call([:config, action] + args) do |reply| - if reply.kind_of?(Array) && action == :get + if reply.is_a?(Array) && action == :get Hashify.call(reply) else reply @@ -260,7 +264,7 @@ def debug(*args) def flushall(options = nil) synchronize do |client| if options && options[:async] - client.call([:flushall, :async]) + client.call(%i[flushall async]) else client.call([:flushall]) end @@ -275,7 +279,7 @@ def flushall(options = nil) def flushdb(options = nil) synchronize do |client| if options && options[:async] - client.call([:flushdb, :async]) + client.call(%i[flushdb async]) else client.call([:flushdb]) end @@ -289,7 +293,7 @@ def flushdb(options = nil) def info(cmd = nil) synchronize do |client| client.call([:info, cmd].compact) do |reply| - if reply.kind_of?(String) + if reply.is_a?(String) reply = HashifyInfo.call(reply) if cmd && cmd.to_s == "commandstats" @@ -362,7 +366,7 @@ def slaveof(host, port) # @param [String] subcommand e.g. `get`, `len`, `reset` # @param [Integer] length maximum number of entries to return # @return [Array, Integer, String] depends on subcommand - def slowlog(subcommand, length=nil) + def slowlog(subcommand, length = nil) synchronize do |client| args = [:slowlog, subcommand] args << length if length @@ -387,7 +391,7 @@ def sync def time synchronize do |client| client.call([:time]) do |reply| - reply.map(&:to_i) if reply + reply&.map(&:to_i) end end end @@ -564,11 +568,7 @@ def exists(*keys) "use `exists?` instead. To opt-in to the new behavior now you can set Redis.exists_returns_integer = true. " \ "(#{::Kernel.caller(1, 1).first})\n" - if defined?(::Warning) - ::Warning.warn(message) - else - $stderr.puts(message) - end + ::Kernel.warn(message) exists?(*keys) else _exists(*keys) @@ -598,7 +598,7 @@ def exists?(*keys) def keys(pattern = "*") synchronize do |client| client.call([:keys, pattern]) do |reply| - if reply.kind_of?(String) + if reply.is_a?(String) reply.split(" ") else reply @@ -715,9 +715,7 @@ def sort(key, options = {}) synchronize do |client| client.call([:sort, key] + args) do |reply| if get.size > 1 && !store - if reply - reply.each_slice(get.size).to_a - end + reply.each_slice(get.size).to_a if reply else reply end @@ -979,7 +977,7 @@ def mget(*keys, &blk) # @see #mget def mapped_mget(*keys) mget(*keys) do |reply| - if reply.kind_of?(Array) + if reply.is_a?(Array) Hash[keys.zip(reply)] else reply @@ -1078,10 +1076,8 @@ def bitop(operation, destkey, *keys) # @param [Integer] stop stop index # @return [Integer] the position of the first 1/0 bit. # -1 if looking for 1 and it is not found or start and stop are given. - def bitpos(key, bit, start=nil, stop=nil) - if stop and not start - raise(ArgumentError, 'stop parameter specified without start parameter') - end + def bitpos(key, bit, start = nil, stop = nil) + raise(ArgumentError, 'stop parameter specified without start parameter') if stop && !start synchronize do |client| command = [:bitpos, key, bit] @@ -1279,7 +1275,7 @@ def brpoplpush(source, destination, options = {}) case options when Integer # Issue deprecation notice in obnoxious mode... - options = { :timeout => options } + options = { timeout: options } end timeout = options[:timeout] || 0 @@ -1592,7 +1588,7 @@ def zcard(key) # pairs that were **added** to the sorted set. # - `Float` when option :incr is specified, holding the score of the member # after incrementing it. - def zadd(key, *args) #, options + def zadd(key, *args) zadd_options = [] if args.last.is_a?(Hash) options = args.pop @@ -2146,9 +2142,7 @@ def hlen(key) # @param [Array | Hash] attrs array or hash of fields and values # @return [Integer] The number of fields that were added to the hash def hset(key, *attrs) - if attrs.size == 1 && attrs.first.is_a?(Hash) - attrs = attrs.first.flatten - end + attrs = attrs.first.flatten if attrs.size == 1 && attrs.first.is_a?(Hash) synchronize do |client| client.call([:hset, key, *attrs]) @@ -2240,7 +2234,7 @@ def hmget(key, *fields, &blk) # @see #hmget def mapped_hmget(key, *fields) hmget(key, *fields) do |reply| - if reply.kind_of?(Array) + if reply.is_a?(Array) Hash[fields.zip(reply)] else reply @@ -2333,20 +2327,21 @@ def publish(channel, message) def subscribed? synchronize do |client| - client.kind_of? SubscribedClient + client.is_a? SubscribedClient end end # Listen for messages published to the given channels. def subscribe(*channels, &block) - synchronize do |client| + synchronize do |_client| _subscription(:subscribe, 0, channels, block) end end - # Listen for messages published to the given channels. Throw a timeout error if there is no messages for a timeout period. + # Listen for messages published to the given channels. Throw a timeout error + # if there is no messages for a timeout period. def subscribe_with_timeout(timeout, *channels, &block) - synchronize do |client| + synchronize do |_client| _subscription(:subscribe_with_timeout, timeout, channels, block) end end @@ -2354,21 +2349,23 @@ def subscribe_with_timeout(timeout, *channels, &block) # Stop listening for messages posted to the given channels. def unsubscribe(*channels) synchronize do |client| - raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed? + raise "Can't unsubscribe if not subscribed." unless subscribed? + client.unsubscribe(*channels) end end # Listen for messages published to channels matching the given patterns. def psubscribe(*channels, &block) - synchronize do |client| + synchronize do |_client| _subscription(:psubscribe, 0, channels, block) end end - # Listen for messages published to channels matching the given patterns. Throw a timeout error if there is no messages for a timeout period. + # Listen for messages published to channels matching the given patterns. + # Throw a timeout error if there is no messages for a timeout period. def psubscribe_with_timeout(timeout, *channels, &block) - synchronize do |client| + synchronize do |_client| _subscription(:psubscribe_with_timeout, timeout, channels, block) end end @@ -2376,7 +2373,8 @@ def psubscribe_with_timeout(timeout, *channels, &block) # Stop listening for messages posted to channels matching the given patterns. def punsubscribe(*channels) synchronize do |client| - raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed? + raise "Can't unsubscribe if not subscribed." unless subscribed? + client.punsubscribe(*channels) end end @@ -2451,7 +2449,7 @@ def unwatch end def pipelined - synchronize do |client| + synchronize do |_client| begin pipeline = Pipeline.new(@client) original, @client = @client, pipeline @@ -2684,7 +2682,7 @@ def _scan(command, cursor, args, options = {}, &block) # - `:count => Integer`: return count keys at most per iteration # # @return [String, Array] the next cursor and all found keys - def scan(cursor, options={}) + def scan(cursor, options = {}) _scan(:scan, cursor, [], options) end @@ -2703,8 +2701,9 @@ def scan(cursor, options={}) # - `:count => Integer`: return count keys at most per iteration # # @return [Enumerator] an enumerator for all found keys - def scan_each(options={}, &block) + def scan_each(options = {}, &block) return to_enum(:scan_each, options) unless block_given? + cursor = 0 loop do cursor, keys = scan(cursor, options) @@ -2724,7 +2723,7 @@ def scan_each(options={}, &block) # - `:count => Integer`: return count keys at most per iteration # # @return [String, Array<[String, String]>] the next cursor and all found keys - def hscan(key, cursor, options={}) + def hscan(key, cursor, options = {}) _scan(:hscan, cursor, [key], options) do |reply| [reply[0], reply[1].each_slice(2).to_a] end @@ -2741,8 +2740,9 @@ def hscan(key, cursor, options={}) # - `:count => Integer`: return count keys at most per iteration # # @return [Enumerator] an enumerator for all found keys - def hscan_each(key, options={}, &block) + def hscan_each(key, options = {}, &block) return to_enum(:hscan_each, key, options) unless block_given? + cursor = 0 loop do cursor, values = hscan(key, cursor, options) @@ -2763,7 +2763,7 @@ def hscan_each(key, options={}, &block) # # @return [String, Array<[String, Float]>] the next cursor and all found # members and scores - def zscan(key, cursor, options={}) + def zscan(key, cursor, options = {}) _scan(:zscan, cursor, [key], options) do |reply| [reply[0], FloatifyPairs.call(reply[1])] end @@ -2780,8 +2780,9 @@ def zscan(key, cursor, options={}) # - `:count => Integer`: return count keys at most per iteration # # @return [Enumerator] an enumerator for all found scores and members - def zscan_each(key, options={}, &block) + def zscan_each(key, options = {}, &block) return to_enum(:zscan_each, key, options) unless block_given? + cursor = 0 loop do cursor, values = zscan(key, cursor, options) @@ -2801,7 +2802,7 @@ def zscan_each(key, options={}, &block) # - `:count => Integer`: return count keys at most per iteration # # @return [String, Array] the next cursor and all found members - def sscan(key, cursor, options={}) + def sscan(key, cursor, options = {}) _scan(:sscan, cursor, [key], options) end @@ -2816,8 +2817,9 @@ def sscan(key, cursor, options={}) # - `:count => Integer`: return count keys at most per iteration # # @return [Enumerator] an enumerator for all keys in the set - def sscan_each(key, options={}, &block) + def sscan_each(key, options = {}, &block) return to_enum(:sscan_each, key, options) unless block_given? + cursor = 0 loop do cursor, keys = sscan(key, cursor, options) @@ -2884,12 +2886,12 @@ def geohash(key, member) end end - # Query a sorted set representing a geospatial index to fetch members matching a # given maximum distance from a point # # @param [Array] args key, longitude, latitude, radius, unit(m|km|ft|mi) - # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest to the nearest relative to the center + # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest + # or the farthest to the nearest relative to the center # @param [Integer] count limit the results to the first N matching items # @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information # @return [Array] may be changed with `options` @@ -2906,7 +2908,8 @@ def georadius(*args, **geoptions) # given maximum distance from an already existing member # # @param [Array] args key, member, radius, unit(m|km|ft|mi) - # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest to the nearest relative to the center + # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest + # to the nearest relative to the center # @param [Integer] count limit the results to the first N matching items # @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information # @return [Array] may be changed with `options` @@ -2923,7 +2926,8 @@ def georadiusbymember(*args, **geoptions) # # @param [String] key # @param [String, Array] member one member or array of members - # @return [Array, nil>] returns array of elements, where each element is either array of longitude and latitude or nil + # @return [Array, nil>] returns array of elements, where each + # element is either array of longitude and latitude or nil def geopos(key, member) synchronize do |client| client.call([:geopos, key, member]) @@ -3045,8 +3049,8 @@ def xdel(key, *ids) # @param count [Integer] the number of entries as limit # # @return [Array>] the ids and entries pairs - def xrange(key, start = '-', _end = '+', count: nil) - args = [:xrange, key, start, _end] + def xrange(key, start = '-', range_end = '+', count: nil) + args = [:xrange, key, start, range_end] args.concat(['COUNT', count]) if count synchronize { |client| client.call(args, &HashifyStreamEntries) } end @@ -3068,8 +3072,8 @@ def xrange(key, start = '-', _end = '+', count: nil) # @params count [Integer] the number of entries as limit # # @return [Array>] the ids and entries pairs - def xrevrange(key, _end = '+', start = '-', count: nil) - args = [:xrevrange, key, _end, start] + def xrevrange(key, range_end = '+', start = '-', count: nil) + args = [:xrevrange, key, range_end, start] args.concat(['COUNT', count]) if count synchronize { |client| client.call(args, &HashifyStreamEntries) } end @@ -3276,8 +3280,8 @@ def sentinel(subcommand, *args) when "get-master-addr-by-name" reply else - if reply.kind_of?(Array) - if reply[0].kind_of?(Array) + if reply.is_a?(Array) + if reply[0].is_a?(Array) reply.map(&Hashify) else Hashify.call(reply) @@ -3301,12 +3305,17 @@ def sentinel(subcommand, *args) def cluster(subcommand, *args) subcommand = subcommand.to_s.downcase block = case subcommand - when 'slots' then HashifyClusterSlots - when 'nodes' then HashifyClusterNodes - when 'slaves' then HashifyClusterSlaves - when 'info' then HashifyInfo - else Noop - end + when 'slots' + HashifyClusterSlots + when 'nodes' + HashifyClusterNodes + when 'slaves' + HashifyClusterSlaves + when 'info' + HashifyInfo + else + Noop + end # @see https://github.com/antirez/redis/blob/unstable/src/redis-trib.rb#L127 raw reply expected block = Noop unless @cluster_mode @@ -3341,21 +3350,21 @@ def connection return @original_client.connection_info if @cluster_mode { - host: @original_client.host, - port: @original_client.port, - db: @original_client.db, - id: @original_client.id, + host: @original_client.host, + port: @original_client.port, + db: @original_client.db, + id: @original_client.id, location: @original_client.location } end - def method_missing(command, *args) + def method_missing(command, *args) # rubocop:disable Style/MissingRespondToMissing synchronize do |client| client.call([command] + args) end end -private + private # Commands returning 1 for true and 0 for false may be executed in a pipeline # where the method call will return nil. Propagate the nil instead of falsely @@ -3435,10 +3444,10 @@ def method_missing(command, *args) HashifyStreamPendings = lambda { |reply| { - 'size' => reply[0], + 'size' => reply[0], 'min_entry_id' => reply[1], 'max_entry_id' => reply[2], - 'consumers' => reply[3].nil? ? {} : reply[3].to_h + 'consumers' => reply[3].nil? ? {} : reply[3].to_h } } @@ -3447,8 +3456,8 @@ def method_missing(command, *args) { 'entry_id' => arr[0], 'consumer' => arr[1], - 'elapsed' => arr[2], - 'count' => arr[3] + 'elapsed' => arr[2], + 'count' => arr[3] } end } @@ -3456,15 +3465,15 @@ def method_missing(command, *args) HashifyClusterNodeInfo = lambda { |str| arr = str.split(' ') { - 'node_id' => arr[0], - 'ip_port' => arr[1], - 'flags' => arr[2].split(','), + 'node_id' => arr[0], + 'ip_port' => arr[1], + 'flags' => arr[2].split(','), 'master_node_id' => arr[3], - 'ping_sent' => arr[4], - 'pong_recv' => arr[5], - 'config_epoch' => arr[6], - 'link_state' => arr[7], - 'slots' => arr[8].nil? ? nil : Range.new(*arr[8].split('-')) + 'ping_sent' => arr[4], + 'pong_recv' => arr[5], + 'config_epoch' => arr[6], + 'link_state' => arr[7], + 'slots' => arr[8].nil? ? nil : Range.new(*arr[8].split('-')) } } @@ -3475,9 +3484,9 @@ def method_missing(command, *args) replicas = arr[3..-1].map { |r| { 'ip' => r[0], 'port' => r[1], 'node_id' => r[2] } } { 'start_slot' => first_slot, - 'end_slot' => last_slot, - 'master' => master, - 'replicas' => replicas + 'end_slot' => last_slot, + 'master' => master, + 'replicas' => replicas } end } diff --git a/lib/redis/client.rb b/lib/redis/client.rb index b42998e82..5ef5fdb6e 100644 --- a/lib/redis/client.rb +++ b/lib/redis/client.rb @@ -6,26 +6,25 @@ class Redis class Client - DEFAULTS = { - :url => lambda { ENV["REDIS_URL"] }, - :scheme => "redis", - :host => "127.0.0.1", - :port => 6379, - :path => nil, - :timeout => 5.0, - :password => nil, - :db => 0, - :driver => nil, - :id => nil, - :tcp_keepalive => 0, - :reconnect_attempts => 1, - :reconnect_delay => 0, - :reconnect_delay_max => 0.5, - :inherit_socket => false, - :sentinels => nil, - :role => nil - } + url: -> { ENV["REDIS_URL"] }, + scheme: "redis", + host: "127.0.0.1", + port: 6379, + path: nil, + timeout: 5.0, + password: nil, + db: 0, + driver: nil, + id: nil, + tcp_keepalive: 0, + reconnect_attempts: 1, + reconnect_delay: 0, + reconnect_delay_max: 0.5, + inherit_socket: false, + sentinels: nil, + role: nil + }.freeze attr_reader :options @@ -168,6 +167,7 @@ def call_pipeline(pipeline) end rescue ConnectionError => e return nil if pipeline.shutdown? + # Assume the pipeline was sent in one piece, but execution of # SHUTDOWN caused none of the replies for commands that were executed # prior to it from coming back around. @@ -246,13 +246,13 @@ def process(commands) end def connected? - !! (connection && connection.connected?) + !!(connection && connection.connected?) end def disconnect connection.disconnect if connected? end - alias_method :close, :disconnect + alias close disconnect def reconnect disconnect @@ -303,30 +303,27 @@ def without_socket_timeout(&blk) with_socket_timeout(0, &blk) end - def with_reconnect(val=true) - begin - original, @reconnect = @reconnect, val - yield - ensure - @reconnect = original - end + def with_reconnect(val = true) + original, @reconnect = @reconnect, val + yield + ensure + @reconnect = original end def without_reconnect(&blk) with_reconnect(false, &blk) end - protected + protected def logging(commands) - return yield unless @logger && @logger.debug? + return yield unless @logger&.debug? begin commands.each do |name, *args| logged_args = args.map do |a| - case - when a.respond_to?(:inspect) then a.inspect - when a.respond_to?(:to_s) then a.to_s + if a.respond_to?(:inspect) then a.inspect + elsif a.respond_to?(:to_s) then a.to_s else # handle poorly-behaved descendants of BasicObject klass = a.instance_exec { (class << self; self end).superclass } @@ -360,9 +357,9 @@ def establish_connection Errno::ENETUNREACH, Errno::ENOENT, Errno::ETIMEDOUT, - Errno::EINVAL + Errno::EINVAL => error - raise CannotConnectError, "Error connecting to Redis on #{location} (#{$!.class})" + raise CannotConnectError, "Error connecting to Redis on #{location} (#{error.class})" end def ensure_connected @@ -376,9 +373,9 @@ def ensure_connected if connected? unless inherit_socket? || Process.pid == @pid raise InheritedError, - "Tried to use a connection from a child process without reconnecting. " + - "You need to reconnect to Redis after forking " + - "or set :inherit_socket to true." + "Tried to use a connection from a child process without reconnecting. " \ + "You need to reconnect to Redis after forking " \ + "or set :inherit_socket to true." end else connect @@ -389,7 +386,7 @@ def ensure_connected disconnect if attempts <= @options[:reconnect_attempts] && @reconnect - sleep_t = [(@options[:reconnect_delay] * 2**(attempts-1)), + sleep_t = [(@options[:reconnect_delay] * 2**(attempts - 1)), @options[:reconnect_delay_max]].min Kernel.sleep(sleep_t) @@ -411,16 +408,14 @@ def _parse_options(options) defaults.keys.each do |key| # Fill in defaults if needed - if defaults[key].respond_to?(:call) - defaults[key] = defaults[key].call - end + defaults[key] = defaults[key].call if defaults[key].respond_to?(:call) # Symbolize only keys that are needed - options[key] = options[key.to_s] if options.has_key?(key.to_s) + options[key] = options[key.to_s] if options.key?(key.to_s) end url = options[:url] - url = defaults[:url] if url == nil + url = defaults[:url] if url.nil? # Override defaults from URL if given if url @@ -429,7 +424,7 @@ def _parse_options(options) uri = URI(url) if uri.scheme == "unix" - defaults[:path] = uri.path + defaults[:path] = uri.path elsif uri.scheme == "redis" || uri.scheme == "rediss" defaults[:scheme] = uri.scheme defaults[:host] = uri.host if uri.host @@ -460,7 +455,7 @@ def _parse_options(options) options[:port] = options[:port].to_i end - if options.has_key?(:timeout) + if options.key?(:timeout) options[:connect_timeout] ||= options[:timeout] options[:read_timeout] ||= options[:timeout] options[:write_timeout] ||= options[:timeout] @@ -479,7 +474,7 @@ def _parse_options(options) case options[:tcp_keepalive] when Hash - [:time, :intvl, :probes].each do |key| + %i[time intvl probes].each do |key| unless options[:tcp_keepalive][key].is_a?(Integer) raise "Expected the #{key.inspect} key in :tcp_keepalive to be an Integer" end @@ -487,13 +482,13 @@ def _parse_options(options) when Integer if options[:tcp_keepalive] >= 60 - options[:tcp_keepalive] = {:time => options[:tcp_keepalive] - 20, :intvl => 10, :probes => 2} + options[:tcp_keepalive] = { time: options[:tcp_keepalive] - 20, intvl: 10, probes: 2 } elsif options[:tcp_keepalive] >= 30 - options[:tcp_keepalive] = {:time => options[:tcp_keepalive] - 10, :intvl => 5, :probes => 2} + options[:tcp_keepalive] = { time: options[:tcp_keepalive] - 10, intvl: 5, probes: 2 } elsif options[:tcp_keepalive] >= 5 - options[:tcp_keepalive] = {:time => options[:tcp_keepalive] - 2, :intvl => 2, :probes => 1} + options[:tcp_keepalive] = { time: options[:tcp_keepalive] - 2, intvl: 2, probes: 1 } end end @@ -505,14 +500,14 @@ def _parse_options(options) def _parse_driver(driver) driver = driver.to_s if driver.is_a?(Symbol) - if driver.kind_of?(String) + if driver.is_a?(String) begin require_relative "connection/#{driver}" - rescue LoadError, NameError => e + rescue LoadError, NameError begin require "connection/#{driver}" - rescue LoadError, NameError => e - raise RuntimeError, "Cannot load driver #{driver.inspect}: #{e.message}" + rescue LoadError, NameError => error + raise "Cannot load driver #{driver.inspect}: #{error.message}" end end @@ -531,8 +526,7 @@ def resolve @options end - def check(client) - end + def check(client); end class Sentinel < Connector def initialize(options) @@ -564,13 +558,13 @@ def check(client) def resolve result = case @role - when "master" - resolve_master - when "slave" - resolve_slave - else - raise ArgumentError, "Unknown instance role #{@role}" - end + when "master" + resolve_master + when "slave" + resolve_slave + else + raise ArgumentError, "Unknown instance role #{@role}" + end result || (raise ConnectionError, "Unable to fetch #{@role} via Sentinel.") end @@ -578,11 +572,11 @@ def resolve def sentinel_detect @sentinels.each do |sentinel| client = Client.new(@options.merge({ - host: sentinel[:host] || sentinel["host"], - port: sentinel[:port] || sentinel["port"], - password: sentinel[:password] || sentinel["password"], - reconnect_attempts: 0 - })) + host: sentinel[:host] || sentinel["host"], + port: sentinel[:port] || sentinel["port"], + password: sentinel[:password] || sentinel["password"], + reconnect_attempts: 0 + })) begin if result = yield(client) @@ -604,7 +598,7 @@ def sentinel_detect def resolve_master sentinel_detect do |client| if reply = client.call(["sentinel", "get-master-addr-by-name", @master]) - {:host => reply[0], :port => reply[1]} + { host: reply[0], port: reply[1] } end end end @@ -622,7 +616,7 @@ def resolve_slave slave = slaves.sample { host: slave.fetch('ip'), - port: slave.fetch('port'), + port: slave.fetch('port') } end end diff --git a/lib/redis/cluster.rb b/lib/redis/cluster.rb index cb35c14eb..b8443192f 100644 --- a/lib/redis/cluster.rb +++ b/lib/redis/cluster.rb @@ -80,6 +80,7 @@ def call_loop(command, timeout = 0, &block) def call_pipeline(pipeline) node_keys, command_keys = extract_keys_in_pipeline(pipeline) raise CrossSlotPipeliningError, command_keys if node_keys.size > 1 + node = find_node(node_keys.first) try_send(node, :call_pipeline, pipeline) end @@ -216,11 +217,13 @@ def try_send(node, method_name, *args, retry_count: 3, &block) rescue CommandError => err if err.message.start_with?('MOVED') raise if retry_count <= 0 + node = assign_redirection_node(err.message) retry_count -= 1 retry elsif err.message.start_with?('ASK') raise if retry_count <= 0 + node = assign_asking_node(err.message) node.call(%i[asking]) retry_count -= 1 @@ -266,6 +269,7 @@ def find_node_key(command) def find_node(node_key) return @node.sample if node_key.nil? + @node.find_by(node_key) rescue Node::ReloadNeeded update_cluster_info!(node_key) diff --git a/lib/redis/cluster/node.rb b/lib/redis/cluster/node.rb index d495b9a6f..6040ea8ea 100644 --- a/lib/redis/cluster/node.rb +++ b/lib/redis/cluster/node.rb @@ -39,6 +39,7 @@ def call_all(command, &block) def call_master(command, &block) try_map do |node_key, client| next if slave?(node_key) + client.call(command, &block) end.values end @@ -48,6 +49,7 @@ def call_slave(command, &block) try_map do |node_key, client| next if master?(node_key) + client.call(command, &block) end.values end @@ -97,6 +99,7 @@ def try_map end return results if errors.empty? + raise CommandErrorCollection, errors end end diff --git a/lib/redis/cluster/option.rb b/lib/redis/cluster/option.rb index 7e0f19100..6641b3081 100644 --- a/lib/redis/cluster/option.rb +++ b/lib/redis/cluster/option.rb @@ -43,6 +43,7 @@ def add_node(host, port) def build_node_options(addrs) raise InvalidClientOptionError, 'Redis option of `cluster` must be an Array' unless addrs.is_a?(Array) + addrs.map { |addr| parse_node_addr(addr) } end @@ -69,7 +70,9 @@ def parse_node_url(addr) def parse_node_option(addr) addr = addr.map { |k, v| [k.to_sym, v] }.to_h - raise InvalidClientOptionError, 'Redis option of `cluster` must includes `:host` and `:port` keys' if addr.values_at(:host, :port).any?(&:nil?) + if addr.values_at(:host, :port).any?(&:nil?) + raise InvalidClientOptionError, 'Redis option of `cluster` must includes `:host` and `:port` keys' + end addr end diff --git a/lib/redis/cluster/slot_loader.rb b/lib/redis/cluster/slot_loader.rb index f1f00f8f0..f89b0679b 100644 --- a/lib/redis/cluster/slot_loader.rb +++ b/lib/redis/cluster/slot_loader.rb @@ -25,9 +25,8 @@ def load(nodes) def fetch_slot_info(node) hash_with_default_arr = Hash.new { |h, k| h[k] = [] } node.call(%i[cluster slots]) - .flat_map { |arr| parse_slot_info(arr, default_ip: node.host) } - .each_with_object(hash_with_default_arr) { |arr, h| h[arr[0]] << arr[1] } - + .flat_map { |arr| parse_slot_info(arr, default_ip: node.host) } + .each_with_object(hash_with_default_arr) { |arr, h| h[arr[0]] << arr[1] } rescue CannotConnectError, ConnectionError, CommandError {} # can retry on another node end diff --git a/lib/redis/connection.rb b/lib/redis/connection.rb index 869c97124..3eb833ce4 100644 --- a/lib/redis/connection.rb +++ b/lib/redis/connection.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative "connection/registry" # If a connection driver was required before this file, the array diff --git a/lib/redis/connection/command_helper.rb b/lib/redis/connection/command_helper.rb index 419ebe2a3..04b89113a 100644 --- a/lib/redis/connection/command_helper.rb +++ b/lib/redis/connection/command_helper.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + class Redis module Connection module CommandHelper - COMMAND_DELIMITER = "\r\n" def build_command(args) @@ -29,7 +29,7 @@ def build_command(args) command.join(COMMAND_DELIMITER) end - protected + protected def encode(string) string.force_encoding(Encoding.default_external) diff --git a/lib/redis/connection/hiredis.rb b/lib/redis/connection/hiredis.rb index 35ecfdf99..8972fb6c7 100644 --- a/lib/redis/connection/hiredis.rb +++ b/lib/redis/connection/hiredis.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative "registry" require_relative "../errors" require "hiredis/connection" @@ -7,7 +8,6 @@ class Redis module Connection class Hiredis - def self.connect(config) connection = ::Hiredis::Connection.new connect_timeout = (config.fetch(:connect_timeout, 0) * 1_000_000).to_i @@ -32,7 +32,7 @@ def initialize(connection) end def connected? - @connection && @connection.connected? + @connection&.connected? end def timeout=(timeout) @@ -58,7 +58,7 @@ def read rescue Errno::EAGAIN raise TimeoutError rescue RuntimeError => err - raise ProtocolError.new(err.message) + raise ProtocolError, err.message end end end diff --git a/lib/redis/connection/registry.rb b/lib/redis/connection/registry.rb index ba3d538bf..26ff8335d 100644 --- a/lib/redis/connection/registry.rb +++ b/lib/redis/connection/registry.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true + class Redis module Connection - # Store a list of loaded connection drivers in the Connection module. # Redis::Client uses the last required driver by default, and will be aware # of the loaded connection drivers if the user chooses to override the diff --git a/lib/redis/connection/ruby.rb b/lib/redis/connection/ruby.rb index 1c3495978..a9aca333d 100644 --- a/lib/redis/connection/ruby.rb +++ b/lib/redis/connection/ruby.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative "registry" require_relative "command_helper" require_relative "../errors" @@ -14,8 +15,7 @@ class Redis module Connection module SocketMixin - - CRLF = "\r\n".freeze + CRLF = "\r\n" def initialize(*args) super(*args) @@ -25,46 +25,32 @@ def initialize(*args) end def timeout=(timeout) - if timeout && timeout > 0 - @timeout = timeout - else - @timeout = nil - end + @timeout = (timeout if timeout && timeout > 0) end def write_timeout=(timeout) - if timeout && timeout > 0 - @write_timeout = timeout - else - @write_timeout = nil - end + @write_timeout = (timeout if timeout && timeout > 0) end def read(nbytes) result = @buffer.slice!(0, nbytes) - while result.bytesize < nbytes - result << _read_from_socket(nbytes - result.bytesize) - end + result << _read_from_socket(nbytes - result.bytesize) while result.bytesize < nbytes result end def gets - crlf = nil - - while (crlf = @buffer.index(CRLF)) == nil - @buffer << _read_from_socket(16384) + while (crlf = @buffer.index(CRLF)).nil? + @buffer << _read_from_socket(16_384) end @buffer.slice!(0, crlf + CRLF.bytesize) end def _read_from_socket(nbytes) - begin read_nonblock(nbytes) - rescue IO::WaitReadable if IO.select([self], nil, nil, @timeout) retry @@ -78,7 +64,6 @@ def _read_from_socket(nbytes) raise Redis::TimeoutError end end - rescue EOFError raise Errno::ECONNRESET end @@ -86,7 +71,6 @@ def _read_from_socket(nbytes) def _write_to_socket(data) begin write_nonblock(data) - rescue IO::WaitWritable if IO.select(nil, [self], nil, @write_timeout) retry @@ -100,7 +84,6 @@ def _write_to_socket(data) raise Redis::TimeoutError end end - rescue EOFError raise Errno::ECONNRESET end @@ -115,6 +98,7 @@ def write(data) total_count += count return total_count if total_count >= length + data = data.byteslice(count..-1) end end @@ -125,7 +109,6 @@ def write(data) require "timeout" class TCPSocket < ::TCPSocket - include SocketMixin def self.connect(host, port, timeout) @@ -141,7 +124,6 @@ def self.connect(host, port, timeout) if defined?(::UNIXSocket) class UNIXSocket < ::UNIXSocket - include SocketMixin def self.connect(path, timeout) @@ -159,7 +141,6 @@ def self.connect(path, timeout) def _read_from_socket(nbytes) readpartial(nbytes) - rescue EOFError raise Errno::ECONNRESET end @@ -170,19 +151,16 @@ def _read_from_socket(nbytes) else class TCPSocket < ::Socket - include SocketMixin - def self.connect_addrinfo(ai, port, timeout) - sock = new(::Socket.const_get(ai[0]), Socket::SOCK_STREAM, 0) - sockaddr = ::Socket.pack_sockaddr_in(port, ai[3]) + def self.connect_addrinfo(addrinfo, port, timeout) + sock = new(::Socket.const_get(addrinfo[0]), Socket::SOCK_STREAM, 0) + sockaddr = ::Socket.pack_sockaddr_in(port, addrinfo[3]) begin sock.connect_nonblock(sockaddr) rescue Errno::EINPROGRESS - if IO.select(nil, [sock], nil, timeout) == nil - raise TimeoutError - end + raise TimeoutError if IO.select(nil, [sock], nil, timeout).nil? begin sock.connect_nonblock(sockaddr) @@ -221,14 +199,13 @@ def self.connect(host, port, timeout) return connect_addrinfo(ai, port, timeout) rescue SystemCallError # Raise if this was our last attempt. - raise if addrinfo.length == i+1 + raise if addrinfo.length == i + 1 end end end end class UNIXSocket < ::Socket - include SocketMixin def self.connect(path, timeout) @@ -238,9 +215,7 @@ def self.connect(path, timeout) begin sock.connect_nonblock(sockaddr) rescue Errno::EINPROGRESS - if IO.select(nil, [sock], nil, timeout) == nil - raise TimeoutError - end + raise TimeoutError if IO.select(nil, [sock], nil, timeout).nil? begin sock.connect_nonblock(sockaddr) @@ -292,7 +267,10 @@ def self.connect(host, port, timeout, ssl_params) end end - unless ctx.verify_mode == OpenSSL::SSL::VERIFY_NONE || (ctx.respond_to?(:verify_hostname) && !ctx.verify_hostname) + unless ctx.verify_mode == OpenSSL::SSL::VERIFY_NONE || ( + ctx.respond_to?(:verify_hostname) && + !ctx.verify_hostname + ) ssl_sock.post_connection_check(host) end @@ -304,15 +282,16 @@ def self.connect(host, port, timeout, ssl_params) class Ruby include Redis::Connection::CommandHelper - MINUS = "-".freeze - PLUS = "+".freeze - COLON = ":".freeze - DOLLAR = "$".freeze - ASTERISK = "*".freeze + MINUS = "-" + PLUS = "+" + COLON = ":" + DOLLAR = "$" + ASTERISK = "*" def self.connect(config) if config[:scheme] == "unix" raise ArgumentError, "SSL incompatible with unix sockets" if config[:ssl] + sock = UNIXSocket.connect(config[:path], config[:connect_timeout]) elsif config[:scheme] == "rediss" || config[:ssl] sock = SSLSocket.connect(config[:host], config[:port], config[:connect_timeout], config[:ssl_params]) @@ -328,7 +307,7 @@ def self.connect(config) instance end - if [:SOL_SOCKET, :SO_KEEPALIVE, :SOL_TCP, :TCP_KEEPIDLE, :TCP_KEEPINTVL, :TCP_KEEPCNT].all?{|c| Socket.const_defined? c} + if %i[SOL_SOCKET SO_KEEPALIVE SOL_TCP TCP_KEEPIDLE TCP_KEEPINTVL TCP_KEEPCNT].all? { |c| Socket.const_defined? c } def set_tcp_keepalive(keepalive) return unless keepalive.is_a?(Hash) @@ -340,14 +319,13 @@ def set_tcp_keepalive(keepalive) def get_tcp_keepalive { - :time => @sock.getsockopt(Socket::SOL_TCP, Socket::TCP_KEEPIDLE).int, - :intvl => @sock.getsockopt(Socket::SOL_TCP, Socket::TCP_KEEPINTVL).int, - :probes => @sock.getsockopt(Socket::SOL_TCP, Socket::TCP_KEEPCNT).int, + time: @sock.getsockopt(Socket::SOL_TCP, Socket::TCP_KEEPIDLE).int, + intvl: @sock.getsockopt(Socket::SOL_TCP, Socket::TCP_KEEPINTVL).int, + probes: @sock.getsockopt(Socket::SOL_TCP, Socket::TCP_KEEPCNT).int } end else - def set_tcp_keepalive(keepalive) - end + def set_tcp_keepalive(keepalive); end def get_tcp_keepalive { @@ -356,13 +334,12 @@ def get_tcp_keepalive end # disables Nagle's Algorithm, prevents multiple round trips with MULTI - if [:IPPROTO_TCP, :TCP_NODELAY].all?{|c| Socket.const_defined? c} + if %i[IPPROTO_TCP TCP_NODELAY].all? { |c| Socket.const_defined? c } def set_tcp_nodelay @sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) end else - def set_tcp_nodelay - end + def set_tcp_nodelay; end end def initialize(sock) @@ -370,7 +347,7 @@ def initialize(sock) end def connected? - !! @sock + !!@sock end def disconnect @@ -381,9 +358,7 @@ def disconnect end def timeout=(timeout) - if @sock.respond_to?(:timeout=) - @sock.timeout = timeout - end + @sock.timeout = timeout if @sock.respond_to?(:timeout=) end def write_timeout=(timeout) @@ -398,7 +373,6 @@ def read line = @sock.gets reply_type = line.slice!(0, 1) format_reply(reply_type, line) - rescue Errno::EAGAIN raise TimeoutError end @@ -410,7 +384,7 @@ def format_reply(reply_type, line) when COLON then format_integer_reply(line) when DOLLAR then format_bulk_reply(line) when ASTERISK then format_multi_bulk_reply(line) - else raise ProtocolError.new(reply_type) + else raise ProtocolError, reply_type end end @@ -429,6 +403,7 @@ def format_integer_reply(line) def format_bulk_reply(line) bulklen = line.to_i return if bulklen == -1 + reply = encode(@sock.read(bulklen)) @sock.read(2) # Discard CRLF. reply diff --git a/lib/redis/connection/synchrony.rb b/lib/redis/connection/synchrony.rb index 4925fef53..43839e967 100644 --- a/lib/redis/connection/synchrony.rb +++ b/lib/redis/connection/synchrony.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative "command_helper" require_relative "registry" require_relative "../errors" @@ -47,9 +48,7 @@ def receive_data(data) def read @req = EventMachine::DefaultDeferrable.new - if @timeout > 0 - @req.timeout(@timeout, :timeout) - end + @req.timeout(@timeout, :timeout) if @timeout > 0 EventMachine::Synchrony.sync @req end @@ -106,7 +105,7 @@ def initialize(connection) end def connected? - @connection && @connection.connected? + @connection&.connected? end def timeout=(timeout) diff --git a/lib/redis/distributed.rb b/lib/redis/distributed.rb index 9ede57a72..d111a40c7 100644 --- a/lib/redis/distributed.rb +++ b/lib/redis/distributed.rb @@ -1,16 +1,17 @@ # frozen_string_literal: true + require_relative "hash_ring" class Redis class Distributed - class CannotDistribute < RuntimeError def initialize(command) @command = command end def message - "#{@command.to_s.upcase} cannot be used in Redis::Distributed because the keys involved need to be on the same server or because we cannot guarantee that the operation will be atomic." + "#{@command.to_s.upcase} cannot be used in Redis::Distributed because the keys involved need " \ + "to be on the same server or because we cannot guarantee that the operation will be atomic." end end @@ -34,9 +35,9 @@ def nodes end def add_node(options) - options = { :url => options } if options.is_a?(String) + options = { url: options } if options.is_a?(String) options = @default_options.merge(options) - @ring.add_node Redis.new( options ) + @ring.add_node Redis.new(options) end # Change the selected database for the current connection. @@ -150,7 +151,7 @@ def restore(key, ttl, serialized_value, options = {}) end # Transfer a key from the connected instance to another instance. - def migrate(key, options) + def migrate(_key, _options) raise CannotDistribute, :migrate end @@ -180,7 +181,7 @@ def exists(*args) if defined?(::Warning) ::Warning.warn(message) else - $stderr.puts(message) + warn(message) end exists?(*args) else @@ -289,20 +290,20 @@ def setnx(key, value) end # Set multiple keys to multiple values. - def mset(*args) + def mset(*_args) raise CannotDistribute, :mset end - def mapped_mset(hash) + def mapped_mset(_hash) raise CannotDistribute, :mapped_mset end # Set multiple keys to multiple values, only if none of the keys exist. - def msetnx(*args) + def msetnx(*_args) raise CannotDistribute, :msetnx end - def mapped_msetnx(hash) + def mapped_msetnx(_hash) raise CannotDistribute, :mapped_msetnx end @@ -361,7 +362,7 @@ def bitop(operation, destkey, *keys) end # Return the position of the first bit set to 1 or 0 in a string. - def bitpos(key, bit, start=nil, stop=nil) + def bitpos(key, bit, start = nil, stop = nil) node_for(key).bitpos(key, bit, start, stop) end @@ -379,7 +380,7 @@ def [](key) get(key) end - def []=(key,value) + def []=(key, value) set(key, value) end @@ -468,7 +469,7 @@ def brpoplpush(source, destination, options = {}) case options when Integer # Issue deprecation notice in obnoxious mode... - options = { :timeout => options } + options = { timeout: options } end ensure_same_node(:brpoplpush, [source, destination]) do |node| @@ -549,12 +550,12 @@ def smembers(key) end # Scan a set - def sscan(key, cursor, options={}) + def sscan(key, cursor, options = {}) node_for(key).sscan(key, cursor, options) end # Scan a set and return an enumerator - def sscan_each(key, options={}, &block) + def sscan_each(key, options = {}, &block) node_for(key).sscan_each(key, options, &block) end @@ -768,7 +769,7 @@ def publish(channel, message) end def subscribed? - !! @subscribed_node + !!@subscribed_node end # Listen for messages published to the given channels. @@ -786,7 +787,8 @@ def subscribe(channel, *channels, &block) # Stop listening for messages posted to the given channels. def unsubscribe(*channels) - raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed? + raise "Can't unsubscribe if not subscribed." unless subscribed? + @subscribed_node.unsubscribe(*channels) end @@ -802,7 +804,7 @@ def punsubscribe(*channels) end # Watch the given keys to determine execution of the MULTI/EXEC block. - def watch(*keys) + def watch(*_keys) raise CannotDistribute, :watch end @@ -886,7 +888,7 @@ def dup self.class.new(@node_configs, @default_options) end - protected + protected def on_each_node(command, *args) nodes.map do |node| diff --git a/lib/redis/errors.rb b/lib/redis/errors.rb index ff5fd8c9d..9833a69d5 100644 --- a/lib/redis/errors.rb +++ b/lib/redis/errors.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + class Redis # Base error for all redis-rb errors. class BaseError < RuntimeError diff --git a/lib/redis/hash_ring.rb b/lib/redis/hash_ring.rb index a9c0498a1..d84084cfd 100644 --- a/lib/redis/hash_ring.rb +++ b/lib/redis/hash_ring.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true + require 'zlib' class Redis class HashRing - POINTS_PER_SERVER = 160 # this is the default in libmemcached attr_reader :ring, :sorted_keys, :replicas, :nodes @@ -11,7 +11,7 @@ class HashRing # nodes is a list of objects that have a proper to_s representation. # replicas indicates how many virtual points should be used pr. node, # replicas are required to improve the distribution. - def initialize(nodes=[], replicas=POINTS_PER_SERVER) + def initialize(nodes = [], replicas = POINTS_PER_SERVER) @replicas = replicas @ring = {} @nodes = [] @@ -33,11 +33,11 @@ def add_node(node) end def remove_node(node) - @nodes.reject!{|n| n.id == node.id} + @nodes.reject! { |n| n.id == node.id } @replicas.times do |i| key = Zlib.crc32("#{node.id}:#{i}") @ring.delete(key) - @sorted_keys.reject! {|k| k == key} + @sorted_keys.reject! { |k| k == key } end end @@ -47,27 +47,29 @@ def get_node(key) end def get_node_pos(key) - return [nil,nil] if @ring.size == 0 + return [nil, nil] if @ring.empty? + crc = Zlib.crc32(key) idx = HashRing.binary_search(@sorted_keys, crc) - return [@ring[@sorted_keys[idx]], idx] + [@ring[@sorted_keys[idx]], idx] end def iter_nodes(key) - return [nil,nil] if @ring.size == 0 + return [nil, nil] if @ring.empty? + _, pos = get_node_pos(key) @ring.size.times do |n| - yield @ring[@sorted_keys[(pos+n) % @ring.size]] + yield @ring[@sorted_keys[(pos + n) % @ring.size]] end end # Find the closest index in HashRing with value <= the given value - def self.binary_search(ary, value, &block) + def self.binary_search(ary, value) upper = ary.size - 1 lower = 0 idx = 0 - while(lower <= upper) do + while lower <= upper idx = (lower + upper) / 2 comp = ary[idx] <=> value @@ -80,10 +82,8 @@ def self.binary_search(ary, value, &block) end end - if upper < 0 - upper = ary.size - 1 - end - return upper + upper = ary.size - 1 if upper < 0 + upper end end end diff --git a/lib/redis/pipeline.rb b/lib/redis/pipeline.rb index eb9f6f3c4..c6a6dc382 100644 --- a/lib/redis/pipeline.rb +++ b/lib/redis/pipeline.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + class Redis class Pipeline attr_accessor :db @@ -61,7 +62,7 @@ def timeouts @futures.map(&:timeout) end - def with_reconnect(val=true) + def with_reconnect(val = true) @with_reconnect = false unless val yield end @@ -93,7 +94,8 @@ def finish(replies) if exec.size < futures.size # Some command wasn't recognized by Redis. - raise replies.detect { |r| r.is_a?(CommandError) } + command_error = replies.detect { |r| r.is_a?(CommandError) } + raise command_error end super(exec) do |reply| @@ -145,11 +147,7 @@ def ==(_other) message << " - You probably meant to call .value == or .value !=" message << " (#{::Kernel.caller(1, 1).first})\n" - if defined?(::Warning) - ::Warning.warn(message) - else - $stderr.puts(message) - end + ::Kernel.warn(message) super end @@ -168,7 +166,7 @@ def _command end def value - ::Kernel.raise(@object) if @object.kind_of?(::RuntimeError) + ::Kernel.raise(@object) if @object.is_a?(::RuntimeError) @object end diff --git a/lib/redis/subscribe.rb b/lib/redis/subscribe.rb index 4c2660556..5573b98f1 100644 --- a/lib/redis/subscribe.rb +++ b/lib/redis/subscribe.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + class Redis class SubscribedClient def initialize(client) @@ -33,24 +34,21 @@ def punsubscribe(*channels) call([:punsubscribe, *channels]) end - protected + protected def subscription(start, stop, channels, block, timeout = 0) sub = Subscription.new(&block) unsubscribed = false - begin - @client.call_loop([start, *channels], timeout) do |line| - type, *rest = line - sub.callbacks[type].call(*rest) - unsubscribed = type == stop && rest.last == 0 - break if unsubscribed - end - ensure - # No need to unsubscribe here. The real client closes the connection - # whenever an exception is raised (see #ensure_connected). + @client.call_loop([start, *channels], timeout) do |line| + type, *rest = line + sub.callbacks[type].call(*rest) + unsubscribed = type == stop && rest.last == 0 + break if unsubscribed end + # No need to unsubscribe here. The real client closes the connection + # whenever an exception is raised (see #ensure_connected). end end @@ -59,7 +57,7 @@ class Subscription def initialize @callbacks = Hash.new do |hash, key| - hash[key] = lambda { |*_| } + hash[key] = ->(*_) {} end yield(self) diff --git a/lib/redis/version.rb b/lib/redis/version.rb index bed5b60e4..03ec38c43 100644 --- a/lib/redis/version.rb +++ b/lib/redis/version.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + class Redis VERSION = '4.1.4' end diff --git a/redis.gemspec b/redis.gemspec index 7d8011490..2c17ae975 100644 --- a/redis.gemspec +++ b/redis.gemspec @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "./lib/redis/version" Gem::Specification.new do |s| @@ -32,11 +33,11 @@ Gem::Specification.new do |s| s.email = ["redis-db@googlegroups.com"] s.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "lib/**/*"] - s.executables = `git ls-files -- exe/*`.split("\n").map{ |f| File.basename(f) } + s.executables = `git ls-files -- exe/*`.split("\n").map { |f| File.basename(f) } s.required_ruby_version = '>= 2.3.0' - s.add_development_dependency("mocha") - s.add_development_dependency("hiredis") s.add_development_dependency("em-synchrony") + s.add_development_dependency("hiredis") + s.add_development_dependency("mocha") end diff --git a/test/bitpos_test.rb b/test/bitpos_test.rb index 06b034eba..d86223dbd 100644 --- a/test/bitpos_test.rb +++ b/test/bitpos_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestBitpos < Minitest::Test - include Helper::Client def test_bitpos_empty_zero @@ -60,5 +60,4 @@ def test_bitpos_raise_exception_if_stop_not_start end end end - end diff --git a/test/blocking_commands_test.rb b/test/blocking_commands_test.rb index 6b1cf9255..c32f11eef 100644 --- a/test/blocking_commands_test.rb +++ b/test/blocking_commands_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/blocking_commands' diff --git a/test/client_test.rb b/test/client_test.rb index 163492e1d..30f7e2cff 100644 --- a/test/client_test.rb +++ b/test/client_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestClient < Minitest::Test - include Helper::Client def test_call diff --git a/test/cluster_client_slots_test.rb b/test/cluster_client_slots_test.rb index d3382ef85..16e851b89 100644 --- a/test/cluster_client_slots_test.rb +++ b/test/cluster_client_slots_test.rb @@ -143,7 +143,7 @@ def test_slot_class_with_empty_slots def test_redirection_when_slot_is_resharding 100.times { |i| redis.set("{key}#{i}", i) } - redis_cluster_resharding(12539, src: '127.0.0.1:7002', dest: '127.0.0.1:7000') do + redis_cluster_resharding(12_539, src: '127.0.0.1:7002', dest: '127.0.0.1:7000') do 100.times { |i| assert_equal i.to_s, redis.get("{key}#{i}") } end end diff --git a/test/cluster_commands_on_cluster_test.rb b/test/cluster_commands_on_cluster_test.rb index 8ac74a3fd..f791797a2 100644 --- a/test/cluster_commands_on_cluster_test.rb +++ b/test/cluster_commands_on_cluster_test.rb @@ -19,19 +19,19 @@ def test_cluster_count_failure_reports end node_id = redis.cluster(:nodes).first.fetch('node_id') - assert_equal true,(redis.cluster('count-failure-reports', node_id) >= 0) + assert_equal true, (redis.cluster('count-failure-reports', node_id) >= 0) end def test_cluster_countkeysinslot - assert_equal true,(redis.cluster(:countkeysinslot, 0) >= 0) - assert_equal true,(redis.cluster(:countkeysinslot, 16383) >= 0) + assert_equal true, (redis.cluster(:countkeysinslot, 0) >= 0) + assert_equal true, (redis.cluster(:countkeysinslot, 16_383) >= 0) assert_raises(Redis::CommandError, 'ERR Invalid slot') do redis.cluster(:countkeysinslot, -1) end assert_raises(Redis::CommandError, 'ERR Invalid slot') do - redis.cluster(:countkeysinslot, 16384) + redis.cluster(:countkeysinslot, 16_384) end end @@ -73,7 +73,7 @@ def test_cluster_keyslot def test_cluster_meet assert_raises(Redis::Cluster::OrchestrationCommandNotSupported, 'CLUSTER MEET command should be...') do - redis.cluster(:meet, '127.0.0.1', 11211) + redis.cluster(:meet, '127.0.0.1', 11_211) end end diff --git a/test/cluster_commands_on_keys_test.rb b/test/cluster_commands_on_keys_test.rb index 1fe9254d9..124a28709 100644 --- a/test/cluster_commands_on_keys_test.rb +++ b/test/cluster_commands_on_keys_test.rb @@ -35,7 +35,7 @@ def test_migrate redis_cluster_mock(migrate: ->(*_) { '-IOERR error or timeout writing to target instance' }) do |redis| assert_raises(Redis::CommandError, 'IOERR error or timeout writing to target instance') do - redis.migrate('mykey', host: '127.0.0.1', port: 11211) + redis.migrate('mykey', host: '127.0.0.1', port: 11_211) end end diff --git a/test/cluster_commands_on_server_test.rb b/test/cluster_commands_on_server_test.rb index 10e829e12..d670f406f 100644 --- a/test/cluster_commands_on_server_test.rb +++ b/test/cluster_commands_on_server_test.rb @@ -43,9 +43,7 @@ def test_client_list a_client_info = redis.client(:list).first actual = a_client_info.keys.sort expected = %w[addr age cmd db events fd flags id idle multi name obl oll omem psub qbuf qbuf-free sub] - if version >= '6' - expected << 'user' - end + expected << 'user' if version >= '6' assert_equal expected, actual end @@ -73,7 +71,7 @@ def test_command end def test_command_count - assert_equal true,(redis.command(:count) > 0) + assert_equal true, (redis.command(:count) > 0) end def test_command_getkeys @@ -96,10 +94,10 @@ def test_command_info def test_config_get expected_keys = if version < '3.2.0' - %w[hash-max-ziplist-entries list-max-ziplist-entries set-max-intset-entries zset-max-ziplist-entries] - else - %w[hash-max-ziplist-entries set-max-intset-entries zset-max-ziplist-entries] - end + %w[hash-max-ziplist-entries list-max-ziplist-entries set-max-intset-entries zset-max-ziplist-entries] + else + %w[hash-max-ziplist-entries set-max-intset-entries zset-max-ziplist-entries] + end assert_equal expected_keys, redis.config(:get, '*max-*-entries*').keys.sort end diff --git a/test/cluster_commands_on_streams_test.rb b/test/cluster_commands_on_streams_test.rb index 38b53fef6..a242867f1 100644 --- a/test/cluster_commands_on_streams_test.rb +++ b/test/cluster_commands_on_streams_test.rb @@ -23,10 +23,10 @@ def test_xread_with_multiple_keys_and_hash_tags actual = redis.xread(%w[{s}1 {s}2], %w[0-1 1-1]) assert_equal %w(0-2), actual['{s}1'].map(&:first) - assert_equal %w(v02), actual['{s}1'].map { |i| i.last['f'] } + assert_equal(%w(v02), actual['{s}1'].map { |i| i.last['f'] }) assert_equal %w(1-2), actual['{s}2'].map(&:first) - assert_equal %w(v12), actual['{s}2'].map { |i| i.last['f'] } + assert_equal(%w(v12), actual['{s}2'].map { |i| i.last['f'] }) end def test_xreadgroup_with_multiple_keys @@ -45,9 +45,9 @@ def test_xreadgroup_with_multiple_keys_and_hash_tags actual = redis.xreadgroup('g1', 'c1', %w[{s}1 {s}2], %w[> >]) assert_equal %w(0-2), actual['{s}1'].map(&:first) - assert_equal %w(v02), actual['{s}1'].map { |i| i.last['f'] } + assert_equal(%w(v02), actual['{s}1'].map { |i| i.last['f'] }) assert_equal %w(1-2), actual['{s}2'].map(&:first) - assert_equal %w(v12), actual['{s}2'].map { |i| i.last['f'] } + assert_equal(%w(v12), actual['{s}2'].map { |i| i.last['f'] }) end end diff --git a/test/command_map_test.rb b/test/command_map_test.rb index f2bba1a6d..5b720ad75 100644 --- a/test/command_map_test.rb +++ b/test/command_map_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestCommandMap < Minitest::Test - include Helper::Client def test_override_existing_commands diff --git a/test/commands_on_geo_test.rb b/test/commands_on_geo_test.rb index c0a93e026..4069a7843 100644 --- a/test/commands_on_geo_test.rb +++ b/test/commands_on_geo_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative "helper" class TestCommandsGeo < Minitest::Test diff --git a/test/commands_on_hashes_test.rb b/test/commands_on_hashes_test.rb index b90311ae6..9cc07bdb2 100644 --- a/test/commands_on_hashes_test.rb +++ b/test/commands_on_hashes_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/hashes' diff --git a/test/commands_on_hyper_log_log_test.rb b/test/commands_on_hyper_log_log_test.rb index 5f9a9821c..87e452171 100644 --- a/test/commands_on_hyper_log_log_test.rb +++ b/test/commands_on_hyper_log_log_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/hyper_log_log' diff --git a/test/commands_on_lists_test.rb b/test/commands_on_lists_test.rb index 9c4d43f86..6c8203f22 100644 --- a/test/commands_on_lists_test.rb +++ b/test/commands_on_lists_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/lists' diff --git a/test/commands_on_sets_test.rb b/test/commands_on_sets_test.rb index 85513d90c..dd2b53640 100644 --- a/test/commands_on_sets_test.rb +++ b/test/commands_on_sets_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/sets' diff --git a/test/commands_on_sorted_sets_test.rb b/test/commands_on_sorted_sets_test.rb index b1c764517..d03dedeea 100644 --- a/test/commands_on_sorted_sets_test.rb +++ b/test/commands_on_sorted_sets_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/sorted_sets' diff --git a/test/commands_on_strings_test.rb b/test/commands_on_strings_test.rb index d88e6a538..016240855 100644 --- a/test/commands_on_strings_test.rb +++ b/test/commands_on_strings_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/strings' diff --git a/test/commands_on_value_types_test.rb b/test/commands_on_value_types_test.rb index ff61fa13b..fddc5f2ac 100644 --- a/test/commands_on_value_types_test.rb +++ b/test/commands_on_value_types_test.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true + require_relative "helper" require_relative "lint/value_types" class TestCommandsOnValueTypes < Minitest::Test - include Helper::Client include Lint::ValueTypes @@ -132,7 +132,7 @@ def test_flushdb assert_equal 2, r.dbsize - r.flushdb(:async => false) + r.flushdb(async: false) assert_equal 0, r.dbsize @@ -143,38 +143,38 @@ def test_flushdb assert_equal 2, r.dbsize - r.flushdb(:async => true) + r.flushdb(async: true) assert_equal 0, r.dbsize - redis_mock(:flushdb => lambda { |args| "+FLUSHDB #{args.upcase}" }) do |redis| - assert_equal "FLUSHDB ASYNC", redis.flushdb(:async => true) + redis_mock(flushdb: ->(args) { "+FLUSHDB #{args.upcase}" }) do |redis| + assert_equal "FLUSHDB ASYNC", redis.flushdb(async: true) end end end def test_flushall # Test defaults - redis_mock(:flushall => lambda { "+FLUSHALL" }) do |redis| + redis_mock(flushall: -> { "+FLUSHALL" }) do |redis| assert_equal "FLUSHALL", redis.flushall end # Test sync - redis_mock(:flushall => lambda { "+FLUSHALL" }) do |redis| - assert_equal "FLUSHALL", redis.flushall(:async => false) + redis_mock(flushall: -> { "+FLUSHALL" }) do |redis| + assert_equal "FLUSHALL", redis.flushall(async: false) end # Test async target_version "3.9.101" do - redis_mock(:flushall => lambda { |args| "+FLUSHALL #{args.upcase}" }) do |redis| - assert_equal "FLUSHALL ASYNC", redis.flushall(:async => true) + redis_mock(flushall: ->(args) { "+FLUSHALL #{args.upcase}" }) do |redis| + assert_equal "FLUSHALL ASYNC", redis.flushall(async: true) end end end def test_migrate - redis_mock(:migrate => lambda { |*args| args }) do |redis| - options = { :host => "127.0.0.1", :port => 1234 } + redis_mock(migrate: ->(*args) { args }) do |redis| + options = { host: "127.0.0.1", port: 1234 } ex = assert_raises(RuntimeError) do redis.migrate("foo", options.reject { |key, _| key == :host }) @@ -195,12 +195,12 @@ def test_migrate assert_equal expected, actual # Test db override - actual = redis.migrate("foo", options.merge(:db => default_db + 1)) + actual = redis.migrate("foo", options.merge(db: default_db + 1)) expected = ["127.0.0.1", "1234", "foo", (default_db + 1).to_s, default_timeout.to_s] assert_equal expected, actual # Test timeout override - actual = redis.migrate("foo", options.merge(:timeout => default_timeout + 1)) + actual = redis.migrate("foo", options.merge(timeout: default_timeout + 1)) expected = ["127.0.0.1", "1234", "foo", default_db.to_s, (default_timeout + 1).to_s] assert_equal expected, actual diff --git a/test/connection_handling_test.rb b/test/connection_handling_test.rb index df857b5e1..7949a2297 100644 --- a/test/connection_handling_test.rb +++ b/test/connection_handling_test.rb @@ -1,32 +1,32 @@ # frozen_string_literal: true + require_relative "helper" class TestConnectionHandling < Minitest::Test - include Helper::Client def test_auth commands = { - :auth => lambda { |password| $auth = password; "+OK" }, - :get => lambda { |key| $auth == "secret" ? "$3\r\nbar" : "$-1" }, + auth: ->(password) { @auth = password; "+OK" }, + get: ->(_key) { @auth == "secret" ? "$3\r\nbar" : "$-1" } } - redis_mock(commands, :password => "secret") do |redis| + redis_mock(commands, password: "secret") do |redis| assert_equal "bar", redis.get("foo") end end def test_id commands = { - :client => lambda { |cmd, name| $name = [cmd, name]; "+OK" }, - :ping => lambda { "+PONG" }, + client: ->(cmd, name) { @name = [cmd, name]; "+OK" }, + ping: -> { "+PONG" } } - redis_mock(commands, :id => "client-name") do |redis| + redis_mock(commands, id: "client-name") do |redis| assert_equal "PONG", redis.ping end - assert_equal ["setname","client-name"], $name + assert_equal ["setname", "client-name"], @name end def test_ping @@ -54,7 +54,7 @@ def test_close quit = 0 commands = { - :quit => lambda do + quit: lambda do quit += 1 "+OK" end @@ -81,7 +81,7 @@ def test_disconnect quit = 0 commands = { - :quit => lambda do + quit: lambda do quit += 1 "+OK" end @@ -106,7 +106,7 @@ def test_disconnect def test_shutdown commands = { - :shutdown => lambda { :exit } + shutdown: -> { :exit } } redis_mock(commands) do |redis| @@ -118,9 +118,9 @@ def test_shutdown def test_shutdown_with_error connections = 0 commands = { - :select => lambda { |*_| connections += 1; "+OK\r\n" }, - :connections => lambda { ":#{connections}\r\n" }, - :shutdown => lambda { "-ERR could not shutdown\r\n" } + select: ->(*_) { connections += 1; "+OK\r\n" }, + connections: -> { ":#{connections}\r\n" }, + shutdown: -> { "-ERR could not shutdown\r\n" } } redis_mock(commands) do |redis| @@ -138,7 +138,7 @@ def test_shutdown_with_error def test_shutdown_from_pipeline commands = { - :shutdown => lambda { :exit } + shutdown: -> { :exit } } redis_mock(commands) do |redis| @@ -154,9 +154,9 @@ def test_shutdown_from_pipeline def test_shutdown_with_error_from_pipeline connections = 0 commands = { - :select => lambda { |*_| connections += 1; "+OK\r\n" }, - :connections => lambda { ":#{connections}\r\n" }, - :shutdown => lambda { "-ERR could not shutdown\r\n" } + select: ->(*_) { connections += 1; "+OK\r\n" }, + connections: -> { ":#{connections}\r\n" }, + shutdown: -> { "-ERR could not shutdown\r\n" } } redis_mock(commands) do |redis| @@ -176,9 +176,9 @@ def test_shutdown_with_error_from_pipeline def test_shutdown_from_multi_exec commands = { - :multi => lambda { "+OK\r\n" }, - :shutdown => lambda { "+QUEUED\r\n" }, - :exec => lambda { :exit } + multi: -> { "+OK\r\n" }, + shutdown: -> { "+QUEUED\r\n" }, + exec: -> { :exit } } redis_mock(commands) do |redis| @@ -194,11 +194,11 @@ def test_shutdown_from_multi_exec def test_shutdown_with_error_from_multi_exec connections = 0 commands = { - :select => lambda { |*_| connections += 1; "+OK\r\n" }, - :connections => lambda { ":#{connections}\r\n" }, - :multi => lambda { "+OK\r\n" }, - :shutdown => lambda { "+QUEUED\r\n" }, - :exec => lambda { "*1\r\n-ERR could not shutdown\r\n" } + select: ->(*_) { connections += 1; "+OK\r\n" }, + connections: -> { ":#{connections}\r\n" }, + multi: -> { "+OK\r\n" }, + shutdown: -> { "+QUEUED\r\n" }, + exec: -> { "*1\r\n-ERR could not shutdown\r\n" } } redis_mock(commands) do |redis| @@ -214,7 +214,7 @@ def test_shutdown_with_error_from_multi_exec rescue => err end - assert err.kind_of?(StandardError) + assert err.is_a?(StandardError) # The connection should remain intact assert_equal connections, redis.connections @@ -222,35 +222,33 @@ def test_shutdown_with_error_from_multi_exec end def test_slaveof - redis_mock(:slaveof => lambda { |host, port| "+SLAVEOF #{host} #{port}" }) do |redis| + redis_mock(slaveof: ->(host, port) { "+SLAVEOF #{host} #{port}" }) do |redis| assert_equal "SLAVEOF somehost 6381", redis.slaveof("somehost", 6381) end end def test_bgrewriteaof - redis_mock(:bgrewriteaof => lambda { "+BGREWRITEAOF" }) do |redis| + redis_mock(bgrewriteaof: -> { "+BGREWRITEAOF" }) do |redis| assert_equal "BGREWRITEAOF", redis.bgrewriteaof end end def test_config_get - assert r.config(:get, "*")["timeout"] != nil + refute_nil r.config(:get, "*")["timeout"] config = r.config(:get, "timeout") assert_equal ["timeout"], config.keys - assert config.values.compact.size > 0 + assert !config.values.compact.empty? end def test_config_set - begin - assert_equal "OK", r.config(:set, "timeout", 200) - assert_equal "200", r.config(:get, "*")["timeout"] - - assert_equal "OK", r.config(:set, "timeout", 100) - assert_equal "100", r.config(:get, "*")["timeout"] - ensure - r.config :set, "timeout", 300 - end + assert_equal "OK", r.config(:set, "timeout", 200) + assert_equal "200", r.config(:get, "*")["timeout"] + + assert_equal "OK", r.config(:set, "timeout", 100) + assert_equal "100", r.config(:get, "*")["timeout"] + ensure + r.config :set, "timeout", 300 end driver(:ruby, :hiredis) do @@ -258,8 +256,8 @@ def test_consistency_on_multithreaded_env t = nil commands = { - :set => lambda { |key, value| t.kill; "+OK\r\n" }, - :incr => lambda { |key| ":1\r\n" }, + set: ->(_key, _value) { t.kill; "+OK\r\n" }, + incr: ->(_key) { ":1\r\n" } } redis_mock(commands) do |redis| diff --git a/test/connection_test.rb b/test/connection_test.rb index a6b0bacea..933bd6155 100644 --- a/test/connection_test.rb +++ b/test/connection_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestConnection < Minitest::Test - include Helper::Client def test_provides_a_meaningful_inspect @@ -18,27 +18,27 @@ def test_connection_information end def test_default_id_with_host_and_port - redis = Redis.new(OPTIONS.merge(:host => "host", :port => "1234", :db => 0)) + redis = Redis.new(OPTIONS.merge(host: "host", port: "1234", db: 0)) assert_equal "redis://host:1234/0", redis.connection.fetch(:id) end def test_default_id_with_host_and_port_and_explicit_scheme - redis = Redis.new(OPTIONS.merge(:host => "host", :port => "1234", :db => 0, :scheme => "foo")) + redis = Redis.new(OPTIONS.merge(host: "host", port: "1234", db: 0, scheme: "foo")) assert_equal "redis://host:1234/0", redis.connection.fetch(:id) end def test_default_id_with_path - redis = Redis.new(OPTIONS.merge(:path => "/tmp/redis.sock", :db => 0)) + redis = Redis.new(OPTIONS.merge(path: "/tmp/redis.sock", db: 0)) assert_equal "redis:///tmp/redis.sock/0", redis.connection.fetch(:id) end def test_default_id_with_path_and_explicit_scheme - redis = Redis.new(OPTIONS.merge(:path => "/tmp/redis.sock", :db => 0, :scheme => "foo")) + redis = Redis.new(OPTIONS.merge(path: "/tmp/redis.sock", db: 0, scheme: "foo")) assert_equal "redis:///tmp/redis.sock/0", redis.connection.fetch(:id) end def test_override_id - redis = Redis.new(OPTIONS.merge(:id => "test")) + redis = Redis.new(OPTIONS.merge(id: "test")) assert_equal "test", redis.connection.fetch(:id) end diff --git a/test/distributed_blocking_commands_test.rb b/test/distributed_blocking_commands_test.rb index b988e7201..efa86918f 100644 --- a/test/distributed_blocking_commands_test.rb +++ b/test/distributed_blocking_commands_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/blocking_commands' diff --git a/test/distributed_commands_on_hashes_test.rb b/test/distributed_commands_on_hashes_test.rb index d76de7b73..e7ba16a32 100644 --- a/test/distributed_commands_on_hashes_test.rb +++ b/test/distributed_commands_on_hashes_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/hashes' diff --git a/test/distributed_commands_on_hyper_log_log_test.rb b/test/distributed_commands_on_hyper_log_log_test.rb index 404ba2d52..dd2629c8e 100644 --- a/test/distributed_commands_on_hyper_log_log_test.rb +++ b/test/distributed_commands_on_hyper_log_log_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/hyper_log_log' diff --git a/test/distributed_commands_on_lists_test.rb b/test/distributed_commands_on_lists_test.rb index 1ccb63117..c9039a059 100644 --- a/test/distributed_commands_on_lists_test.rb +++ b/test/distributed_commands_on_lists_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/lists' diff --git a/test/distributed_commands_on_sets_test.rb b/test/distributed_commands_on_sets_test.rb index 71531d169..26c46cc57 100644 --- a/test/distributed_commands_on_sets_test.rb +++ b/test/distributed_commands_on_sets_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/sets' diff --git a/test/distributed_commands_on_sorted_sets_test.rb b/test/distributed_commands_on_sorted_sets_test.rb index 7a641e32c..2e628364c 100644 --- a/test/distributed_commands_on_sorted_sets_test.rb +++ b/test/distributed_commands_on_sorted_sets_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require_relative 'lint/sorted_sets' diff --git a/test/distributed_commands_on_strings_test.rb b/test/distributed_commands_on_strings_test.rb index 1b1a24060..152f88586 100644 --- a/test/distributed_commands_on_strings_test.rb +++ b/test/distributed_commands_on_strings_test.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true + require_relative "helper" require_relative "lint/strings" class TestDistributedCommandsOnStrings < Minitest::Test - include Helper::Distributed include Lint::Strings @@ -11,7 +11,7 @@ def test_mget r.set("foo", "s1") r.set("bar", "s2") - assert_equal ["s1", "s2"] , r.mget("foo", "bar") + assert_equal ["s1", "s2"], r.mget("foo", "bar") assert_equal ["s1", "s2", nil], r.mget("foo", "bar", "baz") end @@ -39,7 +39,7 @@ def test_mset def test_mset_mapped assert_raises Redis::Distributed::CannotDistribute do - r.mapped_mset(:foo => "s1", :bar => "s2") + r.mapped_mset(foo: "s1", bar: "s2") end end @@ -53,7 +53,7 @@ def test_msetnx def test_msetnx_mapped assert_raises Redis::Distributed::CannotDistribute do r.set("foo", "s1") - r.mapped_msetnx(:foo => "s2", :bar => "s3") + r.mapped_msetnx(foo: "s2", bar: "s3") end end diff --git a/test/distributed_commands_on_value_types_test.rb b/test/distributed_commands_on_value_types_test.rb index 810bfeec3..f882537b5 100644 --- a/test/distributed_commands_on_value_types_test.rb +++ b/test/distributed_commands_on_value_types_test.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true + require_relative "helper" require_relative "lint/value_types" class TestDistributedCommandsOnValueTypes < Minitest::Test - include Helper::Distributed include Lint::ValueTypes diff --git a/test/distributed_commands_requiring_clustering_test.rb b/test/distributed_commands_requiring_clustering_test.rb index c4a047bfe..35bd7988f 100644 --- a/test/distributed_commands_requiring_clustering_test.rb +++ b/test/distributed_commands_requiring_clustering_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestDistributedCommandsRequiringClustering < Minitest::Test - include Helper::Distributed def test_rename @@ -27,7 +27,7 @@ def test_brpoplpush r.rpush "{qux}foo", "s1" r.rpush "{qux}foo", "s2" - assert_equal "s2", r.brpoplpush("{qux}foo", "{qux}bar", :timeout => 1) + assert_equal "s2", r.brpoplpush("{qux}foo", "{qux}bar", timeout: 1) assert_equal ["s2"], r.lrange("{qux}bar", 0, -1) end @@ -115,8 +115,8 @@ def test_sort r.rpush("{qux}bar", "1") r.rpush("{qux}bar", "2") - assert_equal ["s1"], r.sort("{qux}bar", :get => "{qux}foo:*", :limit => [0, 1]) - assert_equal ["s2"], r.sort("{qux}bar", :get => "{qux}foo:*", :limit => [0, 1], :order => "desc alpha") + assert_equal ["s1"], r.sort("{qux}bar", get: "{qux}foo:*", limit: [0, 1]) + assert_equal ["s2"], r.sort("{qux}bar", get: "{qux}foo:*", limit: [0, 1], order: "desc alpha") end def test_sort_with_an_array_of_gets @@ -129,9 +129,9 @@ def test_sort_with_an_array_of_gets r.rpush("{qux}bar", "1") r.rpush("{qux}bar", "2") - assert_equal [["s1a", "s1b"]], r.sort("{qux}bar", :get => ["{qux}foo:*:a", "{qux}foo:*:b"], :limit => [0, 1]) - assert_equal [["s2a", "s2b"]], r.sort("{qux}bar", :get => ["{qux}foo:*:a", "{qux}foo:*:b"], :limit => [0, 1], :order => "desc alpha") - assert_equal [["s1a", "s1b"], ["s2a", "s2b"]], r.sort("{qux}bar", :get => ["{qux}foo:*:a", "{qux}foo:*:b"]) + assert_equal [["s1a", "s1b"]], r.sort("{qux}bar", get: ["{qux}foo:*:a", "{qux}foo:*:b"], limit: [0, 1]) + assert_equal [["s2a", "s2b"]], r.sort("{qux}bar", get: ["{qux}foo:*:a", "{qux}foo:*:b"], limit: [0, 1], order: "desc alpha") + assert_equal [["s1a", "s1b"], ["s2a", "s2b"]], r.sort("{qux}bar", get: ["{qux}foo:*:a", "{qux}foo:*:b"]) end def test_sort_with_store @@ -141,7 +141,7 @@ def test_sort_with_store r.rpush("{qux}bar", "1") r.rpush("{qux}bar", "2") - r.sort("{qux}bar", :get => "{qux}foo:*", :store => "{qux}baz") + r.sort("{qux}bar", get: "{qux}foo:*", store: "{qux}baz") assert_equal ["s1", "s2"], r.lrange("{qux}baz", 0, -1) end diff --git a/test/distributed_connection_handling_test.rb b/test/distributed_connection_handling_test.rb index 8c9532175..c1196923d 100644 --- a/test/distributed_connection_handling_test.rb +++ b/test/distributed_connection_handling_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestDistributedConnectionHandling < Minitest::Test - include Helper::Distributed def test_ping diff --git a/test/distributed_internals_test.rb b/test/distributed_internals_test.rb index 05f590b42..8fe6a1ac2 100644 --- a/test/distributed_internals_test.rb +++ b/test/distributed_internals_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestDistributedInternals < Minitest::Test - include Helper::Distributed def test_provides_a_meaningful_inspect @@ -15,23 +15,23 @@ def test_provides_a_meaningful_inspect def test_default_as_urls nodes = ["redis://127.0.0.1:#{PORT}/15", *NODES] redis = Redis::Distributed.new nodes - assert_equal ["redis://127.0.0.1:#{PORT}/15", *NODES], redis.nodes.map { |node| node._client.id } + assert_equal(["redis://127.0.0.1:#{PORT}/15", *NODES], redis.nodes.map { |node| node._client.id }) end def test_default_as_config_hashes - nodes = [OPTIONS.merge(:host => '127.0.0.1'), OPTIONS.merge(:host => 'somehost', :port => PORT.next)] + nodes = [OPTIONS.merge(host: '127.0.0.1'), OPTIONS.merge(host: 'somehost', port: PORT.next)] redis = Redis::Distributed.new nodes - assert_equal ["redis://127.0.0.1:#{PORT}/15","redis://somehost:#{PORT.next}/15"], redis.nodes.map { |node| node._client.id } + assert_equal(["redis://127.0.0.1:#{PORT}/15", "redis://somehost:#{PORT.next}/15"], redis.nodes.map { |node| node._client.id }) end def test_as_mix_and_match - nodes = ["redis://127.0.0.1:7389/15", OPTIONS.merge(:host => 'somehost'), OPTIONS.merge(:host => 'somehost', :port => PORT.next)] + nodes = ["redis://127.0.0.1:7389/15", OPTIONS.merge(host: 'somehost'), OPTIONS.merge(host: 'somehost', port: PORT.next)] redis = Redis::Distributed.new nodes - assert_equal ["redis://127.0.0.1:7389/15", "redis://somehost:#{PORT}/15", "redis://somehost:#{PORT.next}/15"], redis.nodes.map { |node| node._client.id } + assert_equal(["redis://127.0.0.1:7389/15", "redis://somehost:#{PORT}/15", "redis://somehost:#{PORT.next}/15"], redis.nodes.map { |node| node._client.id }) end def test_override_id - nodes = [OPTIONS.merge(:host => '127.0.0.1', :id => "test"), OPTIONS.merge( :host => 'somehost', :port => PORT.next, :id => "test1")] + nodes = [OPTIONS.merge(host: '127.0.0.1', id: "test"), OPTIONS.merge(host: 'somehost', port: PORT.next, id: "test1")] redis = Redis::Distributed.new nodes assert_equal redis.nodes.first._client.id, "test" assert_equal redis.nodes.last._client.id, "test1" @@ -50,7 +50,7 @@ def test_can_be_duped_to_create_a_new_connection end def test_keeps_options_after_dup - r1 = Redis::Distributed.new(NODES, :tag => /^(\w+):/) + r1 = Redis::Distributed.new(NODES, tag: /^(\w+):/) assert_raises(Redis::Distributed::CannotDistribute) do r1.sinter("foo", "bar") diff --git a/test/distributed_key_tags_test.rb b/test/distributed_key_tags_test.rb index 54ad45bd6..006b54b26 100644 --- a/test/distributed_key_tags_test.rb +++ b/test/distributed_key_tags_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestDistributedKeyTags < Minitest::Test - include Helper include Helper::Distributed @@ -24,7 +24,7 @@ def test_allows_clustering_of_keys r.set "{foo}users:#{i}", i end - assert_equal [0, 100], r.nodes.map { |node| node.keys.size } + assert_equal([0, 100], r.nodes.map { |node| node.keys.size }) end def test_distributes_keys_if_no_clustering_is_used @@ -34,11 +34,11 @@ def test_distributes_keys_if_no_clustering_is_used r.set "users:1", 1 r.set "users:4", 4 - assert_equal [1, 1], r.nodes.map { |node| node.keys.size } + assert_equal([1, 1], r.nodes.map { |node| node.keys.size }) end def test_allows_passing_a_custom_tag_extractor - r = Redis::Distributed.new(NODES, :tag => /^(.+?):/) + r = Redis::Distributed.new(NODES, tag: /^(.+?):/) r.add_node("redis://127.0.0.1:#{PORT}/14") r.flushdb @@ -46,6 +46,6 @@ def test_allows_passing_a_custom_tag_extractor r.set "foo:users:#{i}", i end - assert_equal [0, 100], r.nodes.map { |node| node.keys.size } + assert_equal([0, 100], r.nodes.map { |node| node.keys.size }) end end diff --git a/test/distributed_persistence_control_commands_test.rb b/test/distributed_persistence_control_commands_test.rb index f6eada2ff..f28cfc7eb 100644 --- a/test/distributed_persistence_control_commands_test.rb +++ b/test/distributed_persistence_control_commands_test.rb @@ -1,24 +1,24 @@ # frozen_string_literal: true + require_relative "helper" class TestDistributedPersistenceControlCommands < Minitest::Test - include Helper::Distributed def test_save - redis_mock(:save => lambda { "+SAVE" }) do |redis| + redis_mock(save: -> { "+SAVE" }) do |redis| assert_equal ["SAVE"], redis.save end end def test_bgsave - redis_mock(:bgsave => lambda { "+BGSAVE" }) do |redis| + redis_mock(bgsave: -> { "+BGSAVE" }) do |redis| assert_equal ["BGSAVE"], redis.bgsave end end def test_lastsave - redis_mock(:lastsave => lambda { "+LASTSAVE" }) do |redis| + redis_mock(lastsave: -> { "+LASTSAVE" }) do |redis| assert_equal ["LASTSAVE"], redis.lastsave end end diff --git a/test/distributed_publish_subscribe_test.rb b/test/distributed_publish_subscribe_test.rb index fa6af86f2..2aa6366b3 100644 --- a/test/distributed_publish_subscribe_test.rb +++ b/test/distributed_publish_subscribe_test.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true + require_relative "helper" class TestDistributedPublishSubscribe < Minitest::Test - include Helper::Distributed def test_subscribe_and_unsubscribe assert_raises Redis::Distributed::CannotDistribute do - r.subscribe("foo", "bar") { } + r.subscribe("foo", "bar") {} end assert_raises Redis::Distributed::CannotDistribute do - r.subscribe("{qux}foo", "bar") { } + r.subscribe("{qux}foo", "bar") {} end end @@ -21,19 +21,19 @@ def test_subscribe_and_unsubscribe_with_tags wire = Wire.new do r.subscribe("foo") do |on| - on.subscribe do |channel, total| + on.subscribe do |_channel, total| @subscribed = true @t1 = total end - on.message do |channel, message| + on.message do |_channel, message| if message == "s1" r.unsubscribe @message = message end end - on.unsubscribe do |channel, total| + on.unsubscribe do |_channel, total| @unsubscribed = true @t2 = total end @@ -41,7 +41,7 @@ def test_subscribe_and_unsubscribe_with_tags end # Wait until the subscription is active before publishing - Wire.pass while !@subscribed + Wire.pass until @subscribed Redis::Distributed.new(NODES).publish("foo", "s1") @@ -59,7 +59,7 @@ def test_subscribe_within_subscribe wire = Wire.new do r.subscribe("foo") do |on| - on.subscribe do |channel, total| + on.subscribe do |channel, _total| @channels << channel r.subscribe("bar") if channel == "foo" @@ -76,7 +76,7 @@ def test_subscribe_within_subscribe def test_other_commands_within_a_subscribe assert_raises Redis::CommandError do r.subscribe("foo") do |on| - on.subscribe do |channel, total| + on.subscribe do |_channel, _total| r.set("bar", "s2") end end diff --git a/test/distributed_remote_server_control_commands_test.rb b/test/distributed_remote_server_control_commands_test.rb index c6c4778de..211a1be2b 100644 --- a/test/distributed_remote_server_control_commands_test.rb +++ b/test/distributed_remote_server_control_commands_test.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true + require_relative "helper" class TestDistributedRemoteServerControlCommands < Minitest::Test - include Helper::Distributed def test_info keys = [ - "redis_version", - "uptime_in_seconds", - "uptime_in_days", - "connected_clients", - "used_memory", - "total_connections_received", - "total_commands_processed", + "redis_version", + "uptime_in_seconds", + "uptime_in_days", + "connected_clients", + "used_memory", + "total_connections_received", + "total_commands_processed" ] infos = r.info @@ -40,12 +40,10 @@ def test_info_commandstats end def test_monitor - begin - r.monitor - rescue Exception => ex - ensure - assert ex.kind_of?(NotImplementedError) - end + r.monitor + rescue Exception => ex + ensure + assert ex.is_a?(NotImplementedError) end def test_echo @@ -60,7 +58,7 @@ def test_time redis_usec = rv[0] * 1_000_000 + rv[1] ruby_usec = Integer(Time.now.to_f * 1_000_000) - assert 500_000 > (ruby_usec - redis_usec).abs + assert((ruby_usec - redis_usec).abs < 500_000) end end end diff --git a/test/distributed_scripting_test.rb b/test/distributed_scripting_test.rb index a2f73fe4b..7c1fce031 100644 --- a/test/distributed_scripting_test.rb +++ b/test/distributed_scripting_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestDistributedScripting < Minitest::Test - include Helper::Distributed def to_sha(script) @@ -33,7 +33,7 @@ def test_script_flush def test_script_kill target_version "2.5.9" do # 2.6-rc1 - redis_mock(:script => lambda { |arg| "+#{arg.upcase}" }) do |redis| + redis_mock(script: ->(arg) { "+#{arg.upcase}" }) do |redis| assert_equal ["KILL"], redis.script(:kill) end end @@ -61,11 +61,11 @@ def test_eval_with_options_hash end assert_raises(Redis::Distributed::CannotDistribute) do - r.eval("return KEYS", { :keys => ["k1", "k2"] }) + r.eval("return KEYS", { keys: ["k1", "k2"] }) end - assert_equal ["k1"], r.eval("return KEYS", { :keys => ["k1"] }) - assert_equal ["a1", "a2"], r.eval("return ARGV", { :keys => ["k1"], :argv => ["a1", "a2"] }) + assert_equal ["k1"], r.eval("return KEYS", { keys: ["k1"] }) + assert_equal ["a1", "a2"], r.eval("return ARGV", { keys: ["k1"], argv: ["a1", "a2"] }) end end @@ -91,11 +91,11 @@ def test_evalsha_with_options_hash end assert_raises(Redis::Distributed::CannotDistribute) do - r.evalsha(to_sha("return KEYS"), { :keys => ["k1", "k2"] }) + r.evalsha(to_sha("return KEYS"), { keys: ["k1", "k2"] }) end - assert_equal ["k1"], r.evalsha(to_sha("return KEYS"), { :keys => ["k1"] }) - assert_equal ["a1", "a2"], r.evalsha(to_sha("return ARGV"), { :keys => ["k1"], :argv => ["a1", "a2"] }) + assert_equal ["k1"], r.evalsha(to_sha("return KEYS"), { keys: ["k1"] }) + assert_equal ["a1", "a2"], r.evalsha(to_sha("return ARGV"), { keys: ["k1"], argv: ["a1", "a2"] }) end end end diff --git a/test/distributed_sorting_test.rb b/test/distributed_sorting_test.rb index f8ef0d765..615877c33 100644 --- a/test/distributed_sorting_test.rb +++ b/test/distributed_sorting_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestDistributedSorting < Minitest::Test - include Helper::Distributed def test_sort @@ -13,7 +13,7 @@ def test_sort r.rpush("bar", "1") r.rpush("bar", "2") - r.sort("bar", :get => "foo:*", :limit => [0, 1]) + r.sort("bar", get: "foo:*", limit: [0, 1]) end end end diff --git a/test/distributed_test.rb b/test/distributed_test.rb index 60f7b4b61..d307f760e 100644 --- a/test/distributed_test.rb +++ b/test/distributed_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestDistributed < Minitest::Test - include Helper::Distributed def test_handle_multiple_servers @@ -16,14 +16,14 @@ def test_handle_multiple_servers assert_equal "foo#{idx}", @r.get(idx.to_s) end - assert_equal "0", @r.keys("*").sort.first + assert_equal "0", @r.keys("*").min assert_equal "string", @r.type("1") end def test_add_nodes logger = Logger.new("/dev/null") - @r = Redis::Distributed.new NODES, :logger => logger, :timeout => 10 + @r = Redis::Distributed.new NODES, logger: logger, timeout: 10 assert_equal "127.0.0.1", @r.nodes[0]._client.host assert_equal PORT, @r.nodes[0]._client.port diff --git a/test/distributed_transactions_test.rb b/test/distributed_transactions_test.rb index e1398fff2..73430441c 100644 --- a/test/distributed_transactions_test.rb +++ b/test/distributed_transactions_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestDistributedTransactions < Minitest::Test - include Helper::Distributed def test_multi_discard diff --git a/test/encoding_test.rb b/test/encoding_test.rb index 1d6cd1d93..f1ee94fa8 100644 --- a/test/encoding_test.rb +++ b/test/encoding_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestEncoding < Minitest::Test - include Helper::Client def test_returns_properly_encoded_strings diff --git a/test/error_replies_test.rb b/test/error_replies_test.rb index c04d120f1..9a03cda6a 100644 --- a/test/error_replies_test.rb +++ b/test/error_replies_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestErrorReplies < Minitest::Test - include Helper::Client # Every test shouldn't disconnect from the server. Also, when error replies are diff --git a/test/fork_safety_test.rb b/test/fork_safety_test.rb index d4fbb54da..3a8c284a8 100644 --- a/test/fork_safety_test.rb +++ b/test/fork_safety_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestForkSafety < Minitest::Test - include Helper::Client driver(:ruby, :hiredis) do @@ -28,13 +28,12 @@ def test_fork_safety assert_equal 127, status.exitstatus assert_equal "1", redis.get("foo") - rescue NotImplementedError => error raise unless error.message =~ /fork is not available/ end def test_fork_safety_with_enabled_inherited_socket - redis = Redis.new(OPTIONS.merge(:inherit_socket => true)) + redis = Redis.new(OPTIONS.merge(inherit_socket: true)) redis.set "foo", 1 child_pid = fork do @@ -55,7 +54,6 @@ def test_fork_safety_with_enabled_inherited_socket assert_equal 0, status.exitstatus assert_equal "2", redis.get("foo") - rescue NotImplementedError => error raise unless error.message =~ /fork is not available/ end diff --git a/test/helper.rb b/test/helper.rb index 1a09a02ac..81be94b08 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -11,10 +11,10 @@ require_relative "../lib/redis" require_relative "../lib/redis/distributed" -require_relative "../lib/redis/connection/#{ENV["DRIVER"]}" +require_relative "../lib/redis/connection/#{ENV['DRIVER']}" require_relative "support/redis_mock" -require_relative "support/connection/#{ENV["DRIVER"]}" +require_relative "support/connection/#{ENV['DRIVER']}" require_relative 'support/cluster/orchestrator' PORT = 6381 @@ -24,13 +24,10 @@ OPTIONS = { port: PORT, db: DB, timeout: TIMEOUT }.freeze def driver(*drivers, &blk) - if drivers.map(&:to_s).include?(ENV["DRIVER"]) - class_eval(&blk) - end + class_eval(&blk) if drivers.map(&:to_s).include?(ENV["DRIVER"]) end module Helper - def run if respond_to?(:around) around { super } @@ -61,25 +58,24 @@ def with_external_encoding(encoding) end class Version - include Comparable attr :parts - def initialize(v) - case v + def initialize(version) + @parts = case version when Version - @parts = v.parts + version.parts else - @parts = v.to_s.split(".") + version.to_s.split(".") end end def <=>(other) other = Version.new(other) - length = [self.parts.length, other.parts.length].max + length = [parts.length, other.parts.length].max length.times do |i| - a, b = self.parts[i], other.parts[i] + a, b = parts[i], other.parts[i] return -1 if a.nil? return +1 if b.nil? @@ -91,13 +87,12 @@ def <=>(other) end module Generic - include Helper attr_reader :log attr_reader :redis - alias :r :redis + alias r redis def setup @log = StringIO.new @@ -109,7 +104,7 @@ def setup end def teardown - redis.quit if redis + redis&.quit super end @@ -139,15 +134,15 @@ def init(redis) exit 1 end - def redis_mock(commands, options = {}, &blk) + def redis_mock(commands, options = {}) RedisMock.start(commands, options) do |port| - yield _new_client(options.merge(:port => port)) + yield _new_client(options.merge(port: port)) end end - def redis_mock_with_handler(handler, options = {}, &blk) + def redis_mock_with_handler(handler, options = {}) RedisMock.start_with_handler(handler, options) do |port| - yield _new_client(options.merge(:port => port)) + yield _new_client(options.merge(port: port)) end end @@ -173,17 +168,16 @@ def version end module Client - include Generic private def _format_options(options) - OPTIONS.merge(:logger => ::Logger.new(@log)).merge(options) + OPTIONS.merge(logger: ::Logger.new(@log)).merge(options) end def _new_client(options = {}) - Redis.new(_format_options(options).merge(:driver => ENV["DRIVER"])) + Redis.new(_format_options(options).merge(driver: ENV["DRIVER"])) end end @@ -234,13 +228,13 @@ def version def _format_options(options) { - :timeout => OPTIONS[:timeout], - :logger => ::Logger.new(@log), + timeout: OPTIONS[:timeout], + logger: ::Logger.new(@log) }.merge(options) end def _new_client(options = {}) - Redis::Distributed.new(NODES, _format_options(options).merge(:driver => ENV["conn"])) + Redis::Distributed.new(NODES, _format_options(options).merge(driver: ENV["conn"])) end end @@ -309,12 +303,12 @@ def redis_cluster_mock(commands, options = {}) port = nil cluster_subcommands = if commands.key?(:cluster) - commands.delete(:cluster) - .map { |k, v| [k.to_s.downcase, v] } - .to_h - else - {} - end + commands.delete(:cluster) + .map { |k, v| [k.to_s.downcase, v] } + .to_h + else + {} + end commands[:cluster] = lambda { |subcommand, *args| if cluster_subcommands.key?(subcommand) diff --git a/test/helper_test.rb b/test/helper_test.rb index a2c133dc2..e33c9d3f2 100644 --- a/test/helper_test.rb +++ b/test/helper_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestHelper < Minitest::Test - include Helper def test_version_comparison diff --git a/test/internals_test.rb b/test/internals_test.rb index e7935feca..27e99bb7b 100644 --- a/test/internals_test.rb +++ b/test/internals_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestInternals < Minitest::Test - include Helper::Client def test_logger @@ -33,7 +33,7 @@ def test_recovers_from_failed_commands end def test_raises_on_protocol_errors - redis_mock(:ping => lambda { |*_| "foo" }) do |redis| + redis_mock(ping: ->(*_) { "foo" }) do |redis| assert_raises(Redis::ProtocolError) do redis.ping end @@ -45,7 +45,7 @@ def test_redis_current assert_equal 6379, Redis.current._client.port assert_equal 0, Redis.current._client.db - Redis.current = Redis.new(OPTIONS.merge(:port => 6380, :db => 1)) + Redis.current = Redis.new(OPTIONS.merge(port: 6380, db: 1)) t = Thread.new do assert_equal "127.0.0.1", Redis.current._client.host @@ -72,23 +72,21 @@ def test_redis_connected? end def test_timeout - Redis.new(OPTIONS.merge(:timeout => 0)) + Redis.new(OPTIONS.merge(timeout: 0)) end driver(:ruby) do def test_tcp_keepalive - keepalive = {:time => 20, :intvl => 10, :probes => 5} + keepalive = { time: 20, intvl: 10, probes: 5 } - redis = Redis.new(OPTIONS.merge(:tcp_keepalive => keepalive)) + redis = Redis.new(OPTIONS.merge(tcp_keepalive: keepalive)) redis.ping connection = redis._client.connection actual_keepalive = connection.get_tcp_keepalive - [:time, :intvl, :probes].each do |key| - if actual_keepalive.has_key?(key) - assert_equal actual_keepalive[key], keepalive[key] - end + %i[time intvl probes].each do |key| + assert_equal actual_keepalive[key], keepalive[key] if actual_keepalive.key?(key) end end end @@ -102,39 +100,39 @@ def test_time redis_usec = rv[0] * 1_000_000 + rv[1] ruby_usec = Integer(Time.now.to_f * 1_000_000) - assert 500_000 > (ruby_usec - redis_usec).abs + assert((ruby_usec - redis_usec).abs < 500_000) end end def test_connection_timeout - opts = OPTIONS.merge(:host => "10.255.255.254", :connect_timeout => 0.1, :timeout => 5.0) + opts = OPTIONS.merge(host: "10.255.255.254", connect_timeout: 0.1, timeout: 5.0) start_time = Time.now assert_raises Redis::CannotConnectError do Redis.new(opts).ping end - assert (Time.now - start_time) <= opts[:timeout] + assert((Time.now - start_time) <= opts[:timeout]) end def test_missing_socket - opts = { :path => '/missing.sock' } + opts = { path: '/missing.sock' } assert_raises Redis::CannotConnectError do Redis.new(opts).ping end end def close_on_ping(seq, options = {}) - $request = 0 + @request = 0 command = lambda do - idx = $request - $request += 1 + idx = @request + @request += 1 rv = "+%d" % idx rv = nil if seq.include?(idx) rv end - redis_mock({:ping => command}, {:timeout => 0.1}.merge(options)) do |redis| + redis_mock({ ping: command }, { timeout: 0.1 }.merge(options)) do |redis| yield(redis) end end @@ -184,13 +182,13 @@ def test_retry_only_once_when_read_raises_econnreset end def test_retry_with_custom_reconnect_attempts - close_on_ping([0, 1], :reconnect_attempts => 2) do |redis| + close_on_ping([0, 1], reconnect_attempts: 2) do |redis| assert_equal "2", redis.ping end end def test_retry_with_custom_reconnect_attempts_can_still_fail - close_on_ping([0, 1, 2], :reconnect_attempts => 2) do |redis| + close_on_ping([0, 1, 2], reconnect_attempts: 2) do |redis| assert_raises Redis::ConnectionError do redis.ping end @@ -200,10 +198,9 @@ def test_retry_with_custom_reconnect_attempts_can_still_fail end def test_retry_with_custom_reconnect_attempts_and_exponential_backoff - close_on_ping([0, 1, 2], :reconnect_attempts => 3, - :reconnect_delay_max => 0.5, - :reconnect_delay => 0.01) do |redis| - + close_on_ping([0, 1, 2], reconnect_attempts: 3, + reconnect_delay_max: 0.5, + reconnect_delay: 0.01) do |redis| Kernel.expects(:sleep).with(0.01).returns(true) Kernel.expects(:sleep).with(0.02).returns(true) Kernel.expects(:sleep).with(0.04).returns(true) @@ -226,7 +223,7 @@ def test_don_t_retry_when_second_read_in_pipeline_raises_econnreset end def close_on_connection(seq) - $n = 0 + @n = 0 read_command = lambda do |session| Array.new(session.gets[1..-3].to_i) do @@ -238,8 +235,8 @@ def close_on_connection(seq) end handler = lambda do |session| - n = $n - $n += 1 + n = @n + @n += 1 select = read_command.call(session) if select[0].downcase == "select" @@ -247,11 +244,8 @@ def close_on_connection(seq) else raise "Expected SELECT" end - - if !seq.include?(n) - while read_command.call(session) - session.write("+#{n}\r\n") - end + unless seq.include?(n) # rubocop:disable Style/IfUnlessModifier + session.write("+#{n}\r\n") while read_command.call(session) end end @@ -295,26 +289,25 @@ def test_dont_retry_on_write_error_when_wrapped_in_without_reconnect end def test_connecting_to_unix_domain_socket - Redis.new(OPTIONS.merge(:path => ENV.fetch("SOCKET_PATH"))).ping + Redis.new(OPTIONS.merge(path: ENV.fetch("SOCKET_PATH"))).ping end driver(:ruby, :hiredis) do def test_bubble_timeout_without_retrying serv = TCPServer.new(6380) - redis = Redis.new(:port => 6380, :timeout => 0.1) + redis = Redis.new(port: 6380, timeout: 0.1) assert_raises(Redis::TimeoutError) do redis.ping end - ensure - serv.close if serv + serv&.close end end def test_client_options - redis = Redis.new(OPTIONS.merge(:host => "host", :port => 1234, :db => 1, :scheme => "foo")) + redis = Redis.new(OPTIONS.merge(host: "host", port: 1234, db: 1, scheme: "foo")) assert_equal "host", redis._client.options[:host] assert_equal 1234, redis._client.options[:port] @@ -323,29 +316,27 @@ def test_client_options end def test_resolves_localhost - Redis.new(OPTIONS.merge(:host => 'localhost')).ping + Redis.new(OPTIONS.merge(host: 'localhost')).ping end class << self - def af_family_supported(af) + def af_family_supported(af_type) hosts = { - Socket::AF_INET => "127.0.0.1", - Socket::AF_INET6 => "::1", + Socket::AF_INET => "127.0.0.1", + Socket::AF_INET6 => "::1" } begin - s = Socket.new(af, Socket::SOCK_STREAM, 0) + s = Socket.new(af_type, Socket::SOCK_STREAM, 0) begin tries = 5 begin - sa = Socket.pack_sockaddr_in(1024 + Random.rand(63076), hosts[af]) + sa = Socket.pack_sockaddr_in(Random.rand(1024..64_099), hosts[af_type]) s.bind(sa) rescue Errno::EADDRINUSE => e # On JRuby (9.1.15.0), if IPv6 is globally disabled on the system, # we get an EADDRINUSE with belows message. - if e.message =~ /Protocol family unavailable/ - return - end + return if e.message =~ /Protocol family unavailable/ tries -= 1 retry if tries > 0 @@ -364,12 +355,10 @@ def af_family_supported(af) def af_test(host) commands = { - :ping => lambda { |*_| "+pong" }, + ping: ->(*_) { "+pong" } } - redis_mock(commands, :host => host) do |redis| - redis.ping - end + redis_mock(commands, host: host, &:ping) end driver(:ruby) do diff --git a/test/lint/blocking_commands.rb b/test/lint/blocking_commands.rb index 8a85655b6..11bbe0bf2 100644 --- a/test/lint/blocking_commands.rb +++ b/test/lint/blocking_commands.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module Lint module BlockingCommands def setup diff --git a/test/lint/hashes.rb b/test/lint/hashes.rb index 2578b9d29..9ba578e71 100644 --- a/test/lint/hashes.rb +++ b/test/lint/hashes.rb @@ -1,8 +1,7 @@ # frozen_string_literal: true -module Lint +module Lint module Hashes - def test_hset_and_hget assert_equal 1, r.hset("foo", "f1", "s1") @@ -114,12 +113,12 @@ def test_hvals end def test_hgetall - assert({} == r.hgetall("foo")) + assert(r.hgetall("foo") == {}) r.hset("foo", "f1", "s1") r.hset("foo", "f2", "s2") - assert({"f1" => "s1", "f2" => "s2"} == r.hgetall("foo")) + assert(r.hgetall("foo") == { "f1" => "s1", "f2" => "s2" }) end def test_hmset @@ -136,7 +135,7 @@ def test_hmset_with_invalid_arguments end def test_mapped_hmset - r.mapped_hmset("foo", :f1 => "s1", :f2 => "s2") + r.mapped_hmset("foo", f1: "s1", f2: "s2") assert_equal "s1", r.hget("foo", "f1") assert_equal "s2", r.hget("foo", "f2") @@ -155,8 +154,8 @@ def test_hmget_mapped r.hset("foo", "f2", "s2") r.hset("foo", "f3", "s3") - assert({"f1" => "s1"} == r.mapped_hmget("foo", "f1")) - assert({"f1" => "s1", "f2" => "s2"} == r.mapped_hmget("foo", "f1", "f2")) + assert(r.mapped_hmget("foo", "f1") == { "f1" => "s1" }) + assert(r.mapped_hmget("foo", "f1", "f2") == { "f1" => "s1", "f2" => "s2" }) end def test_mapped_hmget_in_a_pipeline_returns_hash diff --git a/test/lint/hyper_log_log.rb b/test/lint/hyper_log_log.rb index eacd33e66..7db1c14b4 100644 --- a/test/lint/hyper_log_log.rb +++ b/test/lint/hyper_log_log.rb @@ -1,8 +1,7 @@ # frozen_string_literal: true -module Lint +module Lint module HyperLogLog - def test_pfadd target_version "2.8.9" do assert_equal true, r.pfadd("foo", "s1") diff --git a/test/lint/lists.rb b/test/lint/lists.rb index fb96c3219..b0c5a2570 100644 --- a/test/lint/lists.rb +++ b/test/lint/lists.rb @@ -1,8 +1,7 @@ # frozen_string_literal: true -module Lint +module Lint module Lists - def test_lpush r.lpush "foo", "s1" r.lpush "foo", "s2" diff --git a/test/lint/sets.rb b/test/lint/sets.rb index 72204344d..56c167de2 100644 --- a/test/lint/sets.rb +++ b/test/lint/sets.rb @@ -1,8 +1,7 @@ # frozen_string_literal: true -module Lint +module Lint module Sets - def test_sadd assert_equal true, r.sadd("foo", "s1") assert_equal true, r.sadd("foo", "s2") @@ -37,7 +36,7 @@ def test_variadic_srem r.sadd("foo", "s3") assert_equal 1, r.srem("foo", ["s1", "aaa"]) - assert_equal 0, r.srem("foo", ["bbb", "ccc" "ddd"]) + assert_equal 0, r.srem("foo", ["bbb", "ccc", "ddd"]) assert_equal 1, r.srem("foo", ["eee", "s3"]) assert_equal ["s2"], r.smembers("foo") diff --git a/test/lint/sorted_sets.rb b/test/lint/sorted_sets.rb index eead9ee24..40a6f02ea 100644 --- a/test/lint/sorted_sets.rb +++ b/test/lint/sorted_sets.rb @@ -1,10 +1,7 @@ # frozen_string_literal: true -module Lint +module Lint module SortedSets - - Infinity = 1.0/0.0 - def test_zadd assert_equal 0, r.zcard("foo") assert_equal true, r.zadd("foo", 1, "s1") @@ -15,38 +12,38 @@ def test_zadd target_version "3.0.2" do # XX option assert_equal 0, r.zcard("foo") - assert_equal false, r.zadd("foo", 1, "s1", :xx => true) + assert_equal false, r.zadd("foo", 1, "s1", xx: true) r.zadd("foo", 1, "s1") - assert_equal false, r.zadd("foo", 2, "s1", :xx => true) + assert_equal false, r.zadd("foo", 2, "s1", xx: true) assert_equal 2, r.zscore("foo", "s1") r.del "foo" # NX option assert_equal 0, r.zcard("foo") - assert_equal true, r.zadd("foo", 1, "s1", :nx => true) - assert_equal false, r.zadd("foo", 2, "s1", :nx => true) + assert_equal true, r.zadd("foo", 1, "s1", nx: true) + assert_equal false, r.zadd("foo", 2, "s1", nx: true) assert_equal 1, r.zscore("foo", "s1") assert_equal 1, r.zcard("foo") r.del "foo" # CH option assert_equal 0, r.zcard("foo") - assert_equal true, r.zadd("foo", 1, "s1", :ch => true) - assert_equal false, r.zadd("foo", 1, "s1", :ch => true) - assert_equal true, r.zadd("foo", 2, "s1", :ch => true) + assert_equal true, r.zadd("foo", 1, "s1", ch: true) + assert_equal false, r.zadd("foo", 1, "s1", ch: true) + assert_equal true, r.zadd("foo", 2, "s1", ch: true) assert_equal 1, r.zcard("foo") r.del "foo" # INCR option - assert_equal 1.0, r.zadd("foo", 1, "s1", :incr => true) - assert_equal 11.0, r.zadd("foo", 10, "s1", :incr => true) - assert_equal(-Infinity, r.zadd("bar", "-inf", "s1", :incr => true)) - assert_equal(+Infinity, r.zadd("bar", "+inf", "s2", :incr => true)) + assert_equal 1.0, r.zadd("foo", 1, "s1", incr: true) + assert_equal 11.0, r.zadd("foo", 10, "s1", incr: true) + assert_equal(-Float::INFINITY, r.zadd("bar", "-inf", "s1", incr: true)) + assert_equal(+Float::INFINITY, r.zadd("bar", "+inf", "s2", incr: true)) r.del 'foo' r.del 'bar' # Incompatible options combination - assert_raises(Redis::CommandError) { r.zadd("foo", 1, "s1", :xx => true, :nx => true) } + assert_raises(Redis::CommandError) { r.zadd("foo", 1, "s1", xx: true, nx: true) } end end @@ -74,9 +71,9 @@ def test_variadic_zadd target_version "3.0.2" do # XX option assert_equal 0, r.zcard("foo") - assert_equal 0, r.zadd("foo", [1, "s1", 2, "s2"], :xx => true) + assert_equal 0, r.zadd("foo", [1, "s1", 2, "s2"], xx: true) r.zadd("foo", [1, "s1", 2, "s2"]) - assert_equal 0, r.zadd("foo", [2, "s1", 3, "s2", 4, "s3"], :xx => true) + assert_equal 0, r.zadd("foo", [2, "s1", 3, "s2", 4, "s3"], xx: true) assert_equal 2, r.zscore("foo", "s1") assert_equal 3, r.zscore("foo", "s2") assert_nil r.zscore("foo", "s3") @@ -85,8 +82,8 @@ def test_variadic_zadd # NX option assert_equal 0, r.zcard("foo") - assert_equal 2, r.zadd("foo", [1, "s1", 2, "s2"], :nx => true) - assert_equal 1, r.zadd("foo", [2, "s1", 3, "s2", 4, "s3"], :nx => true) + assert_equal 2, r.zadd("foo", [1, "s1", 2, "s2"], nx: true) + assert_equal 1, r.zadd("foo", [2, "s1", 3, "s2", 4, "s3"], nx: true) assert_equal 1, r.zscore("foo", "s1") assert_equal 2, r.zscore("foo", "s2") assert_equal 4, r.zscore("foo", "s3") @@ -95,22 +92,22 @@ def test_variadic_zadd # CH option assert_equal 0, r.zcard("foo") - assert_equal 2, r.zadd("foo", [1, "s1", 2, "s2"], :ch => true) - assert_equal 2, r.zadd("foo", [1, "s1", 3, "s2", 4, "s3"], :ch => true) + assert_equal 2, r.zadd("foo", [1, "s1", 2, "s2"], ch: true) + assert_equal 2, r.zadd("foo", [1, "s1", 3, "s2", 4, "s3"], ch: true) assert_equal 3, r.zcard("foo") r.del "foo" # INCR option - assert_equal 1.0, r.zadd("foo", [1, "s1"], :incr => true) - assert_equal 11.0, r.zadd("foo", [10, "s1"], :incr => true) - assert_equal(-Infinity, r.zadd("bar", ["-inf", "s1"], :incr => true)) - assert_equal(+Infinity, r.zadd("bar", ["+inf", "s2"], :incr => true)) - assert_raises(Redis::CommandError) { r.zadd("foo", [1, "s1", 2, "s2"], :incr => true) } + assert_equal 1.0, r.zadd("foo", [1, "s1"], incr: true) + assert_equal 11.0, r.zadd("foo", [10, "s1"], incr: true) + assert_equal(-Float::INFINITY, r.zadd("bar", ["-inf", "s1"], incr: true)) + assert_equal(+Float::INFINITY, r.zadd("bar", ["+inf", "s2"], incr: true)) + assert_raises(Redis::CommandError) { r.zadd("foo", [1, "s1", 2, "s2"], incr: true) } r.del 'foo' r.del 'bar' # Incompatible options combination - assert_raises(Redis::CommandError) { r.zadd("foo", [1, "s1"], :xx => true, :nx => true) } + assert_raises(Redis::CommandError) { r.zadd("foo", [1, "s1"], xx: true, nx: true) } end end @@ -132,7 +129,7 @@ def test_variadic_zrem assert_equal 3, r.zcard("foo") assert_equal 1, r.zrem("foo", ["s1", "aaa"]) - assert_equal 0, r.zrem("foo", ["bbb", "ccc" "ddd"]) + assert_equal 0, r.zrem("foo", ["bbb", "ccc", "ddd"]) assert_equal 1, r.zrem("foo", ["eee", "s3"]) assert_equal 1, r.zcard("foo") end @@ -146,10 +143,10 @@ def test_zincrby assert_equal 11.0, rv rv = r.zincrby "bar", "-inf", "s1" - assert_equal(-Infinity, rv) + assert_equal(-Float::INFINITY, rv) rv = r.zincrby "bar", "+inf", "s2" - assert_equal(+Infinity, rv) + assert_equal(+Float::INFINITY, rv) end def test_zrank @@ -174,13 +171,13 @@ def test_zrange r.zadd "foo", 3, "s3" assert_equal ["s1", "s2"], r.zrange("foo", 0, 1) - assert_equal [["s1", 1.0], ["s2", 2.0]], r.zrange("foo", 0, 1, :with_scores => true) - assert_equal [["s1", 1.0], ["s2", 2.0]], r.zrange("foo", 0, 1, :withscores => true) + assert_equal [["s1", 1.0], ["s2", 2.0]], r.zrange("foo", 0, 1, with_scores: true) + assert_equal [["s1", 1.0], ["s2", 2.0]], r.zrange("foo", 0, 1, withscores: true) r.zadd "bar", "-inf", "s1" r.zadd "bar", "+inf", "s2" - assert_equal [["s1", -Infinity], ["s2", +Infinity]], r.zrange("bar", 0, 1, :with_scores => true) - assert_equal [["s1", -Infinity], ["s2", +Infinity]], r.zrange("bar", 0, 1, :withscores => true) + assert_equal [["s1", -Float::INFINITY], ["s2", +Float::INFINITY]], r.zrange("bar", 0, 1, with_scores: true) + assert_equal [["s1", -Float::INFINITY], ["s2", +Float::INFINITY]], r.zrange("bar", 0, 1, withscores: true) end def test_zrevrange @@ -189,13 +186,13 @@ def test_zrevrange r.zadd "foo", 3, "s3" assert_equal ["s3", "s2"], r.zrevrange("foo", 0, 1) - assert_equal [["s3", 3.0], ["s2", 2.0]], r.zrevrange("foo", 0, 1, :with_scores => true) - assert_equal [["s3", 3.0], ["s2", 2.0]], r.zrevrange("foo", 0, 1, :withscores => true) + assert_equal [["s3", 3.0], ["s2", 2.0]], r.zrevrange("foo", 0, 1, with_scores: true) + assert_equal [["s3", 3.0], ["s2", 2.0]], r.zrevrange("foo", 0, 1, withscores: true) r.zadd "bar", "-inf", "s1" r.zadd "bar", "+inf", "s2" - assert_equal [["s2", +Infinity], ["s1", -Infinity]], r.zrevrange("bar", 0, 1, :with_scores => true) - assert_equal [["s2", +Infinity], ["s1", -Infinity]], r.zrevrange("bar", 0, 1, :withscores => true) + assert_equal [["s2", +Float::INFINITY], ["s1", -Float::INFINITY]], r.zrevrange("bar", 0, 1, with_scores: true) + assert_equal [["s2", +Float::INFINITY], ["s1", -Float::INFINITY]], r.zrevrange("bar", 0, 1, withscores: true) end def test_zrangebyscore @@ -220,9 +217,9 @@ def test_zrangebyscore_with_limit r.zadd "foo", 3, "s3" r.zadd "foo", 4, "s4" - assert_equal ["s2"], r.zrangebyscore("foo", 2, 4, :limit => [0, 1]) - assert_equal ["s3"], r.zrangebyscore("foo", 2, 4, :limit => [1, 1]) - assert_equal ["s3", "s4"], r.zrangebyscore("foo", 2, 4, :limit => [1, 2]) + assert_equal ["s2"], r.zrangebyscore("foo", 2, 4, limit: [0, 1]) + assert_equal ["s3"], r.zrangebyscore("foo", 2, 4, limit: [1, 1]) + assert_equal ["s3", "s4"], r.zrangebyscore("foo", 2, 4, limit: [1, 2]) end def test_zrevrangebyscore_with_limit @@ -231,9 +228,9 @@ def test_zrevrangebyscore_with_limit r.zadd "foo", 3, "s3" r.zadd "foo", 4, "s4" - assert_equal ["s4"], r.zrevrangebyscore("foo", 4, 2, :limit => [0, 1]) - assert_equal ["s3"], r.zrevrangebyscore("foo", 4, 2, :limit => [1, 1]) - assert_equal ["s3", "s2"], r.zrevrangebyscore("foo", 4, 2, :limit => [1, 2]) + assert_equal ["s4"], r.zrevrangebyscore("foo", 4, 2, limit: [0, 1]) + assert_equal ["s3"], r.zrevrangebyscore("foo", 4, 2, limit: [1, 1]) + assert_equal ["s3", "s2"], r.zrevrangebyscore("foo", 4, 2, limit: [1, 2]) end def test_zrangebyscore_with_withscores @@ -242,17 +239,17 @@ def test_zrangebyscore_with_withscores r.zadd "foo", 3, "s3" r.zadd "foo", 4, "s4" - assert_equal [["s2", 2.0]], r.zrangebyscore("foo", 2, 4, :limit => [0, 1], :with_scores => true) - assert_equal [["s3", 3.0]], r.zrangebyscore("foo", 2, 4, :limit => [1, 1], :with_scores => true) - assert_equal [["s2", 2.0]], r.zrangebyscore("foo", 2, 4, :limit => [0, 1], :withscores => true) - assert_equal [["s3", 3.0]], r.zrangebyscore("foo", 2, 4, :limit => [1, 1], :withscores => true) + assert_equal [["s2", 2.0]], r.zrangebyscore("foo", 2, 4, limit: [0, 1], with_scores: true) + assert_equal [["s3", 3.0]], r.zrangebyscore("foo", 2, 4, limit: [1, 1], with_scores: true) + assert_equal [["s2", 2.0]], r.zrangebyscore("foo", 2, 4, limit: [0, 1], withscores: true) + assert_equal [["s3", 3.0]], r.zrangebyscore("foo", 2, 4, limit: [1, 1], withscores: true) r.zadd "bar", "-inf", "s1" r.zadd "bar", "+inf", "s2" - assert_equal [["s1", -Infinity]], r.zrangebyscore("bar", -Infinity, +Infinity, :limit => [0, 1], :with_scores => true) - assert_equal [["s2", +Infinity]], r.zrangebyscore("bar", -Infinity, +Infinity, :limit => [1, 1], :with_scores => true) - assert_equal [["s1", -Infinity]], r.zrangebyscore("bar", -Infinity, +Infinity, :limit => [0, 1], :withscores => true) - assert_equal [["s2", +Infinity]], r.zrangebyscore("bar", -Infinity, +Infinity, :limit => [1, 1], :withscores => true) + assert_equal [["s1", -Float::INFINITY]], r.zrangebyscore("bar", -Float::INFINITY, +Float::INFINITY, limit: [0, 1], with_scores: true) + assert_equal [["s2", +Float::INFINITY]], r.zrangebyscore("bar", -Float::INFINITY, +Float::INFINITY, limit: [1, 1], with_scores: true) + assert_equal [["s1", -Float::INFINITY]], r.zrangebyscore("bar", -Float::INFINITY, +Float::INFINITY, limit: [0, 1], withscores: true) + assert_equal [["s2", +Float::INFINITY]], r.zrangebyscore("bar", -Float::INFINITY, +Float::INFINITY, limit: [1, 1], withscores: true) end def test_zrevrangebyscore_with_withscores @@ -261,17 +258,17 @@ def test_zrevrangebyscore_with_withscores r.zadd "foo", 3, "s3" r.zadd "foo", 4, "s4" - assert_equal [["s4", 4.0]], r.zrevrangebyscore("foo", 4, 2, :limit => [0, 1], :with_scores => true) - assert_equal [["s3", 3.0]], r.zrevrangebyscore("foo", 4, 2, :limit => [1, 1], :with_scores => true) - assert_equal [["s4", 4.0]], r.zrevrangebyscore("foo", 4, 2, :limit => [0, 1], :withscores => true) - assert_equal [["s3", 3.0]], r.zrevrangebyscore("foo", 4, 2, :limit => [1, 1], :withscores => true) + assert_equal [["s4", 4.0]], r.zrevrangebyscore("foo", 4, 2, limit: [0, 1], with_scores: true) + assert_equal [["s3", 3.0]], r.zrevrangebyscore("foo", 4, 2, limit: [1, 1], with_scores: true) + assert_equal [["s4", 4.0]], r.zrevrangebyscore("foo", 4, 2, limit: [0, 1], withscores: true) + assert_equal [["s3", 3.0]], r.zrevrangebyscore("foo", 4, 2, limit: [1, 1], withscores: true) r.zadd "bar", "-inf", "s1" r.zadd "bar", "+inf", "s2" - assert_equal [["s2", +Infinity]], r.zrevrangebyscore("bar", +Infinity, -Infinity, :limit => [0, 1], :with_scores => true) - assert_equal [["s1", -Infinity]], r.zrevrangebyscore("bar", +Infinity, -Infinity, :limit => [1, 1], :with_scores => true) - assert_equal [["s2", +Infinity]], r.zrevrangebyscore("bar", +Infinity, -Infinity, :limit => [0, 1], :withscores => true) - assert_equal [["s1", -Infinity]], r.zrevrangebyscore("bar", +Infinity, -Infinity, :limit => [1, 1], :withscores => true) + assert_equal [["s2", +Float::INFINITY]], r.zrevrangebyscore("bar", +Float::INFINITY, -Float::INFINITY, limit: [0, 1], with_scores: true) + assert_equal [["s1", -Float::INFINITY]], r.zrevrangebyscore("bar", +Float::INFINITY, -Float::INFINITY, limit: [1, 1], with_scores: true) + assert_equal [["s2", +Float::INFINITY]], r.zrevrangebyscore("bar", +Float::INFINITY, -Float::INFINITY, limit: [0, 1], withscores: true) + assert_equal [["s1", -Float::INFINITY]], r.zrevrangebyscore("bar", +Float::INFINITY, -Float::INFINITY, limit: [1, 1], withscores: true) end def test_zcard @@ -292,8 +289,8 @@ def test_zscore r.zadd "bar", "-inf", "s1" r.zadd "bar", "+inf", "s2" - assert_equal(-Infinity, r.zscore("bar", "s1")) - assert_equal(+Infinity, r.zscore("bar", "s2")) + assert_equal(-Float::INFINITY, r.zscore("bar", "s1")) + assert_equal(+Float::INFINITY, r.zscore("bar", "s2")) end def test_zremrangebyrank diff --git a/test/lint/streams.rb b/test/lint/streams.rb index b4d5f7b53..aa0bae1e0 100644 --- a/test/lint/streams.rb +++ b/test/lint/streams.rb @@ -3,7 +3,7 @@ module Lint module Streams MIN_REDIS_VERSION = '4.9.0' - ENTRY_ID_FORMAT = /\d+-\d+/ + ENTRY_ID_FORMAT = /\d+-\d+/.freeze def setup super @@ -152,7 +152,7 @@ def test_xrange actual = redis.xrange('s1') - assert_equal %w(v1 v2 v3), actual.map { |i| i.last['f'] } + assert_equal(%w(v1 v2 v3), actual.map { |i| i.last['f'] }) end def test_xrange_with_start_option @@ -226,7 +226,7 @@ def test_xrevrange actual = redis.xrevrange('s1') assert_equal %w(0-3 0-2 0-1), actual.map(&:first) - assert_equal %w(v3 v2 v1), actual.map { |i| i.last['f'] } + assert_equal(%w(v3 v2 v1), actual.map { |i| i.last['f'] }) end def test_xrevrange_with_start_option @@ -315,7 +315,7 @@ def test_xread_with_a_key actual = redis.xread('s1', 0) - assert_equal %w(v1 v2), actual.fetch('s1').map { |i| i.last['f'] } + assert_equal(%w(v1 v2), actual.fetch('s1').map { |i| i.last['f'] }) end def test_xread_with_multiple_keys @@ -357,7 +357,7 @@ def test_xread_does_not_raise_timeout_error_when_the_block_option_is_zero_msec redis.dup.xadd('s1', { f: 'v1' }, id: '0-1') wire.join - assert_equal ['v1'], actual.fetch('s1').map { |i| i.last['f'] } + assert_equal(['v1'], actual.fetch('s1').map { |i| i.last['f'] }) end def test_xread_with_invalid_arguments @@ -532,7 +532,7 @@ def test_xclaim_with_splatted_entry_ids actual = redis.xclaim('s1', 'g1', 'c2', 10, '0-2', '0-3') assert_equal %w(0-2 0-3), actual.map(&:first) - assert_equal %w(v2 v3), actual.map { |i| i.last['f'] } + assert_equal(%w(v2 v3), actual.map { |i| i.last['f'] }) end def test_xclaim_with_arrayed_entry_ids @@ -546,7 +546,7 @@ def test_xclaim_with_arrayed_entry_ids actual = redis.xclaim('s1', 'g1', 'c2', 10, %w[0-2 0-3]) assert_equal %w(0-2 0-3), actual.map(&:first) - assert_equal %w(v2 v3), actual.map { |i| i.last['f'] } + assert_equal(%w(v2 v3), actual.map { |i| i.last['f'] }) end def test_xclaim_with_idle_option @@ -560,7 +560,7 @@ def test_xclaim_with_idle_option actual = redis.xclaim('s1', 'g1', 'c2', 10, '0-2', '0-3', idle: 0) assert_equal %w(0-2 0-3), actual.map(&:first) - assert_equal %w(v2 v3), actual.map { |i| i.last['f'] } + assert_equal(%w(v2 v3), actual.map { |i| i.last['f'] }) end def test_xclaim_with_time_option @@ -575,7 +575,7 @@ def test_xclaim_with_time_option actual = redis.xclaim('s1', 'g1', 'c2', 10, '0-2', '0-3', time: time) assert_equal %w(0-2 0-3), actual.map(&:first) - assert_equal %w(v2 v3), actual.map { |i| i.last['f'] } + assert_equal(%w(v2 v3), actual.map { |i| i.last['f'] }) end def test_xclaim_with_retrycount_option @@ -589,7 +589,7 @@ def test_xclaim_with_retrycount_option actual = redis.xclaim('s1', 'g1', 'c2', 10, '0-2', '0-3', retrycount: 10) assert_equal %w(0-2 0-3), actual.map(&:first) - assert_equal %w(v2 v3), actual.map { |i| i.last['f'] } + assert_equal(%w(v2 v3), actual.map { |i| i.last['f'] }) end def test_xclaim_with_force_option @@ -602,8 +602,8 @@ def test_xclaim_with_force_option actual = redis.xclaim('s1', 'g1', 'c2', 10, '0-2', '0-3', force: true) - assert_equal %w(0-2 0-3), actual.map(&:first) - assert_equal %w(v2 v3), actual.map { |i| i.last['f'] } + assert_equal(%w(0-2 0-3), actual.map(&:first)) + assert_equal(%w(v2 v3), actual.map { |i| i.last['f'] }) end def test_xclaim_with_justid_option diff --git a/test/lint/strings.rb b/test/lint/strings.rb index bf18c39fe..e9ecf58c5 100644 --- a/test/lint/strings.rb +++ b/test/lint/strings.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module Lint +module Lint module Strings def mock(*args, &block) redis_mock(*args, &block) @@ -39,26 +39,26 @@ def test_set_and_get_with_ascii_characters def test_set_with_ex target_version "2.6.12" do - r.set("foo", "bar", :ex => 2) + r.set("foo", "bar", ex: 2) assert_in_range 0..2, r.ttl("foo") end end def test_set_with_px target_version "2.6.12" do - r.set("foo", "bar", :px => 2000) + r.set("foo", "bar", px: 2000) assert_in_range 0..2, r.ttl("foo") end end def test_set_with_nx target_version "2.6.12" do - r.set("foo", "qux", :nx => true) - assert !r.set("foo", "bar", :nx => true) + r.set("foo", "qux", nx: true) + assert !r.set("foo", "bar", nx: true) assert_equal "qux", r.get("foo") r.del("foo") - assert r.set("foo", "bar", :nx => true) + assert r.set("foo", "bar", nx: true) assert_equal "bar", r.get("foo") end end @@ -66,19 +66,19 @@ def test_set_with_nx def test_set_with_xx target_version "2.6.12" do r.set("foo", "qux") - assert r.set("foo", "bar", :xx => true) + assert r.set("foo", "bar", xx: true) assert_equal "bar", r.get("foo") r.del("foo") - assert !r.set("foo", "bar", :xx => true) + assert !r.set("foo", "bar", xx: true) end end def test_set_with_keepttl target_version "6.0.0" do - r.set("foo", "qux", :ex => 2) + r.set("foo", "qux", ex: 2) assert_in_range 0..2, r.ttl("foo") - r.set("foo", "bar", :keepttl => true) + r.set("foo", "bar", keepttl: true) assert_in_range 0..2, r.ttl("foo") end end @@ -168,8 +168,8 @@ def test_incrby def test_incrbyfloat target_version "2.5.4" do assert_equal 1.23, r.incrbyfloat("foo", 1.23) - assert_equal 2 , r.incrbyfloat("foo", 0.77) - assert_equal 1.9 , r.incrbyfloat("foo", -0.1) + assert_equal 2, r.incrbyfloat("foo", 0.77) + assert_equal 1.9, r.incrbyfloat("foo", -0.1) end end @@ -247,7 +247,7 @@ def test_setrange_with_non_string_value r.setrange("foo", 2, value) - assert_equal "ab#{value.to_s}", r.get("foo") + assert_equal "ab#{value}", r.get("foo") end def test_strlen @@ -285,7 +285,7 @@ def test_mget_mapped assert_equal 's1', response['{1}foo'] assert_equal 's2', response['{1}bar'] - assert_nil response['{1}baz'] + assert_nil response['{1}baz'] end def test_mapped_mget_in_a_pipeline_returns_hash diff --git a/test/lint/value_types.rb b/test/lint/value_types.rb index 295ee7d2d..59212fed0 100644 --- a/test/lint/value_types.rb +++ b/test/lint/value_types.rb @@ -1,8 +1,7 @@ # frozen_string_literal: true -module Lint +module Lint module ValueTypes - def test_exists assert_equal false, r.exists("foo") @@ -40,7 +39,7 @@ def test_exists? r.set("{1}foo", "s1") - assert_equal true, r.exists?("{1}foo") + assert_equal true, r.exists?("{1}foo") end def test_type @@ -56,7 +55,7 @@ def test_keys r.set("fo", "s2") r.set("foo", "s3") - assert_equal ["f","fo", "foo"], r.keys("f*").sort + assert_equal ["f", "fo", "foo"], r.keys("f*").sort end def test_expire @@ -92,7 +91,7 @@ def test_persist r.expire("foo", 1) r.persist("foo") - assert(-1 == r.ttl("foo")) + assert(r.ttl("foo") == -1) end def test_ttl @@ -129,9 +128,9 @@ def test_dump_and_restore r.set("bar", "somethingelse") assert_raises(Redis::CommandError) { r.restore("bar", 1000, w) } # ensure by default replace is false - assert_raises(Redis::CommandError) { r.restore("bar", 1000, w, :replace => false) } + assert_raises(Redis::CommandError) { r.restore("bar", 1000, w, replace: false) } assert_equal "somethingelse", r.get("bar") - assert r.restore("bar", 1000, w, :replace => true) + assert r.restore("bar", 1000, w, replace: true) assert_equal ["b", "c", "d"], r.lrange("bar", 0, -1) assert [0, 1].include? r.ttl("bar") end diff --git a/test/persistence_control_commands_test.rb b/test/persistence_control_commands_test.rb index cb1e25810..46f27077b 100644 --- a/test/persistence_control_commands_test.rb +++ b/test/persistence_control_commands_test.rb @@ -1,24 +1,24 @@ # frozen_string_literal: true + require_relative "helper" class TestPersistenceControlCommands < Minitest::Test - include Helper::Client def test_save - redis_mock(:save => lambda { "+SAVE" }) do |redis| + redis_mock(save: -> { "+SAVE" }) do |redis| assert_equal "SAVE", redis.save end end def test_bgsave - redis_mock(:bgsave => lambda { "+BGSAVE" }) do |redis| + redis_mock(bgsave: -> { "+BGSAVE" }) do |redis| assert_equal "BGSAVE", redis.bgsave end end def test_lastsave - redis_mock(:lastsave => lambda { "+LASTSAVE" }) do |redis| + redis_mock(lastsave: -> { "+LASTSAVE" }) do |redis| assert_equal "LASTSAVE", redis.lastsave end end diff --git a/test/pipelining_commands_test.rb b/test/pipelining_commands_test.rb index 29cdec430..9f2afea8b 100644 --- a/test/pipelining_commands_test.rb +++ b/test/pipelining_commands_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestPipeliningCommands < Minitest::Test - include Helper::Client def test_bulk_commands @@ -130,7 +130,7 @@ def test_futures_raise_when_trying_to_access_their_values_too_early def test_futures_raise_when_command_errors_and_needs_transformation assert_raises(Redis::CommandError) do r.pipelined do - @result = r.zrange("a", "b", 5, :with_scores => true) + @result = r.zrange("a", "b", 5, with_scores: true) end end end @@ -141,7 +141,7 @@ def test_futures_warn_when_tested_for_equality end assert_output(nil, /deprecated/) do - @result == @result + @result == 1 end end @@ -179,7 +179,7 @@ def test_info_in_a_pipeline_returns_hash r.info end - assert result.first.kind_of?(Hash) + assert result.first.is_a?(Hash) end def test_config_get_in_a_pipeline_returns_hash @@ -187,7 +187,7 @@ def test_config_get_in_a_pipeline_returns_hash r.config(:get, "*") end - assert result.first.kind_of?(Hash) + assert result.first.is_a?(Hash) end def test_hgetall_in_a_pipeline_returns_hash diff --git a/test/publish_subscribe_test.rb b/test/publish_subscribe_test.rb index c725a1429..5f4fbbca3 100644 --- a/test/publish_subscribe_test.rb +++ b/test/publish_subscribe_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestPublishSubscribe < Minitest::Test - include Helper::Client class TestError < StandardError @@ -14,19 +14,19 @@ def test_subscribe_and_unsubscribe wire = Wire.new do r.subscribe("foo") do |on| - on.subscribe do |channel, total| + on.subscribe do |_channel, total| @subscribed = true @t1 = total end - on.message do |channel, message| + on.message do |_channel, message| if message == "s1" r.unsubscribe @message = message end end - on.unsubscribe do |channel, total| + on.unsubscribe do |_channel, total| @unsubscribed = true @t2 = total end @@ -34,7 +34,7 @@ def test_subscribe_and_unsubscribe end # Wait until the subscription is active before publishing - Wire.pass while !@subscribed + Wire.pass until @subscribed Redis.new(OPTIONS).publish("foo", "s1") @@ -53,19 +53,19 @@ def test_psubscribe_and_punsubscribe wire = Wire.new do r.psubscribe("f*") do |on| - on.psubscribe do |pattern, total| + on.psubscribe do |_pattern, total| @subscribed = true @t1 = total end - on.pmessage do |pattern, channel, message| + on.pmessage do |_pattern, _channel, message| if message == "s1" r.punsubscribe @message = message end end - on.punsubscribe do |pattern, total| + on.punsubscribe do |_pattern, total| @unsubscribed = true @t2 = total end @@ -73,7 +73,7 @@ def test_psubscribe_and_punsubscribe end # Wait until the subscription is active before publishing - Wire.pass while !@subscribed + Wire.pass until @subscribed Redis.new(OPTIONS).publish("foo", "s1") @@ -91,11 +91,11 @@ def test_pubsub_with_numpat_subcommand @subscribed = false wire = Wire.new do r.psubscribe("f*") do |on| - on.psubscribe { |channel, total| @subscribed = true } - on.pmessage { |pattern, channel, message| r.punsubscribe } + on.psubscribe { |_channel, _total| @subscribed = true } + on.pmessage { |_pattern, _channel, _message| r.punsubscribe } end end - Wire.pass while !@subscribed + Wire.pass until @subscribed redis = Redis.new(OPTIONS) numpat_result = redis.pubsub(:numpat) @@ -107,21 +107,20 @@ def test_pubsub_with_numpat_subcommand end end - def test_pubsub_with_channels_and_numsub_subcommnads target_version("2.8.0") do @subscribed = false wire = Wire.new do r.subscribe("foo") do |on| - on.subscribe { |channel, total| @subscribed = true } - on.message { |channel, message| r.unsubscribe } + on.subscribe { |_channel, _total| @subscribed = true } + on.message { |_channel, _message| r.unsubscribe } end end - Wire.pass while !@subscribed + Wire.pass until @subscribed redis = Redis.new(OPTIONS) channels_result = redis.pubsub(:channels) channels_result.delete('__sentinel__:hello') - numsub_result = redis.pubsub(:numsub, 'foo', 'boo') + numsub_result = redis.pubsub(:numsub, 'foo', 'boo') redis.publish("foo", "s1") wire.join @@ -137,11 +136,11 @@ def test_subscribe_connection_usable_after_raise wire = Wire.new do begin r.subscribe("foo") do |on| - on.subscribe do |channel, total| + on.subscribe do |_channel, _total| @subscribed = true end - on.message do |channel, message| + on.message do |_channel, _message| raise TestError end end @@ -150,7 +149,7 @@ def test_subscribe_connection_usable_after_raise end # Wait until the subscription is active before publishing - Wire.pass while !@subscribed + Wire.pass until @subscribed Redis.new(OPTIONS).publish("foo", "s1") @@ -165,11 +164,11 @@ def test_psubscribe_connection_usable_after_raise wire = Wire.new do begin r.psubscribe("f*") do |on| - on.psubscribe do |pattern, total| + on.psubscribe do |_pattern, _total| @subscribed = true end - on.pmessage do |pattern, channel, message| + on.pmessage do |_pattern, _channel, _message| raise TestError end end @@ -178,7 +177,7 @@ def test_psubscribe_connection_usable_after_raise end # Wait until the subscription is active before publishing - Wire.pass while !@subscribed + Wire.pass until @subscribed Redis.new(OPTIONS).publish("foo", "s1") @@ -192,7 +191,7 @@ def test_subscribe_within_subscribe wire = Wire.new do r.subscribe("foo") do |on| - on.subscribe do |channel, total| + on.subscribe do |channel, _total| @channels << channel r.subscribe("bar") if channel == "foo" @@ -209,7 +208,7 @@ def test_subscribe_within_subscribe def test_other_commands_within_a_subscribe assert_raises Redis::CommandError do r.subscribe("foo") do |on| - on.subscribe do |channel, total| + on.subscribe do |_channel, _total| r.set("bar", "s2") end end @@ -256,8 +255,8 @@ def test_subscribe_with_timeout received = false assert_raises Redis::TimeoutError do - r.subscribe_with_timeout(LOW_TIMEOUT, "foo") do |on| - on.message do |channel, message| + r.subscribe_with_timeout(LOW_TIMEOUT, "foo") do |on| + on.message do |_channel, _message| received = true end end @@ -270,8 +269,8 @@ def test_psubscribe_with_timeout received = false assert_raises Redis::TimeoutError do - r.psubscribe_with_timeout(LOW_TIMEOUT, "f*") do |on| - on.message do |channel, message| + r.psubscribe_with_timeout(LOW_TIMEOUT, "f*") do |on| + on.message do |_channel, _message| received = true end end diff --git a/test/remote_server_control_commands_test.rb b/test/remote_server_control_commands_test.rb index 0a9560203..646e83055 100644 --- a/test/remote_server_control_commands_test.rb +++ b/test/remote_server_control_commands_test.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true + require_relative "helper" class TestRemoteServerControlCommands < Minitest::Test - include Helper::Client def test_info keys = [ - "redis_version", - "uptime_in_seconds", - "uptime_in_days", - "connected_clients", - "used_memory", - "total_connections_received", - "total_commands_processed", + "redis_version", + "uptime_in_seconds", + "uptime_in_days", + "connected_clients", + "used_memory", + "total_connections_received", + "total_commands_processed" ] info = r.info @@ -52,7 +52,7 @@ def test_monitor_redis_lt_2_5_0 wire.join - assert log[-1][%q{(db 15) "set" "foo" "s1"}] + assert log[-1]['(db 15) "set" "foo" "s1"'] end def test_monitor_redis_gte_2_5_0 @@ -91,7 +91,7 @@ def test_echo def test_debug r.set "foo", "s1" - assert r.debug(:object, "foo").kind_of?(String) + assert r.debug(:object, "foo").is_a?(String) end def test_object @@ -99,12 +99,12 @@ def test_object assert_equal 1, r.object(:refcount, "list") encoding = r.object(:encoding, "list") - assert "ziplist" == encoding || "quicklist" == encoding, "Wrong encoding for list" - assert r.object(:idletime, "list").kind_of?(Integer) + assert encoding == "ziplist" || encoding == "quicklist", "Wrong encoding for list" + assert r.object(:idletime, "list").is_a?(Integer) end def test_sync - redis_mock(:sync => lambda { "+OK" }) do |redis| + redis_mock(sync: -> { "+OK" }) do |redis| assert_equal "OK", redis.sync end end @@ -123,23 +123,23 @@ def test_client_list return if version < "2.4.0" keys = [ - "addr", - "fd", - "name", - "age", - "idle", - "flags", - "db", - "sub", - "psub", - "multi", - "qbuf", - "qbuf-free", - "obl", - "oll", - "omem", - "events", - "cmd" + "addr", + "fd", + "name", + "age", + "idle", + "flags", + "db", + "sub", + "psub", + "multi", + "qbuf", + "qbuf-free", + "obl", + "oll", + "omem", + "events", + "cmd" ] clients = r.client(:list) @@ -156,11 +156,11 @@ def test_client_kill r.client(:setname, 'redis-rb') clients = r.client(:list) - i = clients.index {|client| client['name'] == 'redis-rb'} + i = clients.index { |client| client['name'] == 'redis-rb' } assert_equal "OK", r.client(:kill, clients[i]["addr"]) clients = r.client(:list) - i = clients.index {|client| client['name'] == 'redis-rb'} + i = clients.index { |client| client['name'] == 'redis-rb' } assert_nil i end diff --git a/test/scanning_test.rb b/test/scanning_test.rb index 20c968a41..e21d1bcf0 100644 --- a/test/scanning_test.rb +++ b/test/scanning_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestScanning < Minitest::Test - include Helper::Client def test_scan_basic @@ -10,12 +10,12 @@ def test_scan_basic r.debug :populate, 1000 cursor = 0 - all_keys = [] - loop { + all_keys = [] + loop do cursor, keys = r.scan cursor all_keys += keys break if cursor == "0" - } + end assert_equal 1000, all_keys.uniq.size end @@ -26,12 +26,12 @@ def test_scan_count r.debug :populate, 1000 cursor = 0 - all_keys = [] - loop { - cursor, keys = r.scan cursor, :count => 5 + all_keys = [] + loop do + cursor, keys = r.scan cursor, count: 5 all_keys += keys break if cursor == "0" - } + end assert_equal 1000, all_keys.uniq.size end @@ -42,12 +42,12 @@ def test_scan_match r.debug :populate, 1000 cursor = 0 - all_keys = [] - loop { - cursor, keys = r.scan cursor, :match => "key:1??" + all_keys = [] + loop do + cursor, keys = r.scan cursor, match: "key:1??" all_keys += keys break if cursor == "0" - } + end assert_equal 100, all_keys.uniq.size end @@ -55,7 +55,6 @@ def test_scan_match def test_scan_each_enumerator target_version "2.7.105" do - r.debug :populate, 1000 scan_enumerator = r.scan_each @@ -70,10 +69,9 @@ def test_scan_each_enumerator def test_scan_each_enumerator_match target_version "2.7.105" do - r.debug :populate, 1000 - keys_from_scan = r.scan_each(:match => "key:1??").to_a.uniq + keys_from_scan = r.scan_each(match: "key:1??").to_a.uniq all_keys = r.keys "key:1??" assert all_keys.sort == keys_from_scan.sort @@ -82,13 +80,12 @@ def test_scan_each_enumerator_match def test_scan_each_block target_version "2.7.105" do - r.debug :populate, 100 - keys_from_scan = [] - r.scan_each {|key| + keys_from_scan = [] + r.scan_each do |key| keys_from_scan << key - } + end all_keys = r.keys "*" @@ -98,13 +95,12 @@ def test_scan_each_block def test_scan_each_block_match target_version "2.7.105" do - r.debug :populate, 100 - keys_from_scan = [] - r.scan_each(:match => "key:1?") {|key| + keys_from_scan = [] + r.scan_each(match: "key:1?") do |key| keys_from_scan << key - } + end all_keys = r.keys "key:1?" @@ -114,7 +110,7 @@ def test_scan_each_block_match def test_sscan_with_encoding target_version "2.7.105" do - [:intset, :hashtable].each do |enc| + %i[intset hashtable].each do |enc| r.del "set" prefix = "" @@ -128,12 +124,12 @@ def test_sscan_with_encoding assert_equal enc.to_s, r.object("encoding", "set") cursor = 0 - all_keys = [] - loop { + all_keys = [] + loop do cursor, keys = r.sscan "set", cursor all_keys += keys break if cursor == "0" - } + end assert_equal 100, all_keys.uniq.size end @@ -162,7 +158,7 @@ def test_sscan_each_enumerator_match 100.times { |j| elements << "ele:#{j}" } r.sadd "set", elements - keys_from_scan = r.sscan_each("set", :match => "ele:1?").to_a.uniq + keys_from_scan = r.sscan_each("set", match: "ele:1?").to_a.uniq all_keys = r.smembers("set").grep(/^ele:1.$/) @@ -194,7 +190,7 @@ def test_sscan_each_enumerator_block_match r.sadd "set", elements keys_from_scan = [] - r.sscan_each("set", :match => "ele:1?") do |key| + r.sscan_each("set", match: "ele:1?") do |key| keys_from_scan << key end @@ -206,7 +202,7 @@ def test_sscan_each_enumerator_block_match def test_hscan_with_encoding target_version "2.7.105" do - [:ziplist, :hashtable].each do |enc| + %i[ziplist hashtable].each do |enc| r.del "set" count = 1000 @@ -220,12 +216,12 @@ def test_hscan_with_encoding assert_equal enc.to_s, r.object("encoding", "hash") cursor = 0 - all_key_values = [] - loop { + all_key_values = [] + loop do cursor, key_values = r.hscan "hash", cursor all_key_values.concat key_values break if cursor == "0" - } + end keys2 = [] all_key_values.each do |k, v| @@ -262,8 +258,8 @@ def test_hscan_each_enumerator_match count.times { |j| elements << "key:#{j}" << j.to_s } r.hmset "hash", *elements - keys_from_scan = r.hscan_each("hash", :match => "key:1?").to_a.uniq - all_keys = r.hgetall("hash").to_a.select{|k,v| k =~ /^key:1.$/} + keys_from_scan = r.hscan_each("hash", match: "key:1?").to_a.uniq + all_keys = r.hgetall("hash").to_a.select { |k, _v| k =~ /^key:1.$/ } assert all_keys.sort == keys_from_scan.sort end @@ -294,10 +290,10 @@ def test_hscan_each_block_match r.hmset "hash", *elements keys_from_scan = [] - r.hscan_each("hash", :match => "key:1?") do |field, value| + r.hscan_each("hash", match: "key:1?") do |field, value| keys_from_scan << [field, value] end - all_keys = r.hgetall("hash").to_a.select{|k,v| k =~ /^key:1.$/} + all_keys = r.hgetall("hash").to_a.select { |k, _v| k =~ /^key:1.$/ } assert all_keys.sort == keys_from_scan.uniq.sort end @@ -305,7 +301,7 @@ def test_hscan_each_block_match def test_zscan_with_encoding target_version "2.7.105" do - [:ziplist, :skiplist].each do |enc| + %i[ziplist skiplist].each do |enc| r.del "zset" count = 1000 @@ -319,12 +315,12 @@ def test_zscan_with_encoding assert_equal enc.to_s, r.object("encoding", "zset") cursor = 0 - all_key_scores = [] - loop { + all_key_scores = [] + loop do cursor, key_scores = r.zscan "zset", cursor - all_key_scores.concat key_scores + all_key_scores.concat key_scores break if cursor == "0" - } + end keys2 = [] all_key_scores.each do |k, v| @@ -349,7 +345,7 @@ def test_zscan_each_enumerator assert_equal true, scan_enumerator.is_a?(::Enumerator) scores_from_scan = scan_enumerator.to_a.uniq - member_scores = r.zrange("zset", 0, -1, :with_scores => true) + member_scores = r.zrange("zset", 0, -1, with_scores: true) assert member_scores.sort == scores_from_scan.sort end @@ -362,9 +358,9 @@ def test_zscan_each_enumerator_match count.times { |j| elements << j << "key:#{j}" } r.zadd "zset", elements - scores_from_scan = r.zscan_each("zset", :match => "key:1??").to_a.uniq - member_scores = r.zrange("zset", 0, -1, :with_scores => true) - filtered_members = member_scores.select{|k,s| k =~ /^key:1..$/} + scores_from_scan = r.zscan_each("zset", match: "key:1??").to_a.uniq + member_scores = r.zrange("zset", 0, -1, with_scores: true) + filtered_members = member_scores.select { |k, _s| k =~ /^key:1..$/ } assert filtered_members.sort == scores_from_scan.sort end @@ -381,7 +377,7 @@ def test_zscan_each_block r.zscan_each("zset") do |member, score| scores_from_scan << [member, score] end - member_scores = r.zrange("zset", 0, -1, :with_scores => true) + member_scores = r.zrange("zset", 0, -1, with_scores: true) assert member_scores.sort == scores_from_scan.sort end @@ -395,14 +391,13 @@ def test_zscan_each_block_match r.zadd "zset", elements scores_from_scan = [] - r.zscan_each("zset", :match => "key:1??") do |member, score| + r.zscan_each("zset", match: "key:1??") do |member, score| scores_from_scan << [member, score] end - member_scores = r.zrange("zset", 0, -1, :with_scores => true) - filtered_members = member_scores.select{|k,s| k =~ /^key:1..$/} + member_scores = r.zrange("zset", 0, -1, with_scores: true) + filtered_members = member_scores.select { |k, _s| k =~ /^key:1..$/ } assert filtered_members.sort == scores_from_scan.sort end end - end diff --git a/test/scripting_test.rb b/test/scripting_test.rb index d99394f6d..efd9afe03 100644 --- a/test/scripting_test.rb +++ b/test/scripting_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestScripting < Minitest::Test - include Helper::Client def to_sha(script) @@ -33,7 +33,7 @@ def test_script_flush def test_script_kill target_version "2.5.9" do # 2.6-rc1 - redis_mock(:script => lambda { |arg| "+#{arg.upcase}" }) do |redis| + redis_mock(script: ->(arg) { "+#{arg.upcase}" }) do |redis| assert_equal "KILL", redis.script(:kill) end end @@ -52,8 +52,8 @@ def test_eval_with_options_hash target_version "2.5.9" do # 2.6-rc1 assert_equal 0, r.eval("return #KEYS", {}) assert_equal 0, r.eval("return #ARGV", {}) - assert_equal ["k1", "k2"], r.eval("return KEYS", { :keys => ["k1", "k2"] }) - assert_equal ["a1", "a2"], r.eval("return ARGV", { :argv => ["a1", "a2"] }) + assert_equal ["k1", "k2"], r.eval("return KEYS", { keys: ["k1", "k2"] }) + assert_equal ["a1", "a2"], r.eval("return ARGV", { argv: ["a1", "a2"] }) end end @@ -70,8 +70,8 @@ def test_evalsha_with_options_hash target_version "2.5.9" do # 2.6-rc1 assert_equal 0, r.evalsha(to_sha("return #KEYS"), {}) assert_equal 0, r.evalsha(to_sha("return #ARGV"), {}) - assert_equal ["k1", "k2"], r.evalsha(to_sha("return KEYS"), { :keys => ["k1", "k2"] }) - assert_equal ["a1", "a2"], r.evalsha(to_sha("return ARGV"), { :argv => ["a1", "a2"] }) + assert_equal ["k1", "k2"], r.evalsha(to_sha("return KEYS"), { keys: ["k1", "k2"] }) + assert_equal ["a1", "a2"], r.evalsha(to_sha("return ARGV"), { argv: ["a1", "a2"] }) end end end diff --git a/test/sentinel_test.rb b/test/sentinel_test.rb index 26830b19b..2af3f3934 100644 --- a/test/sentinel_test.rb +++ b/test/sentinel_test.rb @@ -51,23 +51,23 @@ def test_the_client_raises_error_when_there_is_no_available_slaves end def test_sentinel_failover - sentinels = [{:host => "127.0.0.1", :port => 26381}, - {:host => "127.0.0.1", :port => 26382}] + sentinels = [{ host: "127.0.0.1", port: 26_381 }, + { host: "127.0.0.1", port: 26_382 }] commands = { - :s1 => [], - :s2 => [], + s1: [], + s2: [] } s1 = { - :sentinel => lambda do |command, *args| + sentinel: lambda do |command, *args| commands[:s1] << [command, *args] "$-1" # Nil end } s2 = { - :sentinel => lambda do |command, *args| + sentinel: lambda do |command, *args| commands[:s2] << [command, *args] ["127.0.0.1", "6381"] end @@ -77,7 +77,7 @@ def test_sentinel_failover RedisMock.start(s2) do |s2_port| sentinels[0][:port] = s1_port sentinels[1][:port] = s2_port - redis = Redis.new(:url => "redis://master1", :sentinels => sentinels, :role => :master) + redis = Redis.new(url: "redis://master1", sentinels: sentinels, role: :master) assert redis.ping end @@ -88,23 +88,23 @@ def test_sentinel_failover end def test_sentinel_failover_prioritize_healthy_sentinel - sentinels = [{:host => "127.0.0.1", :port => 26381}, - {:host => "127.0.0.1", :port => 26382}] + sentinels = [{ host: "127.0.0.1", port: 26_381 }, + { host: "127.0.0.1", port: 26_382 }] commands = { - :s1 => [], - :s2 => [], + s1: [], + s2: [] } s1 = { - :sentinel => lambda do |command, *args| + sentinel: lambda do |command, *args| commands[:s1] << [command, *args] "$-1" # Nil end } s2 = { - :sentinel => lambda do |command, *args| + sentinel: lambda do |command, *args| commands[:s2] << [command, *args] ["127.0.0.1", "6381"] end @@ -114,7 +114,7 @@ def test_sentinel_failover_prioritize_healthy_sentinel RedisMock.start(s2) do |s2_port| sentinels[0][:port] = s1_port sentinels[1][:port] = s2_port - redis = Redis.new(:url => "redis://master1", :sentinels => sentinels, :role => :master) + redis = Redis.new(url: "redis://master1", sentinels: sentinels, role: :master) assert redis.ping @@ -258,18 +258,18 @@ def test_authentication_for_sentinel_and_redis end def test_sentinel_role_mismatch - sentinels = [{:host => "127.0.0.1", :port => 26381}] + sentinels = [{ host: "127.0.0.1", port: 26_381 }] sentinel = lambda do |port| { - :sentinel => lambda do |command, *args| + sentinel: lambda do |_command, *_args| ["127.0.0.1", port.to_s] end } end master = { - :role => lambda do + role: lambda do ["slave"] end } @@ -278,7 +278,7 @@ def test_sentinel_role_mismatch RedisMock.start(master) do |master_port| RedisMock.start(sentinel.call(master_port)) do |sen_port| sentinels[0][:port] = sen_port - redis = Redis.new(:url => "redis://master1", :sentinels => sentinels, :role => :master) + redis = Redis.new(url: "redis://master1", sentinels: sentinels, role: :master) assert redis.ping end @@ -289,14 +289,14 @@ def test_sentinel_role_mismatch end def test_sentinel_retries - sentinels = [{:host => "127.0.0.1", :port => 26381}, - {:host => "127.0.0.1", :port => 26382}] + sentinels = [{ host: "127.0.0.1", port: 26_381 }, + { host: "127.0.0.1", port: 26_382 }] connections = [] handler = lambda do |id, port| { - :sentinel => lambda do |command, *args| + sentinel: lambda do |_command, *_args| connections << id if connections.count(id) < 2 @@ -309,7 +309,7 @@ def test_sentinel_retries end master = { - :role => lambda do + role: lambda do ["master"] end } @@ -319,14 +319,14 @@ def test_sentinel_retries RedisMock.start(handler.call(:s2, master_port)) do |s2_port| sentinels[0][:port] = s1_port sentinels[1][:port] = s2_port - redis = Redis.new(:url => "redis://master1", :sentinels => sentinels, :role => :master, :reconnect_attempts => 1) + redis = Redis.new(url: "redis://master1", sentinels: sentinels, role: :master, reconnect_attempts: 1) assert redis.ping end end end - assert_equal [:s1, :s2, :s1], connections + assert_equal %i[s1 s2 s1], connections connections.clear @@ -336,7 +336,7 @@ def test_sentinel_retries RedisMock.start(handler.call(:s2, master_port)) do |s2_port| sentinels[0][:port] = s1_port + 1 sentinels[1][:port] = s2_port + 2 - redis = Redis.new(:url => "redis://master1", :sentinels => sentinels, :role => :master, :reconnect_attempts => 0) + redis = Redis.new(url: "redis://master1", sentinels: sentinels, role: :master, reconnect_attempts: 0) assert redis.ping end diff --git a/test/sorting_test.rb b/test/sorting_test.rb index d21871a39..bd0fe4bd0 100644 --- a/test/sorting_test.rb +++ b/test/sorting_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestSorting < Minitest::Test - include Helper::Client def test_sort @@ -12,8 +12,8 @@ def test_sort r.rpush("bar", "1") r.rpush("bar", "2") - assert_equal ["s1"], r.sort("bar", :get => "foo:*", :limit => [0, 1]) - assert_equal ["s2"], r.sort("bar", :get => "foo:*", :limit => [0, 1], :order => "desc alpha") + assert_equal ["s1"], r.sort("bar", get: "foo:*", limit: [0, 1]) + assert_equal ["s2"], r.sort("bar", get: "foo:*", limit: [0, 1], order: "desc alpha") end def test_sort_with_an_array_of_gets @@ -26,9 +26,9 @@ def test_sort_with_an_array_of_gets r.rpush("bar", "1") r.rpush("bar", "2") - assert_equal [["s1a", "s1b"]], r.sort("bar", :get => ["foo:*:a", "foo:*:b"], :limit => [0, 1]) - assert_equal [["s2a", "s2b"]], r.sort("bar", :get => ["foo:*:a", "foo:*:b"], :limit => [0, 1], :order => "desc alpha") - assert_equal [["s1a", "s1b"], ["s2a", "s2b"]], r.sort("bar", :get => ["foo:*:a", "foo:*:b"]) + assert_equal [["s1a", "s1b"]], r.sort("bar", get: ["foo:*:a", "foo:*:b"], limit: [0, 1]) + assert_equal [["s2a", "s2b"]], r.sort("bar", get: ["foo:*:a", "foo:*:b"], limit: [0, 1], order: "desc alpha") + assert_equal [["s1a", "s1b"], ["s2a", "s2b"]], r.sort("bar", get: ["foo:*:a", "foo:*:b"]) end def test_sort_with_store @@ -38,7 +38,7 @@ def test_sort_with_store r.rpush("bar", "1") r.rpush("bar", "2") - r.sort("bar", :get => "foo:*", :store => "baz") + r.sort("bar", get: "foo:*", store: "baz") assert_equal ["s1", "s2"], r.lrange("baz", 0, -1) end @@ -52,7 +52,7 @@ def test_sort_with_an_array_of_gets_and_with_store r.rpush("bar", "1") r.rpush("bar", "2") - r.sort("bar", :get => ["foo:*:a", "foo:*:b"], :store => 'baz') + r.sort("bar", get: ["foo:*:a", "foo:*:b"], store: 'baz') assert_equal ["s1a", "s1b", "s2a", "s2b"], r.lrange("baz", 0, -1) end end diff --git a/test/ssl_test.rb b/test/ssl_test.rb index 42f790985..7f4688163 100644 --- a/test/ssl_test.rb +++ b/test/ssl_test.rb @@ -1,12 +1,11 @@ # frozen_string_literal: true + require_relative "helper" class SslTest < Minitest::Test - include Helper::Client driver(:ruby) do - def test_connection_to_non_ssl_server assert_raises(Redis::CannotConnectError) do redis = Redis.new(OPTIONS.merge(ssl: true, timeout: LOW_TIMEOUT)) @@ -15,16 +14,16 @@ def test_connection_to_non_ssl_server end def test_verified_ssl_connection - RedisMock.start({ :ping => proc { "+PONG" } }, ssl_server_opts("trusted")) do |port| - redis = Redis.new(:port => port, :ssl => true, :ssl_params => { :ca_file => ssl_ca_file }) + RedisMock.start({ ping: proc { "+PONG" } }, ssl_server_opts("trusted")) do |port| + redis = Redis.new(port: port, ssl: true, ssl_params: { ca_file: ssl_ca_file }) assert_equal redis.ping, "PONG" end end def test_unverified_ssl_connection assert_raises(OpenSSL::SSL::SSLError) do - RedisMock.start({ :ping => proc { "+PONG" } }, ssl_server_opts("untrusted")) do |port| - redis = Redis.new(:port => port, :ssl => true, :ssl_params => { :ca_file => ssl_ca_file }) + RedisMock.start({ ping: proc { "+PONG" } }, ssl_server_opts("untrusted")) do |port| + redis = Redis.new(port: port, ssl: true, ssl_params: { ca_file: ssl_ca_file }) redis.ping end end @@ -32,8 +31,8 @@ def test_unverified_ssl_connection def test_verify_certificates_by_default assert_raises(OpenSSL::SSL::SSLError) do - RedisMock.start({ :ping => proc { "+PONG" } }, ssl_server_opts("untrusted")) do |port| - redis = Redis.new(:port => port, :ssl => true) + RedisMock.start({ ping: proc { "+PONG" } }, ssl_server_opts("untrusted")) do |port| + redis = Redis.new(port: port, ssl: true) redis.ping end end @@ -41,24 +40,21 @@ def test_verify_certificates_by_default def test_ssl_blocking RedisMock.start({}, ssl_server_opts("trusted")) do |port| - redis = Redis.new(:port => port, :ssl => true, :ssl_params => { :ca_file => ssl_ca_file }) + redis = Redis.new(port: port, ssl: true, ssl_params: { ca_file: ssl_ca_file }) assert_equal redis.set("boom", "a" * 10_000_000), "OK" end end - end driver(:hiredis, :synchrony) do - def test_ssl_not_implemented_exception assert_raises(NotImplementedError) do - RedisMock.start({ :ping => proc { "+PONG" } }, ssl_server_opts("trusted")) do |port| - redis = Redis.new(:port => port, :ssl => true, :ssl_params => { :ca_file => ssl_ca_file }) + RedisMock.start({ ping: proc { "+PONG" } }, ssl_server_opts("trusted")) do |port| + redis = Redis.new(port: port, ssl: true, ssl_params: { ca_file: ssl_ca_file }) redis.ping end end end - end private @@ -68,10 +64,10 @@ def ssl_server_opts(prefix) ssl_key = File.join(cert_path, "#{prefix}-cert.key") { - :ssl => true, - :ssl_params => { - :cert => OpenSSL::X509::Certificate.new(File.read(ssl_cert)), - :key => OpenSSL::PKey::RSA.new(File.read(ssl_key)) + ssl: true, + ssl_params: { + cert: OpenSSL::X509::Certificate.new(File.read(ssl_cert)), + key: OpenSSL::PKey::RSA.new(File.read(ssl_key)) } } end @@ -81,6 +77,6 @@ def ssl_ca_file end def cert_path - File.expand_path("../support/ssl/", __FILE__) + File.expand_path('support/ssl', __dir__) end end diff --git a/test/support/cluster/orchestrator.rb b/test/support/cluster/orchestrator.rb index ff1d6ef9e..75dda2ec0 100644 --- a/test/support/cluster/orchestrator.rb +++ b/test/support/cluster/orchestrator.rb @@ -3,10 +3,11 @@ require_relative '../../../lib/redis' class ClusterOrchestrator - SLOT_SIZE = 16384 + SLOT_SIZE = 16_384 def initialize(node_addrs, timeout: 30.0) raise 'Redis Cluster requires at least 3 master nodes.' if node_addrs.size < 3 + @clients = node_addrs.map do |addr| Redis.new(url: addr, timeout: timeout, @@ -47,6 +48,7 @@ def fail_serving_master max_attempts = 500 attempt_count.step(max_attempts) do |i| return if slave.role == 'master' || i >= max_attempts + attempt_count += 1 sleep 0.1 end @@ -75,13 +77,16 @@ def start_resharding(slot, src_node_key, dest_node_key, slice_size: 10) keys_count = src_client.cluster(:countkeysinslot, slot) loop do break if keys_count <= 0 + keys = src_client.cluster(:getkeysinslot, slot, slice_size) break if keys.empty? + keys.each do |k| begin src_client.migrate(k, host: dest_host, port: dest_port) rescue Redis::CommandError => err raise unless err.message.start_with?('IOERR') + src_client.migrate(k, host: dest_host, port: dest_port, replace: true) # retry once ensure keys_count -= 1 @@ -150,6 +155,7 @@ def meet_each_other(clients) clients.each do |client| next if first_client.id == client.id + client.cluster(:meet, target_host, target_port) end end @@ -245,8 +251,10 @@ def wait_for_state(clients, max_attempts) clients.each do |client| attempt_count.step(max_attempts) do |i| break if i >= max_attempts + attempt_count += 1 break if yield(client) + sleep 0.1 end end @@ -275,12 +283,14 @@ def hashify_node_map(client) def take_masters(clients) size = clients.size / 2 return clients if size < 3 + clients.take(size) end def take_slaves(clients) size = clients.size / 2 return [] if size < 3 + clients[size..size * 2] end diff --git a/test/support/connection/hiredis.rb b/test/support/connection/hiredis.rb index 03930dd31..2545fa7ba 100644 --- a/test/support/connection/hiredis.rb +++ b/test/support/connection/hiredis.rb @@ -1,2 +1,3 @@ # frozen_string_literal: true + require_relative "../wire/thread" diff --git a/test/support/connection/ruby.rb b/test/support/connection/ruby.rb index 03930dd31..2545fa7ba 100644 --- a/test/support/connection/ruby.rb +++ b/test/support/connection/ruby.rb @@ -1,2 +1,3 @@ # frozen_string_literal: true + require_relative "../wire/thread" diff --git a/test/support/connection/synchrony.rb b/test/support/connection/synchrony.rb index 509674f47..9228b499e 100644 --- a/test/support/connection/synchrony.rb +++ b/test/support/connection/synchrony.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative "../wire/synchrony" module Helper diff --git a/test/support/redis_mock.rb b/test/support/redis_mock.rb index b6335f8a2..2542a3093 100644 --- a/test/support/redis_mock.rb +++ b/test/support/redis_mock.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true + require "socket" module RedisMock class Server - def initialize(options = {}, &block) + def initialize(options = {}) tcp_server = TCPServer.new(options[:host] || "127.0.0.1", 0) tcp_server.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true) @@ -32,23 +33,21 @@ def shutdown end def run - begin - loop do - session = @server.accept - - begin - return if yield(session) == :exit - ensure - session.close - end + loop do + session = @server.accept + + begin + return if yield(session) == :exit + ensure + session.close end - rescue => ex - $stderr.puts "Error running mock server: #{ex.class}: #{ex.message}" - $stderr.puts ex.backtrace - retry - ensure - @server.close end + rescue => ex + warn "Error running mock server: #{ex.class}: #{ex.message}" + warn ex.backtrace + retry + ensure + @server.close end end @@ -95,7 +94,7 @@ def self.start(commands, options = {}, &blk) command = argv.shift blk = commands[command.to_sym] - blk ||= lambda { |*_| "+OK" } + blk ||= ->(*_) { "+OK" } response = blk.call(*argv) diff --git a/test/support/wire/synchrony.rb b/test/support/wire/synchrony.rb index db541d832..b147aae13 100644 --- a/test/support/wire/synchrony.rb +++ b/test/support/wire/synchrony.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + class Wire < Fiber # We cannot run this fiber explicitly because EM schedules it. Resuming the # current fiber on the next tick to let the reactor do work. diff --git a/test/support/wire/thread.rb b/test/support/wire/thread.rb index e0c7e68fb..d91a8f67e 100644 --- a/test/support/wire/thread.rb +++ b/test/support/wire/thread.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + class Wire < Thread def self.sleep(sec) Kernel.sleep(sec) diff --git a/test/synchrony_driver.rb b/test/synchrony_driver.rb index 7c37b6fa8..b80de1241 100644 --- a/test/synchrony_driver.rb +++ b/test/synchrony_driver.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "em-synchrony" require "em-synchrony/connection_pool" @@ -8,7 +9,7 @@ require_relative "helper" PORT = 6381 -OPTIONS = {:port => PORT, :db => 15} +OPTIONS = { port: PORT, db: 15 }.freeze # # if running under Eventmachine + Synchrony (Ruby 1.9+), then @@ -56,7 +57,6 @@ assert_equal "OK", r._client.call(:quit) assert_equal "PONG", r.ping - rpool = EM::Synchrony::ConnectionPool.new(size: 5) { Redis.new OPTIONS } result = rpool.watch 'foo' do |rd| diff --git a/test/thread_safety_test.rb b/test/thread_safety_test.rb index ac71e4865..f5f358962 100644 --- a/test/thread_safety_test.rb +++ b/test/thread_safety_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestThreadSafety < Minitest::Test - include Helper::Client driver(:ruby, :hiredis) do @@ -14,18 +14,18 @@ def test_thread_safety sample = 100 t1 = Thread.new do - $foos = Array.new(sample) { redis.get "foo" } + @foos = Array.new(sample) { redis.get "foo" } end t2 = Thread.new do - $bars = Array.new(sample) { redis.get "bar" } + @bars = Array.new(sample) { redis.get "bar" } end t1.join t2.join - assert_equal ["1"], $foos.uniq - assert_equal ["2"], $bars.uniq + assert_equal ["1"], @foos.uniq + assert_equal ["2"], @bars.uniq end def test_thread_safety_queue_commit @@ -40,7 +40,7 @@ def test_thread_safety_queue_commit r.queue("get", "foo") end - $foos = r.commit + @foos = r.commit end t2 = Thread.new do @@ -48,14 +48,14 @@ def test_thread_safety_queue_commit r.queue("get", "bar") end - $bars = r.commit + @bars = r.commit end t1.join t2.join - assert_equal ["1"], $foos.uniq - assert_equal ["2"], $bars.uniq + assert_equal ["1"], @foos.uniq + assert_equal ["2"], @bars.uniq end end end diff --git a/test/transactions_test.rb b/test/transactions_test.rb index ce700f879..264e1f364 100644 --- a/test/transactions_test.rb +++ b/test/transactions_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestTransactions < Minitest::Test - include Helper::Client def test_multi_discard @@ -79,7 +79,6 @@ def test_raise_immediate_errors_in_multi_exec r.multi do |multi| multi.set "bar", "s2" raise "Some error" - multi.set "baz", "s3" end end @@ -88,19 +87,19 @@ def test_raise_immediate_errors_in_multi_exec end def test_transformed_replies_as_return_values_for_multi_exec_block - info, _ = r.multi do |m| + info, = r.multi do |_m| r.info end - assert info.kind_of?(Hash) + assert info.is_a?(Hash) end def test_transformed_replies_inside_multi_exec_block - r.multi do |m| + r.multi do |_m| @info = r.info end - assert @info.value.kind_of?(Hash) + assert @info.value.is_a?(Hash) end def test_raise_command_errors_when_reply_is_not_transformed @@ -118,7 +117,7 @@ def test_raise_command_errors_when_reply_is_not_transformed def test_empty_multi_exec result = nil - redis_mock(:exec => lambda { |*_| "-ERROR" }) do |redis| + redis_mock(exec: ->(*_) { "-ERROR" }) do |redis| result = redis.multi {} end @@ -154,7 +153,7 @@ def test_raise_command_errors_when_reply_is_transformed_to_float def test_raise_command_errors_when_reply_is_transformed_to_floats assert_raises(Redis::CommandError) do r.multi do |m| - m.zrange("a", "b", 5, :with_scores => true) + m.zrange("a", "b", 5, with_scores: true) end end end @@ -186,7 +185,7 @@ def test_raise_command_errors_when_accessing_futures_after_multi_exec rescue => err end - assert err.kind_of?(RuntimeError) + assert err.is_a?(RuntimeError) end def test_multi_with_a_block_yielding_the_client @@ -198,7 +197,7 @@ def test_multi_with_a_block_yielding_the_client end def test_raise_command_error_when_exec_fails - redis_mock(:exec => lambda { |*_| "-ERROR" }) do |redis| + redis_mock(exec: ->(*_) { "-ERROR" }) do |redis| assert_raises(Redis::CommandError) do redis.multi do |m| m.set "foo", "s1" @@ -255,7 +254,6 @@ def test_watch_with_a_modified_key_passed_as_array def test_watch_with_a_block_and_an_unmodified_key result = r.watch "foo" do |rd| - assert_same r, rd rd.multi do |multi| @@ -269,7 +267,6 @@ def test_watch_with_a_block_and_an_unmodified_key def test_watch_with_a_block_and_a_modified_key result = r.watch "foo" do |rd| - assert_same r, rd rd.set "foo", "s1" diff --git a/test/unknown_commands_test.rb b/test/unknown_commands_test.rb index 0d94b8c95..40aaac4ca 100644 --- a/test/unknown_commands_test.rb +++ b/test/unknown_commands_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestUnknownCommands < Minitest::Test - include Helper::Client def test_should_try_to_work diff --git a/test/url_param_test.rb b/test/url_param_test.rb index 324597636..17ff95482 100644 --- a/test/url_param_test.rb +++ b/test/url_param_test.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true + require_relative "helper" class TestUrlParam < Minitest::Test - include Helper::Client def test_url_defaults_to_______________ @@ -15,7 +15,7 @@ def test_url_defaults_to_______________ end def test_allows_to_pass_in_a_url - redis = Redis.new :url => "redis://:secr3t@foo.com:999/2" + redis = Redis.new url: "redis://:secr3t@foo.com:999/2" assert_equal "foo.com", redis._client.host assert_equal 999, redis._client.port @@ -33,7 +33,7 @@ def test_allows_to_pass_in_a_url_with_string_key end def test_unescape_password_from_url - redis = Redis.new :url => "redis://:secr3t%3A@foo.com:999/2" + redis = Redis.new url: "redis://:secr3t%3A@foo.com:999/2" assert_equal "secr3t:", redis._client.password end @@ -45,7 +45,7 @@ def test_unescape_password_from_url_with_string_key end def test_does_not_unescape_password_when_explicitly_passed - redis = Redis.new :url => "redis://:secr3t%3A@foo.com:999/2", :password => "secr3t%3A" + redis = Redis.new url: "redis://:secr3t%3A@foo.com:999/2", password: "secr3t%3A" assert_equal "secr3t%3A", redis._client.password end @@ -57,7 +57,7 @@ def test_does_not_unescape_password_when_explicitly_passed_with_string_key end def test_override_url_if_path_option_is_passed - redis = Redis.new :url => "redis://:secr3t@foo.com/foo:999/2", :path => "/tmp/redis.sock" + redis = Redis.new url: "redis://:secr3t@foo.com/foo:999/2", path: "/tmp/redis.sock" assert_equal "/tmp/redis.sock", redis._client.path assert_nil redis._client.host @@ -73,7 +73,7 @@ def test_override_url_if_path_option_is_passed_with_string_key end def test_overrides_url_if_another_connection_option_is_passed - redis = Redis.new :url => "redis://:secr3t@foo.com:999/2", :port => 1000 + redis = Redis.new url: "redis://:secr3t@foo.com:999/2", port: 1000 assert_equal "foo.com", redis._client.host assert_equal 1000, redis._client.port @@ -91,7 +91,7 @@ def test_overrides_url_if_another_connection_option_is_passed_with_string_key end def test_does_not_overrides_url_if_a_nil_option_is_passed - redis = Redis.new :url => "redis://:secr3t@foo.com:999/2", :port => nil + redis = Redis.new url: "redis://:secr3t@foo.com:999/2", port: nil assert_equal "foo.com", redis._client.host assert_equal 999, redis._client.port @@ -109,11 +109,11 @@ def test_does_not_overrides_url_if_a_nil_option_is_passed_with_string_key end def test_does_not_modify_the_passed_options - options = { :url => "redis://:secr3t@foo.com:999/2" } + options = { url: "redis://:secr3t@foo.com:999/2" } Redis.new(options) - assert({ :url => "redis://:secr3t@foo.com:999/2" } == options) + assert(options == { url: "redis://:secr3t@foo.com:999/2" }) end def test_uses_redis_url_over_default_if_available @@ -130,7 +130,7 @@ def test_uses_redis_url_over_default_if_available end def test_defaults_to_localhost - redis = Redis.new(:url => "redis:///") + redis = Redis.new(url: "redis:///") assert_equal "127.0.0.1", redis._client.host end