vinted-memcached 1.8.4 → 1.8.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_release_pipeline.yaml +53 -0
  3. data/.gitignore +33 -0
  4. data/BENCHMARKS +130 -126
  5. data/CHANGELOG +1 -6
  6. data/Gemfile +8 -1
  7. data/Gemfile.lock +25 -38
  8. data/README.md +144 -0
  9. data/Rakefile +21 -93
  10. data/ext/rlibmemcached/extconf.rb +76 -0
  11. data/ext/{rlibmemcached.i → rlibmemcached/rlibmemcached.i} +48 -69
  12. data/ext/{rlibmemcached_wrap.c → rlibmemcached/rlibmemcached_wrap.c} +146 -320
  13. data/lib/memcached/exceptions.rb +1 -12
  14. data/lib/memcached/experimental.rb +1 -33
  15. data/lib/memcached/memcached.rb +41 -34
  16. data/lib/memcached/version.rb +1 -1
  17. data/lib/memcached.rb +9 -4
  18. data/memcached.gemspec +0 -0
  19. data/memcached.pem +21 -0
  20. data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_connect.c +23 -13
  21. data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_io.c +18 -13
  22. data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_purge.c +1 -1
  23. metadata +192 -246
  24. data/Manifest +0 -209
  25. data/README.rdoc +0 -124
  26. data/ext/extconf-make.rb +0 -25
  27. data/ext/extconf.rb +0 -78
  28. data/lib/memcached/auth.rb +0 -16
  29. data/test/profile/benchmark.rb +0 -280
  30. data/test/profile/c_profiler.rb +0 -14
  31. data/test/profile/exercise.rb +0 -185
  32. data/test/profile/rb_profiler.rb +0 -21
  33. data/test/profile/valgrind.rb +0 -10
  34. data/test/setup.rb +0 -30
  35. data/test/teardown.rb +0 -0
  36. data/test/test_helper.rb +0 -18
  37. data/test/unit/binding_test.rb +0 -8
  38. data/test/unit/memcached_experimental_test.rb +0 -272
  39. data/test/unit/memcached_test.rb +0 -1487
  40. data/test/unit/rails_test.rb +0 -330
  41. /data/{ext → vendor}/libmemcached-0.32/AUTHORS +0 -0
  42. /data/{ext → vendor}/libmemcached-0.32/COPYING +0 -0
  43. /data/{ext → vendor}/libmemcached-0.32/ChangeLog +0 -0
  44. /data/{ext → vendor}/libmemcached-0.32/INSTALL +0 -0
  45. /data/{ext → vendor}/libmemcached-0.32/Makefile.am +0 -0
  46. /data/{ext → vendor}/libmemcached-0.32/Makefile.in +0 -0
  47. /data/{ext → vendor}/libmemcached-0.32/NEWS +0 -0
  48. /data/{ext → vendor}/libmemcached-0.32/README +0 -0
  49. /data/{ext → vendor}/libmemcached-0.32/THANKS +0 -0
  50. /data/{ext → vendor}/libmemcached-0.32/TODO +0 -0
  51. /data/{ext → vendor}/libmemcached-0.32/aclocal.m4 +0 -0
  52. /data/{ext → vendor}/libmemcached-0.32/clients/Makefile.am +0 -0
  53. /data/{ext → vendor}/libmemcached-0.32/clients/Makefile.in +0 -0
  54. /data/{ext → vendor}/libmemcached-0.32/clients/client_options.h +0 -0
  55. /data/{ext → vendor}/libmemcached-0.32/clients/execute.c +0 -0
  56. /data/{ext → vendor}/libmemcached-0.32/clients/execute.h +0 -0
  57. /data/{ext → vendor}/libmemcached-0.32/clients/generator.c +0 -0
  58. /data/{ext → vendor}/libmemcached-0.32/clients/generator.h +0 -0
  59. /data/{ext → vendor}/libmemcached-0.32/clients/memcat.c +0 -0
  60. /data/{ext → vendor}/libmemcached-0.32/clients/memcp.c +0 -0
  61. /data/{ext → vendor}/libmemcached-0.32/clients/memdump.c +0 -0
  62. /data/{ext → vendor}/libmemcached-0.32/clients/memerror.c +0 -0
  63. /data/{ext → vendor}/libmemcached-0.32/clients/memflush.c +0 -0
  64. /data/{ext → vendor}/libmemcached-0.32/clients/memrm.c +0 -0
  65. /data/{ext → vendor}/libmemcached-0.32/clients/memslap.c +0 -0
  66. /data/{ext → vendor}/libmemcached-0.32/clients/memstat.c +0 -0
  67. /data/{ext → vendor}/libmemcached-0.32/clients/utilities.c +0 -0
  68. /data/{ext → vendor}/libmemcached-0.32/clients/utilities.h +0 -0
  69. /data/{ext → vendor}/libmemcached-0.32/config/compile +0 -0
  70. /data/{ext → vendor}/libmemcached-0.32/config/config.guess +0 -0
  71. /data/{ext → vendor}/libmemcached-0.32/config/config.rpath +0 -0
  72. /data/{ext → vendor}/libmemcached-0.32/config/config.sub +0 -0
  73. /data/{ext → vendor}/libmemcached-0.32/config/depcomp +0 -0
  74. /data/{ext → vendor}/libmemcached-0.32/config/install-sh +0 -0
  75. /data/{ext → vendor}/libmemcached-0.32/config/ltmain.sh +0 -0
  76. /data/{ext → vendor}/libmemcached-0.32/config/missing +0 -0
  77. /data/{ext → vendor}/libmemcached-0.32/config.h.in +0 -0
  78. /data/{ext → vendor}/libmemcached-0.32/configure +0 -0
  79. /data/{ext → vendor}/libmemcached-0.32/configure.ac +0 -0
  80. /data/{ext → vendor}/libmemcached-0.32/libmemcached/Makefile.am +0 -0
  81. /data/{ext → vendor}/libmemcached-0.32/libmemcached/Makefile.in +0 -0
  82. /data/{ext → vendor}/libmemcached-0.32/libmemcached/byteorder.c +0 -0
  83. /data/{ext → vendor}/libmemcached-0.32/libmemcached/common.h +0 -0
  84. /data/{ext → vendor}/libmemcached-0.32/libmemcached/crc.c +0 -0
  85. /data/{ext → vendor}/libmemcached-0.32/libmemcached/hsieh_hash.c +0 -0
  86. /data/{ext → vendor}/libmemcached-0.32/libmemcached/jenkins_hash.c +0 -0
  87. /data/{ext → vendor}/libmemcached-0.32/libmemcached/libmemcached.ver +0 -0
  88. /data/{ext → vendor}/libmemcached-0.32/libmemcached/libmemcached_probes.d +0 -0
  89. /data/{ext → vendor}/libmemcached-0.32/libmemcached/libmemcached_probes.h +0 -0
  90. /data/{ext → vendor}/libmemcached-0.32/libmemcached/md5.c +0 -0
  91. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached/README.txt +0 -0
  92. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached/protocol_binary.h +0 -0
  93. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached.c +0 -0
  94. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached.h +0 -0
  95. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached.hpp +0 -0
  96. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_allocators.c +0 -0
  97. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_analyze.c +0 -0
  98. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_auto.c +0 -0
  99. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_behavior.c +0 -0
  100. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_callback.c +0 -0
  101. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_configure.h.in +0 -0
  102. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_constants.h +0 -0
  103. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_delete.c +0 -0
  104. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_do.c +0 -0
  105. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_dump.c +0 -0
  106. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_exist.c +0 -0
  107. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_exist.h +0 -0
  108. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_fetch.c +0 -0
  109. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_flush.c +0 -0
  110. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_flush_buffers.c +0 -0
  111. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_get.c +0 -0
  112. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_get.h +0 -0
  113. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_hash.c +0 -0
  114. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_hosts.c +0 -0
  115. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_internal.h +0 -0
  116. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_io.h +0 -0
  117. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_key.c +0 -0
  118. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_parse.c +0 -0
  119. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_pool.h +0 -0
  120. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_quit.c +0 -0
  121. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_response.c +0 -0
  122. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_result.c +0 -0
  123. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_result.h +0 -0
  124. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_sasl.c +0 -0
  125. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_sasl.h +0 -0
  126. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_server.c +0 -0
  127. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_server.h +0 -0
  128. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_stats.c +0 -0
  129. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_storage.c +0 -0
  130. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_storage.h +0 -0
  131. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_strerror.c +0 -0
  132. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_string.c +0 -0
  133. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_string.h +0 -0
  134. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_touch.c +0 -0
  135. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_touch.h +0 -0
  136. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_types.h +0 -0
  137. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_util.h +0 -0
  138. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_verbosity.c +0 -0
  139. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_version.c +0 -0
  140. /data/{ext → vendor}/libmemcached-0.32/libmemcached/memcached_watchpoint.h +0 -0
  141. /data/{ext → vendor}/libmemcached-0.32/libmemcached/murmur_hash.c +0 -0
  142. /data/{ext → vendor}/libmemcached-0.32/libmemcached/visibility.h +0 -0
  143. /data/{ext → vendor}/libmemcached-0.32/libmemcachedutil/Makefile.am +0 -0
  144. /data/{ext → vendor}/libmemcached-0.32/libmemcachedutil/Makefile.in +0 -0
  145. /data/{ext → vendor}/libmemcached-0.32/libmemcachedutil/libmemcachedutil.ver +0 -0
  146. /data/{ext → vendor}/libmemcached-0.32/libmemcachedutil/memcached_pool.c +0 -0
  147. /data/{ext → vendor}/libmemcached-0.32/m4/ac_cxx_compile_stdcxx_0x.m4 +0 -0
  148. /data/{ext → vendor}/libmemcached-0.32/m4/ac_cxx_header_stdcxx_98.m4 +0 -0
  149. /data/{ext → vendor}/libmemcached-0.32/m4/acx_pthread.m4 +0 -0
  150. /data/{ext → vendor}/libmemcached-0.32/m4/byteorder.m4 +0 -0
  151. /data/{ext → vendor}/libmemcached-0.32/m4/deprecated.m4 +0 -0
  152. /data/{ext → vendor}/libmemcached-0.32/m4/enable_utillib.m4 +0 -0
  153. /data/{ext → vendor}/libmemcached-0.32/m4/extensions.m4 +0 -0
  154. /data/{ext → vendor}/libmemcached-0.32/m4/hsieh.m4 +0 -0
  155. /data/{ext → vendor}/libmemcached-0.32/m4/lib-prefix.m4 +0 -0
  156. /data/{ext → vendor}/libmemcached-0.32/m4/libtool.m4 +0 -0
  157. /data/{ext → vendor}/libmemcached-0.32/m4/ltoptions.m4 +0 -0
  158. /data/{ext → vendor}/libmemcached-0.32/m4/ltsugar.m4 +0 -0
  159. /data/{ext → vendor}/libmemcached-0.32/m4/ltversion.m4 +0 -0
  160. /data/{ext → vendor}/libmemcached-0.32/m4/lt~obsolete.m4 +0 -0
  161. /data/{ext → vendor}/libmemcached-0.32/m4/memcached.m4 +0 -0
  162. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_64bit.m4 +0 -0
  163. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_canonical.m4 +0 -0
  164. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_check_compiler_version.m4 +0 -0
  165. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_check_cxx_standard.m4 +0 -0
  166. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_enable_dtrace.m4 +0 -0
  167. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_ensure_gcc_version.m4 +0 -0
  168. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_have_better_malloc.m4 +0 -0
  169. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_have_sasl.m4 +0 -0
  170. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_header_assert.m4 +0 -0
  171. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_libtool.m4 +0 -0
  172. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_optimize.m4 +0 -0
  173. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_shared_ptr.m4 +0 -0
  174. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_vc_build.m4 +0 -0
  175. /data/{ext → vendor}/libmemcached-0.32/m4/pandora_warnings.m4 +0 -0
  176. /data/{ext → vendor}/libmemcached-0.32/m4/pod2man.m4 +0 -0
  177. /data/{ext → vendor}/libmemcached-0.32/m4/protocol_binary.m4 +0 -0
  178. /data/{ext → vendor}/libmemcached-0.32/m4/setsockopt.m4 +0 -0
  179. /data/{ext → vendor}/libmemcached-0.32/m4/visibility.m4 +0 -0
  180. /data/{ext → vendor}/libmemcached-0.32/support/Makefile.am +0 -0
  181. /data/{ext → vendor}/libmemcached-0.32/support/Makefile.in +0 -0
  182. /data/{ext → vendor}/libmemcached-0.32/support/libmemcached-fc.spec.in +0 -0
  183. /data/{ext → vendor}/libmemcached-0.32/support/libmemcached.pc.in +0 -0
  184. /data/{ext → vendor}/libmemcached-0.32/support/libmemcached.spec +0 -0
  185. /data/{ext → vendor}/libmemcached-0.32/support/libmemcached.spec.in +0 -0
  186. /data/{ext → vendor}/libmemcached-0.32/support/set_benchmark.sh +0 -0
  187. /data/{ext → vendor}/libmemcached-0.32/tests/Makefile.am +0 -0
  188. /data/{ext → vendor}/libmemcached-0.32/tests/Makefile.in +0 -0
  189. /data/{ext → vendor}/libmemcached-0.32/tests/atomsmasher.c +0 -0
  190. /data/{ext → vendor}/libmemcached-0.32/tests/function.c +0 -0
  191. /data/{ext → vendor}/libmemcached-0.32/tests/ketama_test_cases.h +0 -0
  192. /data/{ext → vendor}/libmemcached-0.32/tests/output.cmp +0 -0
  193. /data/{ext → vendor}/libmemcached-0.32/tests/output.res +0 -0
  194. /data/{ext → vendor}/libmemcached-0.32/tests/output2.res +0 -0
  195. /data/{ext → vendor}/libmemcached-0.32/tests/plus.cpp +0 -0
  196. /data/{ext → vendor}/libmemcached-0.32/tests/r/memcat.res +0 -0
  197. /data/{ext → vendor}/libmemcached-0.32/tests/r/memcp.res +0 -0
  198. /data/{ext → vendor}/libmemcached-0.32/tests/r/memrm.res +0 -0
  199. /data/{ext → vendor}/libmemcached-0.32/tests/r/memslap.res +0 -0
  200. /data/{ext → vendor}/libmemcached-0.32/tests/r/memstat.res +0 -0
  201. /data/{ext → vendor}/libmemcached-0.32/tests/server.c +0 -0
  202. /data/{ext → vendor}/libmemcached-0.32/tests/server.h +0 -0
  203. /data/{ext → vendor}/libmemcached-0.32/tests/start.c +0 -0
  204. /data/{ext → vendor}/libmemcached-0.32/tests/t/memcat.test +0 -0
  205. /data/{ext → vendor}/libmemcached-0.32/tests/t/memcp.test +0 -0
  206. /data/{ext → vendor}/libmemcached-0.32/tests/t/memrm.test +0 -0
  207. /data/{ext → vendor}/libmemcached-0.32/tests/t/memslap.test +0 -0
  208. /data/{ext → vendor}/libmemcached-0.32/tests/t/memstat.test +0 -0
  209. /data/{ext → vendor}/libmemcached-0.32/tests/test.c +0 -0
  210. /data/{ext → vendor}/libmemcached-0.32/tests/test.h +0 -0
  211. /data/{ext → vendor}/libmemcached-0.32/tests/udp.c +0 -0
@@ -1,1487 +0,0 @@
1
- require File.expand_path("#{File.dirname(__FILE__)}/../test_helper")
2
-
3
- class NilClass
4
- def to_str
5
- "nil"
6
- end
7
- end
8
-
9
- class MemcachedTest < Test::Unit::TestCase
10
-
11
- def setup
12
- @servers = ['localhost:43042', 'localhost:43043', "#{UNIX_SOCKET_NAME}0"]
13
- @udp_servers = ['localhost:43052', 'localhost:43053']
14
-
15
- # Maximum allowed prefix key size for :hash_with_prefix_key_key => false
16
- @prefix_key = 'prefix_key_'
17
-
18
- @options = {
19
- :prefix_key => @prefix_key,
20
- :hash => :default,
21
- :distribution => :modula,
22
- :show_backtraces => true}
23
- @cache = Memcached.new(@servers, @options)
24
-
25
- @binary_protocol_options = {
26
- :prefix_key => @prefix_key,
27
- :hash => :default,
28
- :distribution => :modula,
29
- :binary_protocol => true,
30
- :show_backtraces => true}
31
- @binary_protocol_cache = Memcached.new(@servers, @binary_protocol_options)
32
-
33
- @udp_options = {
34
- :prefix_key => @prefix_key,
35
- :hash => :default,
36
- :use_udp => true,
37
- :distribution => :modula,
38
- :show_backtraces => true}
39
- @udp_cache = Memcached.new(@udp_servers, @udp_options)
40
-
41
- @noblock_options = {
42
- :prefix_key => @prefix_key,
43
- :no_block => true,
44
- :noreply => true,
45
- :buffer_requests => true,
46
- :hash => :default,
47
- :distribution => :modula,
48
- :show_backtraces => true}
49
- @noblock_cache = Memcached.new(@servers, @noblock_options)
50
-
51
- @cas_options = {
52
- :prefix_key => @prefix_key,
53
- :hash => :default,
54
- :distribution => :modula,
55
- :support_cas => true,
56
- :show_backtraces => true}
57
- @cas_cache = Memcached.new(@servers, @cas_options)
58
-
59
- @value = OpenStruct.new(:a => 1, :b => 2, :c => GenericClass)
60
- @marshalled_value = Marshal.dump(@value)
61
- end
62
-
63
- # Initialize
64
-
65
- def test_initialize
66
- cache = Memcached.new @servers, :prefix_key => 'test'
67
- assert_equal 'test', cache.prefix_key
68
- assert_equal 3, cache.send(:server_structs).size
69
- assert_equal 'localhost', cache.send(:server_structs).first.hostname
70
- assert_equal 43042, cache.send(:server_structs).first.port
71
- end
72
-
73
- def test_initialize_with_ip_addresses
74
- cache = Memcached.new ['127.0.0.1:43042', '127.0.0.1:43043']
75
- assert_equal '127.0.0.1', cache.send(:server_structs).first.hostname
76
- assert_equal '127.0.0.1', cache.send(:server_structs).last.hostname
77
- end
78
-
79
- def test_initialize_without_port
80
- cache = Memcached.new ['localhost']
81
- assert_equal 'localhost', cache.send(:server_structs).first.hostname
82
- assert_equal 11211, cache.send(:server_structs).first.port
83
- end
84
-
85
- def test_initialize_with_ports_and_weights
86
- cache = Memcached.new ['localhost:43042:2', 'localhost:43043:10']
87
- assert_equal 2, cache.send(:server_structs).first.weight
88
- assert_equal 43043, cache.send(:server_structs).last.port
89
- assert_equal 10, cache.send(:server_structs).last.weight
90
- end
91
-
92
- def test_initialize_with_hostname_only
93
- addresses = (1..8).map { |i| "app-cache-%02d" % i }
94
- cache = Memcached.new(addresses)
95
- addresses.each_with_index do |address, index|
96
- assert_equal address, cache.send(:server_structs)[index].hostname
97
- assert_equal 11211, cache.send(:server_structs)[index].port
98
- end
99
- end
100
-
101
- def test_initialize_with_ip_address_and_options
102
- cache = Memcached.new '127.0.0.1:43042', :ketama_weighted => false
103
- assert_equal '127.0.0.1', cache.send(:server_structs).first.hostname
104
- assert_equal false, cache.options[:ketama_weighted]
105
- end
106
-
107
- def test_options_are_set
108
- Memcached::DEFAULTS.merge(@noblock_options).each do |key, expected|
109
- value = @noblock_cache.options[key]
110
- unless key == :rcv_timeout or key == :poll_timeout or key == :prefix_key or key == :ketama_weighted or key == :snd_timeout
111
- assert(expected == value, "#{key} should be #{expected} but was #{value}")
112
- end
113
- end
114
- end
115
-
116
- def test_options_are_frozen
117
- assert_raise(TypeError, RuntimeError) do
118
- @cache.options[:no_block] = true
119
- end
120
- end
121
-
122
- def test_behaviors_are_set
123
- Memcached::BEHAVIORS.keys.each do |key, value|
124
- assert_not_nil @cache.send(:get_behavior, key)
125
- end
126
- end
127
-
128
- def test_initialize_with_invalid_server_strings
129
- assert_raise(ArgumentError) { Memcached.new ":43042" }
130
- assert_raise(ArgumentError) { Memcached.new "localhost:memcached" }
131
- assert_raise(ArgumentError) { Memcached.new "local host:43043:1" }
132
- end
133
-
134
- def test_initialize_with_invalid_options
135
- assert_raise(ArgumentError) do
136
- Memcached.new @servers, :sort_hosts => true, :distribution => :consistent
137
- end
138
- end
139
-
140
- def test_initialize_with_invalid_prefix_key
141
- assert_raise(ArgumentError) do
142
- Memcached.new @servers, :prefix_key => "x" * 128
143
- end
144
- end
145
-
146
- def test_initialize_without_prefix_key
147
- cache = Memcached.new @servers
148
- assert_equal 3, cache.send(:server_structs).size
149
- end
150
-
151
- def test_set_prefix_key
152
- cache = Memcached.new @servers, :prefix_key => "foo"
153
- cache.set_prefix_key("bar")
154
- assert_equal "bar", cache.prefix_key
155
- end
156
-
157
- def test_set_prefix_key_to_empty_string
158
- cache = Memcached.new @servers, :prefix_key => "foo"
159
- cache.set_prefix_key("")
160
- assert_equal "", cache.prefix_key
161
- end
162
-
163
- def test_memcached_callback_set_with_empty_string_should_not_raise_exception
164
- cache = Memcached.new @servers, :prefix_key => "foo"
165
- assert_nothing_raised do
166
- cache.set_prefix_key("")
167
- end
168
- end
169
-
170
- def test_initialize_negative_behavior
171
- cache = Memcached.new @servers,
172
- :buffer_requests => false
173
- assert_nothing_raised do
174
- cache.set key, @value
175
- end
176
- end
177
-
178
- def test_initialize_without_backtraces
179
- cache = Memcached.new @servers,
180
- :show_backtraces => false
181
- cache.delete key rescue
182
- begin
183
- cache.get key
184
- rescue Memcached::NotFound => e
185
- assert e.backtrace.empty?
186
- end
187
- begin
188
- cache.append key, @value
189
- rescue Memcached::NotStored => e
190
- assert e.backtrace.empty?
191
- end
192
- end
193
-
194
- def test_initialize_with_backtraces
195
- cache = Memcached.new @servers, :show_backtraces => true
196
- cache.delete key rescue nil
197
- begin
198
- cache.get key
199
- rescue Memcached::NotFound => e
200
- assert !e.backtrace.empty?
201
- end
202
- end
203
-
204
- def test_initialize_sort_hosts
205
- # Original
206
- cache = Memcached.new(@servers.sort,
207
- :sort_hosts => false,
208
- :distribution => :modula
209
- )
210
- assert_equal @servers.sort,
211
- cache.servers
212
-
213
- # Original with sort_hosts
214
- cache = Memcached.new(@servers.sort,
215
- :sort_hosts => true,
216
- :distribution => :modula
217
- )
218
- assert_equal @servers.sort,
219
- cache.servers
220
-
221
- # Reversed
222
- cache = Memcached.new(@servers.sort.reverse,
223
- :sort_hosts => false,
224
- :distribution => :modula
225
- )
226
- assert_equal @servers.sort.reverse,
227
- cache.servers
228
-
229
- # Reversed with sort_hosts
230
- cache = Memcached.new(@servers.sort.reverse,
231
- :sort_hosts => true,
232
- :distribution => :modula
233
- )
234
- assert_equal @servers.sort,
235
- cache.servers
236
- end
237
-
238
- def test_initialize_single_server
239
- cache = Memcached.new 'localhost:43042'
240
- assert_equal 1, cache.send(:server_structs).size
241
- end
242
-
243
- def test_initialize_strange_argument
244
- assert_raise(ArgumentError) { Memcached.new 1 }
245
- end
246
-
247
- # Get
248
-
249
- def test_get
250
- @cache.set key, @value
251
- assert_equal @value, @cache.get(key)
252
- assert_equal @value, @binary_protocol_cache.get(key)
253
-
254
- @udp_cache.set(key, @value)
255
- assert_raises(Memcached::ActionNotSupported) do
256
- @udp_cache.get(key)
257
- end
258
- end
259
-
260
- def test_get_nil
261
- @cache.set key, nil, 0
262
- result = @cache.get key
263
- assert_equal nil, result
264
- end
265
-
266
- def test_get_from_last
267
- cache = Memcached.new(@servers, :distribution => :random)
268
- 10.times { |n| cache.set key, n }
269
- 10.times do
270
- assert_equal cache.get(key), cache.get_from_last(key)
271
- end
272
- end
273
-
274
- def test_get_missing
275
- @cache.delete key rescue nil
276
- assert_raise(Memcached::NotFound) do
277
- result = @cache.get key
278
- end
279
- end
280
-
281
- def test_get_coerces_string_type
282
- assert_raises(Memcached::NotFound) do
283
- @cache.get nil
284
- end
285
- assert_raises(TypeError) do
286
- @cache.get 1
287
- end
288
- end
289
-
290
- def test_get_with_server_timeout
291
- socket = stub_server 43047
292
- cache = Memcached.new("localhost:43047:1", :timeout => 0.5, :exception_retry_limit => 0)
293
- assert 0.49 < (Benchmark.measure do
294
- assert_raise(Memcached::ATimeoutOccurred) do
295
- result = cache.get key
296
- end
297
- end).real
298
-
299
- cache = Memcached.new("localhost:43047:1", :poll_timeout => 0.001, :rcv_timeout => 0.5, :exception_retry_limit => 0)
300
- assert 0.49 < (Benchmark.measure do
301
- assert_raise(Memcached::ATimeoutOccurred) do
302
- result = cache.get key
303
- end
304
- end).real
305
-
306
- cache = Memcached.new("localhost:43047:1", :poll_timeout => 0.25, :rcv_timeout => 0.25, :exception_retry_limit => 0)
307
- assert 0.51 > (Benchmark.measure do
308
- assert_raise(Memcached::ATimeoutOccurred) do
309
- result = cache.get key
310
- end
311
- end).real
312
- ensure
313
- socket.close
314
- end
315
-
316
- def test_get_with_no_block_server_timeout
317
- socket = stub_server 43048
318
- cache = Memcached.new("localhost:43048:1", :no_block => true, :timeout => 0.25, :exception_retry_limit => 0)
319
- assert 0.24 < (Benchmark.measure do
320
- assert_raise(Memcached::ATimeoutOccurred) do
321
- result = cache.get key
322
- end
323
- end).real
324
-
325
- cache = Memcached.new("localhost:43048:1", :no_block => true, :poll_timeout => 0.25, :rcv_timeout => 0.001, :exception_retry_limit => 0)
326
- assert 0.24 < (Benchmark.measure do
327
- assert_raise(Memcached::ATimeoutOccurred) do
328
- result = cache.get key
329
- end
330
- end).real
331
-
332
- cache = Memcached.new("localhost:43048:1", :no_block => true,
333
- :poll_timeout => 0.001,
334
- :rcv_timeout => 0.25, # No affect in no-block mode
335
- :exception_retry_limit => 0
336
- )
337
- assert 0.24 > (Benchmark.measure do
338
- assert_raise(Memcached::ATimeoutOccurred) do
339
- result = cache.get key
340
- end
341
- end).real
342
-
343
- ensure
344
- socket.close
345
- end
346
-
347
- def test_get_with_prefix_key
348
- # Prefix_key
349
- cache = Memcached.new(
350
- # We can only use one server because the key is hashed separately from the prefix key
351
- @servers.first,
352
- :prefix_key => @prefix_key,
353
- :hash => :default,
354
- :distribution => :modula
355
- )
356
- cache.set key, @value
357
- assert_equal @value, cache.get(key)
358
-
359
- # No prefix_key specified
360
- cache = Memcached.new(
361
- @servers.first,
362
- :hash => :default,
363
- :distribution => :modula
364
- )
365
- assert_nothing_raised do
366
- assert_equal @value, cache.get("#{@prefix_key}#{key}")
367
- end
368
- end
369
-
370
- def test_values_with_null_characters_are_not_truncated
371
- value = OpenStruct.new(:a => Object.new) # Marshals with a null \000
372
- @cache.set key, value
373
- result = @cache.get key, false
374
- non_wrapped_result = Rlibmemcached.memcached_get(
375
- @cache.instance_variable_get("@struct"),
376
- key
377
- ).first
378
- assert result.size > non_wrapped_result.size
379
- end
380
-
381
- def test_get_multi
382
- @cache.set "#{key}_1", 1
383
- @cache.set "#{key}_2", 2
384
- assert_equal({"#{key}_1" => 1, "#{key}_2" => 2},
385
- @cache.get(["#{key}_1", "#{key}_2"]))
386
- end
387
-
388
- def test_get_multi_missing
389
- @cache.set "#{key}_1", 1
390
- @cache.delete "#{key}_2" rescue nil
391
- @cache.set "#{key}_3", 3
392
- @cache.delete "#{key}_4" rescue nil
393
- assert_equal(
394
- {"test_get_multi_missing_3"=>3, "test_get_multi_missing_1"=>1},
395
- @cache.get(["#{key}_1", "#{key}_2", "#{key}_3", "#{key}_4"])
396
- )
397
- end
398
-
399
- def test_get_multi_binary
400
- @binary_protocol_cache.set "#{key}_1", 1
401
- @binary_protocol_cache.delete "#{key}_2" rescue nil
402
- @binary_protocol_cache.set "#{key}_3", 3
403
- assert_equal(
404
- {"test_get_multi_binary_3"=>3, "test_get_multi_binary_1"=>1},
405
- @binary_protocol_cache.get(["#{key}_1", "#{key}_2", "#{key}_3"])
406
- )
407
- end
408
-
409
- def test_get_multi_binary_one_record_missing
410
- @binary_protocol_cache.delete("magic_key") rescue nil
411
- assert_equal({}, @binary_protocol_cache.get(["magic_key"]))
412
- end
413
-
414
- def test_get_multi_binary_one_record
415
- @binary_protocol_cache.set("magic_key", 1)
416
- assert_equal({"magic_key" => 1}, @binary_protocol_cache.get(["magic_key"]))
417
- end
418
-
419
- def test_get_multi_completely_missing
420
- @cache.delete "#{key}_1" rescue nil
421
- @cache.delete "#{key}_2" rescue nil
422
- assert_equal(
423
- {},
424
- @cache.get(["#{key}_1", "#{key}_2"])
425
- )
426
- end
427
-
428
- def test_get_multi_empty_string
429
- @cache.set "#{key}_1", "", 0, false
430
- assert_equal({"#{key}_1" => ""},
431
- @cache.get(["#{key}_1"], false))
432
- end
433
-
434
- def test_get_multi_coerces_string_type
435
- assert_nothing_raised do
436
- @cache.get [nil]
437
- end
438
- assert_raises(TypeError) do
439
- @cache.get [1]
440
- end
441
- end
442
-
443
- def test_set_and_get_unmarshalled
444
- @cache.set key, @value
445
- result = @cache.get key, false
446
- assert_equal @marshalled_value, result
447
- end
448
-
449
- def test_set_unmarshalled_and_get_unmarshalled
450
- @cache.set key, @marshalled_value, 0, false
451
- result = @cache.get key, false
452
- assert_equal @marshalled_value, result
453
- end
454
-
455
- def test_set_unmarshalled_error
456
- assert_raises(TypeError) do
457
- @cache.set key, @value, 0, false
458
- end
459
- end
460
-
461
- def test_get_multi_unmarshalled
462
- @cache.set "#{key}_1", "1", 0, false
463
- @cache.set "#{key}_2", "2", 0, false
464
- assert_equal(
465
- {"#{key}_1" => "1", "#{key}_2" => "2"},
466
- @cache.get(["#{key}_1", "#{key}_2"], false)
467
- )
468
- end
469
-
470
- def test_get_multi_mixed_marshalling
471
- @cache.set "#{key}_1", 1
472
- @cache.set "#{key}_2", "2", 0, false
473
- assert_nothing_raised do
474
- @cache.get(["#{key}_1", "#{key}_2"], false)
475
- end
476
- assert_raise(ArgumentError, TypeError) do
477
- @cache.get(["#{key}_1", "#{key}_2"])
478
- end
479
- end
480
-
481
- def test_random_distribution_is_statistically_random
482
- cache = Memcached.new(@servers, :distribution => :random)
483
- read_cache = Memcached.new(@servers.first)
484
- hits = 4
485
-
486
- while hits == 4 do
487
- cache.flush
488
- 20.times do |i|
489
- cache.set "#{key}#{i}", @value
490
- end
491
-
492
- hits = 0
493
- 20.times do |i|
494
- begin
495
- read_cache.get "#{key}#{i}"
496
- hits += 1
497
- rescue Memcached::NotFound
498
- end
499
- end
500
- end
501
-
502
- assert_not_equal 4, hits
503
- end
504
-
505
- # Set
506
-
507
- def test_set
508
- assert_nothing_raised do
509
- @cache.set(key, @value)
510
- end
511
-
512
- assert_nothing_raised do
513
- @binary_protocol_cache.set(key, @value)
514
- end
515
-
516
- assert_nothing_raised do
517
- @udp_cache.set(key, @value)
518
- end
519
- end
520
-
521
- def test_set_expiry
522
- @cache.set key, @value, 1
523
- assert_nothing_raised do
524
- @cache.get key
525
- end
526
- sleep(2)
527
- assert_raise(Memcached::NotFound) do
528
- @cache.get key
529
- end
530
-
531
- assert_raise(TypeError) do
532
- @cache.set key, @value, Time.now
533
- end
534
- end
535
-
536
- def test_set_with_default_ttl
537
- cache = Memcached.new(
538
- @servers,
539
- :default_ttl => 1
540
- )
541
- cache.set key, @value
542
- assert_nothing_raised do
543
- cache.get key
544
- end
545
- sleep(2)
546
- assert_raise(Memcached::NotFound) do
547
- cache.get key
548
- end
549
- end
550
-
551
- def test_set_coerces_string_type
552
- assert_nothing_raised do
553
- @cache.set nil, @value
554
- end
555
-
556
- assert_raises(TypeError) do
557
- @cache.set 1, @value
558
- end
559
- end
560
-
561
- def disabled_test_set_retry_on_client_error
562
- # FIXME Test passes, but Mocha doesn't restore the original method properly
563
- Rlibmemcached.stubs(:memcached_set).raises(Memcached::ClientError)
564
- Rlibmemcached.stubs(:memcached_set).returns(0)
565
-
566
- assert_nothing_raised do
567
- @cache.set(key, @value)
568
- end
569
- end
570
-
571
- # Delete
572
-
573
- def test_delete
574
- @cache.set key, @value
575
- @cache.delete key
576
- assert_raise(Memcached::NotFound) do
577
- @cache.get key
578
- end
579
-
580
- @binary_protocol_cache.set key, @value
581
- @binary_protocol_cache.delete key
582
- assert_raise(Memcached::NotFound) do
583
- @binary_protocol_cache.get key
584
- end
585
- end
586
-
587
- def test_missing_delete
588
- @cache.delete key rescue nil
589
- assert_raise(Memcached::NotFound) do
590
- @cache.delete key
591
- end
592
- end
593
-
594
- # Flush
595
-
596
- def test_flush
597
- @cache.set key, @value
598
- assert_equal @value,
599
- @cache.get(key)
600
- @cache.flush
601
- assert_raise(Memcached::NotFound) do
602
- @cache.get key
603
- end
604
- end
605
-
606
- # Add
607
-
608
- def test_add
609
- @cache.delete key rescue nil
610
- @cache.add key, @value
611
- assert_equal @value, @cache.get(key)
612
- end
613
-
614
- def test_existing_add
615
- @cache.set key, @value
616
- assert_raise(Memcached::NotStored) do
617
- @cache.add key, @value
618
- end
619
- end
620
-
621
- def test_add_expiry
622
- @cache.delete key rescue nil
623
- @cache.set key, @value, 1
624
- assert_nothing_raised do
625
- @cache.get key
626
- end
627
- sleep(1)
628
- assert_raise(Memcached::NotFound) do
629
- @cache.get key
630
- end
631
- end
632
-
633
- def test_unmarshalled_add
634
- @cache.delete key rescue nil
635
- @cache.add key, @marshalled_value, 0, false
636
- assert_equal @marshalled_value, @cache.get(key, false)
637
- assert_equal @value, @cache.get(key)
638
- end
639
-
640
- # Increment and decrement
641
-
642
- def test_increment
643
- @cache.set key, "10", 0, false
644
- assert_equal 11, @cache.increment(key)
645
- end
646
-
647
- def test_increment_binary
648
- @binary_protocol_cache.set key, "10", 0, false
649
- assert_equal 11, @binary_protocol_cache.increment(key)
650
- end
651
-
652
- def test_increment_offset
653
- @cache.set key, "10", 0, false
654
- assert_equal 15, @cache.increment(key, 5)
655
- end
656
-
657
- def test_missing_increment
658
- @cache.delete key rescue nil
659
- assert_raise(Memcached::NotFound) do
660
- @cache.increment key
661
- end
662
- end
663
-
664
- def test_decrement
665
- @cache.set key, "10", 0, false
666
- assert_equal 9, @cache.decrement(key)
667
- end
668
-
669
- def test_decrement_binary
670
- @binary_protocol_cache.set key, "10", 0, false
671
- assert_equal 9, @binary_protocol_cache.decrement(key)
672
- end
673
-
674
- def test_decrement_offset
675
- @cache.set key, "10", 0, false
676
- assert_equal 5, @cache.decrement(key, 5)
677
- end
678
-
679
- def test_missing_decrement
680
- @cache.delete key rescue nil
681
- assert_raise(Memcached::NotFound) do
682
- @cache.decrement key
683
- end
684
- end
685
-
686
- # Exist
687
-
688
- def test_missing_exist
689
- assert_raise(Memcached::NotFound) do
690
- @cache.exist key
691
- end
692
- end
693
-
694
- def test_exist
695
- @cache.set key, @value
696
- assert_nil @cache.exist(key)
697
- end
698
-
699
- def test_missing_exist_binary
700
- assert_raise(Memcached::NotFound) do
701
- @binary_protocol_cache.exist key
702
- end
703
- end
704
-
705
- def test_exist_binary
706
- @binary_protocol_cache.set key, @value
707
- assert_nil @binary_protocol_cache.exist(key)
708
- end
709
-
710
- # Replace
711
-
712
- def test_replace
713
- @cache.set key, nil
714
- assert_nothing_raised do
715
- @cache.replace key, @value
716
- end
717
- assert_equal @value, @cache.get(key)
718
- end
719
-
720
- def test_missing_replace
721
- @cache.delete key rescue nil
722
- assert_raise(Memcached::NotStored) do
723
- @cache.replace key, @value
724
- end
725
- assert_raise(Memcached::NotFound) do
726
- assert_equal @value, @cache.get(key)
727
- end
728
- end
729
-
730
- # Append and prepend
731
-
732
- def test_append
733
- @cache.set key, "start", 0, false
734
- assert_nothing_raised do
735
- @cache.append key, "end"
736
- end
737
- assert_equal "startend", @cache.get(key, false)
738
-
739
- @binary_protocol_cache.set key, "start", 0, false
740
- assert_nothing_raised do
741
- @binary_protocol_cache.append key, "end"
742
- end
743
- assert_equal "startend", @binary_protocol_cache.get(key, false)
744
- end
745
-
746
- def test_missing_append
747
- @cache.delete key rescue nil
748
- assert_raise(Memcached::NotStored) do
749
- @cache.append key, "end"
750
- end
751
- assert_raise(Memcached::NotFound) do
752
- assert_equal @value, @cache.get(key)
753
- end
754
-
755
- @binary_protocol_cache.delete key rescue nil
756
- assert_raise(Memcached::NotStored) do
757
- @binary_protocol_cache.append key, "end"
758
- end
759
- assert_raise(Memcached::NotFound) do
760
- assert_equal @value, @binary_protocol_cache.get(key)
761
- end
762
- end
763
-
764
- def test_prepend
765
- @cache.set key, "end", 0, false
766
- assert_nothing_raised do
767
- @cache.prepend key, "start"
768
- end
769
- assert_equal "startend", @cache.get(key, false)
770
- end
771
-
772
- def test_missing_prepend
773
- @cache.delete key rescue nil
774
- assert_raise(Memcached::NotStored) do
775
- @cache.prepend key, "end"
776
- end
777
- assert_raise(Memcached::NotFound) do
778
- assert_equal @value, @cache.get(key)
779
- end
780
- end
781
-
782
- def test_cas
783
- value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
784
-
785
- # Existing set
786
- @cas_cache.set key, @value
787
- @cas_cache.cas(key) do |current|
788
- assert_equal @value, current
789
- value2
790
- end
791
- assert_equal value2, @cas_cache.get(key)
792
-
793
- # Existing test without marshalling
794
- @cas_cache.set(key, "foo", 0, false)
795
- @cas_cache.cas(key, 0, false) do |current|
796
- "#{current}bar"
797
- end
798
- assert_equal "foobar", @cas_cache.get(key, false)
799
-
800
- # Missing set
801
- @cas_cache.delete key
802
- assert_raises(Memcached::NotFound) do
803
- @cas_cache.cas(key) {}
804
- end
805
-
806
- # Conflicting set
807
- @cas_cache.set key, @value
808
- assert_raises(Memcached::ConnectionDataExists) do
809
- @cas_cache.cas(key) do |current|
810
- @cas_cache.set key, value2
811
- current
812
- end
813
- end
814
- end
815
-
816
- def test_multi_cas_with_empty_set
817
- assert_raises Memcached::NotFound do
818
- @cas_cache.cas([]) { flunk }
819
- end
820
- end
821
-
822
- def test_multi_cas_with_existing_set
823
- value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
824
-
825
- @cas_cache.set key, @value
826
- result = @cas_cache.cas([key]) do |current|
827
- assert_equal({key => @value}, current)
828
- {key => value2}
829
- end
830
- assert_equal({key => value2}, result)
831
- assert_equal value2, @cas_cache.get(key)
832
- end
833
-
834
- def test_multi_cas_with_different_key
835
- value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
836
- key2 = "test_multi_cas"
837
-
838
- @cas_cache.delete key2 rescue Memcached::NotFound
839
- @cas_cache.set key, @value
840
- result = @cas_cache.cas([key]) do |current|
841
- assert_equal({key => @value}, current)
842
- {key2 => value2}
843
- end
844
- assert_equal({}, result)
845
- assert_equal @value, @cas_cache.get(key)
846
- assert_raises(Memcached::NotFound) do
847
- @cas_cache.get(key2)
848
- end
849
- end
850
-
851
- def test_multi_cas_with_existing_multi_set
852
- value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
853
- key2 = "test_multi_cas"
854
-
855
- @cas_cache.set key, @value
856
- @cas_cache.set key2, value2
857
- result = @cas_cache.cas([key, key2]) do |current|
858
- assert_equal({key => @value, key2 => value2}, current)
859
- {key => value2}
860
- end
861
- assert_equal({key => value2}, result)
862
- assert_equal value2, @cas_cache.get(key)
863
- assert_equal value2, @cas_cache.get(key2)
864
- end
865
-
866
- def test_multi_cas_with_missing_set
867
- key2 = "test_multi_cas"
868
-
869
- @cas_cache.delete key rescue Memcached::NotFound
870
- @cas_cache.delete key2 rescue Memcached::NotFound
871
- assert_nothing_raised Memcached::NotFound do
872
- assert_equal({}, @cas_cache.cas([key, key2]) { flunk })
873
- end
874
- end
875
-
876
- def test_multi_cas_partial_fulfillment
877
- value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
878
- key2 = "test_multi_cas"
879
-
880
- @cas_cache.delete key rescue Memcached::NotFound
881
- @cas_cache.set key2, value2
882
- result = @cas_cache.cas([key, key2]) do |current|
883
- assert_equal({key2 => value2}, current)
884
- {key2 => @value}
885
- end
886
- assert_equal({key2 => @value}, result)
887
- assert_raises Memcached::NotFound do
888
- @cas_cache.get(key)
889
- end
890
- assert_equal @value, @cas_cache.get(key2)
891
- end
892
-
893
- def test_multi_cas_with_expiration
894
- value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
895
- key2 = "test_multi_cas"
896
-
897
- @cas_cache.set key, @value
898
- @cas_cache.set key2, @value, 1
899
- assert_nothing_raised do
900
- result = @cas_cache.cas([key, key2]) do |current|
901
- assert_equal({key => @value, key2 => @value}, current)
902
- sleep 2
903
- {key => value2, key2 => value2}
904
- end
905
- assert_equal({key => value2}, result)
906
- end
907
- end
908
-
909
- def test_multi_cas_with_partial_conflict
910
- value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
911
- key2 = "test_multi_cas"
912
-
913
- @cas_cache.set key, @value
914
- @cas_cache.set key2, @value
915
- assert_nothing_raised Memcached::ConnectionDataExists do
916
- result = @cas_cache.cas([key, key2]) do |current|
917
- assert_equal({key => @value, key2 => @value}, current)
918
- @cas_cache.set key, value2
919
- {key => @value, key2 => value2}
920
- end
921
- assert_equal({key2 => value2}, result)
922
- end
923
- assert_equal value2, @cas_cache.get(key)
924
- assert_equal value2, @cas_cache.get(key2)
925
- end
926
-
927
- # Error states
928
-
929
- def test_key_with_spaces
930
- key = "i have a space"
931
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
932
- @cache.set key, @value
933
- end
934
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
935
- @cache.get(key)
936
- end
937
- end
938
-
939
- def test_key_with_null
940
- key = "with\000null"
941
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
942
- @cache.set key, @value
943
- end
944
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
945
- @cache.get(key)
946
- end
947
-
948
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
949
- response = @cache.get([key])
950
- end
951
- end
952
-
953
- def test_key_with_invalid_control_characters
954
- key = "ch\303\242teau"
955
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
956
- @cache.set key, @value
957
- end
958
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
959
- @cache.get(key)
960
- end
961
-
962
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
963
- response = @cache.get([key])
964
- end
965
- end
966
-
967
- def test_key_too_long
968
- key = "x"*251
969
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
970
- @cache.set key, @value
971
- end
972
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
973
- @cache.get(key)
974
- end
975
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
976
- @cache.get([key])
977
- end
978
- end
979
-
980
- def test_verify_key_disabled
981
- cache = Memcached.new @servers, :verify_key => false
982
- key = "i have a space"
983
- assert_raises(Memcached::ProtocolError) do
984
- cache.set key, @value
985
- end
986
- assert_raises(Memcached::NotFound) do
987
- cache.get key, @value
988
- end
989
- end
990
-
991
- def test_key_error_message
992
- key = "i have a space"
993
- @cache.get key, @value
994
- assert false # Never reached
995
- rescue Memcached::ABadKeyWasProvidedOrCharactersOutOfRange => e
996
- assert_match /#{key}/, e.message
997
- end
998
-
999
- def test_server_error_message
1000
- @cache.set key, "I'm big" * 1000000
1001
- assert false # Never reached
1002
- rescue Memcached::ServerError => e
1003
- assert_match /^"object too large for cache". Key/, e.message
1004
- end
1005
-
1006
- def test_errno_message
1007
- Rlibmemcached::MemcachedServerSt.any_instance.stubs("cached_errno").returns(1)
1008
- @cache.send(:check_return_code, Rlibmemcached::MEMCACHED_ERRNO, key)
1009
- rescue Memcached::SystemError => e
1010
- assert_match /^Errno 1: "Operation not permitted". Key/, e.message
1011
- end
1012
-
1013
- # Stats
1014
-
1015
- def disable_test_stats
1016
- stats = @cache.stats
1017
- assert_equal 3, stats[:pid].size
1018
- assert_instance_of Fixnum, stats[:pid].first
1019
- assert_instance_of String, stats[:version].first
1020
-
1021
- stats = @binary_protocol_cache.stats
1022
- assert_equal 3, stats[:pid].size
1023
- assert_instance_of Fixnum, stats[:pid].first
1024
- assert_instance_of String, stats[:version].first
1025
-
1026
- assert_nothing_raised do
1027
- @noblock_cache.stats
1028
- end
1029
- assert_raises(TypeError) do
1030
- @udp_cache.stats
1031
- end
1032
- end
1033
-
1034
- def test_missing_stats
1035
- cache = Memcached.new('localhost:43041')
1036
- assert_raises(Memcached::SomeErrorsWereReported) { cache.stats }
1037
- end
1038
-
1039
- # Clone
1040
-
1041
- def test_clone
1042
- cache = @cache.clone
1043
- assert_equal cache.servers, @cache.servers
1044
- assert_not_equal cache, @cache
1045
-
1046
- # Definitely check that the structs are unlinked
1047
- assert_not_equal @cache.instance_variable_get('@struct').object_id,
1048
- cache.instance_variable_get('@struct').object_id
1049
-
1050
- assert_nothing_raised do
1051
- @cache.set key, @value
1052
- end
1053
- end
1054
-
1055
- # Pipelined, non-blocking IO
1056
-
1057
- def test_buffered_requests_return_value
1058
- cache = Memcached.new @servers,
1059
- :buffer_requests => true
1060
- assert_nothing_raised do
1061
- cache.set key, @value
1062
- end
1063
- ret = Rlibmemcached.memcached_set(
1064
- cache.instance_variable_get("@struct"),
1065
- key,
1066
- @marshalled_value,
1067
- 0,
1068
- Memcached::FLAGS
1069
- )
1070
- assert_equal Rlibmemcached::MEMCACHED_BUFFERED, ret
1071
- end
1072
-
1073
- def test_no_block_return_value
1074
- assert_nothing_raised do
1075
- @noblock_cache.set key, @value
1076
- end
1077
- ret = Rlibmemcached.memcached_set(
1078
- @noblock_cache.instance_variable_get("@struct"),
1079
- key,
1080
- @marshalled_value,
1081
- 0,
1082
- Memcached::FLAGS
1083
- )
1084
- assert_equal Rlibmemcached::MEMCACHED_BUFFERED, ret
1085
- end
1086
-
1087
- def test_no_block_prepend
1088
- @cache.set key, "help", 0, false
1089
- @noblock_cache.prepend key, "help"
1090
- assert_equal "help",
1091
- @cache.get(key, false)
1092
- @noblock_cache.get "no_exist", false rescue nil
1093
- assert_equal "helphelp",
1094
- @cache.get(key, false)
1095
- end
1096
-
1097
- def test_no_block_get
1098
- @noblock_cache.set key, @value
1099
- assert_equal @value,
1100
- @noblock_cache.get(key)
1101
- end
1102
-
1103
- def test_no_block_missing_delete
1104
- @noblock_cache.delete key rescue nil
1105
- assert_nothing_raised do
1106
- @noblock_cache.delete key
1107
- @noblock_cache.delete key
1108
- end
1109
- end
1110
-
1111
- def test_no_block_set_invalid_key
1112
- assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
1113
- @noblock_cache.set "I'm so bad", @value
1114
- end
1115
- end
1116
-
1117
- def test_no_block_set_object_too_large
1118
- noblock_cache = Memcached.new(@servers, @noblock_options.merge(:noreply => false))
1119
- assert_nothing_raised do
1120
- noblock_cache.set key, "I'm big" * 1000000
1121
- end
1122
- assert_raise( Memcached::ServerIsMarkedDead) do
1123
- @noblock_cache.set key, "I'm big" * 1000000
1124
- end
1125
- end
1126
-
1127
- def test_no_block_existing_add
1128
- # Should still raise
1129
- noblock_cache = Memcached.new(@servers, @noblock_options.merge(:noreply => false))
1130
- noblock_cache.set key, @value
1131
- assert_raise(Memcached::NotStored) do
1132
- noblock_cache.add key, @value
1133
- end
1134
- end
1135
-
1136
- # Server removal and consistent hashing
1137
-
1138
- def test_unresponsive_server
1139
- socket = stub_server 43041
1140
-
1141
- cache = Memcached.new(
1142
- [@servers.last, 'localhost:43041'],
1143
- :prefix_key => @prefix_key,
1144
- :auto_eject_hosts => true,
1145
- :server_failure_limit => 2,
1146
- :retry_timeout => 1,
1147
- :hash_with_prefix_key => false,
1148
- :hash => :md5,
1149
- :exception_retry_limit => 0
1150
- )
1151
-
1152
- # Hit second server up to the server_failure_limit
1153
- key2 = 'test_missing_server'
1154
- assert_raise(Memcached::ATimeoutOccurred) { cache.set(key2, @value) }
1155
- assert_raise(Memcached::ATimeoutOccurred) { cache.get(key2, @value) }
1156
-
1157
- # Hit second server and pass the limit
1158
- key2 = 'test_missing_server'
1159
- begin
1160
- cache.get(key2)
1161
- rescue => e
1162
- assert_equal Memcached::ServerIsMarkedDead, e.class
1163
- assert_match /localhost:43041/, e.message
1164
- end
1165
-
1166
- # Hit first server on retry
1167
- assert_nothing_raised do
1168
- cache.set(key2, @value)
1169
- assert_equal cache.get(key2), @value
1170
- end
1171
-
1172
- sleep(2)
1173
-
1174
- # Hit second server again after restore, expect same failure
1175
- key2 = 'test_missing_server'
1176
- assert_raise(Memcached::ATimeoutOccurred) do
1177
- cache.set(key2, @value)
1178
- end
1179
-
1180
- ensure
1181
- socket.close
1182
- end
1183
-
1184
- def test_unresponsive_server_retries_greater_than_server_failure_limit
1185
- socket = stub_server 43041
1186
-
1187
- cache = Memcached.new(
1188
- [@servers.last, 'localhost:43041'],
1189
- :prefix_key => @prefix_key,
1190
- :auto_eject_hosts => true,
1191
- :server_failure_limit => 2,
1192
- :retry_timeout => 1,
1193
- :hash_with_prefix_key => false,
1194
- :hash => :md5,
1195
- :exception_retry_limit => 3
1196
- )
1197
-
1198
- key2 = 'test_missing_server'
1199
- assert_nothing_raised do
1200
- cache.set(key2, @value)
1201
- assert_equal cache.get(key2), @value
1202
- end
1203
-
1204
- assert_nothing_raised do
1205
- cache.set(key2, @value)
1206
- assert_equal cache.get(key2), @value
1207
- end
1208
-
1209
- sleep(2)
1210
-
1211
- assert_nothing_raised do
1212
- cache.set(key2, @value)
1213
- assert_equal cache.get(key2), @value
1214
- end
1215
- ensure
1216
- socket.close
1217
- end
1218
-
1219
- def test_unresponsive_server_retries_equals_server_failure_limit
1220
- socket = stub_server 43041
1221
-
1222
- cache = Memcached.new(
1223
- [@servers.last, 'localhost:43041'],
1224
- :prefix_key => @prefix_key,
1225
- :auto_eject_hosts => true,
1226
- :server_failure_limit => 2,
1227
- :retry_timeout => 1,
1228
- :hash_with_prefix_key => false,
1229
- :hash => :md5,
1230
- :exception_retry_limit => 3
1231
- )
1232
-
1233
- key2 = 'test_missing_server'
1234
- begin
1235
- cache.get(key2)
1236
- rescue => e
1237
- assert_equal Memcached::ServerIsMarkedDead, e.class
1238
- assert_match /localhost:43041/, e.message
1239
- end
1240
-
1241
- assert_nothing_raised do
1242
- cache.set(key2, @value)
1243
- assert_equal cache.get(key2), @value
1244
- end
1245
-
1246
- sleep(2)
1247
-
1248
- begin
1249
- cache.get(key2)
1250
- rescue => e
1251
- assert_equal Memcached::ServerIsMarkedDead, e.class
1252
- assert_match /localhost:43041/, e.message
1253
- end
1254
-
1255
- assert_nothing_raised do
1256
- cache.set(key2, @value)
1257
- assert_equal cache.get(key2), @value
1258
- end
1259
- ensure
1260
- socket.close
1261
- end
1262
-
1263
- def test_unresponsive_server_retries_less_than_server_failure_limit
1264
- socket = stub_server 43041
1265
-
1266
- cache = Memcached.new(
1267
- [@servers.last, 'localhost:43041'],
1268
- :prefix_key => @prefix_key,
1269
- :auto_eject_hosts => true,
1270
- :server_failure_limit => 2,
1271
- :retry_timeout => 1,
1272
- :hash_with_prefix_key => false,
1273
- :hash => :md5,
1274
- :exception_retry_limit => 1
1275
- )
1276
-
1277
- key2 = 'test_missing_server'
1278
- assert_raise(Memcached::ATimeoutOccurred) { cache.set(key2, @value) }
1279
- begin
1280
- cache.get(key2)
1281
- rescue => e
1282
- assert_equal Memcached::ServerIsMarkedDead, e.class
1283
- assert_match /localhost:43041/, e.message
1284
- end
1285
-
1286
- sleep(2)
1287
-
1288
- assert_raise(Memcached::ATimeoutOccurred) { cache.set(key2, @value) }
1289
- begin
1290
- cache.get(key2)
1291
- rescue => e
1292
- assert_equal Memcached::ServerIsMarkedDead, e.class
1293
- assert_match /localhost:43041/, e.message
1294
- end
1295
- ensure
1296
- socket.close
1297
- end
1298
-
1299
- def test_wrong_failure_counter
1300
- cache = Memcached.new(
1301
- [@servers.last],
1302
- :prefix_key => @prefix_key,
1303
- :auto_eject_hosts => true,
1304
- :server_failure_limit => 1,
1305
- :retry_timeout => 1,
1306
- :hash_with_prefix_key => false,
1307
- :hash => :md5,
1308
- :exception_retry_limit => 0
1309
- )
1310
-
1311
- # This is an abuse of knowledge, but it's necessary to verify that
1312
- # the library is handling the counter properly.
1313
- struct = cache.instance_variable_get(:@struct)
1314
- server = Memcached::Lib.memcached_server_by_key(struct, "marmotte").first
1315
-
1316
- # set to ensure connectivity
1317
- cache.set("marmotte", "milk")
1318
- server.server_failure_counter = 0
1319
- cache.quit
1320
- assert_equal 0, server.server_failure_counter
1321
- end
1322
-
1323
- def test_missing_server
1324
- cache = Memcached.new(
1325
- [@servers.last, 'localhost:43041'],
1326
- :prefix_key => @prefix_key,
1327
- :auto_eject_hosts => true,
1328
- :server_failure_limit => 2,
1329
- :retry_timeout => 1,
1330
- :hash_with_prefix_key => false,
1331
- :hash => :md5,
1332
- :exception_retry_limit => 0
1333
- )
1334
-
1335
- # Hit second server up to the server_failure_limit
1336
- key2 = 'test_missing_server'
1337
- assert_raise(Memcached::SystemError) { cache.set(key2, @value) }
1338
- assert_raise(Memcached::SystemError) { cache.get(key2, @value) }
1339
-
1340
- # Hit second server and pass the limit
1341
- key2 = 'test_missing_server'
1342
- begin
1343
- cache.get(key2)
1344
- rescue => e
1345
- assert_equal Memcached::ServerIsMarkedDead, e.class
1346
- assert_match /localhost:43041/, e.message
1347
- end
1348
-
1349
- # Hit first server on retry
1350
- assert_nothing_raised do
1351
- cache.set(key2, @value)
1352
- assert_equal cache.get(key2), @value
1353
- end
1354
-
1355
- sleep(2)
1356
-
1357
- # Hit second server again after restore, expect same failure
1358
- key2 = 'test_missing_server'
1359
- assert_raise(Memcached::SystemError) do
1360
- cache.set(key2, @value)
1361
- end
1362
- end
1363
-
1364
- def test_unresponsive_with_random_distribution
1365
- socket = stub_server 43041
1366
- failures = [Memcached::ATimeoutOccurred, Memcached::ServerIsMarkedDead]
1367
-
1368
- cache = Memcached.new(
1369
- [@servers.last, 'localhost:43041'],
1370
- :auto_eject_hosts => true,
1371
- :distribution => :random,
1372
- :server_failure_limit => 1,
1373
- :retry_timeout => 1,
1374
- :exception_retry_limit => 0
1375
- )
1376
-
1377
- # Provoke the errors in 'failures'
1378
- exceptions = []
1379
- 100.times { begin; cache.set key, @value; rescue => e; exceptions << e; end }
1380
- assert_equal failures, exceptions.map { |x| x.class }
1381
-
1382
- # Hit first server on retry
1383
- assert_nothing_raised { cache.set(key, @value) }
1384
-
1385
- # Hit second server again after restore, expect same failures
1386
- sleep(2)
1387
- exceptions = []
1388
- 100.times { begin; cache.set key, @value; rescue => e; exceptions << e; end }
1389
- assert_equal failures, exceptions.map { |x| x.class }
1390
- ensure
1391
- socket.close
1392
- end
1393
-
1394
- def test_consistent_hashing
1395
- keys = %w(EN6qtgMW n6Oz2W4I ss4A8Brr QShqFLZt Y3hgP9bs CokDD4OD Nd3iTSE1 24vBV4AU H9XBUQs5 E5j8vUq1 AzSh8fva PYBlK2Pi Ke3TgZ4I AyAIYanO oxj8Xhyd eBFnE6Bt yZyTikWQ pwGoU7Pw 2UNDkKRN qMJzkgo2 keFXbQXq pBl2QnIg ApRl3mWY wmalTJW1 TLueug8M wPQL4Qfg uACwus23 nmOk9R6w lwgZJrzJ v1UJtKdG RK629Cra U2UXFRqr d9OQLNl8 KAm1K3m5 Z13gKZ1v tNVai1nT LhpVXuVx pRib1Itj I1oLUob7 Z1nUsd5Q ZOwHehUa aXpFX29U ZsnqxlGz ivQRjOdb mB3iBEAj)
1396
-
1397
- # Five servers
1398
- cache = Memcached.new(
1399
- @servers + ['localhost:43044', 'localhost:43045', 'localhost:43046'],
1400
- :prefix_key => @prefix_key
1401
- )
1402
-
1403
- cache.flush
1404
- keys.each do |key|
1405
- cache.set(key, @value)
1406
- end
1407
-
1408
- # Pull a server
1409
- cache = Memcached.new(
1410
- @servers + ['localhost:43044', 'localhost:43046'],
1411
- :prefix_key => @prefix_key
1412
- )
1413
-
1414
- failed = 0
1415
- keys.each_with_index do |key, i|
1416
- begin
1417
- cache.get(key)
1418
- rescue Memcached::NotFound
1419
- failed += 1
1420
- end
1421
- end
1422
-
1423
- assert(failed < keys.size / 3, "#{failed} failed out of #{keys.size}")
1424
- end
1425
-
1426
- # Concurrency
1427
-
1428
- def test_thread_contention
1429
- threads = []
1430
- 4.times do |index|
1431
- threads << Thread.new do
1432
- cache = @cache.clone
1433
- assert_nothing_raised do
1434
- cache.set("test_thread_contention_#{index}", index)
1435
- end
1436
- assert_equal index, cache.get("test_thread_contention_#{index}")
1437
- end
1438
- end
1439
- threads.each {|thread| thread.join}
1440
- end
1441
-
1442
- # Hash
1443
-
1444
- def test_hash
1445
- assert_equal 3157003241,
1446
- Rlibmemcached.memcached_generate_hash_rvalue("test", Rlibmemcached::MEMCACHED_HASH_FNV1_32)
1447
- end
1448
-
1449
- def test_noop_hash
1450
- %w[foo bar baz qux quux].each do |word|
1451
- assert_equal 1,
1452
- Rlibmemcached.memcached_generate_hash_rvalue(word, Rlibmemcached::MEMCACHED_HASH_NONE)
1453
- end
1454
- end
1455
-
1456
- # Memory cleanup
1457
-
1458
- def test_reset
1459
- original_struct = @cache.instance_variable_get("@struct")
1460
- assert_nothing_raised do
1461
- @cache.reset
1462
- end
1463
- assert_not_equal original_struct,
1464
- @cache.instance_variable_get("@struct")
1465
- end
1466
-
1467
- # NOTE: This breaks encapsulation, but there's no other easy way to test this without
1468
- # mocking out Rlibmemcached calls
1469
- def test_reraise_invalid_return_code
1470
- assert_raise Memcached::Error do
1471
- @cache.send(:check_return_code, 5000)
1472
- end
1473
- end
1474
-
1475
- private
1476
-
1477
- def key
1478
- caller.first[/.*[` ](.*)'/, 1] # '
1479
- end
1480
-
1481
- def stub_server(port)
1482
- socket = TCPServer.new('127.0.0.1', port)
1483
- Thread.new { socket.accept }
1484
- socket
1485
- end
1486
-
1487
- end