discourse-redis 3.2.2

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 (107) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +59 -0
  4. data/.travis/Gemfile +11 -0
  5. data/.yardopts +3 -0
  6. data/CHANGELOG.md +349 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +20 -0
  9. data/README.md +328 -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.rb +41 -0
  23. data/examples/sentinel/start +49 -0
  24. data/examples/sets.rb +36 -0
  25. data/examples/unicorn/config.ru +3 -0
  26. data/examples/unicorn/unicorn.rb +20 -0
  27. data/lib/redis.rb +2731 -0
  28. data/lib/redis/client.rb +575 -0
  29. data/lib/redis/connection.rb +9 -0
  30. data/lib/redis/connection/command_helper.rb +44 -0
  31. data/lib/redis/connection/hiredis.rb +64 -0
  32. data/lib/redis/connection/registry.rb +12 -0
  33. data/lib/redis/connection/ruby.rb +322 -0
  34. data/lib/redis/connection/synchrony.rb +124 -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 +83 -0
  40. data/lib/redis/version.rb +3 -0
  41. data/redis.gemspec +34 -0
  42. data/test/bitpos_test.rb +69 -0
  43. data/test/blocking_commands_test.rb +42 -0
  44. data/test/command_map_test.rb +30 -0
  45. data/test/commands_on_hashes_test.rb +21 -0
  46. data/test/commands_on_hyper_log_log_test.rb +21 -0
  47. data/test/commands_on_lists_test.rb +20 -0
  48. data/test/commands_on_sets_test.rb +77 -0
  49. data/test/commands_on_sorted_sets_test.rb +137 -0
  50. data/test/commands_on_strings_test.rb +101 -0
  51. data/test/commands_on_value_types_test.rb +133 -0
  52. data/test/connection_handling_test.rb +250 -0
  53. data/test/distributed_blocking_commands_test.rb +46 -0
  54. data/test/distributed_commands_on_hashes_test.rb +10 -0
  55. data/test/distributed_commands_on_hyper_log_log_test.rb +33 -0
  56. data/test/distributed_commands_on_lists_test.rb +22 -0
  57. data/test/distributed_commands_on_sets_test.rb +83 -0
  58. data/test/distributed_commands_on_sorted_sets_test.rb +18 -0
  59. data/test/distributed_commands_on_strings_test.rb +59 -0
  60. data/test/distributed_commands_on_value_types_test.rb +95 -0
  61. data/test/distributed_commands_requiring_clustering_test.rb +164 -0
  62. data/test/distributed_connection_handling_test.rb +23 -0
  63. data/test/distributed_internals_test.rb +79 -0
  64. data/test/distributed_key_tags_test.rb +52 -0
  65. data/test/distributed_persistence_control_commands_test.rb +26 -0
  66. data/test/distributed_publish_subscribe_test.rb +92 -0
  67. data/test/distributed_remote_server_control_commands_test.rb +66 -0
  68. data/test/distributed_scripting_test.rb +102 -0
  69. data/test/distributed_sorting_test.rb +20 -0
  70. data/test/distributed_test.rb +58 -0
  71. data/test/distributed_transactions_test.rb +32 -0
  72. data/test/encoding_test.rb +18 -0
  73. data/test/error_replies_test.rb +59 -0
  74. data/test/fork_safety_test.rb +65 -0
  75. data/test/helper.rb +232 -0
  76. data/test/helper_test.rb +24 -0
  77. data/test/internals_test.rb +437 -0
  78. data/test/lint/blocking_commands.rb +150 -0
  79. data/test/lint/hashes.rb +162 -0
  80. data/test/lint/hyper_log_log.rb +60 -0
  81. data/test/lint/lists.rb +143 -0
  82. data/test/lint/sets.rb +125 -0
  83. data/test/lint/sorted_sets.rb +316 -0
  84. data/test/lint/strings.rb +260 -0
  85. data/test/lint/value_types.rb +122 -0
  86. data/test/persistence_control_commands_test.rb +26 -0
  87. data/test/pipelining_commands_test.rb +242 -0
  88. data/test/publish_subscribe_test.rb +254 -0
  89. data/test/remote_server_control_commands_test.rb +118 -0
  90. data/test/scanning_test.rb +413 -0
  91. data/test/scripting_test.rb +78 -0
  92. data/test/sentinel_command_test.rb +80 -0
  93. data/test/sentinel_test.rb +255 -0
  94. data/test/sorting_test.rb +59 -0
  95. data/test/support/connection/hiredis.rb +1 -0
  96. data/test/support/connection/ruby.rb +1 -0
  97. data/test/support/connection/synchrony.rb +17 -0
  98. data/test/support/redis_mock.rb +119 -0
  99. data/test/support/wire/synchrony.rb +24 -0
  100. data/test/support/wire/thread.rb +5 -0
  101. data/test/synchrony_driver.rb +88 -0
  102. data/test/test.conf.erb +9 -0
  103. data/test/thread_safety_test.rb +32 -0
  104. data/test/transactions_test.rb +264 -0
  105. data/test/unknown_commands_test.rb +14 -0
  106. data/test/url_param_test.rb +138 -0
  107. metadata +182 -0
@@ -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,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