couchbase-memcached 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (539) hide show
  1. data.tar.gz.sig +2 -0
  2. data/BENCHMARKS +134 -0
  3. data/CHANGELOG +127 -0
  4. data/LICENSE +184 -0
  5. data/Manifest +535 -0
  6. data/README +118 -0
  7. data/Rakefile +83 -0
  8. data/TODO +4 -0
  9. data/couchbase-memcached.gemspec +33 -0
  10. data/ext/extconf-make.rb +25 -0
  11. data/ext/extconf.rb +91 -0
  12. data/ext/libmemcached-0.50/AUTHORS +11 -0
  13. data/ext/libmemcached-0.50/COPYING +33 -0
  14. data/ext/libmemcached-0.50/ChangeLog +392 -0
  15. data/ext/libmemcached-0.50/Makefile.am +114 -0
  16. data/ext/libmemcached-0.50/Makefile.in +4232 -0
  17. data/ext/libmemcached-0.50/NEWS +1 -0
  18. data/ext/libmemcached-0.50/README +43 -0
  19. data/ext/libmemcached-0.50/README.FIRST +31 -0
  20. data/ext/libmemcached-0.50/README.win32 +25 -0
  21. data/ext/libmemcached-0.50/THANKS +14 -0
  22. data/ext/libmemcached-0.50/TODO +11 -0
  23. data/ext/libmemcached-0.50/aclocal.m4 +1077 -0
  24. data/ext/libmemcached-0.50/clients/client_options.h +45 -0
  25. data/ext/libmemcached-0.50/clients/execute.cc +131 -0
  26. data/ext/libmemcached-0.50/clients/execute.h +30 -0
  27. data/ext/libmemcached-0.50/clients/generator.cc +96 -0
  28. data/ext/libmemcached-0.50/clients/generator.h +36 -0
  29. data/ext/libmemcached-0.50/clients/include.am +116 -0
  30. data/ext/libmemcached-0.50/clients/memaslap.c +908 -0
  31. data/ext/libmemcached-0.50/clients/memcapable.cc +2094 -0
  32. data/ext/libmemcached-0.50/clients/memcat.cc +242 -0
  33. data/ext/libmemcached-0.50/clients/memcp.cc +317 -0
  34. data/ext/libmemcached-0.50/clients/memdump.cc +183 -0
  35. data/ext/libmemcached-0.50/clients/memerror.cc +102 -0
  36. data/ext/libmemcached-0.50/clients/memflush.cc +154 -0
  37. data/ext/libmemcached-0.50/clients/memparse.cc +68 -0
  38. data/ext/libmemcached-0.50/clients/memrm.cc +177 -0
  39. data/ext/libmemcached-0.50/clients/memslap.cc +495 -0
  40. data/ext/libmemcached-0.50/clients/memstat.cc +349 -0
  41. data/ext/libmemcached-0.50/clients/ms_atomic.h +69 -0
  42. data/ext/libmemcached-0.50/clients/ms_conn.c +3413 -0
  43. data/ext/libmemcached-0.50/clients/ms_conn.h +241 -0
  44. data/ext/libmemcached-0.50/clients/ms_memslap.h +132 -0
  45. data/ext/libmemcached-0.50/clients/ms_setting.c +1068 -0
  46. data/ext/libmemcached-0.50/clients/ms_setting.h +181 -0
  47. data/ext/libmemcached-0.50/clients/ms_sigsegv.c +126 -0
  48. data/ext/libmemcached-0.50/clients/ms_sigsegv.h +34 -0
  49. data/ext/libmemcached-0.50/clients/ms_stats.c +307 -0
  50. data/ext/libmemcached-0.50/clients/ms_stats.h +69 -0
  51. data/ext/libmemcached-0.50/clients/ms_task.c +1114 -0
  52. data/ext/libmemcached-0.50/clients/ms_task.h +94 -0
  53. data/ext/libmemcached-0.50/clients/ms_thread.c +351 -0
  54. data/ext/libmemcached-0.50/clients/ms_thread.h +78 -0
  55. data/ext/libmemcached-0.50/clients/utilities.cc +231 -0
  56. data/ext/libmemcached-0.50/clients/utilities.h +64 -0
  57. data/ext/libmemcached-0.50/config.h.in +647 -0
  58. data/ext/libmemcached-0.50/config/autorun.sh +126 -0
  59. data/ext/libmemcached-0.50/config/compile +143 -0
  60. data/ext/libmemcached-0.50/config/config.guess +1517 -0
  61. data/ext/libmemcached-0.50/config/config.rpath +666 -0
  62. data/ext/libmemcached-0.50/config/config.sub +1760 -0
  63. data/ext/libmemcached-0.50/config/depcomp +630 -0
  64. data/ext/libmemcached-0.50/config/install-sh +520 -0
  65. data/ext/libmemcached-0.50/config/ltmain.sh +9642 -0
  66. data/ext/libmemcached-0.50/config/missing +376 -0
  67. data/ext/libmemcached-0.50/config/pandora-plugin +752 -0
  68. data/ext/libmemcached-0.50/config/uncrustify.cfg +1112 -0
  69. data/ext/libmemcached-0.50/configure +27103 -0
  70. data/ext/libmemcached-0.50/configure.ac +186 -0
  71. data/ext/libmemcached-0.50/docs/conf.py.in +354 -0
  72. data/ext/libmemcached-0.50/docs/include.am +240 -0
  73. data/ext/libmemcached-0.50/docs/man/hashkit_clone.3 +88 -0
  74. data/ext/libmemcached-0.50/docs/man/hashkit_crc32.3 +105 -0
  75. data/ext/libmemcached-0.50/docs/man/hashkit_create.3 +88 -0
  76. data/ext/libmemcached-0.50/docs/man/hashkit_fnv1_32.3 +105 -0
  77. data/ext/libmemcached-0.50/docs/man/hashkit_fnv1_64.3 +105 -0
  78. data/ext/libmemcached-0.50/docs/man/hashkit_fnv1a_32.3 +105 -0
  79. data/ext/libmemcached-0.50/docs/man/hashkit_fnv1a_64.3 +105 -0
  80. data/ext/libmemcached-0.50/docs/man/hashkit_free.3 +88 -0
  81. data/ext/libmemcached-0.50/docs/man/hashkit_functions.3 +105 -0
  82. data/ext/libmemcached-0.50/docs/man/hashkit_hsieh.3 +105 -0
  83. data/ext/libmemcached-0.50/docs/man/hashkit_is_allocated.3 +88 -0
  84. data/ext/libmemcached-0.50/docs/man/hashkit_jenkins.3 +105 -0
  85. data/ext/libmemcached-0.50/docs/man/hashkit_md5.3 +105 -0
  86. data/ext/libmemcached-0.50/docs/man/hashkit_murmur.3 +105 -0
  87. data/ext/libmemcached-0.50/docs/man/hashkit_value.3 +66 -0
  88. data/ext/libmemcached-0.50/docs/man/libhashkit.3 +57 -0
  89. data/ext/libmemcached-0.50/docs/man/libmemcached.3 +208 -0
  90. data/ext/libmemcached-0.50/docs/man/libmemcached_check_configuration.3 +293 -0
  91. data/ext/libmemcached-0.50/docs/man/libmemcached_configuration.3 +293 -0
  92. data/ext/libmemcached-0.50/docs/man/libmemcached_examples.3 +144 -0
  93. data/ext/libmemcached-0.50/docs/man/libmemcachedutil.3 +68 -0
  94. data/ext/libmemcached-0.50/docs/man/memaslap.1 +1222 -0
  95. data/ext/libmemcached-0.50/docs/man/memcached.3 +293 -0
  96. data/ext/libmemcached-0.50/docs/man/memcached_add.3 +132 -0
  97. data/ext/libmemcached-0.50/docs/man/memcached_add_by_key.3 +132 -0
  98. data/ext/libmemcached-0.50/docs/man/memcached_analyze.3 +77 -0
  99. data/ext/libmemcached-0.50/docs/man/memcached_append.3 +111 -0
  100. data/ext/libmemcached-0.50/docs/man/memcached_append_by_key.3 +111 -0
  101. data/ext/libmemcached-0.50/docs/man/memcached_behavior_get.3 +333 -0
  102. data/ext/libmemcached-0.50/docs/man/memcached_behavior_set.3 +333 -0
  103. data/ext/libmemcached-0.50/docs/man/memcached_callback_get.3 +159 -0
  104. data/ext/libmemcached-0.50/docs/man/memcached_callback_set.3 +159 -0
  105. data/ext/libmemcached-0.50/docs/man/memcached_cas.3 +91 -0
  106. data/ext/libmemcached-0.50/docs/man/memcached_cas_by_key.3 +91 -0
  107. data/ext/libmemcached-0.50/docs/man/memcached_clone.3 +99 -0
  108. data/ext/libmemcached-0.50/docs/man/memcached_create.3 +99 -0
  109. data/ext/libmemcached-0.50/docs/man/memcached_decrement.3 +124 -0
  110. data/ext/libmemcached-0.50/docs/man/memcached_decrement_with_initial.3 +124 -0
  111. data/ext/libmemcached-0.50/docs/man/memcached_delete.3 +83 -0
  112. data/ext/libmemcached-0.50/docs/man/memcached_delete_by_key.3 +83 -0
  113. data/ext/libmemcached-0.50/docs/man/memcached_destroy_sasl_auth_data.3 +95 -0
  114. data/ext/libmemcached-0.50/docs/man/memcached_dump.3 +77 -0
  115. data/ext/libmemcached-0.50/docs/man/memcached_fetch.3 +174 -0
  116. data/ext/libmemcached-0.50/docs/man/memcached_fetch_execute.3 +174 -0
  117. data/ext/libmemcached-0.50/docs/man/memcached_fetch_result.3 +174 -0
  118. data/ext/libmemcached-0.50/docs/man/memcached_flush_buffers.3 +72 -0
  119. data/ext/libmemcached-0.50/docs/man/memcached_free.3 +99 -0
  120. data/ext/libmemcached-0.50/docs/man/memcached_generate_hash.3 +85 -0
  121. data/ext/libmemcached-0.50/docs/man/memcached_generate_hash_value.3 +85 -0
  122. data/ext/libmemcached-0.50/docs/man/memcached_get.3 +174 -0
  123. data/ext/libmemcached-0.50/docs/man/memcached_get_by_key.3 +174 -0
  124. data/ext/libmemcached-0.50/docs/man/memcached_get_memory_allocators.3 +111 -0
  125. data/ext/libmemcached-0.50/docs/man/memcached_get_sasl_callbacks.3 +95 -0
  126. data/ext/libmemcached-0.50/docs/man/memcached_get_user_data.3 +79 -0
  127. data/ext/libmemcached-0.50/docs/man/memcached_increment.3 +124 -0
  128. data/ext/libmemcached-0.50/docs/man/memcached_increment_with_initial.3 +124 -0
  129. data/ext/libmemcached-0.50/docs/man/memcached_lib_version.3 +76 -0
  130. data/ext/libmemcached-0.50/docs/man/memcached_mget.3 +174 -0
  131. data/ext/libmemcached-0.50/docs/man/memcached_mget_by_key.3 +174 -0
  132. data/ext/libmemcached-0.50/docs/man/memcached_mget_execute.3 +174 -0
  133. data/ext/libmemcached-0.50/docs/man/memcached_mget_execute_by_key.3 +174 -0
  134. data/ext/libmemcached-0.50/docs/man/memcached_pool_behavior_get.3 +139 -0
  135. data/ext/libmemcached-0.50/docs/man/memcached_pool_behavior_set.3 +139 -0
  136. data/ext/libmemcached-0.50/docs/man/memcached_pool_create.3 +139 -0
  137. data/ext/libmemcached-0.50/docs/man/memcached_pool_destroy.3 +139 -0
  138. data/ext/libmemcached-0.50/docs/man/memcached_pool_pop.3 +139 -0
  139. data/ext/libmemcached-0.50/docs/man/memcached_pool_push.3 +139 -0
  140. data/ext/libmemcached-0.50/docs/man/memcached_pool_st.3 +139 -0
  141. data/ext/libmemcached-0.50/docs/man/memcached_prepend.3 +111 -0
  142. data/ext/libmemcached-0.50/docs/man/memcached_prepend_by_key.3 +111 -0
  143. data/ext/libmemcached-0.50/docs/man/memcached_quit.3 +74 -0
  144. data/ext/libmemcached-0.50/docs/man/memcached_replace.3 +132 -0
  145. data/ext/libmemcached-0.50/docs/man/memcached_replace_by_key.3 +132 -0
  146. data/ext/libmemcached-0.50/docs/man/memcached_sasl_set_auth_data.3 +95 -0
  147. data/ext/libmemcached-0.50/docs/man/memcached_server_add.3 +141 -0
  148. data/ext/libmemcached-0.50/docs/man/memcached_server_count.3 +141 -0
  149. data/ext/libmemcached-0.50/docs/man/memcached_server_cursor.3 +141 -0
  150. data/ext/libmemcached-0.50/docs/man/memcached_server_list.3 +141 -0
  151. data/ext/libmemcached-0.50/docs/man/memcached_server_list_append.3 +111 -0
  152. data/ext/libmemcached-0.50/docs/man/memcached_server_list_count.3 +111 -0
  153. data/ext/libmemcached-0.50/docs/man/memcached_server_list_free.3 +111 -0
  154. data/ext/libmemcached-0.50/docs/man/memcached_server_push.3 +141 -0
  155. data/ext/libmemcached-0.50/docs/man/memcached_servers_parse.3 +111 -0
  156. data/ext/libmemcached-0.50/docs/man/memcached_set.3 +132 -0
  157. data/ext/libmemcached-0.50/docs/man/memcached_set_by_key.3 +132 -0
  158. data/ext/libmemcached-0.50/docs/man/memcached_set_memory_allocators.3 +111 -0
  159. data/ext/libmemcached-0.50/docs/man/memcached_set_sasl_callbacks.3 +95 -0
  160. data/ext/libmemcached-0.50/docs/man/memcached_set_user_data.3 +79 -0
  161. data/ext/libmemcached-0.50/docs/man/memcached_stat.3 +116 -0
  162. data/ext/libmemcached-0.50/docs/man/memcached_stat_execute.3 +116 -0
  163. data/ext/libmemcached-0.50/docs/man/memcached_stat_get_keys.3 +116 -0
  164. data/ext/libmemcached-0.50/docs/man/memcached_stat_get_value.3 +116 -0
  165. data/ext/libmemcached-0.50/docs/man/memcached_stat_servername.3 +116 -0
  166. data/ext/libmemcached-0.50/docs/man/memcached_strerror.3 +69 -0
  167. data/ext/libmemcached-0.50/docs/man/memcached_verbosity.3 +66 -0
  168. data/ext/libmemcached-0.50/docs/man/memcached_version.3 +76 -0
  169. data/ext/libmemcached-0.50/docs/man/memcapable.1 +92 -0
  170. data/ext/libmemcached-0.50/docs/man/memcat.1 +71 -0
  171. data/ext/libmemcached-0.50/docs/man/memcp.1 +77 -0
  172. data/ext/libmemcached-0.50/docs/man/memdump.1 +66 -0
  173. data/ext/libmemcached-0.50/docs/man/memerror.1 +65 -0
  174. data/ext/libmemcached-0.50/docs/man/memflush.1 +73 -0
  175. data/ext/libmemcached-0.50/docs/man/memrm.1 +72 -0
  176. data/ext/libmemcached-0.50/docs/man/memslap.1 +59 -0
  177. data/ext/libmemcached-0.50/docs/man/memstat.1 +70 -0
  178. data/ext/libmemcached-0.50/example/include.am +24 -0
  179. data/ext/libmemcached-0.50/example/interface_v0.c +594 -0
  180. data/ext/libmemcached-0.50/example/interface_v1.c +411 -0
  181. data/ext/libmemcached-0.50/example/memcached_light.c +474 -0
  182. data/ext/libmemcached-0.50/example/memcached_light.h +7 -0
  183. data/ext/libmemcached-0.50/example/storage.c +172 -0
  184. data/ext/libmemcached-0.50/example/storage.h +27 -0
  185. data/ext/libmemcached-0.50/example/storage_innodb.c +535 -0
  186. data/ext/libmemcached-0.50/libhashkit/algorithm.cc +69 -0
  187. data/ext/libmemcached-0.50/libhashkit/algorithm.h +96 -0
  188. data/ext/libmemcached-0.50/libhashkit/behavior.cc +9 -0
  189. data/ext/libmemcached-0.50/libhashkit/behavior.h +26 -0
  190. data/ext/libmemcached-0.50/libhashkit/common.h +33 -0
  191. data/ext/libmemcached-0.50/libhashkit/configure.h.in +19 -0
  192. data/ext/libmemcached-0.50/libhashkit/crc32.cc +86 -0
  193. data/ext/libmemcached-0.50/libhashkit/digest.cc +62 -0
  194. data/ext/libmemcached-0.50/libhashkit/digest.h +30 -0
  195. data/ext/libmemcached-0.50/libhashkit/fnv.cc +75 -0
  196. data/ext/libmemcached-0.50/libhashkit/function.cc +156 -0
  197. data/ext/libmemcached-0.50/libhashkit/function.h +44 -0
  198. data/ext/libmemcached-0.50/libhashkit/hashkit.cc +100 -0
  199. data/ext/libmemcached-0.50/libhashkit/hashkit.h +95 -0
  200. data/ext/libmemcached-0.50/libhashkit/hashkit.hpp +97 -0
  201. data/ext/libmemcached-0.50/libhashkit/hsieh.cc +70 -0
  202. data/ext/libmemcached-0.50/libhashkit/include.am +69 -0
  203. data/ext/libmemcached-0.50/libhashkit/jenkins.cc +214 -0
  204. data/ext/libmemcached-0.50/libhashkit/ketama.cc +164 -0
  205. data/ext/libmemcached-0.50/libhashkit/md5.cc +367 -0
  206. data/ext/libmemcached-0.50/libhashkit/murmur.cc +77 -0
  207. data/ext/libmemcached-0.50/libhashkit/one_at_a_time.cc +34 -0
  208. data/ext/libmemcached-0.50/libhashkit/str_algorithm.cc +58 -0
  209. data/ext/libmemcached-0.50/libhashkit/str_algorithm.h +48 -0
  210. data/ext/libmemcached-0.50/libhashkit/strerror.cc +25 -0
  211. data/ext/libmemcached-0.50/libhashkit/strerror.h +23 -0
  212. data/ext/libmemcached-0.50/libhashkit/types.h +90 -0
  213. data/ext/libmemcached-0.50/libhashkit/visibility.h +48 -0
  214. data/ext/libmemcached-0.50/libmemcached/allocators.cc +119 -0
  215. data/ext/libmemcached-0.50/libmemcached/allocators.h +87 -0
  216. data/ext/libmemcached-0.50/libmemcached/analyze.cc +110 -0
  217. data/ext/libmemcached-0.50/libmemcached/analyze.h +66 -0
  218. data/ext/libmemcached-0.50/libmemcached/array.c +128 -0
  219. data/ext/libmemcached-0.50/libmemcached/array.h +75 -0
  220. data/ext/libmemcached-0.50/libmemcached/auto.cc +383 -0
  221. data/ext/libmemcached-0.50/libmemcached/auto.h +111 -0
  222. data/ext/libmemcached-0.50/libmemcached/basic_string.h +55 -0
  223. data/ext/libmemcached-0.50/libmemcached/behavior.cc +590 -0
  224. data/ext/libmemcached-0.50/libmemcached/behavior.h +86 -0
  225. data/ext/libmemcached-0.50/libmemcached/byteorder.cc +90 -0
  226. data/ext/libmemcached-0.50/libmemcached/byteorder.h +52 -0
  227. data/ext/libmemcached-0.50/libmemcached/callback.cc +160 -0
  228. data/ext/libmemcached-0.50/libmemcached/callback.h +61 -0
  229. data/ext/libmemcached-0.50/libmemcached/common.h +182 -0
  230. data/ext/libmemcached-0.50/libmemcached/configure.h.in +52 -0
  231. data/ext/libmemcached-0.50/libmemcached/connect.cc +626 -0
  232. data/ext/libmemcached-0.50/libmemcached/constants.h +167 -0
  233. data/ext/libmemcached-0.50/libmemcached/delete.cc +266 -0
  234. data/ext/libmemcached-0.50/libmemcached/delete.h +57 -0
  235. data/ext/libmemcached-0.50/libmemcached/do.cc +100 -0
  236. data/ext/libmemcached-0.50/libmemcached/do.hpp +49 -0
  237. data/ext/libmemcached-0.50/libmemcached/dump.cc +107 -0
  238. data/ext/libmemcached-0.50/libmemcached/dump.h +51 -0
  239. data/ext/libmemcached-0.50/libmemcached/error.cc +419 -0
  240. data/ext/libmemcached-0.50/libmemcached/error.h +61 -0
  241. data/ext/libmemcached-0.50/libmemcached/error.hpp +87 -0
  242. data/ext/libmemcached-0.50/libmemcached/exception.hpp +63 -0
  243. data/ext/libmemcached-0.50/libmemcached/fetch.cc +267 -0
  244. data/ext/libmemcached-0.50/libmemcached/fetch.h +53 -0
  245. data/ext/libmemcached-0.50/libmemcached/flush.cc +149 -0
  246. data/ext/libmemcached-0.50/libmemcached/flush.h +49 -0
  247. data/ext/libmemcached-0.50/libmemcached/flush_buffers.cc +66 -0
  248. data/ext/libmemcached-0.50/libmemcached/flush_buffers.h +49 -0
  249. data/ext/libmemcached-0.50/libmemcached/get.cc +842 -0
  250. data/ext/libmemcached-0.50/libmemcached/get.h +135 -0
  251. data/ext/libmemcached-0.50/libmemcached/hash.cc +178 -0
  252. data/ext/libmemcached-0.50/libmemcached/hash.h +68 -0
  253. data/ext/libmemcached-0.50/libmemcached/hosts.cc +516 -0
  254. data/ext/libmemcached-0.50/libmemcached/include.am +183 -0
  255. data/ext/libmemcached-0.50/libmemcached/initialize_query.cc +70 -0
  256. data/ext/libmemcached-0.50/libmemcached/initialize_query.h +51 -0
  257. data/ext/libmemcached-0.50/libmemcached/internal.h +46 -0
  258. data/ext/libmemcached-0.50/libmemcached/io.cc +920 -0
  259. data/ext/libmemcached-0.50/libmemcached/io.h +119 -0
  260. data/ext/libmemcached-0.50/libmemcached/is.h +48 -0
  261. data/ext/libmemcached-0.50/libmemcached/key.cc +23 -0
  262. data/ext/libmemcached-0.50/libmemcached/libmemcached_probes.d +30 -0
  263. data/ext/libmemcached-0.50/libmemcached/libmemcached_probes.h +118 -0
  264. data/ext/libmemcached-0.50/libmemcached/memcached.cc +437 -0
  265. data/ext/libmemcached-0.50/libmemcached/memcached.h +214 -0
  266. data/ext/libmemcached-0.50/libmemcached/memcached.hpp +799 -0
  267. data/ext/libmemcached-0.50/libmemcached/memcached/README.txt +7 -0
  268. data/ext/libmemcached-0.50/libmemcached/memcached/protocol_binary.h +726 -0
  269. data/ext/libmemcached-0.50/libmemcached/memcached/vbucket.h +26 -0
  270. data/ext/libmemcached-0.50/libmemcached/memcached_util.h +44 -0
  271. data/ext/libmemcached-0.50/libmemcached/memory.h +79 -0
  272. data/ext/libmemcached-0.50/libmemcached/options.cc +178 -0
  273. data/ext/libmemcached-0.50/libmemcached/options.h +49 -0
  274. data/ext/libmemcached-0.50/libmemcached/options.hpp +56 -0
  275. data/ext/libmemcached-0.50/libmemcached/options/context.h +151 -0
  276. data/ext/libmemcached-0.50/libmemcached/options/include.am +19 -0
  277. data/ext/libmemcached-0.50/libmemcached/options/parser.am +0 -0
  278. data/ext/libmemcached-0.50/libmemcached/options/parser.cc +2324 -0
  279. data/ext/libmemcached-0.50/libmemcached/options/parser.h +122 -0
  280. data/ext/libmemcached-0.50/libmemcached/options/scanner.cc +3203 -0
  281. data/ext/libmemcached-0.50/libmemcached/options/scanner.h +479 -0
  282. data/ext/libmemcached-0.50/libmemcached/options/server.h +60 -0
  283. data/ext/libmemcached-0.50/libmemcached/options/symbol.h +57 -0
  284. data/ext/libmemcached-0.50/libmemcached/parse.cc +110 -0
  285. data/ext/libmemcached-0.50/libmemcached/parse.h +23 -0
  286. data/ext/libmemcached-0.50/libmemcached/platform.h +56 -0
  287. data/ext/libmemcached-0.50/libmemcached/prefix_key.cc +65 -0
  288. data/ext/libmemcached-0.50/libmemcached/prefix_key.h +49 -0
  289. data/ext/libmemcached-0.50/libmemcached/protocol/ascii_handler.c +963 -0
  290. data/ext/libmemcached-0.50/libmemcached/protocol/ascii_handler.h +40 -0
  291. data/ext/libmemcached-0.50/libmemcached/protocol/binary_handler.c +1121 -0
  292. data/ext/libmemcached-0.50/libmemcached/protocol/binary_handler.h +47 -0
  293. data/ext/libmemcached-0.50/libmemcached/protocol/cache.c +149 -0
  294. data/ext/libmemcached-0.50/libmemcached/protocol/cache.h +116 -0
  295. data/ext/libmemcached-0.50/libmemcached/protocol/callback.h +418 -0
  296. data/ext/libmemcached-0.50/libmemcached/protocol/common.h +163 -0
  297. data/ext/libmemcached-0.50/libmemcached/protocol/include.am +26 -0
  298. data/ext/libmemcached-0.50/libmemcached/protocol/pedantic.c +202 -0
  299. data/ext/libmemcached-0.50/libmemcached/protocol/protocol_handler.c +365 -0
  300. data/ext/libmemcached-0.50/libmemcached/protocol_handler.h +215 -0
  301. data/ext/libmemcached-0.50/libmemcached/purge.cc +90 -0
  302. data/ext/libmemcached-0.50/libmemcached/quit.cc +139 -0
  303. data/ext/libmemcached-0.50/libmemcached/quit.h +55 -0
  304. data/ext/libmemcached-0.50/libmemcached/response.cc +619 -0
  305. data/ext/libmemcached-0.50/libmemcached/response.h +57 -0
  306. data/ext/libmemcached-0.50/libmemcached/result.cc +173 -0
  307. data/ext/libmemcached-0.50/libmemcached/result.h +100 -0
  308. data/ext/libmemcached-0.50/libmemcached/return.h +98 -0
  309. data/ext/libmemcached-0.50/libmemcached/sasl.c +408 -0
  310. data/ext/libmemcached-0.50/libmemcached/sasl.h +86 -0
  311. data/ext/libmemcached-0.50/libmemcached/server.cc +351 -0
  312. data/ext/libmemcached-0.50/libmemcached/server.h +169 -0
  313. data/ext/libmemcached-0.50/libmemcached/server_list.cc +88 -0
  314. data/ext/libmemcached-0.50/libmemcached/server_list.h +77 -0
  315. data/ext/libmemcached-0.50/libmemcached/stats.cc +623 -0
  316. data/ext/libmemcached-0.50/libmemcached/stats.h +96 -0
  317. data/ext/libmemcached-0.50/libmemcached/storage.cc +567 -0
  318. data/ext/libmemcached-0.50/libmemcached/storage.h +133 -0
  319. data/ext/libmemcached-0.50/libmemcached/strerror.cc +189 -0
  320. data/ext/libmemcached-0.50/libmemcached/strerror.h +50 -0
  321. data/ext/libmemcached-0.50/libmemcached/string.cc +253 -0
  322. data/ext/libmemcached-0.50/libmemcached/string.h +121 -0
  323. data/ext/libmemcached-0.50/libmemcached/touch.cc +106 -0
  324. data/ext/libmemcached-0.50/libmemcached/touch.h +59 -0
  325. data/ext/libmemcached-0.50/libmemcached/types.h +117 -0
  326. data/ext/libmemcached-0.50/libmemcached/util.h +40 -0
  327. data/ext/libmemcached-0.50/libmemcached/util/flush.cc +61 -0
  328. data/ext/libmemcached-0.50/libmemcached/util/flush.h +50 -0
  329. data/ext/libmemcached-0.50/libmemcached/util/include.am +34 -0
  330. data/ext/libmemcached-0.50/libmemcached/util/ping.cc +62 -0
  331. data/ext/libmemcached-0.50/libmemcached/util/ping.h +49 -0
  332. data/ext/libmemcached-0.50/libmemcached/util/pool.cc +392 -0
  333. data/ext/libmemcached-0.50/libmemcached/util/pool.h +78 -0
  334. data/ext/libmemcached-0.50/libmemcached/util/version.cc +87 -0
  335. data/ext/libmemcached-0.50/libmemcached/util/version.h +53 -0
  336. data/ext/libmemcached-0.50/libmemcached/verbosity.cc +97 -0
  337. data/ext/libmemcached-0.50/libmemcached/verbosity.h +50 -0
  338. data/ext/libmemcached-0.50/libmemcached/version.cc +214 -0
  339. data/ext/libmemcached-0.50/libmemcached/version.h +52 -0
  340. data/ext/libmemcached-0.50/libmemcached/virtual_bucket.c +118 -0
  341. data/ext/libmemcached-0.50/libmemcached/virtual_bucket.h +59 -0
  342. data/ext/libmemcached-0.50/libmemcached/visibility.h +51 -0
  343. data/ext/libmemcached-0.50/libmemcached/watchpoint.h +110 -0
  344. data/ext/libmemcached-0.50/libtest/callbacks.h +21 -0
  345. data/ext/libmemcached-0.50/libtest/collection.h +19 -0
  346. data/ext/libmemcached-0.50/libtest/common.h +50 -0
  347. data/ext/libmemcached-0.50/libtest/core.h +11 -0
  348. data/ext/libmemcached-0.50/libtest/error.h +18 -0
  349. data/ext/libmemcached-0.50/libtest/failed.h +52 -0
  350. data/ext/libmemcached-0.50/libtest/framework.cc +57 -0
  351. data/ext/libmemcached-0.50/libtest/framework.h +137 -0
  352. data/ext/libmemcached-0.50/libtest/get.h +22 -0
  353. data/ext/libmemcached-0.50/libtest/include.am +52 -0
  354. data/ext/libmemcached-0.50/libtest/runner.h +19 -0
  355. data/ext/libmemcached-0.50/libtest/server.c +355 -0
  356. data/ext/libmemcached-0.50/libtest/server.h +43 -0
  357. data/ext/libmemcached-0.50/libtest/stats.h +30 -0
  358. data/ext/libmemcached-0.50/libtest/strerror.h +14 -0
  359. data/ext/libmemcached-0.50/libtest/test.cc +319 -0
  360. data/ext/libmemcached-0.50/libtest/test.h +162 -0
  361. data/ext/libmemcached-0.50/libtest/test.hpp +46 -0
  362. data/ext/libmemcached-0.50/libtest/visibility.h +69 -0
  363. data/ext/libmemcached-0.50/m4/ac_cxx_header_stdcxx_98.m4 +83 -0
  364. data/ext/libmemcached-0.50/m4/acx_pthread.m4 +271 -0
  365. data/ext/libmemcached-0.50/m4/byteorder.m4 +19 -0
  366. data/ext/libmemcached-0.50/m4/deprecated.m4 +17 -0
  367. data/ext/libmemcached-0.50/m4/eagain.m4 +28 -0
  368. data/ext/libmemcached-0.50/m4/enable_utillib.m4 +16 -0
  369. data/ext/libmemcached-0.50/m4/gettext.m4 +379 -0
  370. data/ext/libmemcached-0.50/m4/hsieh.m4 +18 -0
  371. data/ext/libmemcached-0.50/m4/iconv.m4 +214 -0
  372. data/ext/libmemcached-0.50/m4/lib-ld.m4 +110 -0
  373. data/ext/libmemcached-0.50/m4/lib-link.m4 +767 -0
  374. data/ext/libmemcached-0.50/m4/lib-prefix.m4 +221 -0
  375. data/ext/libmemcached-0.50/m4/libtool.m4 +7851 -0
  376. data/ext/libmemcached-0.50/m4/ltoptions.m4 +369 -0
  377. data/ext/libmemcached-0.50/m4/ltsugar.m4 +123 -0
  378. data/ext/libmemcached-0.50/m4/ltversion.m4 +23 -0
  379. data/ext/libmemcached-0.50/m4/lt~obsolete.m4 +98 -0
  380. data/ext/libmemcached-0.50/m4/memaslap.m4 +9 -0
  381. data/ext/libmemcached-0.50/m4/memcached.m4 +31 -0
  382. data/ext/libmemcached-0.50/m4/murmur.m4 +18 -0
  383. data/ext/libmemcached-0.50/m4/pandora_64bit.m4 +60 -0
  384. data/ext/libmemcached-0.50/m4/pandora_bison.m4 +33 -0
  385. data/ext/libmemcached-0.50/m4/pandora_canonical.m4 +418 -0
  386. data/ext/libmemcached-0.50/m4/pandora_check_compiler_version.m4 +37 -0
  387. data/ext/libmemcached-0.50/m4/pandora_check_cxx_standard.m4 +23 -0
  388. data/ext/libmemcached-0.50/m4/pandora_cinttypes.m4 +39 -0
  389. data/ext/libmemcached-0.50/m4/pandora_clock_gettime.m4 +15 -0
  390. data/ext/libmemcached-0.50/m4/pandora_compile_stdcxx_0x.m4 +103 -0
  391. data/ext/libmemcached-0.50/m4/pandora_cstdint.m4 +38 -0
  392. data/ext/libmemcached-0.50/m4/pandora_cxx_demangle.m4 +27 -0
  393. data/ext/libmemcached-0.50/m4/pandora_enable_dtrace.m4 +60 -0
  394. data/ext/libmemcached-0.50/m4/pandora_ensure_gcc_version.m4 +62 -0
  395. data/ext/libmemcached-0.50/m4/pandora_extensions.m4 +16 -0
  396. data/ext/libmemcached-0.50/m4/pandora_fdatasync.m4 +25 -0
  397. data/ext/libmemcached-0.50/m4/pandora_flex.m4 +33 -0
  398. data/ext/libmemcached-0.50/m4/pandora_have_better_malloc.m4 +66 -0
  399. data/ext/libmemcached-0.50/m4/pandora_have_boost.m4 +93 -0
  400. data/ext/libmemcached-0.50/m4/pandora_have_gcc_atomics.m4 +37 -0
  401. data/ext/libmemcached-0.50/m4/pandora_have_innodb.m4 +41 -0
  402. data/ext/libmemcached-0.50/m4/pandora_have_libaio.m4 +56 -0
  403. data/ext/libmemcached-0.50/m4/pandora_have_libavahi.m4 +41 -0
  404. data/ext/libmemcached-0.50/m4/pandora_have_libbdb.m4 +40 -0
  405. data/ext/libmemcached-0.50/m4/pandora_have_libboost_date_time.m4 +46 -0
  406. data/ext/libmemcached-0.50/m4/pandora_have_libboost_filesystem.m4 +47 -0
  407. data/ext/libmemcached-0.50/m4/pandora_have_libboost_iostreams.m4 +49 -0
  408. data/ext/libmemcached-0.50/m4/pandora_have_libboost_options.m4 +47 -0
  409. data/ext/libmemcached-0.50/m4/pandora_have_libboost_regex.m4 +54 -0
  410. data/ext/libmemcached-0.50/m4/pandora_have_libboost_test.m4 +45 -0
  411. data/ext/libmemcached-0.50/m4/pandora_have_libboost_thread.m4 +54 -0
  412. data/ext/libmemcached-0.50/m4/pandora_have_libcassandra.m4 +44 -0
  413. data/ext/libmemcached-0.50/m4/pandora_have_libcurl.m4 +62 -0
  414. data/ext/libmemcached-0.50/m4/pandora_have_libdl.m4 +51 -0
  415. data/ext/libmemcached-0.50/m4/pandora_have_libdrizzle.m4 +61 -0
  416. data/ext/libmemcached-0.50/m4/pandora_have_libevent.m4 +66 -0
  417. data/ext/libmemcached-0.50/m4/pandora_have_libgearman.m4 +41 -0
  418. data/ext/libmemcached-0.50/m4/pandora_have_libgtest.m4 +47 -0
  419. data/ext/libmemcached-0.50/m4/pandora_have_libhaildb.m4 +43 -0
  420. data/ext/libmemcached-0.50/m4/pandora_have_libhashkit.m4 +42 -0
  421. data/ext/libmemcached-0.50/m4/pandora_have_libinnodb.m4 +64 -0
  422. data/ext/libmemcached-0.50/m4/pandora_have_libldap.m4 +73 -0
  423. data/ext/libmemcached-0.50/m4/pandora_have_libmemcached.m4 +106 -0
  424. data/ext/libmemcached-0.50/m4/pandora_have_libmysqlclient.m4 +146 -0
  425. data/ext/libmemcached-0.50/m4/pandora_have_libndbclient.m4 +80 -0
  426. data/ext/libmemcached-0.50/m4/pandora_have_libpcre.m4 +73 -0
  427. data/ext/libmemcached-0.50/m4/pandora_have_libpq.m4 +46 -0
  428. data/ext/libmemcached-0.50/m4/pandora_have_libpqxx.m4 +44 -0
  429. data/ext/libmemcached-0.50/m4/pandora_have_libsqlite3.m4 +42 -0
  430. data/ext/libmemcached-0.50/m4/pandora_have_libtokyocabinet.m4 +54 -0
  431. data/ext/libmemcached-0.50/m4/pandora_have_libuuid.m4 +55 -0
  432. data/ext/libmemcached-0.50/m4/pandora_have_libvbucket.m4 +40 -0
  433. data/ext/libmemcached-0.50/m4/pandora_have_libxml2.m4 +52 -0
  434. data/ext/libmemcached-0.50/m4/pandora_have_libz.m4 +51 -0
  435. data/ext/libmemcached-0.50/m4/pandora_have_protobuf.m4 +82 -0
  436. data/ext/libmemcached-0.50/m4/pandora_have_sasl.m4 +133 -0
  437. data/ext/libmemcached-0.50/m4/pandora_have_thrift.m4 +45 -0
  438. data/ext/libmemcached-0.50/m4/pandora_header_assert.m4 +23 -0
  439. data/ext/libmemcached-0.50/m4/pandora_header_stdcxx_98.m4 +83 -0
  440. data/ext/libmemcached-0.50/m4/pandora_intltool.m4 +225 -0
  441. data/ext/libmemcached-0.50/m4/pandora_libtool.m4 +25 -0
  442. data/ext/libmemcached-0.50/m4/pandora_optimize.m4 +75 -0
  443. data/ext/libmemcached-0.50/m4/pandora_platform.m4 +117 -0
  444. data/ext/libmemcached-0.50/m4/pandora_plugins.m4 +62 -0
  445. data/ext/libmemcached-0.50/m4/pandora_print_callstack.m4 +61 -0
  446. data/ext/libmemcached-0.50/m4/pandora_pthread.m4 +258 -0
  447. data/ext/libmemcached-0.50/m4/pandora_python3_devel.m4 +236 -0
  448. data/ext/libmemcached-0.50/m4/pandora_run_cpplint.m4 +8 -0
  449. data/ext/libmemcached-0.50/m4/pandora_sasl.m4 +133 -0
  450. data/ext/libmemcached-0.50/m4/pandora_shared_ptr.m4 +59 -0
  451. data/ext/libmemcached-0.50/m4/pandora_stack_direction.m4 +39 -0
  452. data/ext/libmemcached-0.50/m4/pandora_stl_hash.m4 +94 -0
  453. data/ext/libmemcached-0.50/m4/pandora_swig.m4 +39 -0
  454. data/ext/libmemcached-0.50/m4/pandora_use_pipe.m4 +36 -0
  455. data/ext/libmemcached-0.50/m4/pandora_vc_build.m4 +168 -0
  456. data/ext/libmemcached-0.50/m4/pandora_version.m4 +11 -0
  457. data/ext/libmemcached-0.50/m4/pandora_visibility.m4 +75 -0
  458. data/ext/libmemcached-0.50/m4/pandora_warnings.m4 +447 -0
  459. data/ext/libmemcached-0.50/m4/pandora_with_gettext.m4 +44 -0
  460. data/ext/libmemcached-0.50/m4/pandora_with_lua.m4 +55 -0
  461. data/ext/libmemcached-0.50/m4/pandora_with_memcached.m4 +41 -0
  462. data/ext/libmemcached-0.50/m4/pandora_with_perl.m4 +81 -0
  463. data/ext/libmemcached-0.50/m4/pandora_with_php.m4 +56 -0
  464. data/ext/libmemcached-0.50/m4/pandora_with_python.m4 +37 -0
  465. data/ext/libmemcached-0.50/m4/pandora_with_python3.m4 +44 -0
  466. data/ext/libmemcached-0.50/m4/pandora_with_r.m4 +33 -0
  467. data/ext/libmemcached-0.50/m4/pandora_with_ruby.m4 +79 -0
  468. data/ext/libmemcached-0.50/m4/pandora_with_valgrind.m4 +17 -0
  469. data/ext/libmemcached-0.50/m4/pkg.m4 +157 -0
  470. data/ext/libmemcached-0.50/m4/po.m4 +449 -0
  471. data/ext/libmemcached-0.50/m4/progtest.m4 +92 -0
  472. data/ext/libmemcached-0.50/m4/protocol_binary.m4 +36 -0
  473. data/ext/libmemcached-0.50/m4/setsockopt.m4 +73 -0
  474. data/ext/libmemcached-0.50/m4/socket_send_flags.m4 +66 -0
  475. data/ext/libmemcached-0.50/poll/include.am +8 -0
  476. data/ext/libmemcached-0.50/poll/poll.c +77 -0
  477. data/ext/libmemcached-0.50/poll/poll.h +45 -0
  478. data/ext/libmemcached-0.50/support/include.am +11 -0
  479. data/ext/libmemcached-0.50/support/libmemcached-fc.spec.in +105 -0
  480. data/ext/libmemcached-0.50/support/libmemcached.pc.in +10 -0
  481. data/ext/libmemcached-0.50/support/libmemcached.spec.in +281 -0
  482. data/ext/libmemcached-0.50/support/set_benchmark.sh +5 -0
  483. data/ext/libmemcached-0.50/tests/atomsmasher.cc +295 -0
  484. data/ext/libmemcached-0.50/tests/basic.cc +134 -0
  485. data/ext/libmemcached-0.50/tests/basic.h +66 -0
  486. data/ext/libmemcached-0.50/tests/cpp_example.cc +195 -0
  487. data/ext/libmemcached-0.50/tests/deprecated.cc +72 -0
  488. data/ext/libmemcached-0.50/tests/deprecated.h +49 -0
  489. data/ext/libmemcached-0.50/tests/error_conditions.cc +63 -0
  490. data/ext/libmemcached-0.50/tests/error_conditions.h +48 -0
  491. data/ext/libmemcached-0.50/tests/hash_plus.cc +225 -0
  492. data/ext/libmemcached-0.50/tests/hash_results.h +127 -0
  493. data/ext/libmemcached-0.50/tests/hashkit_functions.cc +619 -0
  494. data/ext/libmemcached-0.50/tests/include.am +342 -0
  495. data/ext/libmemcached-0.50/tests/ketama_test_cases.h +121 -0
  496. data/ext/libmemcached-0.50/tests/ketama_test_cases_spy.h +118 -0
  497. data/ext/libmemcached-0.50/tests/libmemcached_world.h +205 -0
  498. data/ext/libmemcached-0.50/tests/mem_functions.cc +6648 -0
  499. data/ext/libmemcached-0.50/tests/mem_udp.cc +510 -0
  500. data/ext/libmemcached-0.50/tests/output_plus.res +5 -0
  501. data/ext/libmemcached-0.50/tests/parser.cc +599 -0
  502. data/ext/libmemcached-0.50/tests/parser.h +109 -0
  503. data/ext/libmemcached-0.50/tests/plus.cpp +240 -0
  504. data/ext/libmemcached-0.50/tests/pool.cc +78 -0
  505. data/ext/libmemcached-0.50/tests/pool.h +49 -0
  506. data/ext/libmemcached-0.50/tests/print.cc +58 -0
  507. data/ext/libmemcached-0.50/tests/print.h +51 -0
  508. data/ext/libmemcached-0.50/tests/replication.cc +333 -0
  509. data/ext/libmemcached-0.50/tests/replication.h +64 -0
  510. data/ext/libmemcached-0.50/tests/start.cc +29 -0
  511. data/ext/libmemcached-0.50/tests/string.cc +174 -0
  512. data/ext/libmemcached-0.50/tests/string.h +67 -0
  513. data/ext/libmemcached-0.50/tests/virtual_buckets.cc +143 -0
  514. data/ext/libmemcached-0.50/tests/virtual_buckets.h +51 -0
  515. data/ext/libmemcached-0.50/win32/include.am +11 -0
  516. data/ext/libmemcached-0.50/win32/wrappers.h +55 -0
  517. data/ext/rlibmemcached.i +263 -0
  518. data/ext/rlibmemcached_wrap.c +16732 -0
  519. data/lib/memcached.rb +32 -0
  520. data/lib/memcached/auth.rb +16 -0
  521. data/lib/memcached/behaviors.rb +77 -0
  522. data/lib/memcached/exceptions.rb +84 -0
  523. data/lib/memcached/experimental.rb +48 -0
  524. data/lib/memcached/memcached.rb +660 -0
  525. data/lib/memcached/rails.rb +133 -0
  526. data/test/profile/benchmark.rb +245 -0
  527. data/test/profile/c_profiler.rb +14 -0
  528. data/test/profile/exercise.rb +185 -0
  529. data/test/profile/rb_profiler.rb +21 -0
  530. data/test/profile/valgrind.rb +10 -0
  531. data/test/setup.rb +30 -0
  532. data/test/teardown.rb +0 -0
  533. data/test/test_helper.rb +19 -0
  534. data/test/unit/binding_test.rb +8 -0
  535. data/test/unit/memcached_experimental_test.rb +274 -0
  536. data/test/unit/memcached_test.rb +1293 -0
  537. data/test/unit/rails_test.rb +122 -0
  538. metadata +650 -0
  539. metadata.gz.sig +0 -0
@@ -0,0 +1,21 @@
1
+
2
+ require "#{File.dirname(__FILE__)}/../setup"
3
+
4
+ $LOAD_PATH << "#{File.dirname(__FILE__)}/../../lib/"
5
+
6
+ ENV['CPUPROFILE_FREQUENCY'] = '500'
7
+ require 'memcached'
8
+ require 'rubygems'
9
+ require 'perftools'
10
+ require "#{HERE}/profile/exercise"
11
+
12
+ profile = "/tmp/memcached_#{Memcached::VERSION}_rb"
13
+ worker = Worker.new('mixed', 200000)
14
+
15
+ PerfTools::CpuProfiler.start("#{profile}.out") do
16
+ worker.work
17
+ end
18
+
19
+ system("pprof.rb --nodefraction=0.0000001 --text #{profile}.out")
20
+ system("pprof.rb --nodefraction=0.0000001 --edgefraction=0.0000001 --pdf #{profile}.out > #{profile}.pdf")
21
+ system("open #{profile}.pdf")
@@ -0,0 +1,10 @@
1
+ require "#{File.dirname(__FILE__)}/../setup"
2
+
3
+ COMMAND = "--dsymutil=yes ruby -r#{File.dirname(__FILE__)}/exercise.rb -e \"Worker.new(ENV['TEST'] || 'everything', (ENV['LOOPS'] || 50).to_i, 'true').work\""
4
+
5
+ case ENV["TOOL"]
6
+ when nil, "memcheck":
7
+ exec("valgrind --tool=memcheck --error-limit=no --undef-value-errors=no --leak-check=full --show-reachable=no --num-callers=15 --track-fds=yes --workaround-gcc296-bugs=yes --leak-resolution=med --max-stackframe=7304328 #{COMMAND}")
8
+ when "massif":
9
+ exec("valgrind --tool=massif --time-unit=B #{COMMAND}")
10
+ end
@@ -0,0 +1,30 @@
1
+
2
+ unless defined? UNIX_SOCKET_NAME
3
+ HERE = File.dirname(__FILE__)
4
+ UNIX_SOCKET_NAME = File.join(ENV['TMPDIR']||'/tmp','memcached')
5
+
6
+ # Kill memcached
7
+ system("killall -9 memcached")
8
+
9
+ # Start memcached
10
+ verbosity = (ENV['DEBUG'] ? "-vv" : "")
11
+ log = "/tmp/memcached.log"
12
+ memcached = ENV['MEMCACHED_COMMAND'] || 'memcached'
13
+ system ">#{log}"
14
+
15
+ # TCP memcached
16
+ (43042..43046).each do |port|
17
+ cmd = "#{memcached} #{verbosity} -U 0 -p #{port} >> #{log} 2>&1 &"
18
+ raise "'#{cmd}' failed to start" unless system(cmd)
19
+ end
20
+ # UDP memcached
21
+ (43052..43053).each do |port|
22
+ cmd = "#{memcached} #{verbosity} -U #{port} -p 0 >> #{log} 2>&1 &"
23
+ raise "'#{cmd}' failed to start" unless system(cmd)
24
+ end
25
+ # Domain socket memcached
26
+ (0..1).each do |i|
27
+ cmd = "#{memcached} -M -s #{UNIX_SOCKET_NAME}#{i} #{verbosity} >> #{log} 2>&1 &"
28
+ raise "'#{cmd}' failed to start" unless system(cmd)
29
+ end
30
+ end
File without changes
@@ -0,0 +1,19 @@
1
+
2
+ $LOAD_PATH << "#{File.dirname(__FILE__)}/../lib"
3
+
4
+ require 'socket'
5
+ require 'benchmark'
6
+
7
+ require 'rubygems'
8
+ require 'ruby-debug' if ENV['DEBUG']
9
+ require 'memcached'
10
+
11
+ require 'test/unit'
12
+ require 'ostruct'
13
+ require 'mocha'
14
+
15
+ UNIX_SOCKET_NAME = File.join(ENV['TMPDIR']||'/tmp','memcached') unless defined? UNIX_SOCKET_NAME
16
+
17
+ class GenericClass
18
+ end
19
+
@@ -0,0 +1,8 @@
1
+
2
+ require File.expand_path("#{File.dirname(__FILE__)}/../test_helper")
3
+
4
+ class BindingTest < Test::Unit::TestCase
5
+ def test_libmemcached_loaded
6
+ assert_nothing_raised { Rlibmemcached }
7
+ end
8
+ end
@@ -0,0 +1,274 @@
1
+
2
+ require File.expand_path("#{File.dirname(__FILE__)}/../test_helper")
3
+
4
+ class MemcachedExperimentalTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @servers = ['localhost:43042', 'localhost:43043', "#{UNIX_SOCKET_NAME}0"]
8
+
9
+ # Maximum allowed prefix key size for :hash_with_prefix_key_key => false
10
+ @prefix_key = 'prefix_key_'
11
+
12
+ @options = {
13
+ :prefix_key => @prefix_key,
14
+ :hash => :default,
15
+ :distribution => :modula}
16
+ @cache = Memcached.new(@servers, @options)
17
+
18
+ @experimental_options = {
19
+ :prefix_key => @prefix_key,
20
+ :hash => :default,
21
+ :distribution => :modula,
22
+ :experimental_features => true}
23
+ @experimental_cache = Memcached.new(@servers, @experimental_options)
24
+
25
+ @experimental_cas_options = {
26
+ :prefix_key => @prefix_key,
27
+ :support_cas => true,
28
+ :experimental_features => true}
29
+ @experimental_cas_cache = Memcached.new(@servers, @experimental_cas_options)
30
+
31
+ @experimental_binary_protocol_options = {
32
+ :prefix_key => @prefix_key,
33
+ :hash => :default,
34
+ :distribution => :modula,
35
+ :experimental_features => true,
36
+ # binary_protocol does not work -- test_get, test_get, test_append, and test_missing_append will fail when it is set to true.
37
+ :binary_protocol => true}
38
+ @experimental_binary_protocol_cache = Memcached.new(@servers, @experimental_binary_protocol_options)
39
+
40
+ @value = OpenStruct.new(:a => 1, :b => 2, :c => GenericClass)
41
+ end
42
+
43
+ def server_get_len_capable
44
+ begin
45
+ value = "foobar"
46
+ @experimental_cache.set key, value, 0, false
47
+ @experimental_cache.get_len 1, key
48
+ yield
49
+ rescue Memcached::ProtocolError
50
+ # Skip tests when the server does not support the experimental get_len command.
51
+ end
52
+ end
53
+
54
+ def server_touch_capable
55
+ @experimental_binary_protocol_cache.set(key, 'touchval')
56
+ @experimental_binary_protocol_cache.touch(key)
57
+ yield
58
+ rescue Memcached::ProtocolError
59
+ # Skip tests when the server does not support the experimental touch command.
60
+ end
61
+
62
+ def test_get_len
63
+ server_get_len_capable {
64
+ value = "foobar"
65
+ @experimental_cache.set key, value, 0, false
66
+ result = @experimental_cache.get_len 1, key
67
+ assert_equal result.size, 1
68
+ assert_equal result, value[0..0]
69
+
70
+ result = @experimental_cache.get_len 2, key
71
+ assert_equal result.size, 2
72
+ assert_equal result, value[0..1]
73
+
74
+ result = @experimental_cache.get_len 5, key
75
+ assert_equal result.size, 5
76
+ assert_equal result, value[0..4]
77
+
78
+ result = @experimental_cache.get_len 6, key
79
+ assert_equal result.size, 6
80
+ assert_equal result, value
81
+
82
+ result = @experimental_cache.get_len 32, key
83
+ assert_equal result.size, 6
84
+ assert_equal result, value
85
+ }
86
+ end
87
+
88
+ def test_get_len_0_failure
89
+ server_get_len_capable {
90
+ value = "Test that we cannot get 0 bytes with a get_len call."
91
+ @experimental_cache.set key, value, 0, false
92
+ assert_raises(Memcached::Failure) do
93
+ result = @experimental_cache.get_len 0, key
94
+ end
95
+ }
96
+ end
97
+
98
+ def test_get_len_large
99
+ server_get_len_capable {
100
+ value = "Test that we can get the first 20 bytes of a string"
101
+ @experimental_cache.set key, value, 0, false
102
+ result = @experimental_cache.get_len 20, key
103
+ assert_equal result.size, 20
104
+ assert_equal result, value[0..19]
105
+ }
106
+ end
107
+
108
+ def test_get_len_packed
109
+ server_get_len_capable {
110
+ value = [1, 2, 3, 4].pack("Q*")
111
+ @experimental_cache.set key, value, 0, false
112
+ result = @experimental_cache.get_len 8, key
113
+ assert_equal [1], result.unpack("Q*")
114
+ }
115
+ end
116
+
117
+ # get_len is not supported when using the binary protocol.
118
+ # Make sure the single get variant fails appropriately.
119
+ def test_get_len_binary
120
+ server_get_len_capable {
121
+ @experimental_binary_protocol_cache.set key, @value
122
+ assert_raises(Memcached::ActionNotSupported) do
123
+ result = @experimental_binary_protocol_cache.get_len 2, key
124
+ end
125
+ }
126
+ end
127
+
128
+ # Retrieve the first 64 bits of the values for multiple keys.
129
+ def test_get_len_multi_packed
130
+ server_get_len_capable {
131
+ key_1 = "get_len_1"
132
+ value_1 = [1, 2, 3].pack("Q*")
133
+ key_2 = "get_len_missing"
134
+ key_3 = "get_len_2"
135
+ value_3 = [5, 6, 4].pack("Q*")
136
+ keys = [key_1, key_2, key_3]
137
+ @experimental_cache.set key_1, value_1, 0, false
138
+ @experimental_cache.set key_3, value_3, 0, false
139
+ assert_equal(
140
+ {key_1=>value_1[0..7], key_3=>value_3[0..7]},
141
+ @experimental_cache.get_len(8, keys)
142
+ )
143
+ }
144
+ end
145
+
146
+ # Test that the entire value is passed back when the length specified
147
+ # is larger than any of the values (e.g., 32 in the case below).
148
+ def test_get_len_multi_packed_full
149
+ server_get_len_capable {
150
+ key_1 = "get_len_1"
151
+ value_1 = [1, 2, 3].pack("Q*")
152
+ key_2 = "get_len_missing"
153
+ key_3 = "get_len_2"
154
+ value_3 = [5, 6, 4].pack("Q*")
155
+ keys = [key_1, key_2, key_3]
156
+ @experimental_cache.set key_1, value_1, 0, false
157
+ @experimental_cache.set key_3, value_3, 0, false
158
+ assert_equal(
159
+ {key_1=>value_1, key_3=>value_3},
160
+ @experimental_cache.get_len(32, keys)
161
+ )
162
+ }
163
+ end
164
+
165
+ # get_len is not supported when using the binary protocol.
166
+ # Test that the multi get variant fails appropriately.
167
+ def test_get_len_multi_packed_binary
168
+ server_get_len_capable {
169
+ key_1 = "get_len_1"
170
+ value_1 = [1, 2, 3].pack("Q*")
171
+ key_2 = "get_len_2"
172
+ value_2 = [5, 6, 4].pack("Q*")
173
+ keys = [key_1, key_2]
174
+ @experimental_binary_protocol_cache.set key_1, value_1, 0, false
175
+ @experimental_binary_protocol_cache.set key_2, value_2, 0, false
176
+ assert_raises(Memcached::ActionNotSupported) do
177
+ result = @experimental_binary_protocol_cache.get_len 2, keys
178
+ end
179
+ }
180
+ end
181
+
182
+ def test_get_len_multi_completely_missing
183
+ server_get_len_capable {
184
+ @experimental_cache.delete "#{key}_1" rescue nil
185
+ @experimental_cache.delete "#{key}_2" rescue nil
186
+ assert_equal(
187
+ {},
188
+ @experimental_cache.get_len(1, ["#{key}_1", "#{key}_2"])
189
+ )
190
+ }
191
+ end
192
+
193
+ def test_get_len_failure
194
+ server_get_len_capable {
195
+ value = "Test that we cannot use get_len without setting the :experimental_features config."
196
+ assert_raises(NoMethodError) do
197
+ result = @cache.get_len 10, key
198
+ end
199
+ }
200
+ end
201
+
202
+ def test_cas
203
+ server_get_len_capable {
204
+ # Get the first three chars of the value back.
205
+ @experimental_cas_cache.set(key, "foo_bar", 0, false)
206
+ assert_equal "foo", @experimental_cas_cache.get_len(3, key)
207
+ assert_equal "foo_bar", @experimental_cas_cache.get_len(7, key)
208
+ }
209
+ end
210
+
211
+ # Memory cleanup
212
+
213
+ def test_reset
214
+ original_struct = @cache.instance_variable_get("@struct")
215
+ assert_nothing_raised do
216
+ @cache.reset
217
+ end
218
+ assert_not_equal original_struct,
219
+ @cache.instance_variable_get("@struct")
220
+ end
221
+
222
+ # Touch command
223
+
224
+ def test_touch_capability
225
+ server_touch_capable {
226
+ @cache.set(key, "value", 3)
227
+ assert_nothing_raised do
228
+ @experimental_binary_protocol_cache.touch(key, 10)
229
+ end
230
+ assert_raises(Memcached::ActionNotSupported) do
231
+ @experimental_cache.touch(key, 10)
232
+ end
233
+ }
234
+ end
235
+
236
+ def test_touch_missing_key
237
+ server_touch_capable {
238
+ @experimental_binary_protocol_cache.delete key rescue nil
239
+ assert_raises(Memcached::NotFound) do
240
+ @experimental_binary_protocol_cache.touch(key, 10)
241
+ end
242
+ }
243
+ end
244
+
245
+ def test_touch
246
+ server_touch_capable {
247
+ @experimental_binary_protocol_cache.set key, @value, 2
248
+ assert_equal @value, @experimental_binary_protocol_cache.get(key)
249
+ sleep(1)
250
+ assert_equal @value, @experimental_binary_protocol_cache.get(key)
251
+ @experimental_binary_protocol_cache.touch(key, 3)
252
+ sleep(2)
253
+ assert_equal @value, @experimental_binary_protocol_cache.get(key)
254
+ sleep(2)
255
+ assert_raises(Memcached::NotFound) do
256
+ @experimental_binary_protocol_cache.get(key)
257
+ end
258
+ }
259
+ end
260
+
261
+ private
262
+
263
+ def key
264
+ caller.first[/.*[` ](.*)'/, 1] # '
265
+ end
266
+
267
+ def stub_server(port)
268
+ socket = TCPServer.new('127.0.0.1', port)
269
+ Thread.new { socket.accept }
270
+ socket
271
+ end
272
+
273
+ end
274
+
@@ -0,0 +1,1293 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../test_helper")
2
+
3
+ class MemcachedTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @servers = ['localhost:43042', 'localhost:43043', "#{UNIX_SOCKET_NAME}0"]
7
+ @udp_servers = ['localhost:43052', 'localhost:43053']
8
+
9
+ # Maximum allowed prefix key size for :hash_with_prefix_key_key => false
10
+ @prefix_key = 'prefix_key_'
11
+
12
+ @options = {
13
+ :prefix_key => @prefix_key,
14
+ :hash => :default,
15
+ :distribution => :modula,
16
+ :show_backtraces => true}
17
+ @cache = Memcached.new(@servers, @options)
18
+
19
+ @binary_protocol_options = {
20
+ :prefix_key => @prefix_key,
21
+ :hash => :default,
22
+ :distribution => :modula,
23
+ :binary_protocol => true,
24
+ :show_backtraces => true}
25
+ @binary_protocol_cache = Memcached.new(@servers, @binary_protocol_options)
26
+
27
+ @udp_options = {
28
+ :prefix_key => @prefix_key,
29
+ :hash => :default,
30
+ :use_udp => true,
31
+ :distribution => :modula,
32
+ :show_backtraces => true}
33
+ @udp_cache = Memcached.new(@udp_servers, @udp_options)
34
+
35
+ @noblock_options = {
36
+ :prefix_key => @prefix_key,
37
+ :no_block => true,
38
+ :noreply => true,
39
+ :buffer_requests => true,
40
+ :hash => :default,
41
+ :distribution => :modula,
42
+ :show_backtraces => true}
43
+ @noblock_cache = Memcached.new(@servers, @noblock_options)
44
+
45
+ @value = OpenStruct.new(:a => 1, :b => 2, :c => GenericClass)
46
+ @marshalled_value = Marshal.dump(@value)
47
+ end
48
+
49
+ # Initialize
50
+
51
+ def test_initialize
52
+ cache = Memcached.new @servers, :prefix_key => 'test'
53
+ assert_equal 'test', cache.prefix_key
54
+ assert_equal 3, cache.send(:server_structs).size
55
+ assert_equal 'localhost', cache.send(:server_structs).first.hostname
56
+ assert_equal 43042, cache.send(:server_structs).first.port
57
+ end
58
+
59
+ def test_initialize_with_ip_addresses
60
+ cache = Memcached.new ['127.0.0.1:43042', '127.0.0.1:43043']
61
+ assert_equal '127.0.0.1', cache.send(:server_structs).first.hostname
62
+ assert_equal '127.0.0.1', cache.send(:server_structs).last.hostname
63
+ end
64
+
65
+ def test_initialize_without_port
66
+ cache = Memcached.new ['localhost']
67
+ assert_equal 'localhost', cache.send(:server_structs).first.hostname
68
+ assert_equal 11211, cache.send(:server_structs).first.port
69
+ end
70
+
71
+ def test_initialize_with_ports_and_weights
72
+ cache = Memcached.new ['localhost:43042:2', 'localhost:43043:10']
73
+ assert_equal 2, cache.send(:server_structs).first.weight
74
+ assert_equal 43043, cache.send(:server_structs).last.port
75
+ assert_equal 10, cache.send(:server_structs).last.weight
76
+ end
77
+
78
+ def test_initialize_with_hostname_only
79
+ addresses = (1..8).map { |i| "app-cache-%02d" % i }
80
+ cache = Memcached.new(addresses)
81
+ addresses.each_with_index do |address, index|
82
+ assert_equal address, cache.send(:server_structs)[index].hostname
83
+ assert_equal 11211, cache.send(:server_structs)[index].port
84
+ end
85
+ end
86
+
87
+ def test_initialize_with_ip_address_and_options
88
+ cache = Memcached.new '127.0.0.1:43042', :ketama_weighted => false
89
+ assert_equal '127.0.0.1', cache.send(:server_structs).first.hostname
90
+ assert_equal false, cache.options[:ketama_weighted]
91
+ end
92
+
93
+ def test_options_are_set
94
+ Memcached::DEFAULTS.merge(@noblock_options).each do |key, expected|
95
+ value = @noblock_cache.options[key]
96
+ unless key == :rcv_timeout or key == :poll_timeout or key == :prefix_key or key == :ketama_weighted
97
+ assert(expected == value, "#{key} should be #{expected} but was #{value}")
98
+ end
99
+ end
100
+ end
101
+
102
+ def test_options_are_frozen
103
+ assert_raise(TypeError, RuntimeError) do
104
+ @cache.options[:no_block] = true
105
+ end
106
+ end
107
+
108
+ def test_behaviors_are_set
109
+ Memcached::BEHAVIORS.keys.each do |key, value|
110
+ assert_not_nil @cache.send(:get_behavior, key)
111
+ end
112
+ end
113
+
114
+ def test_initialize_with_invalid_server_strings
115
+ assert_raise(ArgumentError) { Memcached.new ":43042" }
116
+ assert_raise(ArgumentError) { Memcached.new "localhost:memcached" }
117
+ assert_raise(ArgumentError) { Memcached.new "local host:43043:1" }
118
+ end
119
+
120
+ def test_initialize_with_invalid_options
121
+ assert_raise(ArgumentError) do
122
+ Memcached.new @servers, :sort_hosts => true, :distribution => :consistent
123
+ end
124
+ end
125
+
126
+ def test_initialize_with_invalid_prefix_key
127
+ assert_raise(ArgumentError) do
128
+ Memcached.new @servers, :prefix_key => "x" * 128
129
+ end
130
+ end
131
+
132
+ def test_initialize_without_prefix_key
133
+ cache = Memcached.new @servers
134
+ assert_equal 3, cache.send(:server_structs).size
135
+ end
136
+
137
+ def test_set_prefix_key
138
+ cache = Memcached.new @servers, :prefix_key => "foo"
139
+ cache.set_prefix_key("bar")
140
+ assert_equal "bar", cache.prefix_key
141
+ end
142
+
143
+ def test_set_prefix_key_to_empty_string
144
+ cache = Memcached.new @servers, :prefix_key => "foo"
145
+ cache.set_prefix_key("")
146
+ assert_equal "", cache.prefix_key
147
+ end
148
+
149
+ def test_memcached_callback_set_with_empty_string_should_not_raise_exception
150
+ cache = Memcached.new @servers, :prefix_key => "foo"
151
+ assert_nothing_raised do
152
+ cache.set_prefix_key("")
153
+ end
154
+ end
155
+
156
+ def test_initialize_negative_behavior
157
+ cache = Memcached.new @servers,
158
+ :buffer_requests => false
159
+ assert_nothing_raised do
160
+ cache.set key, @value
161
+ end
162
+ end
163
+
164
+ def test_initialize_without_backtraces
165
+ cache = Memcached.new @servers,
166
+ :show_backtraces => false
167
+ cache.delete key rescue
168
+ begin
169
+ cache.get key
170
+ rescue Memcached::NotFound => e
171
+ assert e.backtrace.empty?
172
+ end
173
+ begin
174
+ cache.append key, @value
175
+ rescue Memcached::NotStored => e
176
+ assert e.backtrace.empty?
177
+ end
178
+ end
179
+
180
+ def test_initialize_with_backtraces
181
+ cache = Memcached.new @servers, :show_backtraces => true
182
+ cache.delete key rescue nil
183
+ begin
184
+ cache.get key
185
+ rescue Memcached::NotFound => e
186
+ assert !e.backtrace.empty?
187
+ end
188
+ end
189
+
190
+ def test_initialize_sort_hosts
191
+ # Original
192
+ cache = Memcached.new(@servers.sort,
193
+ :sort_hosts => false,
194
+ :distribution => :modula
195
+ )
196
+ assert_equal @servers.sort,
197
+ cache.servers
198
+
199
+ # Original with sort_hosts
200
+ cache = Memcached.new(@servers.sort,
201
+ :sort_hosts => true,
202
+ :distribution => :modula
203
+ )
204
+ assert_equal @servers.sort,
205
+ cache.servers
206
+
207
+ # Reversed
208
+ cache = Memcached.new(@servers.sort.reverse,
209
+ :sort_hosts => false,
210
+ :distribution => :modula
211
+ )
212
+ assert_equal @servers.sort.reverse,
213
+ cache.servers
214
+
215
+ # Reversed with sort_hosts
216
+ cache = Memcached.new(@servers.sort.reverse,
217
+ :sort_hosts => true,
218
+ :distribution => :modula
219
+ )
220
+ assert_equal @servers.sort,
221
+ cache.servers
222
+ end
223
+
224
+ def test_initialize_single_server
225
+ cache = Memcached.new 'localhost:43042'
226
+ assert_equal 1, cache.send(:server_structs).size
227
+ end
228
+
229
+ def test_initialize_strange_argument
230
+ assert_raise(ArgumentError) { Memcached.new 1 }
231
+ end
232
+
233
+ # Get
234
+
235
+ def test_get
236
+ @cache.set key, @value
237
+ assert_equal @value, @cache.get(key)
238
+ assert_equal @value, @binary_protocol_cache.get(key)
239
+
240
+ @udp_cache.set(key, @value)
241
+ assert_raises(Memcached::ActionNotSupported) do
242
+ @udp_cache.get(key)
243
+ end
244
+ end
245
+
246
+ def test_get_nil
247
+ @cache.set key, nil, 0
248
+ result = @cache.get key
249
+ assert_equal nil, result
250
+ end
251
+
252
+ def test_get_from_last
253
+ cache = Memcached.new(@servers, :distribution => :random)
254
+ 10.times { |n| cache.set key, n }
255
+ 10.times do
256
+ assert_equal cache.get(key), cache.get_from_last(key)
257
+ end
258
+ end
259
+
260
+ def test_get_missing
261
+ @cache.delete key rescue nil
262
+ assert_raise(Memcached::NotFound) do
263
+ result = @cache.get key
264
+ end
265
+ end
266
+
267
+ def test_get_with_server_timeout
268
+ socket = stub_server :port => 43047, :listen => true
269
+ cache = Memcached.new("localhost:43047:1", :timeout => 0.5, :exception_retry_limit => 0)
270
+ assert 0.49 < (Benchmark.measure do
271
+ assert_raise(Memcached::NotFound) do
272
+ result = cache.get key
273
+ end
274
+ end).real
275
+
276
+ # libmemcached IO always non-blocking, so rcv_timeout doesn't matter
277
+ # here, and no_block behaviour control flush action
278
+ cache = Memcached.new("localhost:43047:1", :poll_timeout => 0.1, :rcv_timeout => 0.5, :exception_retry_limit => 0)
279
+ assert 0.51 > (Benchmark.measure do
280
+ assert_raise(Memcached::NotFound) do
281
+ result = cache.get key
282
+ end
283
+ end).real
284
+
285
+ cache = Memcached.new("localhost:43047:1", :poll_timeout => 0.25, :rcv_timeout => 0.25, :exception_retry_limit => 0)
286
+ assert 0.51 > (Benchmark.measure do
287
+ assert_raise(Memcached::NotFound) do
288
+ result = cache.get key
289
+ end
290
+ end).real
291
+
292
+ ensure
293
+ socket.close if socket
294
+ end
295
+
296
+ # This test case is passing now, but it seems to be useless because
297
+ # no_block behavior doesn't affect recv() call (at least in
298
+ # libmemcached 0.50)
299
+ def test_get_with_no_block_server_timeout
300
+ socket = stub_server :port => 43048, :listen => true
301
+ cache = Memcached.new("localhost:43048:1", :no_block => true, :timeout => 0.25, :exception_retry_limit => 0)
302
+ assert 0.24 < (Benchmark.measure do
303
+ assert_raise(Memcached::NotFound) do
304
+ result = cache.get key
305
+ end
306
+ end).real
307
+
308
+ cache = Memcached.new("localhost:43048:1", :no_block => true, :poll_timeout => 0.25, :rcv_timeout => 0.001, :exception_retry_limit => 0)
309
+ assert 0.24 < (Benchmark.measure do
310
+ assert_raise(Memcached::NotFound) do
311
+ result = cache.get key
312
+ end
313
+ end).real
314
+
315
+ cache = Memcached.new("localhost:43048:1", :no_block => true,
316
+ :poll_timeout => 0.001,
317
+ :rcv_timeout => 0.25, # No affect in no-block mode
318
+ :exception_retry_limit => 0
319
+ )
320
+ assert 0.24 > (Benchmark.measure do
321
+ assert_raise(Memcached::NotFound) do
322
+ result = cache.get key
323
+ end
324
+ end).real
325
+
326
+ ensure
327
+ socket.close if socket
328
+ end
329
+
330
+ def test_get_with_prefix_key
331
+ # Prefix_key
332
+ cache = Memcached.new(
333
+ # We can only use one server because the key is hashed separately from the prefix key
334
+ @servers.first,
335
+ :prefix_key => @prefix_key,
336
+ :hash => :default,
337
+ :distribution => :modula
338
+ )
339
+ cache.set key, @value
340
+ assert_equal @value, cache.get(key)
341
+
342
+ # No prefix_key specified
343
+ cache = Memcached.new(
344
+ @servers.first,
345
+ :hash => :default,
346
+ :distribution => :modula
347
+ )
348
+ assert_nothing_raised do
349
+ assert_equal @value, cache.get("#{@prefix_key}#{key}")
350
+ end
351
+ end
352
+
353
+ def test_values_with_null_characters_are_not_truncated
354
+ value = OpenStruct.new(:a => Object.new) # Marshals with a null \000
355
+ @cache.set key, value
356
+ result = @cache.get key, false
357
+ non_wrapped_result = Rlibmemcached.memcached_get(
358
+ @cache.instance_variable_get("@struct"),
359
+ key
360
+ ).first
361
+ assert result.size > non_wrapped_result.size
362
+ end
363
+
364
+ def test_get_multi
365
+ @cache.set "#{key}_1", 1
366
+ @cache.set "#{key}_2", 2
367
+ assert_equal({"#{key}_1" => 1, "#{key}_2" => 2},
368
+ @cache.get(["#{key}_1", "#{key}_2"]))
369
+ end
370
+
371
+ def test_get_multi_missing
372
+ @cache.set "#{key}_1", 1
373
+ @cache.delete "#{key}_2" rescue nil
374
+ @cache.set "#{key}_3", 3
375
+ @cache.delete "#{key}_4" rescue nil
376
+ assert_equal(
377
+ {"test_get_multi_missing_3"=>3, "test_get_multi_missing_1"=>1},
378
+ @cache.get(["#{key}_1", "#{key}_2", "#{key}_3", "#{key}_4"])
379
+ )
380
+ end
381
+
382
+ def test_get_multi_binary
383
+ @binary_protocol_cache.set "#{key}_1", 1
384
+ @binary_protocol_cache.delete "#{key}_2" rescue nil
385
+ @binary_protocol_cache.set "#{key}_3", 3
386
+ assert_equal(
387
+ {"prefix_key_test_get_multi_binary_3"=>3, "prefix_key_test_get_multi_binary_1"=>1}.sort,
388
+ @binary_protocol_cache.get(["#{key}_1", "#{key}_2", "#{key}_3"]).sort
389
+ )
390
+ end
391
+
392
+ def test_get_multi_binary_one_record_missing
393
+ @binary_protocol_cache.delete("magic_key") rescue nil
394
+ assert_equal({}, @binary_protocol_cache.get(["magic_key"]))
395
+ end
396
+
397
+ def test_get_multi_binary_one_record
398
+ @binary_protocol_cache.set("magic_key", 1)
399
+ assert_equal({"prefix_key_magic_key" => 1}, @binary_protocol_cache.get(["magic_key"]))
400
+ end
401
+
402
+ def test_get_multi_completely_missing
403
+ @cache.delete "#{key}_1" rescue nil
404
+ @cache.delete "#{key}_2" rescue nil
405
+ assert_equal(
406
+ {},
407
+ @cache.get(["#{key}_1", "#{key}_2"])
408
+ )
409
+ end
410
+
411
+ def test_get_multi_empty_string
412
+ @cache.set "#{key}_1", "", 0, false
413
+ assert_equal({"#{key}_1" => ""},
414
+ @cache.get(["#{key}_1"], false))
415
+ end
416
+
417
+ def test_get_multi_checks_types
418
+ assert_raises(TypeError, ArgumentError) do
419
+ @cache.get([nil])
420
+ end
421
+ end
422
+
423
+ def test_set_and_get_unmarshalled
424
+ @cache.set key, @value
425
+ result = @cache.get key, false
426
+ assert_equal @marshalled_value, result
427
+ end
428
+
429
+ def test_set_unmarshalled_and_get_unmarshalled
430
+ @cache.set key, @marshalled_value, 0, false
431
+ result = @cache.get key, false
432
+ assert_equal @marshalled_value, result
433
+ end
434
+
435
+ def test_set_unmarshalled_error
436
+ assert_raises(TypeError) do
437
+ @cache.set key, @value, 0, false
438
+ end
439
+ end
440
+
441
+ def test_get_multi_unmarshalled
442
+ @cache.set "#{key}_1", "1", 0, false
443
+ @cache.set "#{key}_2", "2", 0, false
444
+ assert_equal(
445
+ {"#{key}_1" => "1", "#{key}_2" => "2"},
446
+ @cache.get(["#{key}_1", "#{key}_2"], false)
447
+ )
448
+ end
449
+
450
+ def test_get_multi_mixed_marshalling
451
+ @cache.set "#{key}_1", 1
452
+ @cache.set "#{key}_2", "2", 0, false
453
+ assert_nothing_raised do
454
+ @cache.get(["#{key}_1", "#{key}_2"], false)
455
+ end
456
+ assert_raise(ArgumentError) do
457
+ @cache.get(["#{key}_1", "#{key}_2"])
458
+ end
459
+ end
460
+
461
+ def test_random_distribution_is_statistically_random
462
+ cache = Memcached.new(@servers, :distribution => :random)
463
+ read_cache = Memcached.new(@servers.first)
464
+ hits = 4
465
+
466
+ while hits == 4 do
467
+ cache.flush
468
+ 20.times do |i|
469
+ cache.set "#{key}#{i}", @value
470
+ end
471
+
472
+ hits = 0
473
+ 20.times do |i|
474
+ begin
475
+ read_cache.get "#{key}#{i}"
476
+ hits += 1
477
+ rescue Memcached::NotFound
478
+ end
479
+ end
480
+ end
481
+
482
+ assert_not_equal 4, hits
483
+ end
484
+
485
+ # Set
486
+
487
+ def test_set
488
+ assert_nothing_raised do
489
+ @cache.set(key, @value)
490
+ end
491
+
492
+ assert_nothing_raised do
493
+ @binary_protocol_cache.set(key, @value)
494
+ end
495
+
496
+ assert_nothing_raised do
497
+ @udp_cache.set(key, @value)
498
+ end
499
+ end
500
+
501
+ def test_set_expiry
502
+ @cache.set key, @value, 1
503
+ assert_nothing_raised do
504
+ @cache.get key
505
+ end
506
+ sleep(2)
507
+ assert_raise(Memcached::NotFound) do
508
+ @cache.get key
509
+ end
510
+
511
+ assert_raise(TypeError) do
512
+ @cache.set key, @value, Time.now
513
+ end
514
+ end
515
+
516
+ def test_set_with_default_ttl
517
+ cache = Memcached.new(
518
+ @servers,
519
+ :default_ttl => 1
520
+ )
521
+ cache.set key, @value
522
+ assert_nothing_raised do
523
+ cache.get key
524
+ end
525
+ sleep(2)
526
+ assert_raise(Memcached::NotFound) do
527
+ cache.get key
528
+ end
529
+ end
530
+
531
+ def disabled_test_set_retry_on_client_error
532
+ # FIXME Test passes, but Mocha doesn't restore the original method properly
533
+ Rlibmemcached.stubs(:memcached_set).raises(Memcached::ClientError)
534
+ Rlibmemcached.stubs(:memcached_set).returns(0)
535
+
536
+ assert_nothing_raised do
537
+ @cache.set(key, @value)
538
+ end
539
+ end
540
+
541
+ # Delete
542
+
543
+ def test_delete
544
+ @cache.set key, @value
545
+ @cache.delete key
546
+ assert_raise(Memcached::NotFound) do
547
+ @cache.get key
548
+ end
549
+
550
+ @binary_protocol_cache.set key, @value
551
+ @binary_protocol_cache.delete key
552
+ assert_raise(Memcached::NotFound) do
553
+ @binary_protocol_cache.get key
554
+ end
555
+ end
556
+
557
+ def test_missing_delete
558
+ @cache.delete key rescue nil
559
+ assert_raise(Memcached::NotFound) do
560
+ @cache.delete key
561
+ end
562
+ end
563
+
564
+ # Flush
565
+
566
+ def test_flush
567
+ @cache.set key, @value
568
+ assert_equal @value,
569
+ @cache.get(key)
570
+ @cache.flush
571
+ assert_raise(Memcached::NotFound) do
572
+ @cache.get key
573
+ end
574
+ end
575
+
576
+ # Add
577
+
578
+ def test_add
579
+ @cache.delete key rescue nil
580
+ @cache.add key, @value
581
+ assert_equal @value, @cache.get(key)
582
+ end
583
+
584
+ def test_existing_add
585
+ @cache.set key, @value
586
+ assert_raise(Memcached::NotStored) do
587
+ @cache.add key, @value
588
+ end
589
+ end
590
+
591
+ def test_add_expiry
592
+ @cache.delete key rescue nil
593
+ @cache.set key, @value, 1
594
+ assert_nothing_raised do
595
+ @cache.get key
596
+ end
597
+ sleep(1)
598
+ assert_raise(Memcached::NotFound) do
599
+ @cache.get key
600
+ end
601
+ end
602
+
603
+ def test_unmarshalled_add
604
+ @cache.delete key rescue nil
605
+ @cache.add key, @marshalled_value, 0, false
606
+ assert_equal @marshalled_value, @cache.get(key, false)
607
+ assert_equal @value, @cache.get(key)
608
+ end
609
+
610
+ # Increment and decrement
611
+
612
+ def test_increment
613
+ @cache.set key, "10", 0, false
614
+ assert_equal 11, @cache.increment(key)
615
+ end
616
+
617
+ def test_increment_binary
618
+ @binary_protocol_cache.set key, "10", 0, false
619
+ assert_equal 11, @binary_protocol_cache.increment(key)
620
+ end
621
+
622
+ def test_increment_offset
623
+ @cache.set key, "10", 0, false
624
+ assert_equal 15, @cache.increment(key, 5)
625
+ end
626
+
627
+ def test_missing_increment
628
+ @cache.delete key rescue nil
629
+ assert_raise(Memcached::NotFound) do
630
+ @cache.increment key
631
+ end
632
+ end
633
+
634
+ def test_decrement
635
+ @cache.set key, "10", 0, false
636
+ assert_equal 9, @cache.decrement(key)
637
+ end
638
+
639
+ def test_decrement_binary
640
+ @binary_protocol_cache.set key, "10", 0, false
641
+ assert_equal 9, @binary_protocol_cache.decrement(key)
642
+ end
643
+
644
+ def test_decrement_offset
645
+ @cache.set key, "10", 0, false
646
+ assert_equal 5, @cache.decrement(key, 5)
647
+ end
648
+
649
+ def test_missing_decrement
650
+ @cache.delete key rescue nil
651
+ assert_raise(Memcached::NotFound) do
652
+ @cache.decrement key
653
+ end
654
+ end
655
+
656
+ # Replace
657
+
658
+ def test_replace
659
+ @cache.set key, nil
660
+ assert_nothing_raised do
661
+ @cache.replace key, @value
662
+ end
663
+ assert_equal @value, @cache.get(key)
664
+ end
665
+
666
+ def test_missing_replace
667
+ @cache.delete key rescue nil
668
+ assert_raise(Memcached::NotStored) do
669
+ @cache.replace key, @value
670
+ end
671
+ assert_raise(Memcached::NotFound) do
672
+ assert_equal @value, @cache.get(key)
673
+ end
674
+ end
675
+
676
+ # Append and prepend
677
+
678
+ def test_append
679
+ @cache.set key, "start", 0, false
680
+ assert_nothing_raised do
681
+ @cache.append key, "end"
682
+ end
683
+ assert_equal "startend", @cache.get(key, false)
684
+
685
+ @binary_protocol_cache.set key, "start", 0, false
686
+ assert_nothing_raised do
687
+ @binary_protocol_cache.append key, "end"
688
+ end
689
+ assert_equal "startend", @binary_protocol_cache.get(key, false)
690
+ end
691
+
692
+ def test_missing_append
693
+ @cache.delete key rescue nil
694
+ assert_raise(Memcached::NotStored) do
695
+ @cache.append key, "end"
696
+ end
697
+ assert_raise(Memcached::NotFound) do
698
+ assert_equal @value, @cache.get(key)
699
+ end
700
+
701
+ @binary_protocol_cache.delete key rescue nil
702
+ assert_raise(Memcached::NotStored) do
703
+ @binary_protocol_cache.append key, "end"
704
+ end
705
+ assert_raise(Memcached::NotFound) do
706
+ assert_equal @value, @binary_protocol_cache.get(key)
707
+ end
708
+ end
709
+
710
+ def test_prepend
711
+ @cache.set key, "end", 0, false
712
+ assert_nothing_raised do
713
+ @cache.prepend key, "start"
714
+ end
715
+ assert_equal "startend", @cache.get(key, false)
716
+ end
717
+
718
+ def test_missing_prepend
719
+ @cache.delete key rescue nil
720
+ assert_raise(Memcached::NotStored) do
721
+ @cache.prepend key, "end"
722
+ end
723
+ assert_raise(Memcached::NotFound) do
724
+ assert_equal @value, @cache.get(key)
725
+ end
726
+ end
727
+
728
+ def test_cas
729
+ cache = Memcached.new(
730
+ @servers,
731
+ :prefix_key => @prefix_key,
732
+ :support_cas => true
733
+ )
734
+ value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
735
+
736
+ # Existing set
737
+ cache.set key, @value
738
+ cache.cas(key) do |current|
739
+ assert_equal @value, current
740
+ value2
741
+ end
742
+ assert_equal value2, cache.get(key)
743
+
744
+ # Existing test without marshalling
745
+ cache.set(key, "foo", 0, false)
746
+ cache.cas(key, 0, false) do |current|
747
+ "#{current}bar"
748
+ end
749
+ assert_equal "foobar", cache.get(key, false)
750
+
751
+ # Missing set
752
+ cache.delete key
753
+ assert_raises(Memcached::NotFound) do
754
+ cache.cas(key) {}
755
+ end
756
+
757
+ # Conflicting set
758
+ cache.set key, @value
759
+ assert_raises(Memcached::ConnectionDataExists) do
760
+ cache.cas(key) do |current|
761
+ cache.set key, value2
762
+ current
763
+ end
764
+ end
765
+ end
766
+
767
+ # Error states
768
+
769
+ def test_key_with_spaces
770
+ key = "i have a space"
771
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
772
+ @cache.set key, @value
773
+ end
774
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
775
+ @cache.get(key)
776
+ end
777
+ end
778
+
779
+ def test_key_with_null
780
+ key = "with\000null"
781
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
782
+ @cache.set key, @value
783
+ end
784
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
785
+ @cache.get(key)
786
+ end
787
+
788
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
789
+ response = @cache.get([key])
790
+ end
791
+ end
792
+
793
+ def test_key_with_invalid_control_characters
794
+ key = "ch\303\242teau"
795
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
796
+ @cache.set key, @value
797
+ end
798
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
799
+ @cache.get(key)
800
+ end
801
+
802
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
803
+ response = @cache.get([key])
804
+ end
805
+ end
806
+
807
+ def test_key_too_long
808
+ key = "x"*251
809
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
810
+ @cache.set key, @value
811
+ end
812
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
813
+ @cache.get(key)
814
+ end
815
+
816
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
817
+ @cache.get([key])
818
+ end
819
+ end
820
+
821
+ def test_server_error_message
822
+ @cache.set key, "I'm big" * 1000000
823
+ assert false # Never reached
824
+ rescue Memcached::ServerError => e
825
+ assert_match /^"object too large for cache". Key/, e.message
826
+ end
827
+
828
+ def test_errno_message
829
+ Rlibmemcached::MemcachedServerSt.any_instance.stubs("cached_errno").returns(1)
830
+ @cache.send(:check_return_code, Rlibmemcached::MEMCACHED_ERRNO, key)
831
+ rescue Memcached::SystemError => e
832
+ assert_match /^Errno 1: "Operation not permitted". Key/, e.message
833
+ end
834
+
835
+ # Stats
836
+
837
+ def disable_test_stats
838
+ stats = @cache.stats
839
+ assert_equal 3, stats[:pid].size
840
+ assert_instance_of Fixnum, stats[:pid].first
841
+ assert_instance_of String, stats[:version].first
842
+
843
+ stats = @binary_protocol_cache.stats
844
+ assert_equal 3, stats[:pid].size
845
+ assert_instance_of Fixnum, stats[:pid].first
846
+ assert_instance_of String, stats[:version].first
847
+
848
+ assert_nothing_raised do
849
+ @noblock_cache.stats
850
+ end
851
+ assert_raises(TypeError) do
852
+ @udp_cache.stats
853
+ end
854
+ end
855
+
856
+ def test_missing_stats
857
+ cache = Memcached.new('localhost:43041')
858
+ assert_raises(Memcached::SomeErrorsWereReported) { cache.stats }
859
+ end
860
+
861
+ # Clone
862
+
863
+ def test_clone
864
+ cache = @cache.clone
865
+ assert_equal cache.servers, @cache.servers
866
+ assert_not_equal cache, @cache
867
+
868
+ # Definitely check that the structs are unlinked
869
+ assert_not_equal @cache.instance_variable_get('@struct').object_id,
870
+ cache.instance_variable_get('@struct').object_id
871
+
872
+ assert_nothing_raised do
873
+ @cache.set key, @value
874
+ end
875
+ end
876
+
877
+ # Pipelined, non-blocking IO
878
+
879
+ def test_buffered_requests_return_value
880
+ cache = Memcached.new @servers,
881
+ :buffer_requests => true
882
+ assert_nothing_raised do
883
+ cache.set key, @value
884
+ end
885
+ ret = Rlibmemcached.memcached_set(
886
+ cache.instance_variable_get("@struct"),
887
+ key,
888
+ @marshalled_value,
889
+ 0,
890
+ Memcached::FLAGS
891
+ )
892
+ assert_equal Rlibmemcached::MEMCACHED_BUFFERED, ret
893
+ end
894
+
895
+ def test_no_block_return_value
896
+ assert_nothing_raised do
897
+ @noblock_cache.set key, @value
898
+ end
899
+ ret = Rlibmemcached.memcached_set(
900
+ @noblock_cache.instance_variable_get("@struct"),
901
+ key,
902
+ @marshalled_value,
903
+ 0,
904
+ Memcached::FLAGS
905
+ )
906
+ assert_equal Rlibmemcached::MEMCACHED_BUFFERED, ret
907
+ end
908
+
909
+ def test_no_block_prepend
910
+ return "Each time we fetch the response libmemcached flushes buffers"
911
+ @cache.set key, "help", 0, false
912
+ @noblock_cache.prepend key, "help"
913
+ assert_equal "help", @cache.get(key, false)
914
+ @noblock_cache.get "no_exist", false rescue nil
915
+ assert_equal "helphelp", @cache.get(key, false)
916
+ end
917
+
918
+ def test_no_block_get
919
+ @noblock_cache.set key, @value
920
+ assert_equal @value,
921
+ @noblock_cache.get(key)
922
+ end
923
+
924
+ def test_no_block_missing_delete
925
+ @noblock_cache.delete key rescue nil
926
+ assert_nothing_raised do
927
+ @noblock_cache.delete key
928
+ @noblock_cache.delete key
929
+ end
930
+ end
931
+
932
+ def test_no_block_set_invalid_key
933
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
934
+ @noblock_cache.set "I'm so bad", @value
935
+ end
936
+ end
937
+
938
+ def test_no_block_set_object_too_large
939
+ noblock_cache = Memcached.new(@servers, @noblock_options.merge(:noreply => false))
940
+ assert_nothing_raised do
941
+ noblock_cache.set key, "I'm big" * 1000000
942
+ end
943
+ assert_raise( Memcached::WriteFailure) do
944
+ @noblock_cache.set key, "I'm big" * 1000000
945
+ end
946
+ end
947
+
948
+ def test_no_block_existing_add
949
+ # Should still raise
950
+ noblock_cache = Memcached.new(@servers, @noblock_options.merge(:noreply => false))
951
+ noblock_cache.set key, @value
952
+ assert_raise(Memcached::NotStored) do
953
+ noblock_cache.add key, @value
954
+ end
955
+ end
956
+
957
+ # Server removal and consistent hashing
958
+
959
+ def test_unresponsive_server
960
+ socket = stub_server :port => 43041, :listen => false
961
+
962
+ cache = Memcached.new(
963
+ [@servers.last, 'localhost:43041'],
964
+ :prefix_key => @prefix_key,
965
+ :auto_eject_hosts => true,
966
+ :server_failure_limit => 2,
967
+ :retry_timeout => 1,
968
+ :hash_with_prefix_key => false,
969
+ :hash => :md5,
970
+ :exception_retry_limit => 0
971
+ )
972
+
973
+ # Hit second server up to the server_failure_limit
974
+ key2 = 'test_missing_server'
975
+ assert_raise(Memcached::ConnectionFailure) { cache.set(key2, @value) }
976
+ assert_raise(Memcached::ConnectionFailure) { cache.set(key2, @value) }
977
+
978
+ # Hit second server and pass the limit
979
+ key2 = 'test_missing_server'
980
+ begin
981
+ cache.get(key2)
982
+ rescue => e
983
+ assert_equal Memcached::ServerIsMarkedDead, e.class
984
+ assert_match /localhost:43041/, e.message
985
+ end
986
+
987
+ # Hit first server on retry
988
+ assert_nothing_raised do
989
+ cache.set(key2, @value)
990
+ assert_equal cache.get(key2), @value
991
+ end
992
+
993
+ sleep(2)
994
+
995
+ # Hit second server again after restore, expect same failure
996
+ key2 = 'test_missing_server'
997
+ assert_raise(Memcached::ConnectionFailure) do
998
+ cache.set(key2, @value)
999
+ end
1000
+ end
1001
+
1002
+ def test_unresponsive_server_retries_greater_than_server_failure_limit
1003
+ cache = Memcached.new(
1004
+ [@servers.last, 'localhost:43041'], # just free port
1005
+ :prefix_key => @prefix_key,
1006
+ :auto_eject_hosts => true,
1007
+ :server_failure_limit => 2,
1008
+ :retry_timeout => 1,
1009
+ :hash_with_prefix_key => false,
1010
+ :hash => :md5,
1011
+ :exception_retry_limit => 3
1012
+ )
1013
+
1014
+ key2 = 'test_missing_server'
1015
+ assert_nothing_raised do
1016
+ cache.set(key2, @value)
1017
+ assert_equal cache.get(key2), @value
1018
+ end
1019
+
1020
+ assert_nothing_raised do
1021
+ cache.set(key2, @value)
1022
+ assert_equal cache.get(key2), @value
1023
+ end
1024
+
1025
+ sleep(2)
1026
+
1027
+ assert_nothing_raised do
1028
+ cache.set(key2, @value)
1029
+ assert_equal cache.get(key2), @value
1030
+ end
1031
+ end
1032
+
1033
+ def test_unresponsive_server_retries_equals_server_failure_limit
1034
+ socket = stub_server :port => 43041, :listen => false
1035
+
1036
+ cache = Memcached.new(
1037
+ [@servers.last, 'localhost:43041'],
1038
+ :prefix_key => @prefix_key,
1039
+ :auto_eject_hosts => true,
1040
+ :server_failure_limit => 2,
1041
+ :retry_timeout => 1,
1042
+ :hash_with_prefix_key => false,
1043
+ :hash => :md5,
1044
+ :exception_retry_limit => 3
1045
+ )
1046
+
1047
+ key2 = 'test_missing_server'
1048
+ begin
1049
+ cache.get(key2)
1050
+ rescue => e
1051
+ assert_equal Memcached::ServerIsMarkedDead, e.class
1052
+ assert_match /localhost:43041/, e.message
1053
+ end
1054
+
1055
+ assert_nothing_raised do
1056
+ cache.set(key2, @value)
1057
+ assert_equal cache.get(key2), @value
1058
+ end
1059
+
1060
+ sleep(2)
1061
+
1062
+ begin
1063
+ cache.get(key2)
1064
+ rescue => e
1065
+ assert_equal Memcached::ServerIsMarkedDead, e.class
1066
+ assert_match /localhost:43041/, e.message
1067
+ end
1068
+
1069
+ assert_nothing_raised do
1070
+ cache.set(key2, @value)
1071
+ assert_equal cache.get(key2), @value
1072
+ end
1073
+ end
1074
+
1075
+ def test_unresponsive_server_retries_less_than_server_failure_limit
1076
+ socket = stub_server :port => 43041, :listen => false
1077
+
1078
+ cache = Memcached.new(
1079
+ [@servers.last, 'localhost:43041'],
1080
+ :prefix_key => @prefix_key,
1081
+ :auto_eject_hosts => true,
1082
+ :server_failure_limit => 2,
1083
+ :retry_timeout => 1,
1084
+ :hash_with_prefix_key => false,
1085
+ :hash => :md5,
1086
+ :exception_retry_limit => 1
1087
+ )
1088
+
1089
+ key2 = 'test_missing_server'
1090
+ assert_raise(Memcached::ConnectionFailure) { cache.set(key2, @value) }
1091
+ begin
1092
+ cache.get(key2)
1093
+ rescue => e
1094
+ assert_equal Memcached::ConnectionFailure, e.class
1095
+ assert_match /localhost:43041/, e.message
1096
+ end
1097
+
1098
+ sleep(2)
1099
+
1100
+ assert_raise(Memcached::ConnectionFailure) { cache.set(key2, @value) }
1101
+ begin
1102
+ cache.get(key2)
1103
+ rescue => e
1104
+ assert_equal Memcached::ServerIsMarkedDead, e.class
1105
+ assert_match /localhost:43041/, e.message
1106
+ end
1107
+ end
1108
+
1109
+ def test_wrong_failure_counter
1110
+ cache = Memcached.new(
1111
+ [@servers.last],
1112
+ :prefix_key => @prefix_key,
1113
+ :auto_eject_hosts => true,
1114
+ :server_failure_limit => 1,
1115
+ :retry_timeout => 1,
1116
+ :hash_with_prefix_key => false,
1117
+ :hash => :md5,
1118
+ :exception_retry_limit => 0
1119
+ )
1120
+
1121
+ # This is an abuse of knowledge, but it's necessary to verify that
1122
+ # the library is handling the counter properly.
1123
+ struct = cache.instance_variable_get(:@struct)
1124
+ server = Memcached::Lib.memcached_server_by_key(struct, "marmotte").first
1125
+
1126
+ # set to ensure connectivity
1127
+ cache.set("marmotte", "milk")
1128
+ server.server_failure_counter = 0
1129
+ cache.quit
1130
+ assert_equal 0, server.server_failure_counter
1131
+ end
1132
+
1133
+ def test_missing_server
1134
+ socket = stub_server :port => 43041, :listen => false
1135
+ cache = Memcached.new(
1136
+ [@servers.last, 'localhost:43041'],
1137
+ :prefix_key => @prefix_key,
1138
+ :auto_eject_hosts => true,
1139
+ :server_failure_limit => 2,
1140
+ :retry_timeout => 1,
1141
+ :hash_with_prefix_key => false,
1142
+ :hash => :md5,
1143
+ :exception_retry_limit => 0
1144
+ )
1145
+
1146
+ # Hit second server up to the server_failure_limit
1147
+ key2 = 'test_missing_server'
1148
+ assert_raise(Memcached::ConnectionFailure) { cache.set(key2, @value) }
1149
+ assert_raise(Memcached::ConnectionFailure) { cache.get(key2, @value) }
1150
+
1151
+ # Hit second server and pass the limit
1152
+ key2 = 'test_missing_server'
1153
+ begin
1154
+ cache.get(key2)
1155
+ rescue => e
1156
+ assert_equal Memcached::ServerIsMarkedDead, e.class
1157
+ assert_match /localhost:43041/, e.message
1158
+ end
1159
+
1160
+ # Hit first server on retry
1161
+ assert_nothing_raised do
1162
+ cache.set(key2, @value)
1163
+ assert_equal cache.get(key2), @value
1164
+ end
1165
+
1166
+ sleep(2)
1167
+
1168
+ # Hit second server again after restore, expect same failure
1169
+ key2 = 'test_missing_server'
1170
+ assert_raise(Memcached::ConnectionFailure) do
1171
+ cache.set(key2, @value)
1172
+ end
1173
+ end
1174
+
1175
+ def test_unresponsive_with_random_distribution
1176
+ return "Random distribution doesn't eject servers automatically anymore"
1177
+
1178
+ socket = stub_server :port => 43041, :listen => false
1179
+ failures = [Memcached::ConnectionFailure, Memcached::ServerIsMarkedDead]
1180
+
1181
+ cache = Memcached.new(
1182
+ [@servers.last, 'localhost:43041'],
1183
+ :auto_eject_hosts => true,
1184
+ :distribution => :random,
1185
+ :server_failure_limit => 1,
1186
+ :retry_timeout => 1,
1187
+ :exception_retry_limit => 0
1188
+ )
1189
+
1190
+ # Provoke the errors in 'failures'
1191
+ exceptions = []
1192
+ 100.times { begin; cache.set key, @value; rescue => e; exceptions << e; end }
1193
+ assert_equal failures, exceptions.map { |x| x.class }
1194
+
1195
+ # Hit first server on retry
1196
+ assert_nothing_raised { cache.set(key, @value) }
1197
+
1198
+ # Hit second server again after restore, expect same failures
1199
+ sleep(2)
1200
+ exceptions = []
1201
+ 100.times { begin; cache.set key, @value; rescue => e; exceptions << e; end }
1202
+ assert_equal failures, exceptions.map { |x| x.class }
1203
+ end
1204
+
1205
+ def test_consistent_hashing
1206
+ 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)
1207
+
1208
+ # Five servers
1209
+ cache = Memcached.new(
1210
+ @servers + ['localhost:43044', 'localhost:43045', 'localhost:43046'],
1211
+ :prefix_key => @prefix_key
1212
+ )
1213
+
1214
+ cache.flush
1215
+ keys.each do |key|
1216
+ cache.set(key, @value)
1217
+ end
1218
+
1219
+ # Pull a server
1220
+ cache = Memcached.new(
1221
+ @servers + ['localhost:43044', 'localhost:43046'],
1222
+ :prefix_key => @prefix_key
1223
+ )
1224
+
1225
+ failed = 0
1226
+ keys.each_with_index do |key, i|
1227
+ begin
1228
+ cache.get(key)
1229
+ rescue Memcached::NotFound
1230
+ failed += 1
1231
+ end
1232
+ end
1233
+
1234
+ assert(failed < keys.size / 3, "#{failed} failed out of #{keys.size}")
1235
+ end
1236
+
1237
+ # Concurrency
1238
+
1239
+ def test_thread_contention
1240
+ threads = []
1241
+ 4.times do |index|
1242
+ threads << Thread.new do
1243
+ cache = @cache.clone
1244
+ assert_nothing_raised do
1245
+ cache.set("test_thread_contention_#{index}", index)
1246
+ end
1247
+ assert_equal index, cache.get("test_thread_contention_#{index}")
1248
+ end
1249
+ end
1250
+ threads.each {|thread| thread.join}
1251
+ end
1252
+
1253
+ # Hash
1254
+
1255
+ def test_hash
1256
+ assert_equal 3157003241,
1257
+ Rlibmemcached.memcached_generate_hash_rvalue("test", Rlibmemcached::MEMCACHED_HASH_FNV1_32)
1258
+ end
1259
+
1260
+ def test_noop_hash
1261
+ %w[foo bar baz qux quux].each do |word|
1262
+ assert_equal 1,
1263
+ Rlibmemcached.memcached_generate_hash_rvalue(word, Rlibmemcached::MEMCACHED_HASH_NONE)
1264
+ end
1265
+ end
1266
+
1267
+ # Memory cleanup
1268
+
1269
+ def test_reset
1270
+ original_struct = @cache.instance_variable_get("@struct")
1271
+ assert_nothing_raised do
1272
+ @cache.reset
1273
+ end
1274
+ assert_not_equal original_struct,
1275
+ @cache.instance_variable_get("@struct")
1276
+ end
1277
+
1278
+ private
1279
+
1280
+ def key
1281
+ caller.first[/.*[` ](.*)'/, 1] # '
1282
+ end
1283
+
1284
+ def stub_server(options = {})
1285
+ if options[:listen]
1286
+ socket = TCPServer.new('127.0.0.1', options[:port])
1287
+ Thread.new { socket.accept }
1288
+ socket
1289
+ end
1290
+ end
1291
+
1292
+ end
1293
+