finsync_redis 3.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis/Gemfile +11 -0
  4. data/.travis.yml +89 -0
  5. data/.yardopts +3 -0
  6. data/CHANGELOG.md +373 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +20 -0
  9. data/README.md +410 -0
  10. data/Rakefile +87 -0
  11. data/benchmarking/logging.rb +71 -0
  12. data/benchmarking/pipeline.rb +51 -0
  13. data/benchmarking/speed.rb +21 -0
  14. data/benchmarking/suite.rb +24 -0
  15. data/benchmarking/worker.rb +71 -0
  16. data/examples/basic.rb +15 -0
  17. data/examples/consistency.rb +114 -0
  18. data/examples/dist_redis.rb +43 -0
  19. data/examples/incr-decr.rb +17 -0
  20. data/examples/list.rb +26 -0
  21. data/examples/pubsub.rb +37 -0
  22. data/examples/sentinel/sentinel.conf +9 -0
  23. data/examples/sentinel/start +49 -0
  24. data/examples/sentinel.rb +41 -0
  25. data/examples/sets.rb +36 -0
  26. data/examples/unicorn/config.ru +3 -0
  27. data/examples/unicorn/unicorn.rb +20 -0
  28. data/lib/redis/client.rb +590 -0
  29. data/lib/redis/connection/command_helper.rb +44 -0
  30. data/lib/redis/connection/hiredis.rb +66 -0
  31. data/lib/redis/connection/registry.rb +12 -0
  32. data/lib/redis/connection/ruby.rb +429 -0
  33. data/lib/redis/connection/synchrony.rb +133 -0
  34. data/lib/redis/connection.rb +9 -0
  35. data/lib/redis/distributed.rb +873 -0
  36. data/lib/redis/errors.rb +40 -0
  37. data/lib/redis/hash_ring.rb +132 -0
  38. data/lib/redis/pipeline.rb +141 -0
  39. data/lib/redis/subscribe.rb +91 -0
  40. data/lib/redis/version.rb +3 -0
  41. data/lib/redis.rb +2788 -0
  42. data/redis.gemspec +44 -0
  43. data/test/bitpos_test.rb +69 -0
  44. data/test/blocking_commands_test.rb +42 -0
  45. data/test/client_test.rb +59 -0
  46. data/test/command_map_test.rb +30 -0
  47. data/test/commands_on_hashes_test.rb +21 -0
  48. data/test/commands_on_hyper_log_log_test.rb +21 -0
  49. data/test/commands_on_lists_test.rb +20 -0
  50. data/test/commands_on_sets_test.rb +77 -0
  51. data/test/commands_on_sorted_sets_test.rb +137 -0
  52. data/test/commands_on_strings_test.rb +101 -0
  53. data/test/commands_on_value_types_test.rb +133 -0
  54. data/test/connection_handling_test.rb +277 -0
  55. data/test/connection_test.rb +57 -0
  56. data/test/db/.gitkeep +0 -0
  57. data/test/distributed_blocking_commands_test.rb +46 -0
  58. data/test/distributed_commands_on_hashes_test.rb +10 -0
  59. data/test/distributed_commands_on_hyper_log_log_test.rb +33 -0
  60. data/test/distributed_commands_on_lists_test.rb +22 -0
  61. data/test/distributed_commands_on_sets_test.rb +83 -0
  62. data/test/distributed_commands_on_sorted_sets_test.rb +18 -0
  63. data/test/distributed_commands_on_strings_test.rb +59 -0
  64. data/test/distributed_commands_on_value_types_test.rb +95 -0
  65. data/test/distributed_commands_requiring_clustering_test.rb +164 -0
  66. data/test/distributed_connection_handling_test.rb +23 -0
  67. data/test/distributed_internals_test.rb +79 -0
  68. data/test/distributed_key_tags_test.rb +52 -0
  69. data/test/distributed_persistence_control_commands_test.rb +26 -0
  70. data/test/distributed_publish_subscribe_test.rb +92 -0
  71. data/test/distributed_remote_server_control_commands_test.rb +66 -0
  72. data/test/distributed_scripting_test.rb +102 -0
  73. data/test/distributed_sorting_test.rb +20 -0
  74. data/test/distributed_test.rb +58 -0
  75. data/test/distributed_transactions_test.rb +32 -0
  76. data/test/encoding_test.rb +18 -0
  77. data/test/error_replies_test.rb +59 -0
  78. data/test/fork_safety_test.rb +65 -0
  79. data/test/helper.rb +232 -0
  80. data/test/helper_test.rb +24 -0
  81. data/test/internals_test.rb +417 -0
  82. data/test/lint/blocking_commands.rb +150 -0
  83. data/test/lint/hashes.rb +162 -0
  84. data/test/lint/hyper_log_log.rb +60 -0
  85. data/test/lint/lists.rb +143 -0
  86. data/test/lint/sets.rb +140 -0
  87. data/test/lint/sorted_sets.rb +316 -0
  88. data/test/lint/strings.rb +260 -0
  89. data/test/lint/value_types.rb +122 -0
  90. data/test/persistence_control_commands_test.rb +26 -0
  91. data/test/pipelining_commands_test.rb +242 -0
  92. data/test/publish_subscribe_test.rb +282 -0
  93. data/test/remote_server_control_commands_test.rb +118 -0
  94. data/test/scanning_test.rb +413 -0
  95. data/test/scripting_test.rb +78 -0
  96. data/test/sentinel_command_test.rb +80 -0
  97. data/test/sentinel_test.rb +255 -0
  98. data/test/sorting_test.rb +59 -0
  99. data/test/ssl_test.rb +73 -0
  100. data/test/support/connection/hiredis.rb +1 -0
  101. data/test/support/connection/ruby.rb +1 -0
  102. data/test/support/connection/synchrony.rb +17 -0
  103. data/test/support/redis_mock.rb +130 -0
  104. data/test/support/ssl/gen_certs.sh +31 -0
  105. data/test/support/ssl/trusted-ca.crt +25 -0
  106. data/test/support/ssl/trusted-ca.key +27 -0
  107. data/test/support/ssl/trusted-cert.crt +81 -0
  108. data/test/support/ssl/trusted-cert.key +28 -0
  109. data/test/support/ssl/untrusted-ca.crt +26 -0
  110. data/test/support/ssl/untrusted-ca.key +27 -0
  111. data/test/support/ssl/untrusted-cert.crt +82 -0
  112. data/test/support/ssl/untrusted-cert.key +28 -0
  113. data/test/support/wire/synchrony.rb +24 -0
  114. data/test/support/wire/thread.rb +5 -0
  115. data/test/synchrony_driver.rb +88 -0
  116. data/test/test.conf.erb +9 -0
  117. data/test/thread_safety_test.rb +62 -0
  118. data/test/transactions_test.rb +264 -0
  119. data/test/unknown_commands_test.rb +14 -0
  120. data/test/url_param_test.rb +138 -0
  121. metadata +202 -0
data/redis.gemspec ADDED
@@ -0,0 +1,44 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.unshift File.expand_path("../lib", __FILE__)
4
+
5
+ require "redis/version"
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "finsync_redis"
9
+
10
+ s.version = Redis::VERSION
11
+
12
+ s.homepage = "https://github.com/finsync/redis-rb"
13
+
14
+ s.summary = "FINSYNC modifications for Redis"
15
+
16
+ s.description = <<-EOS
17
+ A Ruby client that tries to match Redis' API one-to-one, while still
18
+ providing an idiomatic interface. It features thread-safety,
19
+ client-side sharding, pipelining, and an obsession for performance.
20
+ EOS
21
+
22
+ s.license = "MIT"
23
+
24
+ s.authors = [
25
+ "Ezra Zygmuntowicz",
26
+ "Taylor Weibley",
27
+ "Matthew Clark",
28
+ "Brian McKinney",
29
+ "Salvatore Sanfilippo",
30
+ "Luca Guidi",
31
+ "Michel Martens",
32
+ "Damian Janowski",
33
+ "Pieter Noordhuis"
34
+ ]
35
+
36
+ s.email = ["redis-db@googlegroups.com"]
37
+
38
+ s.files = `git ls-files`.split("\n")
39
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
40
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
41
+
42
+ s.add_development_dependency("rake", "<11.0.0")
43
+ s.add_development_dependency("test-unit", "3.1.5")
44
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+
5
+ unless defined?(Enumerator)
6
+ Enumerator = Enumerable::Enumerator
7
+ end
8
+
9
+ class TestBitpos < Test::Unit::TestCase
10
+
11
+ include Helper::Client
12
+
13
+ def test_bitpos_empty_zero
14
+ target_version "2.9.11" do
15
+ r.del "foo"
16
+ assert_equal 0, r.bitpos("foo", 0)
17
+ end
18
+ end
19
+
20
+ def test_bitpos_empty_one
21
+ target_version "2.9.11" do
22
+ r.del "foo"
23
+ assert_equal -1, r.bitpos("foo", 1)
24
+ end
25
+ end
26
+
27
+ def test_bitpos_zero
28
+ target_version "2.9.11" do
29
+ r.set "foo", "\xff\xf0\x00"
30
+ assert_equal 12, r.bitpos("foo", 0)
31
+ end
32
+ end
33
+
34
+ def test_bitpos_one
35
+ target_version "2.9.11" do
36
+ r.set "foo", "\x00\x0f\x00"
37
+ assert_equal 12, r.bitpos("foo", 1)
38
+ end
39
+ end
40
+
41
+ def test_bitpos_zero_end_is_given
42
+ target_version "2.9.11" do
43
+ r.set "foo", "\xff\xff\xff"
44
+ assert_equal 24, r.bitpos("foo", 0)
45
+ assert_equal 24, r.bitpos("foo", 0, 0)
46
+ assert_equal -1, r.bitpos("foo", 0, 0, -1)
47
+ end
48
+ end
49
+
50
+ def test_bitpos_one_intervals
51
+ target_version "2.9.11" do
52
+ r.set "foo", "\x00\xff\x00"
53
+ assert_equal 8, r.bitpos("foo", 1, 0, -1)
54
+ assert_equal 8, r.bitpos("foo", 1, 1, -1)
55
+ assert_equal -1, r.bitpos("foo", 1, 2, -1)
56
+ assert_equal -1, r.bitpos("foo", 1, 2, 200)
57
+ assert_equal 8, r.bitpos("foo", 1, 1, 1)
58
+ end
59
+ end
60
+
61
+ def test_bitpos_raise_exception_if_stop_not_start
62
+ target_version "2.9.11" do
63
+ assert_raises(ArgumentError) do
64
+ r.bitpos("foo", 0, nil, 2)
65
+ end
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/blocking_commands"
5
+
6
+ class TestBlockingCommands < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::BlockingCommands
10
+
11
+ def assert_takes_longer_than_client_timeout
12
+ timeout = OPTIONS[:timeout]
13
+ delay = timeout * 2
14
+
15
+ mock(:delay => delay) do |r|
16
+ t1 = Time.now
17
+ yield(r)
18
+ t2 = Time.now
19
+
20
+ assert timeout == r.client.timeout
21
+ assert delay <= (t2 - t1)
22
+ end
23
+ end
24
+
25
+ def test_blpop_disable_client_timeout
26
+ assert_takes_longer_than_client_timeout do |r|
27
+ assert_equal ["foo", "0"], r.blpop("foo")
28
+ end
29
+ end
30
+
31
+ def test_brpop_disable_client_timeout
32
+ assert_takes_longer_than_client_timeout do |r|
33
+ assert_equal ["foo", "0"], r.brpop("foo")
34
+ end
35
+ end
36
+
37
+ def test_brpoplpush_disable_client_timeout
38
+ assert_takes_longer_than_client_timeout do |r|
39
+ assert_equal "0", r.brpoplpush("foo", "bar")
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path("helper", File.dirname(__FILE__))
2
+
3
+ class TestClient < Test::Unit::TestCase
4
+
5
+ include Helper::Client
6
+
7
+ def test_call
8
+ result = r.call("PING")
9
+ assert_equal result, "PONG"
10
+ end
11
+
12
+ def test_call_with_arguments
13
+ result = r.call("SET", "foo", "bar")
14
+ assert_equal result, "OK"
15
+ end
16
+
17
+ def test_call_integers
18
+ result = r.call("INCR", "foo")
19
+ assert_equal result, 1
20
+ end
21
+
22
+ def test_call_raise
23
+ assert_raises(Redis::CommandError) do
24
+ r.call("INCR")
25
+ end
26
+ end
27
+
28
+ def test_queue_commit
29
+ r.queue("SET", "foo", "bar")
30
+ r.queue("GET", "foo")
31
+ result = r.commit
32
+
33
+ assert_equal result, ["OK", "bar"]
34
+ end
35
+
36
+ def test_commit_raise
37
+ r.queue("SET", "foo", "bar")
38
+ r.queue("INCR")
39
+
40
+ assert_raise(Redis::CommandError) do
41
+ r.commit
42
+ end
43
+ end
44
+
45
+ def test_queue_after_error
46
+ r.queue("SET", "foo", "bar")
47
+ r.queue("INCR")
48
+
49
+ assert_raise(Redis::CommandError) do
50
+ r.commit
51
+ end
52
+
53
+ r.queue("SET", "foo", "bar")
54
+ r.queue("INCR", "baz")
55
+ result = r.commit
56
+
57
+ assert_equal result, ["OK", 1]
58
+ end
59
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+
5
+ class TestCommandMap < Test::Unit::TestCase
6
+
7
+ include Helper::Client
8
+
9
+ def test_override_existing_commands
10
+ r.set("counter", 1)
11
+
12
+ assert_equal 2, r.incr("counter")
13
+
14
+ r.client.command_map[:incr] = :decr
15
+
16
+ assert_equal 1, r.incr("counter")
17
+ end
18
+
19
+ def test_override_non_existing_commands
20
+ r.set("key", "value")
21
+
22
+ assert_raise Redis::CommandError do
23
+ r.idontexist("key")
24
+ end
25
+
26
+ r.client.command_map[:idontexist] = :get
27
+
28
+ assert_equal "value", r.idontexist("key")
29
+ end
30
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/hashes"
5
+
6
+ class TestCommandsOnHashes < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::Hashes
10
+
11
+ def test_mapped_hmget_in_a_pipeline_returns_hash
12
+ r.hset("foo", "f1", "s1")
13
+ r.hset("foo", "f2", "s2")
14
+
15
+ result = r.pipelined do
16
+ r.mapped_hmget("foo", "f1", "f2")
17
+ end
18
+
19
+ assert_equal result[0], { "f1" => "s1", "f2" => "s2" }
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/hyper_log_log"
5
+
6
+ class TestCommandsOnHyperLogLog < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::HyperLogLog
10
+
11
+ def test_pfmerge
12
+ target_version "2.8.9" do
13
+ r.pfadd "foo", "s1"
14
+ r.pfadd "bar", "s2"
15
+
16
+ assert_equal true, r.pfmerge("res", "foo", "bar")
17
+ assert_equal 2, r.pfcount("res")
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/lists"
5
+
6
+ class TestCommandsOnLists < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::Lists
10
+
11
+ def test_rpoplpush
12
+ r.rpush "foo", "s1"
13
+ r.rpush "foo", "s2"
14
+
15
+ assert_equal "s2", r.rpoplpush("foo", "bar")
16
+ assert_equal ["s2"], r.lrange("bar", 0, -1)
17
+ assert_equal "s1", r.rpoplpush("foo", "bar")
18
+ assert_equal ["s1", "s2"], r.lrange("bar", 0, -1)
19
+ end
20
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/sets"
5
+
6
+ class TestCommandsOnSets < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::Sets
10
+
11
+ def test_smove
12
+ r.sadd "foo", "s1"
13
+ r.sadd "bar", "s2"
14
+
15
+ assert r.smove("foo", "bar", "s1")
16
+ assert r.sismember("bar", "s1")
17
+ end
18
+
19
+ def test_sinter
20
+ r.sadd "foo", "s1"
21
+ r.sadd "foo", "s2"
22
+ r.sadd "bar", "s2"
23
+
24
+ assert_equal ["s2"], r.sinter("foo", "bar")
25
+ end
26
+
27
+ def test_sinterstore
28
+ r.sadd "foo", "s1"
29
+ r.sadd "foo", "s2"
30
+ r.sadd "bar", "s2"
31
+
32
+ r.sinterstore("baz", "foo", "bar")
33
+
34
+ assert_equal ["s2"], r.smembers("baz")
35
+ end
36
+
37
+ def test_sunion
38
+ r.sadd "foo", "s1"
39
+ r.sadd "foo", "s2"
40
+ r.sadd "bar", "s2"
41
+ r.sadd "bar", "s3"
42
+
43
+ assert_equal ["s1", "s2", "s3"], r.sunion("foo", "bar").sort
44
+ end
45
+
46
+ def test_sunionstore
47
+ r.sadd "foo", "s1"
48
+ r.sadd "foo", "s2"
49
+ r.sadd "bar", "s2"
50
+ r.sadd "bar", "s3"
51
+
52
+ r.sunionstore("baz", "foo", "bar")
53
+
54
+ assert_equal ["s1", "s2", "s3"], r.smembers("baz").sort
55
+ end
56
+
57
+ def test_sdiff
58
+ r.sadd "foo", "s1"
59
+ r.sadd "foo", "s2"
60
+ r.sadd "bar", "s2"
61
+ r.sadd "bar", "s3"
62
+
63
+ assert_equal ["s1"], r.sdiff("foo", "bar")
64
+ assert_equal ["s3"], r.sdiff("bar", "foo")
65
+ end
66
+
67
+ def test_sdiffstore
68
+ r.sadd "foo", "s1"
69
+ r.sadd "foo", "s2"
70
+ r.sadd "bar", "s2"
71
+ r.sadd "bar", "s3"
72
+
73
+ r.sdiffstore("baz", "foo", "bar")
74
+
75
+ assert_equal ["s1"], r.smembers("baz")
76
+ end
77
+ end
@@ -0,0 +1,137 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/sorted_sets"
5
+
6
+ class TestCommandsOnSortedSets < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::SortedSets
10
+
11
+ def test_zrangebylex
12
+ target_version "2.8.9" do
13
+ r.zadd "foo", 0, "aaren"
14
+ r.zadd "foo", 0, "abagael"
15
+ r.zadd "foo", 0, "abby"
16
+ r.zadd "foo", 0, "abbygail"
17
+
18
+ assert_equal ["aaren", "abagael", "abby", "abbygail"], r.zrangebylex("foo", "[a", "[a\xff")
19
+ assert_equal ["aaren", "abagael"], r.zrangebylex("foo", "[a", "[a\xff", :limit => [0, 2])
20
+ assert_equal ["abby", "abbygail"], r.zrangebylex("foo", "(abb", "(abb\xff")
21
+ assert_equal ["abbygail"], r.zrangebylex("foo", "(abby", "(abby\xff")
22
+ end
23
+ end
24
+
25
+ def test_zrevrangebylex
26
+ target_version "2.9.9" do
27
+ r.zadd "foo", 0, "aaren"
28
+ r.zadd "foo", 0, "abagael"
29
+ r.zadd "foo", 0, "abby"
30
+ r.zadd "foo", 0, "abbygail"
31
+
32
+ assert_equal ["abbygail", "abby", "abagael", "aaren"], r.zrevrangebylex("foo", "[a\xff", "[a")
33
+ assert_equal ["abbygail", "abby"], r.zrevrangebylex("foo", "[a\xff", "[a", :limit => [0, 2])
34
+ assert_equal ["abbygail", "abby"], r.zrevrangebylex("foo", "(abb\xff", "(abb")
35
+ assert_equal ["abbygail"], r.zrevrangebylex("foo", "(abby\xff", "(abby")
36
+ end
37
+ end
38
+
39
+ def test_zcount
40
+ r.zadd "foo", 1, "s1"
41
+ r.zadd "foo", 2, "s2"
42
+ r.zadd "foo", 3, "s3"
43
+
44
+ assert_equal 2, r.zcount("foo", 2, 3)
45
+ end
46
+
47
+ def test_zunionstore
48
+ r.zadd "foo", 1, "s1"
49
+ r.zadd "bar", 2, "s2"
50
+ r.zadd "foo", 3, "s3"
51
+ r.zadd "bar", 4, "s4"
52
+
53
+ assert_equal 4, r.zunionstore("foobar", ["foo", "bar"])
54
+ assert_equal ["s1", "s2", "s3", "s4"], r.zrange("foobar", 0, -1)
55
+ end
56
+
57
+ def test_zunionstore_with_weights
58
+ r.zadd "foo", 1, "s1"
59
+ r.zadd "foo", 3, "s3"
60
+ r.zadd "bar", 20, "s2"
61
+ r.zadd "bar", 40, "s4"
62
+
63
+ assert_equal 4, r.zunionstore("foobar", ["foo", "bar"])
64
+ assert_equal ["s1", "s3", "s2", "s4"], r.zrange("foobar", 0, -1)
65
+
66
+ assert_equal 4, r.zunionstore("foobar", ["foo", "bar"], :weights => [10, 1])
67
+ assert_equal ["s1", "s2", "s3", "s4"], r.zrange("foobar", 0, -1)
68
+ end
69
+
70
+ def test_zunionstore_with_aggregate
71
+ r.zadd "foo", 1, "s1"
72
+ r.zadd "foo", 2, "s2"
73
+ r.zadd "bar", 4, "s2"
74
+ r.zadd "bar", 3, "s3"
75
+
76
+ assert_equal 3, r.zunionstore("foobar", ["foo", "bar"])
77
+ assert_equal ["s1", "s3", "s2"], r.zrange("foobar", 0, -1)
78
+
79
+ assert_equal 3, r.zunionstore("foobar", ["foo", "bar"], :aggregate => :min)
80
+ assert_equal ["s1", "s2", "s3"], r.zrange("foobar", 0, -1)
81
+
82
+ assert_equal 3, r.zunionstore("foobar", ["foo", "bar"], :aggregate => :max)
83
+ assert_equal ["s1", "s3", "s2"], r.zrange("foobar", 0, -1)
84
+ end
85
+
86
+ def test_zinterstore
87
+ r.zadd "foo", 1, "s1"
88
+ r.zadd "bar", 2, "s1"
89
+ r.zadd "foo", 3, "s3"
90
+ r.zadd "bar", 4, "s4"
91
+
92
+ assert_equal 1, r.zinterstore("foobar", ["foo", "bar"])
93
+ assert_equal ["s1"], r.zrange("foobar", 0, -1)
94
+ end
95
+
96
+ def test_zinterstore_with_weights
97
+ r.zadd "foo", 1, "s1"
98
+ r.zadd "foo", 2, "s2"
99
+ r.zadd "foo", 3, "s3"
100
+ r.zadd "bar", 20, "s2"
101
+ r.zadd "bar", 30, "s3"
102
+ r.zadd "bar", 40, "s4"
103
+
104
+ assert_equal 2, r.zinterstore("foobar", ["foo", "bar"])
105
+ assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
106
+
107
+ assert_equal 2, r.zinterstore("foobar", ["foo", "bar"], :weights => [10, 1])
108
+ assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
109
+
110
+ assert_equal 40.0, r.zscore("foobar", "s2")
111
+ assert_equal 60.0, r.zscore("foobar", "s3")
112
+ end
113
+
114
+ def test_zinterstore_with_aggregate
115
+ r.zadd "foo", 1, "s1"
116
+ r.zadd "foo", 2, "s2"
117
+ r.zadd "foo", 3, "s3"
118
+ r.zadd "bar", 20, "s2"
119
+ r.zadd "bar", 30, "s3"
120
+ r.zadd "bar", 40, "s4"
121
+
122
+ assert_equal 2, r.zinterstore("foobar", ["foo", "bar"])
123
+ assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
124
+ assert_equal 22.0, r.zscore("foobar", "s2")
125
+ assert_equal 33.0, r.zscore("foobar", "s3")
126
+
127
+ assert_equal 2, r.zinterstore("foobar", ["foo", "bar"], :aggregate => :min)
128
+ assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
129
+ assert_equal 2.0, r.zscore("foobar", "s2")
130
+ assert_equal 3.0, r.zscore("foobar", "s3")
131
+
132
+ assert_equal 2, r.zinterstore("foobar", ["foo", "bar"], :aggregate => :max)
133
+ assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
134
+ assert_equal 20.0, r.zscore("foobar", "s2")
135
+ assert_equal 30.0, r.zscore("foobar", "s3")
136
+ end
137
+ end
@@ -0,0 +1,101 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/strings"
5
+
6
+ class TestCommandsOnStrings < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::Strings
10
+
11
+ def test_mget
12
+ r.set("foo", "s1")
13
+ r.set("bar", "s2")
14
+
15
+ assert_equal ["s1", "s2"] , r.mget("foo", "bar")
16
+ assert_equal ["s1", "s2", nil], r.mget("foo", "bar", "baz")
17
+ end
18
+
19
+ def test_mget_mapped
20
+ r.set("foo", "s1")
21
+ r.set("bar", "s2")
22
+
23
+ response = r.mapped_mget("foo", "bar")
24
+
25
+ assert_equal "s1", response["foo"]
26
+ assert_equal "s2", response["bar"]
27
+
28
+ response = r.mapped_mget("foo", "bar", "baz")
29
+
30
+ assert_equal "s1", response["foo"]
31
+ assert_equal "s2", response["bar"]
32
+ assert_equal nil , response["baz"]
33
+ end
34
+
35
+ def test_mapped_mget_in_a_pipeline_returns_hash
36
+ r.set("foo", "s1")
37
+ r.set("bar", "s2")
38
+
39
+ result = r.pipelined do
40
+ r.mapped_mget("foo", "bar")
41
+ end
42
+
43
+ assert_equal result[0], { "foo" => "s1", "bar" => "s2" }
44
+ end
45
+
46
+ def test_mset
47
+ r.mset(:foo, "s1", :bar, "s2")
48
+
49
+ assert_equal "s1", r.get("foo")
50
+ assert_equal "s2", r.get("bar")
51
+ end
52
+
53
+ def test_mset_mapped
54
+ r.mapped_mset(:foo => "s1", :bar => "s2")
55
+
56
+ assert_equal "s1", r.get("foo")
57
+ assert_equal "s2", r.get("bar")
58
+ end
59
+
60
+ def test_msetnx
61
+ r.set("foo", "s1")
62
+ assert_equal false, r.msetnx(:foo, "s2", :bar, "s3")
63
+ assert_equal "s1", r.get("foo")
64
+ assert_equal nil, r.get("bar")
65
+
66
+ r.del("foo")
67
+ assert_equal true, r.msetnx(:foo, "s2", :bar, "s3")
68
+ assert_equal "s2", r.get("foo")
69
+ assert_equal "s3", r.get("bar")
70
+ end
71
+
72
+ def test_msetnx_mapped
73
+ r.set("foo", "s1")
74
+ assert_equal false, r.mapped_msetnx(:foo => "s2", :bar => "s3")
75
+ assert_equal "s1", r.get("foo")
76
+ assert_equal nil, r.get("bar")
77
+
78
+ r.del("foo")
79
+ assert_equal true, r.mapped_msetnx(:foo => "s2", :bar => "s3")
80
+ assert_equal "s2", r.get("foo")
81
+ assert_equal "s3", r.get("bar")
82
+ end
83
+
84
+ def test_bitop
85
+ try_encoding("UTF-8") do
86
+ target_version "2.5.10" do
87
+ r.set("foo", "a")
88
+ r.set("bar", "b")
89
+
90
+ r.bitop(:and, "foo&bar", "foo", "bar")
91
+ assert_equal "\x60", r.get("foo&bar")
92
+ r.bitop(:or, "foo|bar", "foo", "bar")
93
+ assert_equal "\x63", r.get("foo|bar")
94
+ r.bitop(:xor, "foo^bar", "foo", "bar")
95
+ assert_equal "\x03", r.get("foo^bar")
96
+ r.bitop(:not, "~foo", "foo")
97
+ assert_equal "\x9E", r.get("~foo")
98
+ end
99
+ end
100
+ end
101
+ end