diff --git a/.travis.yml b/.travis.yml index e04473f6c..aa82ac9da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,13 @@ language: ruby +script: make test + rvm: - - 1.8.7 - - 1.9.3 - - 2.0 - - 2.1 - - 2.2 - - 2.3.0 + - 2.2.2 + - 2.3.3 - 2.4.1 - - jruby-18mode - - jruby-19mode - - jruby-9.0.5.0 - - rbx-2 + - jruby-9 + - rbx-3 gemfile: ".travis/Gemfile" @@ -25,13 +21,13 @@ env: - VERBOSE=true - TIMEOUT=1 matrix: - - conn=ruby REDIS_BRANCH=3.0 - - conn=ruby REDIS_BRANCH=3.2 - - conn=hiredis REDIS_BRANCH=3.0 - - conn=hiredis REDIS_BRANCH=3.2 - - conn=synchrony REDIS_BRANCH=3.0 - - conn=synchrony REDIS_BRANCH=3.2 - - conn=ruby REDIS_BRANCH=unstable + - DRIVER=ruby REDIS_BRANCH=3.0 + - DRIVER=ruby REDIS_BRANCH=3.2 + - DRIVER=hiredis REDIS_BRANCH=3.0 + - DRIVER=hiredis REDIS_BRANCH=3.2 + - DRIVER=synchrony REDIS_BRANCH=3.0 + - DRIVER=synchrony REDIS_BRANCH=3.2 + - DRIVER=ruby REDIS_BRANCH=unstable branches: only: @@ -42,52 +38,34 @@ branches: matrix: exclude: # hiredis - - rvm: jruby-18mode - gemfile: .travis/Gemfile - env: conn=hiredis REDIS_BRANCH=3.0 - - rvm: jruby-18mode + - rvm: jruby-9 gemfile: .travis/Gemfile - env: conn=hiredis REDIS_BRANCH=3.2 - - rvm: jruby-19mode + env: DRIVER=hiredis REDIS_BRANCH=3.0 + - rvm: jruby-9 gemfile: .travis/Gemfile - env: conn=hiredis REDIS_BRANCH=3.0 - - rvm: jruby-19mode + env: DRIVER=hiredis REDIS_BRANCH=3.2 + - rvm: jruby-9 gemfile: .travis/Gemfile - env: conn=hiredis REDIS_BRANCH=3.2 - - rvm: jruby-9.0.5.0 + env: DRIVER=hiredis REDIS_BRANCH=3.0 + - rvm: jruby-9 gemfile: .travis/Gemfile - env: conn=hiredis REDIS_BRANCH=3.0 - - rvm: jruby-9.0.5.0 - gemfile: .travis/Gemfile - env: conn=hiredis REDIS_BRANCH=3.2 + env: DRIVER=hiredis REDIS_BRANCH=3.2 # synchrony - - rvm: 1.8.7 - gemfile: .travis/Gemfile - env: conn=synchrony REDIS_BRANCH=3.0 - - rvm: 1.8.7 - gemfile: .travis/Gemfile - env: conn=synchrony REDIS_BRANCH=3.2 - - rvm: jruby-18mode - gemfile: .travis/Gemfile - env: conn=synchrony REDIS_BRANCH=3.0 - - rvm: jruby-18mode - gemfile: .travis/Gemfile - env: conn=synchrony REDIS_BRANCH=3.2 - - rvm: jruby-19mode + - rvm: jruby-9 gemfile: .travis/Gemfile - env: conn=synchrony REDIS_BRANCH=3.0 - - rvm: jruby-19mode + env: DRIVER=synchrony REDIS_BRANCH=3.0 + - rvm: jruby-9 gemfile: .travis/Gemfile - env: conn=synchrony REDIS_BRANCH=3.2 - - rvm: jruby-9.0.5.0 + env: DRIVER=synchrony REDIS_BRANCH=3.2 + - rvm: jruby-9 gemfile: .travis/Gemfile - env: conn=synchrony REDIS_BRANCH=3.0 - - rvm: jruby-9.0.5.0 + env: DRIVER=synchrony REDIS_BRANCH=3.0 + - rvm: jruby-9 gemfile: .travis/Gemfile - env: conn=synchrony REDIS_BRANCH=3.2 + env: DRIVER=synchrony REDIS_BRANCH=3.2 allow_failures: - - rvm: rbx-2 + - rvm: rbx-3 notifications: irc: diff --git a/.travis/Gemfile b/.travis/Gemfile index 9e4a237cf..3573ead2b 100644 --- a/.travis/Gemfile +++ b/.travis/Gemfile @@ -2,7 +2,7 @@ source "https://rubygems.org" gemspec :path => "../" -case ENV["conn"] +case ENV["DRIVER"] when "hiredis" gem "hiredis" when "synchrony" @@ -10,8 +10,4 @@ when "synchrony" gem "em-synchrony" end -if RUBY_VERSION.to_f < 1.9 - gem 'test-unit', '3.1.5' -else - gem 'test-unit', '>= 3.2.5' -end +gem 'test-unit', '>= 3.2.5' diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e10f7ca2..87691c976 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,13 @@ -# 4.x (unreleased) +# 4.0 (unreleased) -## Planned breaking changes: -* `Redis#client` will no longer expose the underlying `Redis::Client`; - it has not yet been determined how 4.0 will expose the underlying - functionality, but we will make every attempt to provide a final minor - release of 3.x that provides the new interfaces in order to facilitate - a smooth transition. +* Removed `Redis.connect`. Use `Redis.new`. -* Ruby 1.8.7 (and the 1.8 modes of JRuby and Rubinius) will no longer be - supported; 1.8.x entered end-of-life in June of 2012 and stopped receiving - security updates in June of 2013; continuing to support it would prevent - the use of newer features of Ruby. +* Removed `Redis#[]` and `Redis#[]=` aliases. + +* Added support for `CLIENT` commands. The lower-level client can be + accessed via `Redis#_client`. + +* Dropped official support for Ruby < 2.2.2. # 3.3.3 @@ -18,7 +15,7 @@ # 3.3.2 -* Added support for SPOP with COUNT. See #628. +* Added support for `SPOP` with COUNT. See #628. * Fixed connection glitches when using SSL. See #644. diff --git a/Gemfile b/Gemfile index b14f14cdd..fa75df156 100644 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,3 @@ -# encoding: utf-8 source 'https://rubygems.org' gemspec - -if RUBY_VERSION.to_f < 1.9 - gem 'test-unit', '3.1.5' -else - gem 'test-unit', '>= 3.2.5' -end diff --git a/README.md b/README.md index 472b1bbca..68f3dc705 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,17 @@ # redis-rb [![Build Status][travis-image]][travis-link] [![Inline docs][inchpages-image]][inchpages-link] -[travis-image]: https://secure.travis-ci.org/redis/redis-rb.svg?branch=master -[travis-link]: http://travis-ci.org/redis/redis-rb -[travis-home]: http://travis-ci.org/ -[inchpages-image]: http://inch-ci.org/github/redis/redis-rb.svg -[inchpages-link]: http://inch-ci.org/github/redis/redis-rb +A Ruby client that tries to match [Redis][redis-home]' API one-to-one, while still +providing an idiomatic interface. -A Ruby client library for [Redis][redis-home]. - -[redis-home]: http://redis.io - -A Ruby client that tries to match Redis' API one-to-one, while still -providing an idiomatic interface. It features thread-safety, client-side -sharding, pipelining, and an obsession for performance. - -## Upgrading from 2.x to 3.0 - -Please refer to the [CHANGELOG][changelog-3.0.0] for a summary of the -most important changes, as well as a full list of changes. - -[changelog-3.0.0]: https://github.com/redis/redis-rb/blob/master/CHANGELOG.md#300 ## Getting started -To install **redis-rb**, run the following command: - -``` - gem install redis -``` - -Or if you are using **bundler**, add +Install with: ``` - gem 'redis', '~>3.2' +$ gem install redis ``` -to your `Gemfile`, and run `bundle install` - -As of version 2.0 this client only targets Redis version 2.0 and higher. -You can use an older version of this client if you need to interface -with a Redis instance older than 2.0, but this is no longer supported. - You can connect to Redis by instantiating the `Redis` class: ```ruby @@ -54,17 +25,15 @@ listening on `localhost`, port 6379. If you need to connect to a remote server or a different port, try: ```ruby -redis = Redis.new(:host => "10.0.1.1", :port => 6380, :db => 15) +redis = Redis.new(host: "10.0.1.1", port: 6380, db: 15) ``` You can also specify connection options as a [`redis://` URL][redis-url]: ```ruby -redis = Redis.new(:url => "redis://:p4ssw0rd@10.0.1.1:6380/15") +redis = Redis.new(url: "redis://:p4ssw0rd@10.0.1.1:6380/15") ``` -[redis-url]: http://www.iana.org/assignments/uri-schemes/prov/redis - By default, the client will try to read the `REDIS_URL` environment variable and use that as URL to connect to. The above statement is therefore equivalent to setting this environment variable and calling `Redis.new` without arguments. @@ -72,13 +41,13 @@ to setting this environment variable and calling `Redis.new` without arguments. To connect to Redis listening on a Unix socket, try: ```ruby -redis = Redis.new(:path => "/tmp/redis.sock") +redis = Redis.new(path: "/tmp/redis.sock") ``` To connect to a password protected Redis instance, use: ```ruby -redis = Redis.new(:password => "mysecret") +redis = Redis.new(password: "mysecret") ``` The Redis class exports methods that are named identical to the commands @@ -86,8 +55,6 @@ they execute. The arguments these methods accept are often identical to the arguments specified on the [Redis website][redis-commands]. For instance, the `SET` and `GET` commands can be called like this: -[redis-commands]: http://redis.io/commands - ```ruby redis.set("mykey", "hello world") # => "OK" @@ -96,24 +63,22 @@ redis.get("mykey") # => "hello world" ``` -All commands, their arguments and return values are documented, and -available on [rdoc.info][rdoc]. - -[rdoc]: http://rdoc.info/github/redis/redis-rb/ +All commands, their arguments, and return values are documented and +available on [RubyDoc.info][rubydoc]. ## Sentinel support -The client is able to perform automatic failovers by using [Redis +The client is able to perform automatic failover by using [Redis Sentinel](http://redis.io/topics/sentinel). Make sure to run Redis 2.8+ if you want to use this feature. To connect using Sentinel, use: ```ruby -SENTINELS = [{:host => "127.0.0.1", :port => 26380}, - {:host => "127.0.0.1", :port => 26381}] +SENTINELS = [{ host: "127.0.0.1", port: 26380 }, + { host: "127.0.0.1", port: 26381 }] -redis = Redis.new(:url => "redis://mymaster", :sentinels => SENTINELS, :role => :master) +redis = Redis.new(url: "redis://mymaster", sentinels: SENTINELS, role: :master) ``` * The master name identifies a group of Redis instances composed of a master @@ -374,37 +339,28 @@ redis = Redis.new(:driver => :synchrony) ## Testing -This library is tested using [Travis][travis-home], where it is tested -against the following interpreters and drivers: - -* MRI 1.8.7 (drivers: ruby, hiredis) -* MRI 1.9.3 (drivers: ruby, hiredis, synchrony) -* MRI 2.0 (drivers: ruby, hiredis, synchrony) -* MRI 2.1 (drivers: ruby, hiredis, synchrony) -* MRI 2.2 (drivers: ruby, hiredis, synchrony) -* MRI 2.3 (drivers: ruby, hiredis, synchrony) -* JRuby 1.7 (1.8 mode) (drivers: ruby) -* JRuby 1.7 (1.9 mode) (drivers: ruby) +This library is tested against recent Ruby and Redis versions. +Check [Travis][travis-link] for the exact versions supported. ## Contributors -(ordered chronologically with more than 5 commits, see `git shortlog -sn` for -all contributors) - -* Ezra Zygmuntowicz -* Taylor Weibley -* Matthew Clark -* Brian McKinney -* Luca Guidi -* Salvatore Sanfilippo -* Chris Wanstrath -* Damian Janowski -* Michel Martens -* Nick Quaranto -* Pieter Noordhuis -* Ilya Grigorik +Several people contributed to redis-rb, but we would like to especially +mention Ezra Zygmuntowicz. Ezra introduced the Ruby community to many +new cool technologies, like Redis. He wrote the first version of this +client and evangelized Redis in Rubyland. Thank you, Ezra. ## Contributing [Fork the project](https://github.com/redis/redis-rb) and send pull requests. You can also ask for help at `#redis-rb` on Freenode. + + +[inchpages-image]: https://inch-ci.org/github/redis/redis-rb.svg +[inchpages-link]: https://inch-ci.org/github/redis/redis-rb +[redis-commands]: https://redis.io/commands +[redis-home]: https://redis.io +[redis-url]: http://www.iana.org/assignments/uri-schemes/prov/redis +[travis-home]: https://travis-ci.org/ +[travis-image]: https://secure.travis-ci.org/redis/redis-rb.svg?branch=master +[travis-link]: https://travis-ci.org/redis/redis-rb +[rubydoc]: https://www.rubydoc.info/gems/redis diff --git a/Rakefile b/Rakefile deleted file mode 100644 index 2d9e137d8..000000000 --- a/Rakefile +++ /dev/null @@ -1,87 +0,0 @@ -require "rake/testtask" - -ENV["REDIS_BRANCH"] ||= "unstable" - -REDIS_DIR = File.expand_path(File.join("..", "test"), __FILE__) -REDIS_CNF = File.join(REDIS_DIR, "test.conf") -REDIS_CNF_TEMPLATE = File.join(REDIS_DIR, "test.conf.erb") -REDIS_PID = File.join(REDIS_DIR, "db", "redis.pid") -REDIS_LOG = File.join(REDIS_DIR, "db", "redis.log") -REDIS_SOCKET = File.join(REDIS_DIR, "db", "redis.sock") -BINARY = "tmp/redis-#{ENV["REDIS_BRANCH"]}/src/redis-server" - -task :default => :run - -desc "Run tests and manage server start/stop" -task :run => [:start, :test, :stop] - -desc "Start the Redis server" -task :start => [BINARY, REDIS_CNF] do - sh "#{BINARY} --version" - - redis_running = \ - begin - File.exists?(REDIS_PID) && Process.kill(0, File.read(REDIS_PID).to_i) - rescue Errno::ESRCH - FileUtils.rm REDIS_PID - false - end - - unless redis_running - unless system("#{BINARY} #{REDIS_CNF}") - abort "could not start redis-server" - end - end - - at_exit do - Rake::Task["stop"].invoke - end -end - -desc "Stop the Redis server" -task :stop do - if File.exists?(REDIS_PID) - Process.kill "INT", File.read(REDIS_PID).to_i - FileUtils.rm REDIS_PID - end -end - -desc "Clean up testing artifacts" -task :clean do - FileUtils.rm_f(BINARY) - FileUtils.rm_f(REDIS_CNF) -end - -file BINARY do - branch = ENV.fetch("REDIS_BRANCH") - - sh <<-SH - mkdir -p tmp; - cd tmp; - rm -rf redis-#{branch}; - wget https://github.com/antirez/redis/archive/#{branch}.tar.gz -O #{branch}.tar.gz; - tar xf #{branch}.tar.gz; - cd redis-#{branch}; - make - SH -end - -file REDIS_CNF => [REDIS_CNF_TEMPLATE, __FILE__] do |t| - require 'erb' - - erb = t.prerequisites[0] - template = File.read(erb) - - File.open(REDIS_CNF, 'w') do |file| - file.puts "\# This file was auto-generated at #{Time.now}", - "\# from (#{erb})", - "\#" - conf = ERB.new(template).result - file << conf - end -end - -Rake::TestTask.new do |t| - t.options = "-v" if $VERBOSE - t.test_files = FileList["test/*_test.rb"] -end diff --git a/benchmarking/logging.rb b/benchmarking/logging.rb index 353e91bd0..702ee28ee 100644 --- a/benchmarking/logging.rb +++ b/benchmarking/logging.rb @@ -54,7 +54,7 @@ def stress(redis) end logging_redises.each do |redis| - logger = redis.client.logger + logger = redis._client.logger case logger when Logger diff --git a/lib/redis.rb b/lib/redis.rb index 6851eb9cb..99c439c5c 100644 --- a/lib/redis.rb +++ b/lib/redis.rb @@ -1,21 +1,8 @@ require "monitor" -require "redis/errors" +require_relative "redis/errors" class Redis - def self.deprecate(message, trace = caller[0]) - $stderr.puts "\n#{message} (in #{trace})" - end - - attr :client - - # @deprecated The preferred way to create a new client object is using `#new`. - # This method does not actually establish a connection to Redis, - # in contrary to what you might expect. - def self.connect(options = {}) - new(options) - end - def self.current @current ||= Redis.new end @@ -119,6 +106,10 @@ def commit end end + def _client + @client + end + # Authenticate to the server. # # @param [String] password must match the password specified in the @@ -210,6 +201,25 @@ def config(action, *args) end end + # Manage client connections. + # + # @param [String, Symbol] subcommand e.g. `kill`, `list`, `getname`, `setname` + # @return [String, Hash] depends on subcommand + def client(subcommand = nil, *args) + synchronize do |client| + client.call([:client, subcommand] + args) do |reply| + if subcommand.to_s == "list" + reply.lines.map do |line| + entries = line.chomp.split(/[ =]/) + Hash[entries.each_slice(2).to_a] + end + else + reply + end + end + end + end + # Return the number of keys in the selected database. # # @return [Fixnum] @@ -484,8 +494,8 @@ def restore(key, ttl, serialized_value, options = {}) def migrate(key, options) host = options[:host] || raise(RuntimeError, ":host not specified") port = options[:port] || raise(RuntimeError, ":port not specified") - db = (options[:db] || client.db).to_i - timeout = (options[:timeout] || client.timeout).to_i + db = (options[:db] || @client.db).to_i + timeout = (options[:timeout] || @client.timeout).to_i synchronize do |client| client.call([:migrate, host, port, key, db, timeout]) @@ -763,8 +773,6 @@ def set(key, value, options = {}) end end - alias :[]= :set - # Set the time to live in seconds of a key. # # @param [String] key @@ -870,8 +878,6 @@ def get(key) end end - alias :[] :get - # Get the values of all the given keys. # # @example @@ -2802,8 +2808,8 @@ def _subscription(method, timeout, channels, block) end -require "redis/version" -require "redis/connection" -require "redis/client" -require "redis/pipeline" -require "redis/subscribe" +require_relative "redis/version" +require_relative "redis/connection" +require_relative "redis/client" +require_relative "redis/pipeline" +require_relative "redis/subscribe" diff --git a/lib/redis/client.rb b/lib/redis/client.rb index 31be2de33..8ca869c7e 100644 --- a/lib/redis/client.rb +++ b/lib/redis/client.rb @@ -1,4 +1,4 @@ -require "redis/errors" +require_relative "errors" require "socket" require "cgi" @@ -21,9 +21,7 @@ class Client :inherit_socket => false } - def options - Marshal.load(Marshal.dump(@options)) - end + attr_reader :options def scheme @options[:scheme] @@ -340,6 +338,7 @@ def establish_connection Errno::EHOSTDOWN, Errno::EHOSTUNREACH, Errno::ENETUNREACH, + Errno::ENOENT, Errno::ETIMEDOUT raise CannotConnectError, "Error connecting to Redis on #{location} (#{$!.class})" @@ -478,11 +477,16 @@ def _parse_driver(driver) if driver.kind_of?(String) begin - require "redis/connection/#{driver}" - driver = Connection.const_get(driver.capitalize) - rescue LoadError, NameError - raise RuntimeError, "Cannot load driver #{driver.inspect}" + require_relative "connection/#{driver}" + rescue LoadError, NameError => e + begin + require "connection/#{driver}" + rescue LoadError, NameError => e + raise RuntimeError, "Cannot load driver #{driver.inspect}: #{e.message}" + end end + + driver = Connection.const_get(driver.capitalize) end driver diff --git a/lib/redis/connection.rb b/lib/redis/connection.rb index badff22b9..d8a51b334 100644 --- a/lib/redis/connection.rb +++ b/lib/redis/connection.rb @@ -1,4 +1,4 @@ -require "redis/connection/registry" +require_relative "connection/registry" # If a connection driver was required before this file, the array # Redis::Connection.drivers will contain one or more classes. The last driver @@ -6,4 +6,4 @@ # the plain Ruby driver as our default. Another driver can be required at a # later point in time, causing it to be the last element of the #drivers array # and therefore be chosen by default. -require "redis/connection/ruby" if Redis::Connection.drivers.empty? \ No newline at end of file +require_relative "connection/ruby" if Redis::Connection.drivers.empty? diff --git a/lib/redis/connection/command_helper.rb b/lib/redis/connection/command_helper.rb index 74e89dc10..b1c2d0fd9 100644 --- a/lib/redis/connection/command_helper.rb +++ b/lib/redis/connection/command_helper.rb @@ -30,14 +30,8 @@ def build_command(args) protected - if defined?(Encoding::default_external) - def encode(string) - string.force_encoding(Encoding::default_external) - end - else - def encode(string) - string - end + def encode(string) + string.force_encoding(Encoding.default_external) end end end diff --git a/lib/redis/connection/hiredis.rb b/lib/redis/connection/hiredis.rb index f4056d386..f7baf31b6 100644 --- a/lib/redis/connection/hiredis.rb +++ b/lib/redis/connection/hiredis.rb @@ -1,5 +1,5 @@ -require "redis/connection/registry" -require "redis/errors" +require_relative "registry" +require_relative "../errors" require "hiredis/connection" require "timeout" diff --git a/lib/redis/connection/ruby.rb b/lib/redis/connection/ruby.rb index c01edd913..c3cadcd64 100644 --- a/lib/redis/connection/ruby.rb +++ b/lib/redis/connection/ruby.rb @@ -1,6 +1,6 @@ -require "redis/connection/registry" -require "redis/connection/command_helper" -require "redis/errors" +require_relative "registry" +require_relative "command_helper" +require_relative "../errors" require "socket" require "timeout" @@ -10,31 +10,12 @@ # Not all systems have OpenSSL support end -if RUBY_VERSION < "1.9.3" - class String - # Ruby 1.8.7 does not have byteslice, but it handles encodings differently anyway. - # We can simply slice the string, which is a byte array there. - def byteslice(*args) - slice(*args) - end - end -end - class Redis module Connection module SocketMixin CRLF = "\r\n".freeze - # Exceptions raised during non-blocking I/O ops that require retrying the op - if RUBY_VERSION >= "1.9.3" - NBIO_READ_EXCEPTIONS = [IO::WaitReadable] - NBIO_WRITE_EXCEPTIONS = [IO::WaitWritable] - else - NBIO_READ_EXCEPTIONS = [Errno::EWOULDBLOCK, Errno::EAGAIN] - NBIO_WRITE_EXCEPTIONS = [Errno::EWOULDBLOCK, Errno::EAGAIN] - end - def initialize(*args) super(*args) @@ -83,13 +64,13 @@ def _read_from_socket(nbytes) begin read_nonblock(nbytes) - rescue *NBIO_READ_EXCEPTIONS + rescue IO::WaitReadable if IO.select([self], nil, nil, @timeout) retry else raise Redis::TimeoutError end - rescue *NBIO_WRITE_EXCEPTIONS + rescue IO::WaitWritable if IO.select(nil, [self], nil, @timeout) retry else @@ -105,13 +86,13 @@ def _write_to_socket(data) begin write_nonblock(data) - rescue *NBIO_WRITE_EXCEPTIONS + rescue IO::WaitWritable if IO.select(nil, [self], nil, @write_timeout) retry else raise Redis::TimeoutError end - rescue *NBIO_READ_EXCEPTIONS + rescue IO::WaitReadable if IO.select([self], nil, nil, @write_timeout) retry else @@ -307,7 +288,6 @@ def self.connect(config) raise ArgumentError, "SSL incompatible with unix sockets" if config[:ssl] sock = UNIXSocket.connect(config[:path], config[:connect_timeout]) elsif config[:scheme] == "rediss" || config[:ssl] - raise ArgumentError, "This library does not support SSL on Ruby < 1.9" if RUBY_VERSION < "1.9.3" sock = SSLSocket.connect(config[:host], config[:port], config[:connect_timeout], config[:ssl_params]) else sock = TCPSocket.connect(config[:host], config[:port], config[:connect_timeout]) diff --git a/lib/redis/connection/synchrony.rb b/lib/redis/connection/synchrony.rb index 9f0b67cdc..e15fd627d 100644 --- a/lib/redis/connection/synchrony.rb +++ b/lib/redis/connection/synchrony.rb @@ -1,6 +1,6 @@ -require "redis/connection/command_helper" -require "redis/connection/registry" -require "redis/errors" +require_relative "command_helper" +require_relative "registry" +require_relative "../errors" require "em-synchrony" require "hiredis/reader" @@ -72,7 +72,15 @@ class Synchrony def self.connect(config) if config[:scheme] == "unix" - conn = EventMachine.connect_unix_domain(config[:path], RedisClient) + begin + conn = EventMachine.connect_unix_domain(config[:path], RedisClient) + rescue RuntimeError => e + if e.message == "no connection" + raise Errno::ECONNREFUSED + else + raise e + end + end elsif config[:scheme] == "rediss" || config[:ssl] raise NotImplementedError, "SSL not supported by synchrony driver" else diff --git a/lib/redis/distributed.rb b/lib/redis/distributed.rb index 1f03a2126..0206ab8e2 100644 --- a/lib/redis/distributed.rb +++ b/lib/redis/distributed.rb @@ -1,4 +1,4 @@ -require "redis/hash_ring" +require_relative "hash_ring" class Redis class Distributed diff --git a/lib/redis/hash_ring.rb b/lib/redis/hash_ring.rb index 2a199bd53..e1c93b25a 100644 --- a/lib/redis/hash_ring.rb +++ b/lib/redis/hash_ring.rb @@ -25,7 +25,6 @@ def add_node(node) @nodes << node @replicas.times do |i| key = Zlib.crc32("#{node.id}:#{i}") - raise "Node ID collision" if @ring.has_key?(key) @ring[key] = node @sorted_keys << key end @@ -61,72 +60,29 @@ def iter_nodes(key) end end - class << self - - # gem install RubyInline to use this code - # Native extension to perform the binary search within the hashring. - # There's a pure ruby version below so this is purely optional - # for performance. In testing 20k gets and sets, the native - # binary search shaved about 12% off the runtime (9sec -> 8sec). - begin - require 'inline' - inline do |builder| - builder.c <<-EOM - int binary_search(VALUE ary, unsigned int r) { - int upper = RARRAY_LEN(ary) - 1; - int lower = 0; - int idx = 0; - - while (lower <= upper) { - idx = (lower + upper) / 2; - - VALUE continuumValue = RARRAY_PTR(ary)[idx]; - unsigned int l = NUM2UINT(continuumValue); - if (l == r) { - return idx; - } - else if (l > r) { - upper = idx - 1; - } - else { - lower = idx + 1; - } - } - if (upper < 0) { - upper = RARRAY_LEN(ary) - 1; - } - return upper; - } - EOM - end - rescue Exception - # Find the closest index in HashRing with value <= the given value - def binary_search(ary, value, &block) - upper = ary.size - 1 - lower = 0 - idx = 0 - - while(lower <= upper) do - idx = (lower + upper) / 2 - comp = ary[idx] <=> value - - if comp == 0 - return idx - elsif comp > 0 - upper = idx - 1 - else - lower = idx + 1 - end - end - - if upper < 0 - upper = ary.size - 1 - end - return upper + # Find the closest index in HashRing with value <= the given value + def self.binary_search(ary, value, &block) + upper = ary.size - 1 + lower = 0 + idx = 0 + + while(lower <= upper) do + idx = (lower + upper) / 2 + comp = ary[idx] <=> value + + if comp == 0 + return idx + elsif comp > 0 + upper = idx - 1 + else + lower = idx + 1 end + end + if upper < 0 + upper = ary.size - 1 end + return upper end - end end diff --git a/lib/redis/pipeline.rb b/lib/redis/pipeline.rb index a77f86d9b..3af1e2af9 100644 --- a/lib/redis/pipeline.rb +++ b/lib/redis/pipeline.rb @@ -1,10 +1,4 @@ class Redis - unless defined?(::BasicObject) - class BasicObject - instance_methods.each { |meth| undef_method(meth) unless meth =~ /\A(__|instance_eval)/ } - end - end - class Pipeline attr_accessor :db diff --git a/lib/redis/version.rb b/lib/redis/version.rb index b5d80d24d..b5610308b 100644 --- a/lib/redis/version.rb +++ b/lib/redis/version.rb @@ -1,3 +1,3 @@ class Redis - VERSION = "3.3.3" + VERSION = "4.0.0.rc1" end diff --git a/makefile b/makefile new file mode 100644 index 000000000..6ea12e249 --- /dev/null +++ b/makefile @@ -0,0 +1,42 @@ +TEST_FILES := $(shell find test -name *_test.rb -type f) +REDIS_BRANCH := unstable +TMP := tmp +BUILD_DIR := ${TMP}/redis-${REDIS_BRANCH} +TARBALL := ${TMP}/redis-${REDIS_BRANCH}.tar.gz +BINARY := ${BUILD_DIR}/src/redis-server +PID_PATH := ${BUILD_DIR}/redis.pid +SOCKET_PATH := ${BUILD_DIR}/redis.sock +PORT := 6381 + +test: ${TEST_FILES} + make start + env SOCKET_PATH=${SOCKET_PATH} \ + ruby -v $$(echo $? | tr ' ' '\n' | awk '{ print "-r./" $$0 }') -e '' + make stop + +${TMP}: + mkdir $@ + +${TARBALL}: ${TMP} + wget https://github.com/antirez/redis/archive/${REDIS_BRANCH}.tar.gz -O $@ + +${BINARY}: ${TARBALL} ${TMP} + rm -rf ${BUILD_DIR} + mkdir -p ${BUILD_DIR} + tar xf ${TARBALL} -C ${TMP} + cd ${BUILD_DIR} && make + +stop: + (test -f ${PID_PATH} && (kill $$(cat ${PID_PATH}) || true) && rm -f ${PID_PATH}) || true + +start: ${BINARY} + ${BINARY} \ + --daemonize yes \ + --pidfile ${PID_PATH} \ + --port ${PORT} \ + --unixsocket ${SOCKET_PATH} + +clean: + (test -d ${BUILD_DIR} && cd ${BUILD_DIR}/src && make clean distclean) || true + +.PHONY: test start stop diff --git a/redis.gemspec b/redis.gemspec index a661410dd..c05ae5e20 100644 --- a/redis.gemspec +++ b/redis.gemspec @@ -1,8 +1,4 @@ -# -*- encoding: utf-8 -*- - -$:.unshift File.expand_path("../lib", __FILE__) - -require "redis/version" +require "./lib/redis/version" Gem::Specification.new do |s| s.name = "redis" @@ -15,8 +11,7 @@ Gem::Specification.new do |s| s.description = <<-EOS A Ruby client that tries to match Redis' API one-to-one, while still - providing an idiomatic interface. It features thread-safety, - client-side sharding, pipelining, and an obsession for performance. + providing an idiomatic interface. EOS s.license = "MIT" @@ -39,6 +34,9 @@ Gem::Specification.new do |s| s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } - s.add_development_dependency("rake", "<11.0.0") + s.required_ruby_version = '>= 2.2.2' + s.add_development_dependency("test-unit", ">= 3.1.5") + s.add_development_dependency("hiredis") + s.add_development_dependency("em-synchrony") end diff --git a/test/bitpos_test.rb b/test/bitpos_test.rb index 118294da7..d810a7f23 100644 --- a/test/bitpos_test.rb +++ b/test/bitpos_test.rb @@ -1,10 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) - -unless defined?(Enumerator) - Enumerator = Enumerable::Enumerator -end +require_relative "helper" class TestBitpos < Test::Unit::TestCase @@ -13,48 +7,48 @@ class TestBitpos < Test::Unit::TestCase def test_bitpos_empty_zero target_version "2.9.11" do r.del "foo" - assert_equal 0, r.bitpos("foo", 0) + assert_equal(0, r.bitpos("foo", 0)) end end def test_bitpos_empty_one target_version "2.9.11" do r.del "foo" - assert_equal -1, r.bitpos("foo", 1) + assert_equal(-1, r.bitpos("foo", 1)) end end def test_bitpos_zero target_version "2.9.11" do r.set "foo", "\xff\xf0\x00" - assert_equal 12, r.bitpos("foo", 0) + assert_equal(12, r.bitpos("foo", 0)) end end def test_bitpos_one target_version "2.9.11" do r.set "foo", "\x00\x0f\x00" - assert_equal 12, r.bitpos("foo", 1) + assert_equal(12, r.bitpos("foo", 1)) end end def test_bitpos_zero_end_is_given target_version "2.9.11" do r.set "foo", "\xff\xff\xff" - assert_equal 24, r.bitpos("foo", 0) - assert_equal 24, r.bitpos("foo", 0, 0) - assert_equal -1, r.bitpos("foo", 0, 0, -1) + assert_equal(24, r.bitpos("foo", 0)) + assert_equal(24, r.bitpos("foo", 0, 0)) + assert_equal(-1, r.bitpos("foo", 0, 0, -1)) end end def test_bitpos_one_intervals target_version "2.9.11" do r.set "foo", "\x00\xff\x00" - assert_equal 8, r.bitpos("foo", 1, 0, -1) - assert_equal 8, r.bitpos("foo", 1, 1, -1) - assert_equal -1, r.bitpos("foo", 1, 2, -1) - assert_equal -1, r.bitpos("foo", 1, 2, 200) - assert_equal 8, r.bitpos("foo", 1, 1, 1) + assert_equal(8, r.bitpos("foo", 1, 0, -1)) + assert_equal(8, r.bitpos("foo", 1, 1, -1)) + assert_equal(-1, r.bitpos("foo", 1, 2, -1)) + assert_equal(-1, r.bitpos("foo", 1, 2, 200)) + assert_equal(8, r.bitpos("foo", 1, 1, 1)) end end diff --git a/test/blocking_commands_test.rb b/test/blocking_commands_test.rb index 4a2a9652d..d9559e675 100644 --- a/test/blocking_commands_test.rb +++ b/test/blocking_commands_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/blocking_commands" +require_relative "helper" +require_relative "lint/blocking_commands" class TestBlockingCommands < Test::Unit::TestCase @@ -17,7 +15,7 @@ def assert_takes_longer_than_client_timeout yield(r) t2 = Time.now - assert timeout == r.client.timeout + assert timeout == r._client.timeout assert delay <= (t2 - t1) end end diff --git a/test/client_test.rb b/test/client_test.rb index 1d0b8d3a6..b8244b429 100644 --- a/test/client_test.rb +++ b/test/client_test.rb @@ -1,4 +1,4 @@ -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestClient < Test::Unit::TestCase diff --git a/test/command_map_test.rb b/test/command_map_test.rb index cb401db36..a85163b2e 100644 --- a/test/command_map_test.rb +++ b/test/command_map_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestCommandMap < Test::Unit::TestCase @@ -11,7 +9,7 @@ def test_override_existing_commands assert_equal 2, r.incr("counter") - r.client.command_map[:incr] = :decr + r._client.command_map[:incr] = :decr assert_equal 1, r.incr("counter") end @@ -23,7 +21,7 @@ def test_override_non_existing_commands r.idontexist("key") end - r.client.command_map[:idontexist] = :get + r._client.command_map[:idontexist] = :get assert_equal "value", r.idontexist("key") end diff --git a/test/commands_on_hashes_test.rb b/test/commands_on_hashes_test.rb index f3bbfa5b3..3e0f7ba4e 100644 --- a/test/commands_on_hashes_test.rb +++ b/test/commands_on_hashes_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/hashes" +require_relative "helper" +require_relative "lint/hashes" class TestCommandsOnHashes < Test::Unit::TestCase diff --git a/test/commands_on_hyper_log_log_test.rb b/test/commands_on_hyper_log_log_test.rb index a2fc95be1..194e6d4c6 100644 --- a/test/commands_on_hyper_log_log_test.rb +++ b/test/commands_on_hyper_log_log_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/hyper_log_log" +require_relative "helper" +require_relative "lint/hyper_log_log" class TestCommandsOnHyperLogLog < Test::Unit::TestCase @@ -18,4 +16,4 @@ def test_pfmerge end end -end \ No newline at end of file +end diff --git a/test/commands_on_lists_test.rb b/test/commands_on_lists_test.rb index 2916c2854..5f286706f 100644 --- a/test/commands_on_lists_test.rb +++ b/test/commands_on_lists_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/lists" +require_relative "helper" +require_relative "lint/lists" class TestCommandsOnLists < Test::Unit::TestCase diff --git a/test/commands_on_sets_test.rb b/test/commands_on_sets_test.rb index 7ac2f4e03..cd186cd34 100644 --- a/test/commands_on_sets_test.rb +++ b/test/commands_on_sets_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/sets" +require_relative "helper" +require_relative "lint/sets" class TestCommandsOnSets < Test::Unit::TestCase diff --git a/test/commands_on_sorted_sets_test.rb b/test/commands_on_sorted_sets_test.rb index f63b84fe3..9d30d22fe 100644 --- a/test/commands_on_sorted_sets_test.rb +++ b/test/commands_on_sorted_sets_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/sorted_sets" +require_relative "helper" +require_relative "lint/sorted_sets" class TestCommandsOnSortedSets < Test::Unit::TestCase diff --git a/test/commands_on_strings_test.rb b/test/commands_on_strings_test.rb index 9172aaccd..58fe7e510 100644 --- a/test/commands_on_strings_test.rb +++ b/test/commands_on_strings_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/strings" +require_relative "helper" +require_relative "lint/strings" class TestCommandsOnStrings < Test::Unit::TestCase @@ -82,7 +80,7 @@ def test_msetnx_mapped end def test_bitop - try_encoding("UTF-8") do + with_external_encoding("UTF-8") do target_version "2.5.10" do r.set("foo", "a") r.set("bar", "b") diff --git a/test/commands_on_value_types_test.rb b/test/commands_on_value_types_test.rb index 6b2f211ca..1967c1755 100644 --- a/test/commands_on_value_types_test.rb +++ b/test/commands_on_value_types_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/value_types" +require_relative "helper" +require_relative "lint/value_types" class TestCommandsOnValueTypes < Test::Unit::TestCase @@ -111,8 +109,8 @@ def test_migrate end assert ex.message =~ /port not specified/ - default_db = redis.client.db.to_i - default_timeout = redis.client.timeout.to_i + default_db = redis._client.db.to_i + default_timeout = redis._client.timeout.to_i # Test defaults actual = redis.migrate("foo", options) diff --git a/test/connection_handling_test.rb b/test/connection_handling_test.rb index f11553bae..cc9fd5129 100644 --- a/test/connection_handling_test.rb +++ b/test/connection_handling_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestConnectionHandling < Test::Unit::TestCase @@ -40,7 +38,7 @@ def test_select r.select 14 assert_equal nil, r.get("foo") - r.client.disconnect + r._client.disconnect assert_equal nil, r.get("foo") end @@ -48,7 +46,7 @@ def test_select def test_quit r.quit - assert !r.client.connected? + assert !r._client.connected? end def test_close @@ -148,7 +146,7 @@ def test_shutdown_from_pipeline end assert_equal nil, result - assert !redis.client.connected? + assert !redis._client.connected? end end @@ -188,7 +186,7 @@ def test_shutdown_from_multi_exec end assert_equal nil, result - assert !redis.client.connected? + assert !redis._client.connected? end end diff --git a/test/distributed_blocking_commands_test.rb b/test/distributed_blocking_commands_test.rb index b28cf2743..f03f45b09 100644 --- a/test/distributed_blocking_commands_test.rb +++ b/test/distributed_blocking_commands_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/blocking_commands" +require_relative "helper" +require_relative "lint/blocking_commands" class TestDistributedBlockingCommands < Test::Unit::TestCase diff --git a/test/distributed_commands_on_hashes_test.rb b/test/distributed_commands_on_hashes_test.rb index ffd14f519..732fef64c 100644 --- a/test/distributed_commands_on_hashes_test.rb +++ b/test/distributed_commands_on_hashes_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/hashes" +require_relative "helper" +require_relative "lint/hashes" class TestDistributedCommandsOnHashes < Test::Unit::TestCase diff --git a/test/distributed_commands_on_hyper_log_log_test.rb b/test/distributed_commands_on_hyper_log_log_test.rb index c118b9574..a6b7110f7 100644 --- a/test/distributed_commands_on_hyper_log_log_test.rb +++ b/test/distributed_commands_on_hyper_log_log_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/hyper_log_log" +require_relative "helper" +require_relative "lint/hyper_log_log" class TestDistributedCommandsOnHyperLogLog < Test::Unit::TestCase diff --git a/test/distributed_commands_on_lists_test.rb b/test/distributed_commands_on_lists_test.rb index d22f3be80..dd629bc2f 100644 --- a/test/distributed_commands_on_lists_test.rb +++ b/test/distributed_commands_on_lists_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/lists" +require_relative "helper" +require_relative "lint/lists" class TestDistributedCommandsOnLists < Test::Unit::TestCase diff --git a/test/distributed_commands_on_sets_test.rb b/test/distributed_commands_on_sets_test.rb index 43a070c8c..c7180e6ac 100644 --- a/test/distributed_commands_on_sets_test.rb +++ b/test/distributed_commands_on_sets_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/sets" +require_relative "helper" +require_relative "lint/sets" class TestDistributedCommandsOnSets < Test::Unit::TestCase diff --git a/test/distributed_commands_on_sorted_sets_test.rb b/test/distributed_commands_on_sorted_sets_test.rb index a4150b834..ae23a6c83 100644 --- a/test/distributed_commands_on_sorted_sets_test.rb +++ b/test/distributed_commands_on_sorted_sets_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/sorted_sets" +require_relative "helper" +require_relative "lint/sorted_sets" class TestDistributedCommandsOnSortedSets < Test::Unit::TestCase diff --git a/test/distributed_commands_on_strings_test.rb b/test/distributed_commands_on_strings_test.rb index ad83c12e5..5b964684f 100644 --- a/test/distributed_commands_on_strings_test.rb +++ b/test/distributed_commands_on_strings_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/strings" +require_relative "helper" +require_relative "lint/strings" class TestDistributedCommandsOnStrings < Test::Unit::TestCase diff --git a/test/distributed_commands_on_value_types_test.rb b/test/distributed_commands_on_value_types_test.rb index 0be9ce298..b360dbe98 100644 --- a/test/distributed_commands_on_value_types_test.rb +++ b/test/distributed_commands_on_value_types_test.rb @@ -1,7 +1,5 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) -require "lint/value_types" +require_relative "helper" +require_relative "lint/value_types" class TestDistributedCommandsOnValueTypes < Test::Unit::TestCase diff --git a/test/distributed_commands_requiring_clustering_test.rb b/test/distributed_commands_requiring_clustering_test.rb index da8063c56..dc5c6ed3f 100644 --- a/test/distributed_commands_requiring_clustering_test.rb +++ b/test/distributed_commands_requiring_clustering_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestDistributedCommandsRequiringClustering < Test::Unit::TestCase diff --git a/test/distributed_connection_handling_test.rb b/test/distributed_connection_handling_test.rb index 330886090..335046abe 100644 --- a/test/distributed_connection_handling_test.rb +++ b/test/distributed_connection_handling_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestDistributedConnectionHandling < Test::Unit::TestCase diff --git a/test/distributed_internals_test.rb b/test/distributed_internals_test.rb index 887881f1d..82b9df3ea 100644 --- a/test/distributed_internals_test.rb +++ b/test/distributed_internals_test.rb @@ -1,41 +1,39 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestDistributedInternals < Test::Unit::TestCase include Helper::Distributed def test_provides_a_meaningful_inspect - nodes = ["redis://localhost:#{PORT}/15", *NODES] + nodes = ["redis://127.0.0.1:#{PORT}/15", *NODES] redis = Redis::Distributed.new nodes assert_equal "#", redis.inspect end def test_default_as_urls - nodes = ["redis://localhost:#{PORT}/15", *NODES] + nodes = ["redis://127.0.0.1:#{PORT}/15", *NODES] redis = Redis::Distributed.new nodes - assert_equal ["redis://localhost:#{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)] 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)] 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")] redis = Redis::Distributed.new nodes - assert_equal redis.nodes.first.client.id, "test" - assert_equal redis.nodes.last.client.id, "test1" + assert_equal redis.nodes.first._client.id, "test" + assert_equal redis.nodes.last._client.id, "test1" assert_equal "#", redis.inspect end @@ -67,13 +65,4 @@ def test_keeps_options_after_dup assert_equal [], r2.sinter("baz:foo", "baz:bar") end - - def test_colliding_node_ids - nodes = ["redis://localhost:#{PORT}/15", "redis://localhost:#{PORT}/15", *NODES] - - assert_raise(RuntimeError) do - Redis::Distributed.new nodes - end - end - end diff --git a/test/distributed_key_tags_test.rb b/test/distributed_key_tags_test.rb index 12b6d688d..a778fec72 100644 --- a/test/distributed_key_tags_test.rb +++ b/test/distributed_key_tags_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestDistributedKeyTags < Test::Unit::TestCase @@ -8,9 +6,9 @@ class TestDistributedKeyTags < Test::Unit::TestCase include Helper::Distributed def test_hashes_consistently - r1 = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES] - r2 = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES] - r3 = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES] + r1 = Redis::Distributed.new ["redis://127.0.0.1:#{PORT}/15", *NODES] + r2 = Redis::Distributed.new ["redis://127.0.0.1:#{PORT}/15", *NODES] + r3 = Redis::Distributed.new ["redis://127.0.0.1:#{PORT}/15", *NODES] assert_equal r1.node_for("foo").id, r2.node_for("foo").id assert_equal r1.node_for("foo").id, r3.node_for("foo").id diff --git a/test/distributed_persistence_control_commands_test.rb b/test/distributed_persistence_control_commands_test.rb index c24360192..2d844258a 100644 --- a/test/distributed_persistence_control_commands_test.rb +++ b/test/distributed_persistence_control_commands_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestDistributedPersistenceControlCommands < Test::Unit::TestCase diff --git a/test/distributed_publish_subscribe_test.rb b/test/distributed_publish_subscribe_test.rb index df36506d9..a5fcfa53f 100644 --- a/test/distributed_publish_subscribe_test.rb +++ b/test/distributed_publish_subscribe_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestDistributedPublishSubscribe < Test::Unit::TestCase diff --git a/test/distributed_remote_server_control_commands_test.rb b/test/distributed_remote_server_control_commands_test.rb index 7799d4fce..66ec349f8 100644 --- a/test/distributed_remote_server_control_commands_test.rb +++ b/test/distributed_remote_server_control_commands_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestDistributedRemoteServerControlCommands < Test::Unit::TestCase diff --git a/test/distributed_scripting_test.rb b/test/distributed_scripting_test.rb index 00bdaa622..224ab2b05 100644 --- a/test/distributed_scripting_test.rb +++ b/test/distributed_scripting_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestDistributedScripting < Test::Unit::TestCase diff --git a/test/distributed_sorting_test.rb b/test/distributed_sorting_test.rb index 4ae3cf575..7afb670b9 100644 --- a/test/distributed_sorting_test.rb +++ b/test/distributed_sorting_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestDistributedSorting < Test::Unit::TestCase diff --git a/test/distributed_test.rb b/test/distributed_test.rb index b55287bde..b19e5329b 100644 --- a/test/distributed_test.rb +++ b/test/distributed_test.rb @@ -1,13 +1,11 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestDistributed < Test::Unit::TestCase include Helper::Distributed def test_handle_multiple_servers - @r = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES] + @r = Redis::Distributed.new ["redis://127.0.0.1:#{PORT}/15", *NODES] 100.times do |idx| @r.set(idx.to_s, "foo#{idx}") @@ -26,19 +24,19 @@ def test_add_nodes @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 - assert_equal 15, @r.nodes[0].client.db - assert_equal 10, @r.nodes[0].client.timeout - assert_equal logger, @r.nodes[0].client.logger + assert_equal "127.0.0.1", @r.nodes[0]._client.host + assert_equal PORT, @r.nodes[0]._client.port + assert_equal 15, @r.nodes[0]._client.db + assert_equal 10, @r.nodes[0]._client.timeout + assert_equal logger, @r.nodes[0]._client.logger @r.add_node("redis://127.0.0.1:6380/14") - assert_equal "127.0.0.1", @r.nodes[1].client.host - assert_equal 6380, @r.nodes[1].client.port - assert_equal 14, @r.nodes[1].client.db - assert_equal 10, @r.nodes[1].client.timeout - assert_equal logger, @r.nodes[1].client.logger + assert_equal "127.0.0.1", @r.nodes[1]._client.host + assert_equal 6380, @r.nodes[1]._client.port + assert_equal 14, @r.nodes[1]._client.db + assert_equal 10, @r.nodes[1]._client.timeout + assert_equal logger, @r.nodes[1]._client.logger end def test_pipelining_commands_cannot_be_distributed diff --git a/test/distributed_transactions_test.rb b/test/distributed_transactions_test.rb index abfb8aa3c..526e96d45 100644 --- a/test/distributed_transactions_test.rb +++ b/test/distributed_transactions_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestDistributedTransactions < Test::Unit::TestCase diff --git a/test/encoding_test.rb b/test/encoding_test.rb index cb54bcb2a..195f1e8ad 100644 --- a/test/encoding_test.rb +++ b/test/encoding_test.rb @@ -1,18 +1,14 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestEncoding < Test::Unit::TestCase include Helper::Client def test_returns_properly_encoded_strings - if defined?(Encoding) - with_external_encoding("UTF-8") do - r.set "foo", "שלום" + with_external_encoding("UTF-8") do + r.set "foo", "שלום" - assert_equal "Shalom שלום", "Shalom " + r.get("foo") - end + assert_equal "Shalom שלום", "Shalom " + r.get("foo") end end end diff --git a/test/error_replies_test.rb b/test/error_replies_test.rb index 08ec81e15..a5f4694ff 100644 --- a/test/error_replies_test.rb +++ b/test/error_replies_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestErrorReplies < Test::Unit::TestCase @@ -47,7 +45,7 @@ def test_raise_first_error_reply_in_pipeline def test_recover_from_raise_in__call_loop with_reconnection_check do begin - r.client.call_loop([:invalid_monitor]) do + r._client.call_loop([:invalid_monitor]) do assert false # Should never be executed end rescue => ex diff --git a/test/fork_safety_test.rb b/test/fork_safety_test.rb index a49d5b46d..73b541f74 100644 --- a/test/fork_safety_test.rb +++ b/test/fork_safety_test.rb @@ -1,11 +1,8 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestForkSafety < Test::Unit::TestCase include Helper::Client - include Helper::Skipable driver(:ruby, :hiredis) do def test_fork_safety @@ -32,7 +29,6 @@ def test_fork_safety rescue NotImplementedError => error raise unless error.message =~ /fork is not available/ - return skip(error.message) end def test_fork_safety_with_enabled_inherited_socket @@ -59,7 +55,6 @@ def test_fork_safety_with_enabled_inherited_socket rescue NotImplementedError => error raise unless error.message =~ /fork is not available/ - return skip(error.message) end end end diff --git a/test/helper.rb b/test/helper.rb index 169440728..4d3e1610d 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -1,27 +1,17 @@ -$:.unshift File.expand_path("../lib", File.dirname(__FILE__)) -$:.unshift File.expand_path(File.dirname(__FILE__)) - require "test/unit" require "logger" require "stringio" -(class Random; def self.rand(*args) super end; end) unless defined?(Random) - -begin - require "ruby-debug" -rescue LoadError -end - $VERBOSE = true -ENV["conn"] ||= "ruby" +ENV["DRIVER"] ||= "ruby" -require "redis" -require "redis/distributed" -require "redis/connection/#{ENV["conn"]}" +require_relative "../lib/redis" +require_relative "../lib/redis/distributed" +require_relative "../lib/redis/connection/#{ENV["DRIVER"]}" -require "support/redis_mock" -require "support/connection/#{ENV["conn"]}" +require_relative "support/redis_mock" +require_relative "support/connection/#{ENV["DRIVER"]}" PORT = 6381 OPTIONS = {:port => PORT, :db => 15, :timeout => Float(ENV["TIMEOUT"] || 0.1)} @@ -44,11 +34,11 @@ def init(redis) Try this once: - $ rake clean + $ make clean Then run the build again: - $ rake + $ make EOS exit 1 @@ -56,7 +46,7 @@ def init(redis) end def driver(*drivers, &blk) - if drivers.map(&:to_s).include?(ENV["conn"]) + if drivers.map(&:to_s).include?(ENV["DRIVER"]) class_eval(&blk) end end @@ -92,14 +82,6 @@ def with_external_encoding(encoding) end end - def try_encoding(encoding, &block) - if defined?(Encoding) - with_external_encoding(encoding, &block) - else - yield - end - end - class Version include Comparable @@ -191,7 +173,7 @@ def _format_options(options) end def _new_client(options = {}) - Redis.new(_format_options(options).merge(:driver => ENV["conn"])) + Redis.new(_format_options(options).merge(:driver => ENV["DRIVER"])) end end @@ -216,17 +198,4 @@ def _new_client(options = {}) Redis::Distributed.new(NODES, _format_options(options).merge(:driver => ENV["conn"])) end end - - # Basic support for `skip` in 1.8.x - # Note: YOU MUST use `return skip(message)` in order to appropriately bail - # from a running test. - module Skipable - Skipped = Class.new(RuntimeError) - - def skip(message = nil, bt = caller) - return super if defined?(super) - - $stderr.puts("SKIPPED: #{self} #{message || 'no reason given'}") - end - end end diff --git a/test/helper_test.rb b/test/helper_test.rb index 23da68dce..b4b027ced 100644 --- a/test/helper_test.rb +++ b/test/helper_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestHelper < Test::Unit::TestCase diff --git a/test/internals_test.rb b/test/internals_test.rb index a49873054..3117bfea5 100644 --- a/test/internals_test.rb +++ b/test/internals_test.rb @@ -1,11 +1,8 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestInternals < Test::Unit::TestCase include Helper::Client - include Helper::Skipable def test_logger r.ping @@ -49,23 +46,23 @@ def test_provides_a_meaningful_inspect end def test_redis_current - assert_equal "127.0.0.1", Redis.current.client.host - assert_equal 6379, Redis.current.client.port - assert_equal 0, Redis.current.client.db + assert_equal "127.0.0.1", Redis.current._client.host + assert_equal 6379, Redis.current._client.port + assert_equal 0, Redis.current._client.db Redis.current = Redis.new(OPTIONS.merge(:port => 6380, :db => 1)) t = Thread.new do - assert_equal "127.0.0.1", Redis.current.client.host - assert_equal 6380, Redis.current.client.port - assert_equal 1, Redis.current.client.db + assert_equal "127.0.0.1", Redis.current._client.host + assert_equal 6380, Redis.current._client.port + assert_equal 1, Redis.current._client.db end t.join - assert_equal "127.0.0.1", Redis.current.client.host - assert_equal 6380, Redis.current.client.port - assert_equal 1, Redis.current.client.db + assert_equal "127.0.0.1", Redis.current._client.host + assert_equal 6380, Redis.current._client.port + assert_equal 1, Redis.current._client.db end def test_redis_connected? @@ -81,27 +78,27 @@ def test_redis_connected? def test_default_id_with_host_and_port redis = Redis.new(OPTIONS.merge(:host => "host", :port => "1234", :db => 0)) - assert_equal "redis://host:1234/0", redis.client.id + assert_equal "redis://host:1234/0", redis._client.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")) - assert_equal "redis://host:1234/0", redis.client.id + assert_equal "redis://host:1234/0", redis._client.id end def test_default_id_with_path redis = Redis.new(OPTIONS.merge(:path => "/tmp/redis.sock", :db => 0)) - assert_equal "redis:///tmp/redis.sock/0", redis.client.id + assert_equal "redis:///tmp/redis.sock/0", redis._client.id end def test_default_id_with_path_and_explicit_scheme redis = Redis.new(OPTIONS.merge(:path => "/tmp/redis.sock", :db => 0, :scheme => "foo")) - assert_equal "redis:///tmp/redis.sock/0", redis.client.id + assert_equal "redis:///tmp/redis.sock/0", redis._client.id end def test_override_id redis = Redis.new(OPTIONS.merge(:id => "test")) - assert_equal redis.client.id, "test" + assert_equal redis._client.id, "test" end def test_timeout @@ -128,7 +125,7 @@ def test_tcp_keepalive redis = Redis.new(OPTIONS.merge(:tcp_keepalive => keepalive)) redis.ping - connection = redis.client.connection + connection = redis._client.connection actual_keepalive = connection.get_tcp_keepalive [:time, :intvl, :probes].each do |key| @@ -161,22 +158,10 @@ def test_connection_timeout assert (Time.now - start_time) <= opts[:timeout] end - driver(:ruby) do - def test_write_timeout - return skip("Relies on buffer sizes, might be unreliable") - - server = TCPServer.new("127.0.0.1", 0) - port = server.addr[1] - - # Hacky, but we need the buffer size - val = TCPSocket.new("127.0.0.1", port).getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).unpack("i")[0] - - assert_raise(Redis::TimeoutError) do - Timeout.timeout(1) do - redis = Redis.new(:port => port, :timeout => 5, :write_timeout => 0.1) - redis.set("foo", "1" * val*2) - end - end + def test_missing_socket + opts = { :path => '/missing.sock' } + assert_raise Redis::CannotConnectError do + Redis.new(opts).ping end end @@ -237,7 +222,7 @@ def test_retry_only_once_when_read_raises_econnreset redis.ping end - assert !redis.client.connected? + assert !redis._client.connected? end end @@ -253,7 +238,7 @@ def test_retry_with_custom_reconnect_attempts_can_still_fail redis.ping end - assert !redis.client.connected? + assert !redis._client.connected? end end @@ -266,7 +251,7 @@ def test_don_t_retry_when_second_read_in_pipeline_raises_econnreset end end - assert !redis.client.connected? + assert !redis._client.connected? end end @@ -307,14 +292,14 @@ def close_on_connection(seq) def test_retry_on_write_error_by_default close_on_connection([0]) do |redis| - assert_equal "1", redis.client.call(["x" * 128 * 1024]) + assert_equal "1", redis._client.call(["x" * 128 * 1024]) end end def test_retry_on_write_error_when_wrapped_in_with_reconnect_true close_on_connection([0]) do |redis| redis.with_reconnect(true) do - assert_equal "1", redis.client.call(["x" * 128 * 1024]) + assert_equal "1", redis._client.call(["x" * 128 * 1024]) end end end @@ -323,7 +308,7 @@ def test_dont_retry_on_write_error_when_wrapped_in_with_reconnect_false close_on_connection([0]) do |redis| assert_raise Redis::ConnectionError do redis.with_reconnect(false) do - redis.client.call(["x" * 128 * 1024]) + redis._client.call(["x" * 128 * 1024]) end end end @@ -333,7 +318,7 @@ def test_dont_retry_on_write_error_when_wrapped_in_without_reconnect close_on_connection([0]) do |redis| assert_raise Redis::ConnectionError do redis.without_reconnect do - redis.client.call(["x" * 128 * 1024]) + redis._client.call(["x" * 128 * 1024]) end end end @@ -341,7 +326,7 @@ def test_dont_retry_on_write_error_when_wrapped_in_without_reconnect def test_connecting_to_unix_domain_socket assert_nothing_raised do - Redis.new(OPTIONS.merge(:path => "./test/db/redis.sock")).ping + Redis.new(OPTIONS.merge(:path => ENV.fetch("SOCKET_PATH"))).ping end end @@ -363,23 +348,10 @@ def test_bubble_timeout_without_retrying def test_client_options 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] - assert_equal 1, redis.client.options[:db] - assert_equal "foo", redis.client.options[:scheme] - end - - def test_does_not_change_self_client_options - redis = Redis.new(OPTIONS.merge(:host => "host", :port => 1234, :db => 1, :scheme => "foo")) - options = redis.client.options - - options[:host] << "new_host" - options[:scheme] << "bar" - options.merge!(:db => 0) - - assert_equal "host", redis.client.options[:host] - assert_equal 1, redis.client.options[:db] - assert_equal "foo", redis.client.options[:scheme] + assert_equal "host", redis._client.options[:host] + assert_equal 1234, redis._client.options[:port] + assert_equal 1, redis._client.options[:db] + assert_equal "foo", redis._client.options[:scheme] end def test_resolves_localhost diff --git a/test/lint/strings.rb b/test/lint/strings.rb index 381df3cdc..e17eaf7fb 100644 --- a/test/lint/strings.rb +++ b/test/lint/strings.rb @@ -8,18 +8,6 @@ def test_set_and_get assert_equal "s1", r.get("foo") end - def test_set_and_get_with_brackets - r["foo"] = "s1" - - assert_equal "s1", r["foo"] - end - - def test_set_and_get_with_brackets_and_symbol - r[:foo] = "s1" - - assert_equal "s1", r[:foo] - end - def test_set_and_get_with_newline_characters r.set("foo", "1\n") @@ -35,14 +23,12 @@ def test_set_and_get_with_non_string_value end def test_set_and_get_with_ascii_characters - if defined?(Encoding) - with_external_encoding("ASCII-8BIT") do - (0..255).each do |i| - str = "#{i.chr}---#{i.chr}" - r.set("foo", str) - - assert_equal str, r.get("foo") - end + with_external_encoding("ASCII-8BIT") do + (0..255).each do |i| + str = "#{i.chr}---#{i.chr}" + r.set("foo", str) + + assert_equal str, r.get("foo") end end end diff --git a/test/persistence_control_commands_test.rb b/test/persistence_control_commands_test.rb index 281657152..bf7f8e9a3 100644 --- a/test/persistence_control_commands_test.rb +++ b/test/persistence_control_commands_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestPersistenceControlCommands < Test::Unit::TestCase diff --git a/test/pipelining_commands_test.rb b/test/pipelining_commands_test.rb index 82cd92f80..3f07d15e2 100644 --- a/test/pipelining_commands_test.rb +++ b/test/pipelining_commands_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestPipeliningCommands < Test::Unit::TestCase @@ -136,9 +134,7 @@ def test_futures_can_be_identified end assert_equal true, @result.is_a?(Redis::Future) - if defined?(::BasicObject) - assert_equal true, @result.is_a?(::BasicObject) - end + assert_equal true, @result.is_a?(::BasicObject) assert_equal Redis::Future, @result.class end @@ -225,7 +221,7 @@ def test_pipeline_select_client_db p2.select 2 end - assert_equal 2, r.client.db + assert_equal 2, r._client.db end def test_nested_pipeline_select_client_db @@ -237,6 +233,6 @@ def test_nested_pipeline_select_client_db end end - assert_equal 3, r.client.db + assert_equal 3, r._client.db end end diff --git a/test/publish_subscribe_test.rb b/test/publish_subscribe_test.rb index e607e628a..701e3cf7c 100644 --- a/test/publish_subscribe_test.rb +++ b/test/publish_subscribe_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestPublishSubscribe < Test::Unit::TestCase diff --git a/test/remote_server_control_commands_test.rb b/test/remote_server_control_commands_test.rb index 3ca9f879e..b5b1017e4 100644 --- a/test/remote_server_control_commands_test.rb +++ b/test/remote_server_control_commands_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestRemoteServerControlCommands < Test::Unit::TestCase @@ -115,4 +113,63 @@ def test_slowlog result = r.slowlog(:len) assert_equal 0, result end + + def test_client + assert_equal r.instance_variable_get(:@client), r._client + end + + 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" + ] + + clients = r.client(:list) + clients.each do |client| + keys.each do |k| + msg = "expected #client(:list) to include #{k}" + assert client.keys.include?(k), msg + end + end + end + + def test_client_kill + return if version < "2.6.9" + + r.client(:setname, 'redis-rb') + clients = r.client(:list) + 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'} + assert_equal nil, i + end + + def test_client_getname_and_setname + return if version < "2.6.9" + + assert_equal nil, r.client(:getname) + + r.client(:setname, 'redis-rb') + name = r.client(:getname) + assert_equal 'redis-rb', name + end end diff --git a/test/scanning_test.rb b/test/scanning_test.rb index 9a4cf7dbf..8ec0f28c0 100644 --- a/test/scanning_test.rb +++ b/test/scanning_test.rb @@ -1,10 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) - -unless defined?(Enumerator) - Enumerator = Enumerable::Enumerator -end +require_relative "helper" class TestScanning < Test::Unit::TestCase diff --git a/test/scripting_test.rb b/test/scripting_test.rb index 82d0d89e2..ea8e1532a 100644 --- a/test/scripting_test.rb +++ b/test/scripting_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestScripting < Test::Unit::TestCase diff --git a/test/sentinel_command_test.rb b/test/sentinel_command_test.rb index 1b57b1ded..50153712a 100644 --- a/test/sentinel_command_test.rb +++ b/test/sentinel_command_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class SentinelCommandsTest < Test::Unit::TestCase diff --git a/test/sentinel_test.rb b/test/sentinel_test.rb index 823e0762c..dc96ea481 100644 --- a/test/sentinel_test.rb +++ b/test/sentinel_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class SentinelTest < Test::Unit::TestCase diff --git a/test/sorting_test.rb b/test/sorting_test.rb index e8aec56a9..c9e583331 100644 --- a/test/sorting_test.rb +++ b/test/sorting_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestSorting < Test::Unit::TestCase diff --git a/test/ssl_test.rb b/test/ssl_test.rb index a92901cae..1523c99a4 100644 --- a/test/ssl_test.rb +++ b/test/ssl_test.rb @@ -1,73 +1,69 @@ -# encoding: UTF-8 +require_relative "helper" -if RUBY_VERSION >= "1.9.3" - require File.expand_path("helper", File.dirname(__FILE__)) +class SslTest < Test::Unit::TestCase - class SslTest < Test::Unit::TestCase + include Helper::Client - include Helper::Client + driver(:ruby) do - driver(:ruby) do - - 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 }) - assert_equal redis.ping, "PONG" - end - end - - def test_unverified_ssl_connection - assert_raise(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 }) - redis.ping - end - 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 }) + assert_equal redis.ping, "PONG" end + end - def test_ssl_blocking - RedisMock.start({}, ssl_server_opts("trusted")) do |port| + def test_unverified_ssl_connection + assert_raise(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 }) - assert_equal redis.set("boom", "a" * 10_000_000), "OK" + redis.ping end end + end + 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 }) + assert_equal redis.set("boom", "a" * 10_000_000), "OK" + end end - driver(:hiredis, :synchrony) do + end + + driver(:hiredis, :synchrony) do - def test_ssl_not_implemented_exception - assert_raise(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 }) - redis.ping - end + def test_ssl_not_implemented_exception + assert_raise(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 }) + redis.ping end end - end - private + end + + private - def ssl_server_opts(prefix) - ssl_cert = File.join(cert_path, "#{prefix}-cert.crt") - ssl_key = File.join(cert_path, "#{prefix}-cert.key") + def ssl_server_opts(prefix) + ssl_cert = File.join(cert_path, "#{prefix}-cert.crt") + 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 + } + end - def ssl_ca_file - File.join(cert_path, "trusted-ca.crt") - end + def ssl_ca_file + File.join(cert_path, "trusted-ca.crt") + end - def cert_path - File.expand_path("../support/ssl/", __FILE__) - end + def cert_path + File.expand_path("../support/ssl/", __FILE__) end end diff --git a/test/support/connection/hiredis.rb b/test/support/connection/hiredis.rb index f2ccbca5f..46078c1c5 100644 --- a/test/support/connection/hiredis.rb +++ b/test/support/connection/hiredis.rb @@ -1 +1 @@ -require "support/wire/thread" +require_relative "../wire/thread" diff --git a/test/support/connection/ruby.rb b/test/support/connection/ruby.rb index f2ccbca5f..46078c1c5 100644 --- a/test/support/connection/ruby.rb +++ b/test/support/connection/ruby.rb @@ -1 +1 @@ -require "support/wire/thread" +require_relative "../wire/thread" diff --git a/test/support/connection/synchrony.rb b/test/support/connection/synchrony.rb index 80acb0afe..90b516b5f 100644 --- a/test/support/connection/synchrony.rb +++ b/test/support/connection/synchrony.rb @@ -1,4 +1,4 @@ -require "support/wire/synchrony" +require_relative "../wire/synchrony" module Helper def around diff --git a/test/synchrony_driver.rb b/test/synchrony_driver.rb index 82b13a794..842c74504 100644 --- a/test/synchrony_driver.rb +++ b/test/synchrony_driver.rb @@ -1,13 +1,10 @@ -# encoding: UTF-8 +require "em-synchrony" +require "em-synchrony/connection_pool" -require 'em-synchrony' -require 'em-synchrony/connection_pool' +require_relative "../lib/redis" +require_relative "../lib/redis/connection/synchrony" -require 'redis' -require 'redis/connection/synchrony' - - -require File.expand_path("./helper", File.dirname(__FILE__)) +require_relative "helper" PORT = 6381 OPTIONS = {:port => PORT, :db => 15} @@ -55,7 +52,7 @@ assert_equal "s2", r.lpop("foo") assert_equal "s1", r.lpop("foo") - assert_equal "OK", r.client.call(:quit) + assert_equal "OK", r._client.call(:quit) assert_equal "PONG", r.ping diff --git a/test/thread_safety_test.rb b/test/thread_safety_test.rb index f03ad7762..91ce0f73d 100644 --- a/test/thread_safety_test.rb +++ b/test/thread_safety_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestThreadSafety < Test::Unit::TestCase diff --git a/test/transactions_test.rb b/test/transactions_test.rb index 3f588b29f..de916cb80 100644 --- a/test/transactions_test.rb +++ b/test/transactions_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestTransactions < Test::Unit::TestCase diff --git a/test/unknown_commands_test.rb b/test/unknown_commands_test.rb index 0d1ca5827..374690bc8 100644 --- a/test/unknown_commands_test.rb +++ b/test/unknown_commands_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestUnknownCommands < Test::Unit::TestCase diff --git a/test/url_param_test.rb b/test/url_param_test.rb index 468bbf1f7..a30167c5e 100644 --- a/test/url_param_test.rb +++ b/test/url_param_test.rb @@ -1,6 +1,4 @@ -# encoding: UTF-8 - -require File.expand_path("helper", File.dirname(__FILE__)) +require_relative "helper" class TestUrlParam < Test::Unit::TestCase @@ -9,104 +7,104 @@ class TestUrlParam < Test::Unit::TestCase def test_url_defaults_to_______________ redis = Redis.new - assert_equal "127.0.0.1", redis.client.host - assert_equal 6379, redis.client.port - assert_equal 0, redis.client.db - assert_equal nil, redis.client.password + assert_equal "127.0.0.1", redis._client.host + assert_equal 6379, redis._client.port + assert_equal 0, redis._client.db + assert_equal nil, redis._client.password end def test_allows_to_pass_in_a_url redis = Redis.new :url => "redis://:secr3t@foo.com:999/2" - assert_equal "foo.com", redis.client.host - assert_equal 999, redis.client.port - assert_equal 2, redis.client.db - assert_equal "secr3t", redis.client.password + assert_equal "foo.com", redis._client.host + assert_equal 999, redis._client.port + assert_equal 2, redis._client.db + assert_equal "secr3t", redis._client.password end def test_allows_to_pass_in_a_url_with_string_key redis = Redis.new "url" => "redis://:secr3t@foo.com:999/2" - assert_equal "foo.com", redis.client.host - assert_equal 999, redis.client.port - assert_equal 2, redis.client.db - assert_equal "secr3t", redis.client.password + assert_equal "foo.com", redis._client.host + assert_equal 999, redis._client.port + assert_equal 2, redis._client.db + assert_equal "secr3t", redis._client.password end def test_unescape_password_from_url redis = Redis.new :url => "redis://:secr3t%3A@foo.com:999/2" - assert_equal "secr3t:", redis.client.password + assert_equal "secr3t:", redis._client.password end def test_unescape_password_from_url_with_string_key redis = Redis.new "url" => "redis://:secr3t%3A@foo.com:999/2" - assert_equal "secr3t:", redis.client.password + assert_equal "secr3t:", redis._client.password end def test_does_not_unescape_password_when_explicitly_passed redis = Redis.new :url => "redis://:secr3t%3A@foo.com:999/2", :password => "secr3t%3A" - assert_equal "secr3t%3A", redis.client.password + assert_equal "secr3t%3A", redis._client.password end def test_does_not_unescape_password_when_explicitly_passed_with_string_key redis = Redis.new :url => "redis://:secr3t%3A@foo.com:999/2", "password" => "secr3t%3A" - assert_equal "secr3t%3A", redis.client.password + assert_equal "secr3t%3A", redis._client.password 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" - assert_equal "/tmp/redis.sock", redis.client.path - assert_equal nil, redis.client.host - assert_equal nil, redis.client.port + assert_equal "/tmp/redis.sock", redis._client.path + assert_equal nil, redis._client.host + assert_equal nil, redis._client.port end def test_override_url_if_path_option_is_passed_with_string_key redis = Redis.new :url => "redis://:secr3t@foo.com/foo:999/2", "path" => "/tmp/redis.sock" - assert_equal "/tmp/redis.sock", redis.client.path - assert_equal nil, redis.client.host - assert_equal nil, redis.client.port + assert_equal "/tmp/redis.sock", redis._client.path + assert_equal nil, redis._client.host + assert_equal nil, redis._client.port end def test_overrides_url_if_another_connection_option_is_passed 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 - assert_equal 2, redis.client.db - assert_equal "secr3t", redis.client.password + assert_equal "foo.com", redis._client.host + assert_equal 1000, redis._client.port + assert_equal 2, redis._client.db + assert_equal "secr3t", redis._client.password end def test_overrides_url_if_another_connection_option_is_passed_with_string_key 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 - assert_equal 2, redis.client.db - assert_equal "secr3t", redis.client.password + assert_equal "foo.com", redis._client.host + assert_equal 1000, redis._client.port + assert_equal 2, redis._client.db + assert_equal "secr3t", redis._client.password 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 - assert_equal "foo.com", redis.client.host - assert_equal 999, redis.client.port - assert_equal 2, redis.client.db - assert_equal "secr3t", redis.client.password + assert_equal "foo.com", redis._client.host + assert_equal 999, redis._client.port + assert_equal 2, redis._client.db + assert_equal "secr3t", redis._client.password end def test_does_not_overrides_url_if_a_nil_option_is_passed_with_string_key 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 - assert_equal 2, redis.client.db - assert_equal "secr3t", redis.client.password + assert_equal "foo.com", redis._client.host + assert_equal 999, redis._client.port + assert_equal 2, redis._client.db + assert_equal "secr3t", redis._client.password end def test_does_not_modify_the_passed_options @@ -122,10 +120,10 @@ def test_uses_redis_url_over_default_if_available redis = Redis.new - assert_equal "foo.com", redis.client.host - assert_equal 999, redis.client.port - assert_equal 2, redis.client.db - assert_equal "secr3t", redis.client.password + assert_equal "foo.com", redis._client.host + assert_equal 999, redis._client.port + assert_equal 2, redis._client.db + assert_equal "secr3t", redis._client.password ENV.delete("REDIS_URL") end @@ -133,6 +131,6 @@ def test_uses_redis_url_over_default_if_available def test_defaults_to_localhost redis = Redis.new(:url => "redis:///") - assert_equal "127.0.0.1", redis.client.host + assert_equal "127.0.0.1", redis._client.host end end