couchbase-memcached 1.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +2 -0
- data/BENCHMARKS +134 -0
- data/CHANGELOG +127 -0
- data/LICENSE +184 -0
- data/Manifest +535 -0
- data/README +118 -0
- data/Rakefile +83 -0
- data/TODO +4 -0
- data/couchbase-memcached.gemspec +33 -0
- data/ext/extconf-make.rb +25 -0
- data/ext/extconf.rb +91 -0
- data/ext/libmemcached-0.50/AUTHORS +11 -0
- data/ext/libmemcached-0.50/COPYING +33 -0
- data/ext/libmemcached-0.50/ChangeLog +392 -0
- data/ext/libmemcached-0.50/Makefile.am +114 -0
- data/ext/libmemcached-0.50/Makefile.in +4232 -0
- data/ext/libmemcached-0.50/NEWS +1 -0
- data/ext/libmemcached-0.50/README +43 -0
- data/ext/libmemcached-0.50/README.FIRST +31 -0
- data/ext/libmemcached-0.50/README.win32 +25 -0
- data/ext/libmemcached-0.50/THANKS +14 -0
- data/ext/libmemcached-0.50/TODO +11 -0
- data/ext/libmemcached-0.50/aclocal.m4 +1077 -0
- data/ext/libmemcached-0.50/clients/client_options.h +45 -0
- data/ext/libmemcached-0.50/clients/execute.cc +131 -0
- data/ext/libmemcached-0.50/clients/execute.h +30 -0
- data/ext/libmemcached-0.50/clients/generator.cc +96 -0
- data/ext/libmemcached-0.50/clients/generator.h +36 -0
- data/ext/libmemcached-0.50/clients/include.am +116 -0
- data/ext/libmemcached-0.50/clients/memaslap.c +908 -0
- data/ext/libmemcached-0.50/clients/memcapable.cc +2094 -0
- data/ext/libmemcached-0.50/clients/memcat.cc +242 -0
- data/ext/libmemcached-0.50/clients/memcp.cc +317 -0
- data/ext/libmemcached-0.50/clients/memdump.cc +183 -0
- data/ext/libmemcached-0.50/clients/memerror.cc +102 -0
- data/ext/libmemcached-0.50/clients/memflush.cc +154 -0
- data/ext/libmemcached-0.50/clients/memparse.cc +68 -0
- data/ext/libmemcached-0.50/clients/memrm.cc +177 -0
- data/ext/libmemcached-0.50/clients/memslap.cc +495 -0
- data/ext/libmemcached-0.50/clients/memstat.cc +349 -0
- data/ext/libmemcached-0.50/clients/ms_atomic.h +69 -0
- data/ext/libmemcached-0.50/clients/ms_conn.c +3413 -0
- data/ext/libmemcached-0.50/clients/ms_conn.h +241 -0
- data/ext/libmemcached-0.50/clients/ms_memslap.h +132 -0
- data/ext/libmemcached-0.50/clients/ms_setting.c +1068 -0
- data/ext/libmemcached-0.50/clients/ms_setting.h +181 -0
- data/ext/libmemcached-0.50/clients/ms_sigsegv.c +126 -0
- data/ext/libmemcached-0.50/clients/ms_sigsegv.h +34 -0
- data/ext/libmemcached-0.50/clients/ms_stats.c +307 -0
- data/ext/libmemcached-0.50/clients/ms_stats.h +69 -0
- data/ext/libmemcached-0.50/clients/ms_task.c +1114 -0
- data/ext/libmemcached-0.50/clients/ms_task.h +94 -0
- data/ext/libmemcached-0.50/clients/ms_thread.c +351 -0
- data/ext/libmemcached-0.50/clients/ms_thread.h +78 -0
- data/ext/libmemcached-0.50/clients/utilities.cc +231 -0
- data/ext/libmemcached-0.50/clients/utilities.h +64 -0
- data/ext/libmemcached-0.50/config.h.in +647 -0
- data/ext/libmemcached-0.50/config/autorun.sh +126 -0
- data/ext/libmemcached-0.50/config/compile +143 -0
- data/ext/libmemcached-0.50/config/config.guess +1517 -0
- data/ext/libmemcached-0.50/config/config.rpath +666 -0
- data/ext/libmemcached-0.50/config/config.sub +1760 -0
- data/ext/libmemcached-0.50/config/depcomp +630 -0
- data/ext/libmemcached-0.50/config/install-sh +520 -0
- data/ext/libmemcached-0.50/config/ltmain.sh +9642 -0
- data/ext/libmemcached-0.50/config/missing +376 -0
- data/ext/libmemcached-0.50/config/pandora-plugin +752 -0
- data/ext/libmemcached-0.50/config/uncrustify.cfg +1112 -0
- data/ext/libmemcached-0.50/configure +27103 -0
- data/ext/libmemcached-0.50/configure.ac +186 -0
- data/ext/libmemcached-0.50/docs/conf.py.in +354 -0
- data/ext/libmemcached-0.50/docs/include.am +240 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_clone.3 +88 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_crc32.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_create.3 +88 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_fnv1_32.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_fnv1_64.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_fnv1a_32.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_fnv1a_64.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_free.3 +88 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_functions.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_hsieh.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_is_allocated.3 +88 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_jenkins.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_md5.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_murmur.3 +105 -0
- data/ext/libmemcached-0.50/docs/man/hashkit_value.3 +66 -0
- data/ext/libmemcached-0.50/docs/man/libhashkit.3 +57 -0
- data/ext/libmemcached-0.50/docs/man/libmemcached.3 +208 -0
- data/ext/libmemcached-0.50/docs/man/libmemcached_check_configuration.3 +293 -0
- data/ext/libmemcached-0.50/docs/man/libmemcached_configuration.3 +293 -0
- data/ext/libmemcached-0.50/docs/man/libmemcached_examples.3 +144 -0
- data/ext/libmemcached-0.50/docs/man/libmemcachedutil.3 +68 -0
- data/ext/libmemcached-0.50/docs/man/memaslap.1 +1222 -0
- data/ext/libmemcached-0.50/docs/man/memcached.3 +293 -0
- data/ext/libmemcached-0.50/docs/man/memcached_add.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_add_by_key.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_analyze.3 +77 -0
- data/ext/libmemcached-0.50/docs/man/memcached_append.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_append_by_key.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_behavior_get.3 +333 -0
- data/ext/libmemcached-0.50/docs/man/memcached_behavior_set.3 +333 -0
- data/ext/libmemcached-0.50/docs/man/memcached_callback_get.3 +159 -0
- data/ext/libmemcached-0.50/docs/man/memcached_callback_set.3 +159 -0
- data/ext/libmemcached-0.50/docs/man/memcached_cas.3 +91 -0
- data/ext/libmemcached-0.50/docs/man/memcached_cas_by_key.3 +91 -0
- data/ext/libmemcached-0.50/docs/man/memcached_clone.3 +99 -0
- data/ext/libmemcached-0.50/docs/man/memcached_create.3 +99 -0
- data/ext/libmemcached-0.50/docs/man/memcached_decrement.3 +124 -0
- data/ext/libmemcached-0.50/docs/man/memcached_decrement_with_initial.3 +124 -0
- data/ext/libmemcached-0.50/docs/man/memcached_delete.3 +83 -0
- data/ext/libmemcached-0.50/docs/man/memcached_delete_by_key.3 +83 -0
- data/ext/libmemcached-0.50/docs/man/memcached_destroy_sasl_auth_data.3 +95 -0
- data/ext/libmemcached-0.50/docs/man/memcached_dump.3 +77 -0
- data/ext/libmemcached-0.50/docs/man/memcached_fetch.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_fetch_execute.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_fetch_result.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_flush_buffers.3 +72 -0
- data/ext/libmemcached-0.50/docs/man/memcached_free.3 +99 -0
- data/ext/libmemcached-0.50/docs/man/memcached_generate_hash.3 +85 -0
- data/ext/libmemcached-0.50/docs/man/memcached_generate_hash_value.3 +85 -0
- data/ext/libmemcached-0.50/docs/man/memcached_get.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_get_by_key.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_get_memory_allocators.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_get_sasl_callbacks.3 +95 -0
- data/ext/libmemcached-0.50/docs/man/memcached_get_user_data.3 +79 -0
- data/ext/libmemcached-0.50/docs/man/memcached_increment.3 +124 -0
- data/ext/libmemcached-0.50/docs/man/memcached_increment_with_initial.3 +124 -0
- data/ext/libmemcached-0.50/docs/man/memcached_lib_version.3 +76 -0
- data/ext/libmemcached-0.50/docs/man/memcached_mget.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_mget_by_key.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_mget_execute.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_mget_execute_by_key.3 +174 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_behavior_get.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_behavior_set.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_create.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_destroy.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_pop.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_push.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_pool_st.3 +139 -0
- data/ext/libmemcached-0.50/docs/man/memcached_prepend.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_prepend_by_key.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_quit.3 +74 -0
- data/ext/libmemcached-0.50/docs/man/memcached_replace.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_replace_by_key.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_sasl_set_auth_data.3 +95 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_add.3 +141 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_count.3 +141 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_cursor.3 +141 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_list.3 +141 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_list_append.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_list_count.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_list_free.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_server_push.3 +141 -0
- data/ext/libmemcached-0.50/docs/man/memcached_servers_parse.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_set.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_set_by_key.3 +132 -0
- data/ext/libmemcached-0.50/docs/man/memcached_set_memory_allocators.3 +111 -0
- data/ext/libmemcached-0.50/docs/man/memcached_set_sasl_callbacks.3 +95 -0
- data/ext/libmemcached-0.50/docs/man/memcached_set_user_data.3 +79 -0
- data/ext/libmemcached-0.50/docs/man/memcached_stat.3 +116 -0
- data/ext/libmemcached-0.50/docs/man/memcached_stat_execute.3 +116 -0
- data/ext/libmemcached-0.50/docs/man/memcached_stat_get_keys.3 +116 -0
- data/ext/libmemcached-0.50/docs/man/memcached_stat_get_value.3 +116 -0
- data/ext/libmemcached-0.50/docs/man/memcached_stat_servername.3 +116 -0
- data/ext/libmemcached-0.50/docs/man/memcached_strerror.3 +69 -0
- data/ext/libmemcached-0.50/docs/man/memcached_verbosity.3 +66 -0
- data/ext/libmemcached-0.50/docs/man/memcached_version.3 +76 -0
- data/ext/libmemcached-0.50/docs/man/memcapable.1 +92 -0
- data/ext/libmemcached-0.50/docs/man/memcat.1 +71 -0
- data/ext/libmemcached-0.50/docs/man/memcp.1 +77 -0
- data/ext/libmemcached-0.50/docs/man/memdump.1 +66 -0
- data/ext/libmemcached-0.50/docs/man/memerror.1 +65 -0
- data/ext/libmemcached-0.50/docs/man/memflush.1 +73 -0
- data/ext/libmemcached-0.50/docs/man/memrm.1 +72 -0
- data/ext/libmemcached-0.50/docs/man/memslap.1 +59 -0
- data/ext/libmemcached-0.50/docs/man/memstat.1 +70 -0
- data/ext/libmemcached-0.50/example/include.am +24 -0
- data/ext/libmemcached-0.50/example/interface_v0.c +594 -0
- data/ext/libmemcached-0.50/example/interface_v1.c +411 -0
- data/ext/libmemcached-0.50/example/memcached_light.c +474 -0
- data/ext/libmemcached-0.50/example/memcached_light.h +7 -0
- data/ext/libmemcached-0.50/example/storage.c +172 -0
- data/ext/libmemcached-0.50/example/storage.h +27 -0
- data/ext/libmemcached-0.50/example/storage_innodb.c +535 -0
- data/ext/libmemcached-0.50/libhashkit/algorithm.cc +69 -0
- data/ext/libmemcached-0.50/libhashkit/algorithm.h +96 -0
- data/ext/libmemcached-0.50/libhashkit/behavior.cc +9 -0
- data/ext/libmemcached-0.50/libhashkit/behavior.h +26 -0
- data/ext/libmemcached-0.50/libhashkit/common.h +33 -0
- data/ext/libmemcached-0.50/libhashkit/configure.h.in +19 -0
- data/ext/libmemcached-0.50/libhashkit/crc32.cc +86 -0
- data/ext/libmemcached-0.50/libhashkit/digest.cc +62 -0
- data/ext/libmemcached-0.50/libhashkit/digest.h +30 -0
- data/ext/libmemcached-0.50/libhashkit/fnv.cc +75 -0
- data/ext/libmemcached-0.50/libhashkit/function.cc +156 -0
- data/ext/libmemcached-0.50/libhashkit/function.h +44 -0
- data/ext/libmemcached-0.50/libhashkit/hashkit.cc +100 -0
- data/ext/libmemcached-0.50/libhashkit/hashkit.h +95 -0
- data/ext/libmemcached-0.50/libhashkit/hashkit.hpp +97 -0
- data/ext/libmemcached-0.50/libhashkit/hsieh.cc +70 -0
- data/ext/libmemcached-0.50/libhashkit/include.am +69 -0
- data/ext/libmemcached-0.50/libhashkit/jenkins.cc +214 -0
- data/ext/libmemcached-0.50/libhashkit/ketama.cc +164 -0
- data/ext/libmemcached-0.50/libhashkit/md5.cc +367 -0
- data/ext/libmemcached-0.50/libhashkit/murmur.cc +77 -0
- data/ext/libmemcached-0.50/libhashkit/one_at_a_time.cc +34 -0
- data/ext/libmemcached-0.50/libhashkit/str_algorithm.cc +58 -0
- data/ext/libmemcached-0.50/libhashkit/str_algorithm.h +48 -0
- data/ext/libmemcached-0.50/libhashkit/strerror.cc +25 -0
- data/ext/libmemcached-0.50/libhashkit/strerror.h +23 -0
- data/ext/libmemcached-0.50/libhashkit/types.h +90 -0
- data/ext/libmemcached-0.50/libhashkit/visibility.h +48 -0
- data/ext/libmemcached-0.50/libmemcached/allocators.cc +119 -0
- data/ext/libmemcached-0.50/libmemcached/allocators.h +87 -0
- data/ext/libmemcached-0.50/libmemcached/analyze.cc +110 -0
- data/ext/libmemcached-0.50/libmemcached/analyze.h +66 -0
- data/ext/libmemcached-0.50/libmemcached/array.c +128 -0
- data/ext/libmemcached-0.50/libmemcached/array.h +75 -0
- data/ext/libmemcached-0.50/libmemcached/auto.cc +383 -0
- data/ext/libmemcached-0.50/libmemcached/auto.h +111 -0
- data/ext/libmemcached-0.50/libmemcached/basic_string.h +55 -0
- data/ext/libmemcached-0.50/libmemcached/behavior.cc +590 -0
- data/ext/libmemcached-0.50/libmemcached/behavior.h +86 -0
- data/ext/libmemcached-0.50/libmemcached/byteorder.cc +90 -0
- data/ext/libmemcached-0.50/libmemcached/byteorder.h +52 -0
- data/ext/libmemcached-0.50/libmemcached/callback.cc +160 -0
- data/ext/libmemcached-0.50/libmemcached/callback.h +61 -0
- data/ext/libmemcached-0.50/libmemcached/common.h +182 -0
- data/ext/libmemcached-0.50/libmemcached/configure.h.in +52 -0
- data/ext/libmemcached-0.50/libmemcached/connect.cc +626 -0
- data/ext/libmemcached-0.50/libmemcached/constants.h +167 -0
- data/ext/libmemcached-0.50/libmemcached/delete.cc +266 -0
- data/ext/libmemcached-0.50/libmemcached/delete.h +57 -0
- data/ext/libmemcached-0.50/libmemcached/do.cc +100 -0
- data/ext/libmemcached-0.50/libmemcached/do.hpp +49 -0
- data/ext/libmemcached-0.50/libmemcached/dump.cc +107 -0
- data/ext/libmemcached-0.50/libmemcached/dump.h +51 -0
- data/ext/libmemcached-0.50/libmemcached/error.cc +419 -0
- data/ext/libmemcached-0.50/libmemcached/error.h +61 -0
- data/ext/libmemcached-0.50/libmemcached/error.hpp +87 -0
- data/ext/libmemcached-0.50/libmemcached/exception.hpp +63 -0
- data/ext/libmemcached-0.50/libmemcached/fetch.cc +267 -0
- data/ext/libmemcached-0.50/libmemcached/fetch.h +53 -0
- data/ext/libmemcached-0.50/libmemcached/flush.cc +149 -0
- data/ext/libmemcached-0.50/libmemcached/flush.h +49 -0
- data/ext/libmemcached-0.50/libmemcached/flush_buffers.cc +66 -0
- data/ext/libmemcached-0.50/libmemcached/flush_buffers.h +49 -0
- data/ext/libmemcached-0.50/libmemcached/get.cc +842 -0
- data/ext/libmemcached-0.50/libmemcached/get.h +135 -0
- data/ext/libmemcached-0.50/libmemcached/hash.cc +178 -0
- data/ext/libmemcached-0.50/libmemcached/hash.h +68 -0
- data/ext/libmemcached-0.50/libmemcached/hosts.cc +516 -0
- data/ext/libmemcached-0.50/libmemcached/include.am +183 -0
- data/ext/libmemcached-0.50/libmemcached/initialize_query.cc +70 -0
- data/ext/libmemcached-0.50/libmemcached/initialize_query.h +51 -0
- data/ext/libmemcached-0.50/libmemcached/internal.h +46 -0
- data/ext/libmemcached-0.50/libmemcached/io.cc +920 -0
- data/ext/libmemcached-0.50/libmemcached/io.h +119 -0
- data/ext/libmemcached-0.50/libmemcached/is.h +48 -0
- data/ext/libmemcached-0.50/libmemcached/key.cc +23 -0
- data/ext/libmemcached-0.50/libmemcached/libmemcached_probes.d +30 -0
- data/ext/libmemcached-0.50/libmemcached/libmemcached_probes.h +118 -0
- data/ext/libmemcached-0.50/libmemcached/memcached.cc +437 -0
- data/ext/libmemcached-0.50/libmemcached/memcached.h +214 -0
- data/ext/libmemcached-0.50/libmemcached/memcached.hpp +799 -0
- data/ext/libmemcached-0.50/libmemcached/memcached/README.txt +7 -0
- data/ext/libmemcached-0.50/libmemcached/memcached/protocol_binary.h +726 -0
- data/ext/libmemcached-0.50/libmemcached/memcached/vbucket.h +26 -0
- data/ext/libmemcached-0.50/libmemcached/memcached_util.h +44 -0
- data/ext/libmemcached-0.50/libmemcached/memory.h +79 -0
- data/ext/libmemcached-0.50/libmemcached/options.cc +178 -0
- data/ext/libmemcached-0.50/libmemcached/options.h +49 -0
- data/ext/libmemcached-0.50/libmemcached/options.hpp +56 -0
- data/ext/libmemcached-0.50/libmemcached/options/context.h +151 -0
- data/ext/libmemcached-0.50/libmemcached/options/include.am +19 -0
- data/ext/libmemcached-0.50/libmemcached/options/parser.am +0 -0
- data/ext/libmemcached-0.50/libmemcached/options/parser.cc +2324 -0
- data/ext/libmemcached-0.50/libmemcached/options/parser.h +122 -0
- data/ext/libmemcached-0.50/libmemcached/options/scanner.cc +3203 -0
- data/ext/libmemcached-0.50/libmemcached/options/scanner.h +479 -0
- data/ext/libmemcached-0.50/libmemcached/options/server.h +60 -0
- data/ext/libmemcached-0.50/libmemcached/options/symbol.h +57 -0
- data/ext/libmemcached-0.50/libmemcached/parse.cc +110 -0
- data/ext/libmemcached-0.50/libmemcached/parse.h +23 -0
- data/ext/libmemcached-0.50/libmemcached/platform.h +56 -0
- data/ext/libmemcached-0.50/libmemcached/prefix_key.cc +65 -0
- data/ext/libmemcached-0.50/libmemcached/prefix_key.h +49 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/ascii_handler.c +963 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/ascii_handler.h +40 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/binary_handler.c +1121 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/binary_handler.h +47 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/cache.c +149 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/cache.h +116 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/callback.h +418 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/common.h +163 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/include.am +26 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/pedantic.c +202 -0
- data/ext/libmemcached-0.50/libmemcached/protocol/protocol_handler.c +365 -0
- data/ext/libmemcached-0.50/libmemcached/protocol_handler.h +215 -0
- data/ext/libmemcached-0.50/libmemcached/purge.cc +90 -0
- data/ext/libmemcached-0.50/libmemcached/quit.cc +139 -0
- data/ext/libmemcached-0.50/libmemcached/quit.h +55 -0
- data/ext/libmemcached-0.50/libmemcached/response.cc +619 -0
- data/ext/libmemcached-0.50/libmemcached/response.h +57 -0
- data/ext/libmemcached-0.50/libmemcached/result.cc +173 -0
- data/ext/libmemcached-0.50/libmemcached/result.h +100 -0
- data/ext/libmemcached-0.50/libmemcached/return.h +98 -0
- data/ext/libmemcached-0.50/libmemcached/sasl.c +408 -0
- data/ext/libmemcached-0.50/libmemcached/sasl.h +86 -0
- data/ext/libmemcached-0.50/libmemcached/server.cc +351 -0
- data/ext/libmemcached-0.50/libmemcached/server.h +169 -0
- data/ext/libmemcached-0.50/libmemcached/server_list.cc +88 -0
- data/ext/libmemcached-0.50/libmemcached/server_list.h +77 -0
- data/ext/libmemcached-0.50/libmemcached/stats.cc +623 -0
- data/ext/libmemcached-0.50/libmemcached/stats.h +96 -0
- data/ext/libmemcached-0.50/libmemcached/storage.cc +567 -0
- data/ext/libmemcached-0.50/libmemcached/storage.h +133 -0
- data/ext/libmemcached-0.50/libmemcached/strerror.cc +189 -0
- data/ext/libmemcached-0.50/libmemcached/strerror.h +50 -0
- data/ext/libmemcached-0.50/libmemcached/string.cc +253 -0
- data/ext/libmemcached-0.50/libmemcached/string.h +121 -0
- data/ext/libmemcached-0.50/libmemcached/touch.cc +106 -0
- data/ext/libmemcached-0.50/libmemcached/touch.h +59 -0
- data/ext/libmemcached-0.50/libmemcached/types.h +117 -0
- data/ext/libmemcached-0.50/libmemcached/util.h +40 -0
- data/ext/libmemcached-0.50/libmemcached/util/flush.cc +61 -0
- data/ext/libmemcached-0.50/libmemcached/util/flush.h +50 -0
- data/ext/libmemcached-0.50/libmemcached/util/include.am +34 -0
- data/ext/libmemcached-0.50/libmemcached/util/ping.cc +62 -0
- data/ext/libmemcached-0.50/libmemcached/util/ping.h +49 -0
- data/ext/libmemcached-0.50/libmemcached/util/pool.cc +392 -0
- data/ext/libmemcached-0.50/libmemcached/util/pool.h +78 -0
- data/ext/libmemcached-0.50/libmemcached/util/version.cc +87 -0
- data/ext/libmemcached-0.50/libmemcached/util/version.h +53 -0
- data/ext/libmemcached-0.50/libmemcached/verbosity.cc +97 -0
- data/ext/libmemcached-0.50/libmemcached/verbosity.h +50 -0
- data/ext/libmemcached-0.50/libmemcached/version.cc +214 -0
- data/ext/libmemcached-0.50/libmemcached/version.h +52 -0
- data/ext/libmemcached-0.50/libmemcached/virtual_bucket.c +118 -0
- data/ext/libmemcached-0.50/libmemcached/virtual_bucket.h +59 -0
- data/ext/libmemcached-0.50/libmemcached/visibility.h +51 -0
- data/ext/libmemcached-0.50/libmemcached/watchpoint.h +110 -0
- data/ext/libmemcached-0.50/libtest/callbacks.h +21 -0
- data/ext/libmemcached-0.50/libtest/collection.h +19 -0
- data/ext/libmemcached-0.50/libtest/common.h +50 -0
- data/ext/libmemcached-0.50/libtest/core.h +11 -0
- data/ext/libmemcached-0.50/libtest/error.h +18 -0
- data/ext/libmemcached-0.50/libtest/failed.h +52 -0
- data/ext/libmemcached-0.50/libtest/framework.cc +57 -0
- data/ext/libmemcached-0.50/libtest/framework.h +137 -0
- data/ext/libmemcached-0.50/libtest/get.h +22 -0
- data/ext/libmemcached-0.50/libtest/include.am +52 -0
- data/ext/libmemcached-0.50/libtest/runner.h +19 -0
- data/ext/libmemcached-0.50/libtest/server.c +355 -0
- data/ext/libmemcached-0.50/libtest/server.h +43 -0
- data/ext/libmemcached-0.50/libtest/stats.h +30 -0
- data/ext/libmemcached-0.50/libtest/strerror.h +14 -0
- data/ext/libmemcached-0.50/libtest/test.cc +319 -0
- data/ext/libmemcached-0.50/libtest/test.h +162 -0
- data/ext/libmemcached-0.50/libtest/test.hpp +46 -0
- data/ext/libmemcached-0.50/libtest/visibility.h +69 -0
- data/ext/libmemcached-0.50/m4/ac_cxx_header_stdcxx_98.m4 +83 -0
- data/ext/libmemcached-0.50/m4/acx_pthread.m4 +271 -0
- data/ext/libmemcached-0.50/m4/byteorder.m4 +19 -0
- data/ext/libmemcached-0.50/m4/deprecated.m4 +17 -0
- data/ext/libmemcached-0.50/m4/eagain.m4 +28 -0
- data/ext/libmemcached-0.50/m4/enable_utillib.m4 +16 -0
- data/ext/libmemcached-0.50/m4/gettext.m4 +379 -0
- data/ext/libmemcached-0.50/m4/hsieh.m4 +18 -0
- data/ext/libmemcached-0.50/m4/iconv.m4 +214 -0
- data/ext/libmemcached-0.50/m4/lib-ld.m4 +110 -0
- data/ext/libmemcached-0.50/m4/lib-link.m4 +767 -0
- data/ext/libmemcached-0.50/m4/lib-prefix.m4 +221 -0
- data/ext/libmemcached-0.50/m4/libtool.m4 +7851 -0
- data/ext/libmemcached-0.50/m4/ltoptions.m4 +369 -0
- data/ext/libmemcached-0.50/m4/ltsugar.m4 +123 -0
- data/ext/libmemcached-0.50/m4/ltversion.m4 +23 -0
- data/ext/libmemcached-0.50/m4/lt~obsolete.m4 +98 -0
- data/ext/libmemcached-0.50/m4/memaslap.m4 +9 -0
- data/ext/libmemcached-0.50/m4/memcached.m4 +31 -0
- data/ext/libmemcached-0.50/m4/murmur.m4 +18 -0
- data/ext/libmemcached-0.50/m4/pandora_64bit.m4 +60 -0
- data/ext/libmemcached-0.50/m4/pandora_bison.m4 +33 -0
- data/ext/libmemcached-0.50/m4/pandora_canonical.m4 +418 -0
- data/ext/libmemcached-0.50/m4/pandora_check_compiler_version.m4 +37 -0
- data/ext/libmemcached-0.50/m4/pandora_check_cxx_standard.m4 +23 -0
- data/ext/libmemcached-0.50/m4/pandora_cinttypes.m4 +39 -0
- data/ext/libmemcached-0.50/m4/pandora_clock_gettime.m4 +15 -0
- data/ext/libmemcached-0.50/m4/pandora_compile_stdcxx_0x.m4 +103 -0
- data/ext/libmemcached-0.50/m4/pandora_cstdint.m4 +38 -0
- data/ext/libmemcached-0.50/m4/pandora_cxx_demangle.m4 +27 -0
- data/ext/libmemcached-0.50/m4/pandora_enable_dtrace.m4 +60 -0
- data/ext/libmemcached-0.50/m4/pandora_ensure_gcc_version.m4 +62 -0
- data/ext/libmemcached-0.50/m4/pandora_extensions.m4 +16 -0
- data/ext/libmemcached-0.50/m4/pandora_fdatasync.m4 +25 -0
- data/ext/libmemcached-0.50/m4/pandora_flex.m4 +33 -0
- data/ext/libmemcached-0.50/m4/pandora_have_better_malloc.m4 +66 -0
- data/ext/libmemcached-0.50/m4/pandora_have_boost.m4 +93 -0
- data/ext/libmemcached-0.50/m4/pandora_have_gcc_atomics.m4 +37 -0
- data/ext/libmemcached-0.50/m4/pandora_have_innodb.m4 +41 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libaio.m4 +56 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libavahi.m4 +41 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libbdb.m4 +40 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_date_time.m4 +46 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_filesystem.m4 +47 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_iostreams.m4 +49 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_options.m4 +47 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_regex.m4 +54 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_test.m4 +45 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libboost_thread.m4 +54 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libcassandra.m4 +44 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libcurl.m4 +62 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libdl.m4 +51 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libdrizzle.m4 +61 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libevent.m4 +66 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libgearman.m4 +41 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libgtest.m4 +47 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libhaildb.m4 +43 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libhashkit.m4 +42 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libinnodb.m4 +64 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libldap.m4 +73 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libmemcached.m4 +106 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libmysqlclient.m4 +146 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libndbclient.m4 +80 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libpcre.m4 +73 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libpq.m4 +46 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libpqxx.m4 +44 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libsqlite3.m4 +42 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libtokyocabinet.m4 +54 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libuuid.m4 +55 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libvbucket.m4 +40 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libxml2.m4 +52 -0
- data/ext/libmemcached-0.50/m4/pandora_have_libz.m4 +51 -0
- data/ext/libmemcached-0.50/m4/pandora_have_protobuf.m4 +82 -0
- data/ext/libmemcached-0.50/m4/pandora_have_sasl.m4 +133 -0
- data/ext/libmemcached-0.50/m4/pandora_have_thrift.m4 +45 -0
- data/ext/libmemcached-0.50/m4/pandora_header_assert.m4 +23 -0
- data/ext/libmemcached-0.50/m4/pandora_header_stdcxx_98.m4 +83 -0
- data/ext/libmemcached-0.50/m4/pandora_intltool.m4 +225 -0
- data/ext/libmemcached-0.50/m4/pandora_libtool.m4 +25 -0
- data/ext/libmemcached-0.50/m4/pandora_optimize.m4 +75 -0
- data/ext/libmemcached-0.50/m4/pandora_platform.m4 +117 -0
- data/ext/libmemcached-0.50/m4/pandora_plugins.m4 +62 -0
- data/ext/libmemcached-0.50/m4/pandora_print_callstack.m4 +61 -0
- data/ext/libmemcached-0.50/m4/pandora_pthread.m4 +258 -0
- data/ext/libmemcached-0.50/m4/pandora_python3_devel.m4 +236 -0
- data/ext/libmemcached-0.50/m4/pandora_run_cpplint.m4 +8 -0
- data/ext/libmemcached-0.50/m4/pandora_sasl.m4 +133 -0
- data/ext/libmemcached-0.50/m4/pandora_shared_ptr.m4 +59 -0
- data/ext/libmemcached-0.50/m4/pandora_stack_direction.m4 +39 -0
- data/ext/libmemcached-0.50/m4/pandora_stl_hash.m4 +94 -0
- data/ext/libmemcached-0.50/m4/pandora_swig.m4 +39 -0
- data/ext/libmemcached-0.50/m4/pandora_use_pipe.m4 +36 -0
- data/ext/libmemcached-0.50/m4/pandora_vc_build.m4 +168 -0
- data/ext/libmemcached-0.50/m4/pandora_version.m4 +11 -0
- data/ext/libmemcached-0.50/m4/pandora_visibility.m4 +75 -0
- data/ext/libmemcached-0.50/m4/pandora_warnings.m4 +447 -0
- data/ext/libmemcached-0.50/m4/pandora_with_gettext.m4 +44 -0
- data/ext/libmemcached-0.50/m4/pandora_with_lua.m4 +55 -0
- data/ext/libmemcached-0.50/m4/pandora_with_memcached.m4 +41 -0
- data/ext/libmemcached-0.50/m4/pandora_with_perl.m4 +81 -0
- data/ext/libmemcached-0.50/m4/pandora_with_php.m4 +56 -0
- data/ext/libmemcached-0.50/m4/pandora_with_python.m4 +37 -0
- data/ext/libmemcached-0.50/m4/pandora_with_python3.m4 +44 -0
- data/ext/libmemcached-0.50/m4/pandora_with_r.m4 +33 -0
- data/ext/libmemcached-0.50/m4/pandora_with_ruby.m4 +79 -0
- data/ext/libmemcached-0.50/m4/pandora_with_valgrind.m4 +17 -0
- data/ext/libmemcached-0.50/m4/pkg.m4 +157 -0
- data/ext/libmemcached-0.50/m4/po.m4 +449 -0
- data/ext/libmemcached-0.50/m4/progtest.m4 +92 -0
- data/ext/libmemcached-0.50/m4/protocol_binary.m4 +36 -0
- data/ext/libmemcached-0.50/m4/setsockopt.m4 +73 -0
- data/ext/libmemcached-0.50/m4/socket_send_flags.m4 +66 -0
- data/ext/libmemcached-0.50/poll/include.am +8 -0
- data/ext/libmemcached-0.50/poll/poll.c +77 -0
- data/ext/libmemcached-0.50/poll/poll.h +45 -0
- data/ext/libmemcached-0.50/support/include.am +11 -0
- data/ext/libmemcached-0.50/support/libmemcached-fc.spec.in +105 -0
- data/ext/libmemcached-0.50/support/libmemcached.pc.in +10 -0
- data/ext/libmemcached-0.50/support/libmemcached.spec.in +281 -0
- data/ext/libmemcached-0.50/support/set_benchmark.sh +5 -0
- data/ext/libmemcached-0.50/tests/atomsmasher.cc +295 -0
- data/ext/libmemcached-0.50/tests/basic.cc +134 -0
- data/ext/libmemcached-0.50/tests/basic.h +66 -0
- data/ext/libmemcached-0.50/tests/cpp_example.cc +195 -0
- data/ext/libmemcached-0.50/tests/deprecated.cc +72 -0
- data/ext/libmemcached-0.50/tests/deprecated.h +49 -0
- data/ext/libmemcached-0.50/tests/error_conditions.cc +63 -0
- data/ext/libmemcached-0.50/tests/error_conditions.h +48 -0
- data/ext/libmemcached-0.50/tests/hash_plus.cc +225 -0
- data/ext/libmemcached-0.50/tests/hash_results.h +127 -0
- data/ext/libmemcached-0.50/tests/hashkit_functions.cc +619 -0
- data/ext/libmemcached-0.50/tests/include.am +342 -0
- data/ext/libmemcached-0.50/tests/ketama_test_cases.h +121 -0
- data/ext/libmemcached-0.50/tests/ketama_test_cases_spy.h +118 -0
- data/ext/libmemcached-0.50/tests/libmemcached_world.h +205 -0
- data/ext/libmemcached-0.50/tests/mem_functions.cc +6648 -0
- data/ext/libmemcached-0.50/tests/mem_udp.cc +510 -0
- data/ext/libmemcached-0.50/tests/output_plus.res +5 -0
- data/ext/libmemcached-0.50/tests/parser.cc +599 -0
- data/ext/libmemcached-0.50/tests/parser.h +109 -0
- data/ext/libmemcached-0.50/tests/plus.cpp +240 -0
- data/ext/libmemcached-0.50/tests/pool.cc +78 -0
- data/ext/libmemcached-0.50/tests/pool.h +49 -0
- data/ext/libmemcached-0.50/tests/print.cc +58 -0
- data/ext/libmemcached-0.50/tests/print.h +51 -0
- data/ext/libmemcached-0.50/tests/replication.cc +333 -0
- data/ext/libmemcached-0.50/tests/replication.h +64 -0
- data/ext/libmemcached-0.50/tests/start.cc +29 -0
- data/ext/libmemcached-0.50/tests/string.cc +174 -0
- data/ext/libmemcached-0.50/tests/string.h +67 -0
- data/ext/libmemcached-0.50/tests/virtual_buckets.cc +143 -0
- data/ext/libmemcached-0.50/tests/virtual_buckets.h +51 -0
- data/ext/libmemcached-0.50/win32/include.am +11 -0
- data/ext/libmemcached-0.50/win32/wrappers.h +55 -0
- data/ext/rlibmemcached.i +263 -0
- data/ext/rlibmemcached_wrap.c +16732 -0
- data/lib/memcached.rb +32 -0
- data/lib/memcached/auth.rb +16 -0
- data/lib/memcached/behaviors.rb +77 -0
- data/lib/memcached/exceptions.rb +84 -0
- data/lib/memcached/experimental.rb +48 -0
- data/lib/memcached/memcached.rb +660 -0
- data/lib/memcached/rails.rb +133 -0
- data/test/profile/benchmark.rb +245 -0
- data/test/profile/c_profiler.rb +14 -0
- data/test/profile/exercise.rb +185 -0
- data/test/profile/rb_profiler.rb +21 -0
- data/test/profile/valgrind.rb +10 -0
- data/test/setup.rb +30 -0
- data/test/teardown.rb +0 -0
- data/test/test_helper.rb +19 -0
- data/test/unit/binding_test.rb +8 -0
- data/test/unit/memcached_experimental_test.rb +274 -0
- data/test/unit/memcached_test.rb +1293 -0
- data/test/unit/rails_test.rb +122 -0
- metadata +650 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,2094 @@
|
|
|
1
|
+
/* LibMemcached
|
|
2
|
+
* Copyright (C) 2006-2009 Brian Aker
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use and distribution licensed under the BSD license. See
|
|
6
|
+
* the COPYING file in the parent directory for full text.
|
|
7
|
+
*
|
|
8
|
+
* Summary:
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
13
|
+
#undef NDEBUG
|
|
14
|
+
|
|
15
|
+
#include "config.h"
|
|
16
|
+
#include <pthread.h>
|
|
17
|
+
#include <sys/types.h>
|
|
18
|
+
#include <fcntl.h>
|
|
19
|
+
#include <signal.h>
|
|
20
|
+
#include <stdio.h>
|
|
21
|
+
#include <stdlib.h>
|
|
22
|
+
#include <errno.h>
|
|
23
|
+
#include <assert.h>
|
|
24
|
+
#include <string.h>
|
|
25
|
+
#include <inttypes.h>
|
|
26
|
+
#include <stdbool.h>
|
|
27
|
+
#include <unistd.h>
|
|
28
|
+
#include <ctype.h>
|
|
29
|
+
|
|
30
|
+
#include <libmemcached/memcached.h>
|
|
31
|
+
#include <libmemcached/memcached/protocol_binary.h>
|
|
32
|
+
#include <libmemcached/byteorder.h>
|
|
33
|
+
#include "utilities.h"
|
|
34
|
+
|
|
35
|
+
#ifdef linux
|
|
36
|
+
/* /usr/include/netinet/in.h defines macros from ntohs() to _bswap_nn to
|
|
37
|
+
* optimize the conversion functions, but the prototypes generate warnings
|
|
38
|
+
* from gcc. The conversion methods isn't the bottleneck for my app, so
|
|
39
|
+
* just remove the warnings by undef'ing the optimization ..
|
|
40
|
+
*/
|
|
41
|
+
#undef ntohs
|
|
42
|
+
#undef ntohl
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
/* Should we generate coredumps when we enounter an error (-c) */
|
|
46
|
+
static bool do_core= false;
|
|
47
|
+
/* connection to the server */
|
|
48
|
+
static memcached_socket_t sock;
|
|
49
|
+
/* Should the output from test failures be verbose or quiet? */
|
|
50
|
+
static bool verbose= false;
|
|
51
|
+
|
|
52
|
+
/* The number of seconds to wait for an IO-operation */
|
|
53
|
+
static int timeout= 2;
|
|
54
|
+
|
|
55
|
+
/*
|
|
56
|
+
* Instead of having to cast between the different datatypes we create
|
|
57
|
+
* a union of all of the different types of pacages we want to send.
|
|
58
|
+
* A lot of the different commands use the same packet layout, so I'll
|
|
59
|
+
* just define the different types I need. The typedefs only contain
|
|
60
|
+
* the header of the message, so we need some space for keys and body
|
|
61
|
+
* To avoid to have to do multiple writes, lets add a chunk of memory
|
|
62
|
+
* to use. 1k should be more than enough for header, key and body.
|
|
63
|
+
*/
|
|
64
|
+
typedef union
|
|
65
|
+
{
|
|
66
|
+
protocol_binary_request_no_extras plain;
|
|
67
|
+
protocol_binary_request_flush flush;
|
|
68
|
+
protocol_binary_request_incr incr;
|
|
69
|
+
protocol_binary_request_set set;
|
|
70
|
+
char bytes[1024];
|
|
71
|
+
} command;
|
|
72
|
+
|
|
73
|
+
typedef union
|
|
74
|
+
{
|
|
75
|
+
protocol_binary_response_no_extras plain;
|
|
76
|
+
protocol_binary_response_incr incr;
|
|
77
|
+
protocol_binary_response_decr decr;
|
|
78
|
+
char bytes[1024];
|
|
79
|
+
} response;
|
|
80
|
+
|
|
81
|
+
enum test_return
|
|
82
|
+
{
|
|
83
|
+
TEST_SKIP, TEST_PASS, TEST_PASS_RECONNECT, TEST_FAIL
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Try to get an addrinfo struct for a given port on a given host
|
|
88
|
+
*/
|
|
89
|
+
static struct addrinfo *lookuphost(const char *hostname, const char *port)
|
|
90
|
+
{
|
|
91
|
+
struct addrinfo *ai= 0;
|
|
92
|
+
struct addrinfo hints;
|
|
93
|
+
memset(&hints, 0, sizeof(struct addrinfo));
|
|
94
|
+
hints.ai_family=AF_UNSPEC;
|
|
95
|
+
hints.ai_protocol=IPPROTO_TCP;
|
|
96
|
+
hints.ai_socktype=SOCK_STREAM;
|
|
97
|
+
|
|
98
|
+
int error= getaddrinfo(hostname, port, &hints, &ai);
|
|
99
|
+
if (error != 0)
|
|
100
|
+
{
|
|
101
|
+
if (error != EAI_SYSTEM)
|
|
102
|
+
fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(error));
|
|
103
|
+
else
|
|
104
|
+
perror("getaddrinfo()");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return ai;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Set the socket in nonblocking mode
|
|
112
|
+
* @return -1 if failure, the socket otherwise
|
|
113
|
+
*/
|
|
114
|
+
static memcached_socket_t set_noblock(void)
|
|
115
|
+
{
|
|
116
|
+
#ifdef WIN32
|
|
117
|
+
u_long arg = 1;
|
|
118
|
+
if (ioctlsocket(sock, FIONBIO, &arg) == SOCKET_ERROR)
|
|
119
|
+
{
|
|
120
|
+
perror("Failed to set nonblocking io");
|
|
121
|
+
closesocket(sock);
|
|
122
|
+
return INVALID_SOCKET;
|
|
123
|
+
}
|
|
124
|
+
#else
|
|
125
|
+
int flags= fcntl(sock, F_GETFL, 0);
|
|
126
|
+
if (flags == -1)
|
|
127
|
+
{
|
|
128
|
+
perror("Failed to get socket flags");
|
|
129
|
+
closesocket(sock);
|
|
130
|
+
return INVALID_SOCKET;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if ((flags & O_NONBLOCK) != O_NONBLOCK)
|
|
134
|
+
{
|
|
135
|
+
if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1)
|
|
136
|
+
{
|
|
137
|
+
perror("Failed to set socket to nonblocking mode");
|
|
138
|
+
closesocket(sock);
|
|
139
|
+
return INVALID_SOCKET;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
#endif
|
|
143
|
+
return sock;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Try to open a connection to the server
|
|
148
|
+
* @param hostname the name of the server to connect to
|
|
149
|
+
* @param port the port number (or service) to connect to
|
|
150
|
+
* @return positive integer if success, -1 otherwise
|
|
151
|
+
*/
|
|
152
|
+
static memcached_socket_t connect_server(const char *hostname, const char *port)
|
|
153
|
+
{
|
|
154
|
+
struct addrinfo *ai= lookuphost(hostname, port);
|
|
155
|
+
sock= INVALID_SOCKET;
|
|
156
|
+
if (ai != NULL)
|
|
157
|
+
{
|
|
158
|
+
if ((sock= socket(ai->ai_family, ai->ai_socktype,
|
|
159
|
+
ai->ai_protocol)) != INVALID_SOCKET)
|
|
160
|
+
{
|
|
161
|
+
if (connect(sock, ai->ai_addr, ai->ai_addrlen) == SOCKET_ERROR)
|
|
162
|
+
{
|
|
163
|
+
fprintf(stderr, "Failed to connect socket: %s\n",
|
|
164
|
+
strerror(get_socket_errno()));
|
|
165
|
+
closesocket(sock);
|
|
166
|
+
sock= INVALID_SOCKET;
|
|
167
|
+
}
|
|
168
|
+
else
|
|
169
|
+
{
|
|
170
|
+
sock= set_noblock();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else
|
|
174
|
+
fprintf(stderr, "Failed to create socket: %s\n",
|
|
175
|
+
strerror(get_socket_errno()));
|
|
176
|
+
|
|
177
|
+
freeaddrinfo(ai);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return sock;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
static ssize_t timeout_io_op(memcached_socket_t fd, short direction, void *buf, size_t len)
|
|
184
|
+
{
|
|
185
|
+
ssize_t ret;
|
|
186
|
+
|
|
187
|
+
if (direction == POLLOUT)
|
|
188
|
+
{
|
|
189
|
+
ret= send(fd, buf, len, 0);
|
|
190
|
+
}
|
|
191
|
+
else
|
|
192
|
+
{
|
|
193
|
+
ret= recv(fd, buf, len, 0);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (ret == SOCKET_ERROR && get_socket_errno() == EWOULDBLOCK)
|
|
197
|
+
{
|
|
198
|
+
struct pollfd fds;
|
|
199
|
+
memset(&fds, 0, sizeof(struct pollfd));
|
|
200
|
+
fds.events= direction;
|
|
201
|
+
fds.fd= fd;
|
|
202
|
+
|
|
203
|
+
int err= poll(&fds, 1, timeout * 1000);
|
|
204
|
+
if (err == 1)
|
|
205
|
+
{
|
|
206
|
+
if (direction == POLLOUT)
|
|
207
|
+
{
|
|
208
|
+
ret= send(fd, buf, len, 0);
|
|
209
|
+
}
|
|
210
|
+
else
|
|
211
|
+
{
|
|
212
|
+
ret= recv(fd, buf, len, 0);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else if (err == 0)
|
|
216
|
+
{
|
|
217
|
+
errno= ETIMEDOUT;
|
|
218
|
+
}
|
|
219
|
+
else
|
|
220
|
+
{
|
|
221
|
+
perror("Failed to poll");
|
|
222
|
+
return -1;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return ret;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Ensure that an expression is true. If it isn't print out a message similar
|
|
231
|
+
* to assert() and create a coredump if the user wants that. If not an error
|
|
232
|
+
* message is returned.
|
|
233
|
+
*
|
|
234
|
+
*/
|
|
235
|
+
static enum test_return ensure(bool val, const char *expression, const char *file, int line)
|
|
236
|
+
{
|
|
237
|
+
if (!val)
|
|
238
|
+
{
|
|
239
|
+
if (verbose)
|
|
240
|
+
fprintf(stderr, "\n%s:%d: %s", file, line, expression);
|
|
241
|
+
|
|
242
|
+
if (do_core)
|
|
243
|
+
abort();
|
|
244
|
+
|
|
245
|
+
return TEST_FAIL;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return TEST_PASS;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
#define verify(expression) do { if (ensure(expression, #expression, __FILE__, __LINE__) == TEST_FAIL) return TEST_FAIL; } while (0)
|
|
252
|
+
#define execute(expression) do { if (ensure(expression == TEST_PASS, #expression, __FILE__, __LINE__) == TEST_FAIL) return TEST_FAIL; } while (0)
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Send a chunk of memory over the socket (retry if the call is iterrupted
|
|
256
|
+
*/
|
|
257
|
+
static enum test_return retry_write(const void* buf, size_t len)
|
|
258
|
+
{
|
|
259
|
+
size_t offset= 0;
|
|
260
|
+
const char* ptr= static_cast<const char *>(buf);
|
|
261
|
+
|
|
262
|
+
do
|
|
263
|
+
{
|
|
264
|
+
size_t num_bytes= len - offset;
|
|
265
|
+
ssize_t nw= timeout_io_op(sock, POLLOUT, (void*)(ptr + offset), num_bytes);
|
|
266
|
+
if (nw == -1)
|
|
267
|
+
verify(get_socket_errno() == EINTR || get_socket_errno() == EAGAIN);
|
|
268
|
+
else
|
|
269
|
+
offset+= (size_t)nw;
|
|
270
|
+
} while (offset < len);
|
|
271
|
+
|
|
272
|
+
return TEST_PASS;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Resend a packet to the server (All fields in the command header should
|
|
277
|
+
* be in network byte order)
|
|
278
|
+
*/
|
|
279
|
+
static enum test_return resend_packet(command *cmd)
|
|
280
|
+
{
|
|
281
|
+
size_t length= sizeof (protocol_binary_request_no_extras) +
|
|
282
|
+
ntohl(cmd->plain.message.header.request.bodylen);
|
|
283
|
+
|
|
284
|
+
execute(retry_write(cmd, length));
|
|
285
|
+
return TEST_PASS;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Send a command to the server. The command header needs to be updated
|
|
290
|
+
* to network byte order
|
|
291
|
+
*/
|
|
292
|
+
static enum test_return send_packet(command *cmd)
|
|
293
|
+
{
|
|
294
|
+
/* Fix the byteorder of the header */
|
|
295
|
+
cmd->plain.message.header.request.keylen=
|
|
296
|
+
ntohs(cmd->plain.message.header.request.keylen);
|
|
297
|
+
cmd->plain.message.header.request.bodylen=
|
|
298
|
+
ntohl(cmd->plain.message.header.request.bodylen);
|
|
299
|
+
cmd->plain.message.header.request.cas=
|
|
300
|
+
memcached_ntohll(cmd->plain.message.header.request.cas);
|
|
301
|
+
|
|
302
|
+
execute(resend_packet(cmd));
|
|
303
|
+
return TEST_PASS;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Read a fixed length chunk of data from the server
|
|
308
|
+
*/
|
|
309
|
+
static enum test_return retry_read(void *buf, size_t len)
|
|
310
|
+
{
|
|
311
|
+
size_t offset= 0;
|
|
312
|
+
do
|
|
313
|
+
{
|
|
314
|
+
ssize_t nr= timeout_io_op(sock, POLLIN, ((char*) buf) + offset, len - offset);
|
|
315
|
+
switch (nr) {
|
|
316
|
+
case -1 :
|
|
317
|
+
fprintf(stderr, "Errno: %d %s\n", get_socket_errno(), strerror(errno));
|
|
318
|
+
verify(get_socket_errno() == EINTR || get_socket_errno() == EAGAIN);
|
|
319
|
+
break;
|
|
320
|
+
case 0:
|
|
321
|
+
return TEST_FAIL;
|
|
322
|
+
default:
|
|
323
|
+
offset+= (size_t)nr;
|
|
324
|
+
}
|
|
325
|
+
} while (offset < len);
|
|
326
|
+
|
|
327
|
+
return TEST_PASS;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Receive a response from the server and conver the fields in the header
|
|
332
|
+
* to local byte order
|
|
333
|
+
*/
|
|
334
|
+
static enum test_return recv_packet(response *rsp)
|
|
335
|
+
{
|
|
336
|
+
execute(retry_read(rsp, sizeof(protocol_binary_response_no_extras)));
|
|
337
|
+
|
|
338
|
+
/* Fix the byte order in the packet header */
|
|
339
|
+
rsp->plain.message.header.response.keylen=
|
|
340
|
+
ntohs(rsp->plain.message.header.response.keylen);
|
|
341
|
+
rsp->plain.message.header.response.status=
|
|
342
|
+
ntohs(rsp->plain.message.header.response.status);
|
|
343
|
+
rsp->plain.message.header.response.bodylen=
|
|
344
|
+
ntohl(rsp->plain.message.header.response.bodylen);
|
|
345
|
+
rsp->plain.message.header.response.cas=
|
|
346
|
+
memcached_ntohll(rsp->plain.message.header.response.cas);
|
|
347
|
+
|
|
348
|
+
size_t bodysz= rsp->plain.message.header.response.bodylen;
|
|
349
|
+
if (bodysz > 0)
|
|
350
|
+
execute(retry_read(rsp->bytes + sizeof (protocol_binary_response_no_extras), bodysz));
|
|
351
|
+
|
|
352
|
+
return TEST_PASS;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Create a storage command (add, set, replace etc)
|
|
357
|
+
*
|
|
358
|
+
* @param cmd destination buffer
|
|
359
|
+
* @param cc the storage command to create
|
|
360
|
+
* @param key the key to store
|
|
361
|
+
* @param keylen the length of the key
|
|
362
|
+
* @param dta the data to store with the key
|
|
363
|
+
* @param dtalen the length of the data to store with the key
|
|
364
|
+
* @param flags the flags to store along with the key
|
|
365
|
+
* @param exptime the expiry time for the key
|
|
366
|
+
*/
|
|
367
|
+
static void storage_command(command *cmd,
|
|
368
|
+
uint8_t cc,
|
|
369
|
+
const void* key,
|
|
370
|
+
size_t keylen,
|
|
371
|
+
const void* dta,
|
|
372
|
+
size_t dtalen,
|
|
373
|
+
uint32_t flags,
|
|
374
|
+
uint32_t exptime)
|
|
375
|
+
{
|
|
376
|
+
/* all of the storage commands use the same command layout */
|
|
377
|
+
protocol_binary_request_set *request= &cmd->set;
|
|
378
|
+
|
|
379
|
+
memset(request, 0, sizeof (*request));
|
|
380
|
+
request->message.header.request.magic= PROTOCOL_BINARY_REQ;
|
|
381
|
+
request->message.header.request.opcode= cc;
|
|
382
|
+
request->message.header.request.keylen= (uint16_t)keylen;
|
|
383
|
+
request->message.header.request.extlen= 8;
|
|
384
|
+
request->message.header.request.bodylen= (uint32_t)(keylen + 8 + dtalen);
|
|
385
|
+
request->message.header.request.opaque= 0xdeadbeef;
|
|
386
|
+
request->message.body.flags= flags;
|
|
387
|
+
request->message.body.expiration= exptime;
|
|
388
|
+
|
|
389
|
+
off_t key_offset= sizeof (protocol_binary_request_no_extras) + 8;
|
|
390
|
+
memcpy(cmd->bytes + key_offset, key, keylen);
|
|
391
|
+
if (dta != NULL)
|
|
392
|
+
memcpy(cmd->bytes + key_offset + keylen, dta, dtalen);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Create a basic command to send to the server
|
|
397
|
+
* @param cmd destination buffer
|
|
398
|
+
* @param cc the command to create
|
|
399
|
+
* @param key the key to store
|
|
400
|
+
* @param keylen the length of the key
|
|
401
|
+
* @param dta the data to store with the key
|
|
402
|
+
* @param dtalen the length of the data to store with the key
|
|
403
|
+
*/
|
|
404
|
+
static void raw_command(command *cmd,
|
|
405
|
+
uint8_t cc,
|
|
406
|
+
const void* key,
|
|
407
|
+
size_t keylen,
|
|
408
|
+
const void* dta,
|
|
409
|
+
size_t dtalen)
|
|
410
|
+
{
|
|
411
|
+
/* all of the storage commands use the same command layout */
|
|
412
|
+
memset(cmd, 0, sizeof (*cmd));
|
|
413
|
+
cmd->plain.message.header.request.magic= PROTOCOL_BINARY_REQ;
|
|
414
|
+
cmd->plain.message.header.request.opcode= cc;
|
|
415
|
+
cmd->plain.message.header.request.keylen= (uint16_t)keylen;
|
|
416
|
+
cmd->plain.message.header.request.bodylen= (uint32_t)(keylen + dtalen);
|
|
417
|
+
cmd->plain.message.header.request.opaque= 0xdeadbeef;
|
|
418
|
+
|
|
419
|
+
off_t key_offset= sizeof (protocol_binary_request_no_extras);
|
|
420
|
+
|
|
421
|
+
if (key != NULL)
|
|
422
|
+
memcpy(cmd->bytes + key_offset, key, keylen);
|
|
423
|
+
|
|
424
|
+
if (dta != NULL)
|
|
425
|
+
memcpy(cmd->bytes + key_offset + keylen, dta, dtalen);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Create the flush command
|
|
430
|
+
* @param cmd destination buffer
|
|
431
|
+
* @param cc the command to create (FLUSH/FLUSHQ)
|
|
432
|
+
* @param exptime when to flush
|
|
433
|
+
* @param use_extra to force using of the extra field?
|
|
434
|
+
*/
|
|
435
|
+
static void flush_command(command *cmd,
|
|
436
|
+
uint8_t cc, uint32_t exptime, bool use_extra)
|
|
437
|
+
{
|
|
438
|
+
memset(cmd, 0, sizeof (cmd->flush));
|
|
439
|
+
cmd->flush.message.header.request.magic= PROTOCOL_BINARY_REQ;
|
|
440
|
+
cmd->flush.message.header.request.opcode= cc;
|
|
441
|
+
cmd->flush.message.header.request.opaque= 0xdeadbeef;
|
|
442
|
+
|
|
443
|
+
if (exptime != 0 || use_extra)
|
|
444
|
+
{
|
|
445
|
+
cmd->flush.message.header.request.extlen= 4;
|
|
446
|
+
cmd->flush.message.body.expiration= htonl(exptime);
|
|
447
|
+
cmd->flush.message.header.request.bodylen= 4;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Create a incr/decr command
|
|
453
|
+
* @param cc the cmd to create (FLUSH/FLUSHQ)
|
|
454
|
+
* @param key the key to operate on
|
|
455
|
+
* @param keylen the number of bytes in the key
|
|
456
|
+
* @param delta the number to add/subtract
|
|
457
|
+
* @param initial the initial value if the key doesn't exist
|
|
458
|
+
* @param exptime when the key should expire if it isn't set
|
|
459
|
+
*/
|
|
460
|
+
static void arithmetic_command(command *cmd,
|
|
461
|
+
uint8_t cc,
|
|
462
|
+
const void* key,
|
|
463
|
+
size_t keylen,
|
|
464
|
+
uint64_t delta,
|
|
465
|
+
uint64_t initial,
|
|
466
|
+
uint32_t exptime)
|
|
467
|
+
{
|
|
468
|
+
memset(cmd, 0, sizeof (cmd->incr));
|
|
469
|
+
cmd->incr.message.header.request.magic= PROTOCOL_BINARY_REQ;
|
|
470
|
+
cmd->incr.message.header.request.opcode= cc;
|
|
471
|
+
cmd->incr.message.header.request.keylen= (uint16_t)keylen;
|
|
472
|
+
cmd->incr.message.header.request.extlen= 20;
|
|
473
|
+
cmd->incr.message.header.request.bodylen= (uint32_t)(keylen + 20);
|
|
474
|
+
cmd->incr.message.header.request.opaque= 0xdeadbeef;
|
|
475
|
+
cmd->incr.message.body.delta= memcached_htonll(delta);
|
|
476
|
+
cmd->incr.message.body.initial= memcached_htonll(initial);
|
|
477
|
+
cmd->incr.message.body.expiration= htonl(exptime);
|
|
478
|
+
|
|
479
|
+
off_t key_offset= sizeof (protocol_binary_request_no_extras) + 20;
|
|
480
|
+
memcpy(cmd->bytes + key_offset, key, keylen);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Validate the response header from the server
|
|
485
|
+
* @param rsp the response to check
|
|
486
|
+
* @param cc the expected command
|
|
487
|
+
* @param status the expected status
|
|
488
|
+
*/
|
|
489
|
+
static enum test_return do_validate_response_header(response *rsp,
|
|
490
|
+
uint8_t cc, uint16_t status)
|
|
491
|
+
{
|
|
492
|
+
verify(rsp->plain.message.header.response.magic == PROTOCOL_BINARY_RES);
|
|
493
|
+
verify(rsp->plain.message.header.response.opcode == cc);
|
|
494
|
+
verify(rsp->plain.message.header.response.datatype == PROTOCOL_BINARY_RAW_BYTES);
|
|
495
|
+
verify(rsp->plain.message.header.response.status == status);
|
|
496
|
+
verify(rsp->plain.message.header.response.opaque == 0xdeadbeef);
|
|
497
|
+
|
|
498
|
+
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS)
|
|
499
|
+
{
|
|
500
|
+
switch (cc) {
|
|
501
|
+
case PROTOCOL_BINARY_CMD_ADDQ:
|
|
502
|
+
case PROTOCOL_BINARY_CMD_APPENDQ:
|
|
503
|
+
case PROTOCOL_BINARY_CMD_DECREMENTQ:
|
|
504
|
+
case PROTOCOL_BINARY_CMD_DELETEQ:
|
|
505
|
+
case PROTOCOL_BINARY_CMD_FLUSHQ:
|
|
506
|
+
case PROTOCOL_BINARY_CMD_INCREMENTQ:
|
|
507
|
+
case PROTOCOL_BINARY_CMD_PREPENDQ:
|
|
508
|
+
case PROTOCOL_BINARY_CMD_QUITQ:
|
|
509
|
+
case PROTOCOL_BINARY_CMD_REPLACEQ:
|
|
510
|
+
case PROTOCOL_BINARY_CMD_SETQ:
|
|
511
|
+
verify("Quiet command shouldn't return on success" == NULL);
|
|
512
|
+
default:
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
switch (cc) {
|
|
517
|
+
case PROTOCOL_BINARY_CMD_ADD:
|
|
518
|
+
case PROTOCOL_BINARY_CMD_REPLACE:
|
|
519
|
+
case PROTOCOL_BINARY_CMD_SET:
|
|
520
|
+
case PROTOCOL_BINARY_CMD_APPEND:
|
|
521
|
+
case PROTOCOL_BINARY_CMD_PREPEND:
|
|
522
|
+
verify(rsp->plain.message.header.response.keylen == 0);
|
|
523
|
+
verify(rsp->plain.message.header.response.extlen == 0);
|
|
524
|
+
verify(rsp->plain.message.header.response.bodylen == 0);
|
|
525
|
+
verify(rsp->plain.message.header.response.cas != 0);
|
|
526
|
+
break;
|
|
527
|
+
case PROTOCOL_BINARY_CMD_FLUSH:
|
|
528
|
+
case PROTOCOL_BINARY_CMD_NOOP:
|
|
529
|
+
case PROTOCOL_BINARY_CMD_QUIT:
|
|
530
|
+
case PROTOCOL_BINARY_CMD_DELETE:
|
|
531
|
+
verify(rsp->plain.message.header.response.keylen == 0);
|
|
532
|
+
verify(rsp->plain.message.header.response.extlen == 0);
|
|
533
|
+
verify(rsp->plain.message.header.response.bodylen == 0);
|
|
534
|
+
verify(rsp->plain.message.header.response.cas == 0);
|
|
535
|
+
break;
|
|
536
|
+
|
|
537
|
+
case PROTOCOL_BINARY_CMD_DECREMENT:
|
|
538
|
+
case PROTOCOL_BINARY_CMD_INCREMENT:
|
|
539
|
+
verify(rsp->plain.message.header.response.keylen == 0);
|
|
540
|
+
verify(rsp->plain.message.header.response.extlen == 0);
|
|
541
|
+
verify(rsp->plain.message.header.response.bodylen == 8);
|
|
542
|
+
verify(rsp->plain.message.header.response.cas != 0);
|
|
543
|
+
break;
|
|
544
|
+
|
|
545
|
+
case PROTOCOL_BINARY_CMD_STAT:
|
|
546
|
+
verify(rsp->plain.message.header.response.extlen == 0);
|
|
547
|
+
/* key and value exists in all packets except in the terminating */
|
|
548
|
+
verify(rsp->plain.message.header.response.cas == 0);
|
|
549
|
+
break;
|
|
550
|
+
|
|
551
|
+
case PROTOCOL_BINARY_CMD_VERSION:
|
|
552
|
+
verify(rsp->plain.message.header.response.keylen == 0);
|
|
553
|
+
verify(rsp->plain.message.header.response.extlen == 0);
|
|
554
|
+
verify(rsp->plain.message.header.response.bodylen != 0);
|
|
555
|
+
verify(rsp->plain.message.header.response.cas == 0);
|
|
556
|
+
break;
|
|
557
|
+
|
|
558
|
+
case PROTOCOL_BINARY_CMD_GET:
|
|
559
|
+
case PROTOCOL_BINARY_CMD_GETQ:
|
|
560
|
+
verify(rsp->plain.message.header.response.keylen == 0);
|
|
561
|
+
verify(rsp->plain.message.header.response.extlen == 4);
|
|
562
|
+
verify(rsp->plain.message.header.response.cas != 0);
|
|
563
|
+
break;
|
|
564
|
+
|
|
565
|
+
case PROTOCOL_BINARY_CMD_GETK:
|
|
566
|
+
case PROTOCOL_BINARY_CMD_GETKQ:
|
|
567
|
+
verify(rsp->plain.message.header.response.keylen != 0);
|
|
568
|
+
verify(rsp->plain.message.header.response.extlen == 4);
|
|
569
|
+
verify(rsp->plain.message.header.response.cas != 0);
|
|
570
|
+
break;
|
|
571
|
+
|
|
572
|
+
default:
|
|
573
|
+
/* Undefined command code */
|
|
574
|
+
break;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
else
|
|
578
|
+
{
|
|
579
|
+
verify(rsp->plain.message.header.response.cas == 0);
|
|
580
|
+
verify(rsp->plain.message.header.response.extlen == 0);
|
|
581
|
+
if (cc != PROTOCOL_BINARY_CMD_GETK)
|
|
582
|
+
{
|
|
583
|
+
verify(rsp->plain.message.header.response.keylen == 0);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
return TEST_PASS;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/* We call verify(validate_response_header), but that macro
|
|
591
|
+
* expects a boolean expression, and the function returns
|
|
592
|
+
* an enum.... Let's just create a macro to avoid cluttering
|
|
593
|
+
* the code with all of the == TEST_PASS ;-)
|
|
594
|
+
*/
|
|
595
|
+
#define validate_response_header(a,b,c) \
|
|
596
|
+
do_validate_response_header(a,b,c) == TEST_PASS
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
static enum test_return send_binary_noop(void)
|
|
600
|
+
{
|
|
601
|
+
command cmd;
|
|
602
|
+
raw_command(&cmd, PROTOCOL_BINARY_CMD_NOOP, NULL, 0, NULL, 0);
|
|
603
|
+
execute(send_packet(&cmd));
|
|
604
|
+
return TEST_PASS;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
static enum test_return receive_binary_noop(void)
|
|
608
|
+
{
|
|
609
|
+
response rsp;
|
|
610
|
+
execute(recv_packet(&rsp));
|
|
611
|
+
verify(validate_response_header(&rsp, PROTOCOL_BINARY_CMD_NOOP,
|
|
612
|
+
PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
613
|
+
return TEST_PASS;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
static enum test_return test_binary_noop(void)
|
|
617
|
+
{
|
|
618
|
+
execute(send_binary_noop());
|
|
619
|
+
execute(receive_binary_noop());
|
|
620
|
+
return TEST_PASS;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
static enum test_return test_binary_quit_impl(uint8_t cc)
|
|
624
|
+
{
|
|
625
|
+
command cmd;
|
|
626
|
+
response rsp;
|
|
627
|
+
raw_command(&cmd, cc, NULL, 0, NULL, 0);
|
|
628
|
+
|
|
629
|
+
execute(send_packet(&cmd));
|
|
630
|
+
if (cc == PROTOCOL_BINARY_CMD_QUIT)
|
|
631
|
+
{
|
|
632
|
+
execute(recv_packet(&rsp));
|
|
633
|
+
verify(validate_response_header(&rsp, PROTOCOL_BINARY_CMD_QUIT,
|
|
634
|
+
PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/* Socket should be closed now, read should return EXIT_SUCCESS */
|
|
638
|
+
verify(timeout_io_op(sock, POLLIN, rsp.bytes, sizeof(rsp.bytes)) == 0);
|
|
639
|
+
|
|
640
|
+
return TEST_PASS_RECONNECT;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
static enum test_return test_binary_quit(void)
|
|
644
|
+
{
|
|
645
|
+
return test_binary_quit_impl(PROTOCOL_BINARY_CMD_QUIT);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
static enum test_return test_binary_quitq(void)
|
|
649
|
+
{
|
|
650
|
+
return test_binary_quit_impl(PROTOCOL_BINARY_CMD_QUITQ);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
static enum test_return test_binary_set_impl(const char* key, uint8_t cc)
|
|
654
|
+
{
|
|
655
|
+
command cmd;
|
|
656
|
+
response rsp;
|
|
657
|
+
|
|
658
|
+
uint64_t value= 0xdeadbeefdeadcafeULL;
|
|
659
|
+
storage_command(&cmd, cc, key, strlen(key), &value, sizeof (value), 0, 0);
|
|
660
|
+
|
|
661
|
+
/* set should always work */
|
|
662
|
+
for (int ii= 0; ii < 10; ii++)
|
|
663
|
+
{
|
|
664
|
+
if (ii == 0)
|
|
665
|
+
execute(send_packet(&cmd));
|
|
666
|
+
else
|
|
667
|
+
execute(resend_packet(&cmd));
|
|
668
|
+
|
|
669
|
+
if (cc == PROTOCOL_BINARY_CMD_SET)
|
|
670
|
+
{
|
|
671
|
+
execute(recv_packet(&rsp));
|
|
672
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
673
|
+
}
|
|
674
|
+
else
|
|
675
|
+
execute(test_binary_noop());
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/*
|
|
679
|
+
* We need to get the current CAS id, and at this time we haven't
|
|
680
|
+
* verified that we have a working get
|
|
681
|
+
*/
|
|
682
|
+
if (cc == PROTOCOL_BINARY_CMD_SETQ)
|
|
683
|
+
{
|
|
684
|
+
cmd.set.message.header.request.opcode= PROTOCOL_BINARY_CMD_SET;
|
|
685
|
+
execute(resend_packet(&cmd));
|
|
686
|
+
execute(recv_packet(&rsp));
|
|
687
|
+
verify(validate_response_header(&rsp, PROTOCOL_BINARY_CMD_SET,
|
|
688
|
+
PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
689
|
+
cmd.set.message.header.request.opcode= PROTOCOL_BINARY_CMD_SETQ;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/* try to set with the correct CAS value */
|
|
693
|
+
cmd.plain.message.header.request.cas= memcached_htonll(rsp.plain.message.header.response.cas);
|
|
694
|
+
execute(resend_packet(&cmd));
|
|
695
|
+
if (cc == PROTOCOL_BINARY_CMD_SET)
|
|
696
|
+
{
|
|
697
|
+
execute(recv_packet(&rsp));
|
|
698
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
699
|
+
}
|
|
700
|
+
else
|
|
701
|
+
execute(test_binary_noop());
|
|
702
|
+
|
|
703
|
+
/* try to set with an incorrect CAS value */
|
|
704
|
+
cmd.plain.message.header.request.cas= memcached_htonll(rsp.plain.message.header.response.cas - 1);
|
|
705
|
+
execute(resend_packet(&cmd));
|
|
706
|
+
execute(send_binary_noop());
|
|
707
|
+
execute(recv_packet(&rsp));
|
|
708
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS));
|
|
709
|
+
execute(receive_binary_noop());
|
|
710
|
+
|
|
711
|
+
return TEST_PASS;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
static enum test_return test_binary_set(void)
|
|
715
|
+
{
|
|
716
|
+
return test_binary_set_impl("test_binary_set", PROTOCOL_BINARY_CMD_SET);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
static enum test_return test_binary_setq(void)
|
|
720
|
+
{
|
|
721
|
+
return test_binary_set_impl("test_binary_setq", PROTOCOL_BINARY_CMD_SETQ);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
static enum test_return test_binary_add_impl(const char* key, uint8_t cc)
|
|
725
|
+
{
|
|
726
|
+
command cmd;
|
|
727
|
+
response rsp;
|
|
728
|
+
uint64_t value= 0xdeadbeefdeadcafeULL;
|
|
729
|
+
storage_command(&cmd, cc, key, strlen(key), &value, sizeof (value), 0, 0);
|
|
730
|
+
|
|
731
|
+
/* first add should work, rest of them should fail (even with cas
|
|
732
|
+
as wildcard */
|
|
733
|
+
for (int ii=0; ii < 10; ii++)
|
|
734
|
+
{
|
|
735
|
+
if (ii == 0)
|
|
736
|
+
execute(send_packet(&cmd));
|
|
737
|
+
else
|
|
738
|
+
execute(resend_packet(&cmd));
|
|
739
|
+
|
|
740
|
+
if (cc == PROTOCOL_BINARY_CMD_ADD || ii > 0)
|
|
741
|
+
{
|
|
742
|
+
uint16_t expected_result;
|
|
743
|
+
if (ii == 0)
|
|
744
|
+
expected_result= PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
745
|
+
else
|
|
746
|
+
expected_result= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
|
|
747
|
+
|
|
748
|
+
execute(send_binary_noop());
|
|
749
|
+
execute(recv_packet(&rsp));
|
|
750
|
+
execute(receive_binary_noop());
|
|
751
|
+
verify(validate_response_header(&rsp, cc, expected_result));
|
|
752
|
+
}
|
|
753
|
+
else
|
|
754
|
+
execute(test_binary_noop());
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
return TEST_PASS;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
static enum test_return test_binary_add(void)
|
|
761
|
+
{
|
|
762
|
+
return test_binary_add_impl("test_binary_add", PROTOCOL_BINARY_CMD_ADD);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
static enum test_return test_binary_addq(void)
|
|
766
|
+
{
|
|
767
|
+
return test_binary_add_impl("test_binary_addq", PROTOCOL_BINARY_CMD_ADDQ);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
static enum test_return binary_set_item(const char *key, const char *value)
|
|
771
|
+
{
|
|
772
|
+
command cmd;
|
|
773
|
+
response rsp;
|
|
774
|
+
storage_command(&cmd, PROTOCOL_BINARY_CMD_SET, key, strlen(key),
|
|
775
|
+
value, strlen(value), 0, 0);
|
|
776
|
+
execute(send_packet(&cmd));
|
|
777
|
+
execute(recv_packet(&rsp));
|
|
778
|
+
verify(validate_response_header(&rsp, PROTOCOL_BINARY_CMD_SET,
|
|
779
|
+
PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
780
|
+
return TEST_PASS;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
static enum test_return test_binary_replace_impl(const char* key, uint8_t cc)
|
|
784
|
+
{
|
|
785
|
+
command cmd;
|
|
786
|
+
response rsp;
|
|
787
|
+
uint64_t value= 0xdeadbeefdeadcafeULL;
|
|
788
|
+
storage_command(&cmd, cc, key, strlen(key), &value, sizeof (value), 0, 0);
|
|
789
|
+
|
|
790
|
+
/* first replace should fail, successive should succeed (when the
|
|
791
|
+
item is added! */
|
|
792
|
+
for (int ii= 0; ii < 10; ii++)
|
|
793
|
+
{
|
|
794
|
+
if (ii == 0)
|
|
795
|
+
execute(send_packet(&cmd));
|
|
796
|
+
else
|
|
797
|
+
execute(resend_packet(&cmd));
|
|
798
|
+
|
|
799
|
+
if (cc == PROTOCOL_BINARY_CMD_REPLACE || ii == 0)
|
|
800
|
+
{
|
|
801
|
+
uint16_t expected_result;
|
|
802
|
+
if (ii == 0)
|
|
803
|
+
expected_result=PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
|
|
804
|
+
else
|
|
805
|
+
expected_result=PROTOCOL_BINARY_RESPONSE_SUCCESS;
|
|
806
|
+
|
|
807
|
+
execute(send_binary_noop());
|
|
808
|
+
execute(recv_packet(&rsp));
|
|
809
|
+
execute(receive_binary_noop());
|
|
810
|
+
verify(validate_response_header(&rsp, cc, expected_result));
|
|
811
|
+
|
|
812
|
+
if (ii == 0)
|
|
813
|
+
execute(binary_set_item(key, key));
|
|
814
|
+
}
|
|
815
|
+
else
|
|
816
|
+
execute(test_binary_noop());
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/* verify that replace with CAS value works! */
|
|
820
|
+
cmd.plain.message.header.request.cas= memcached_htonll(rsp.plain.message.header.response.cas);
|
|
821
|
+
execute(resend_packet(&cmd));
|
|
822
|
+
|
|
823
|
+
if (cc == PROTOCOL_BINARY_CMD_REPLACE)
|
|
824
|
+
{
|
|
825
|
+
execute(recv_packet(&rsp));
|
|
826
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
827
|
+
}
|
|
828
|
+
else
|
|
829
|
+
execute(test_binary_noop());
|
|
830
|
+
|
|
831
|
+
/* try to set with an incorrect CAS value */
|
|
832
|
+
cmd.plain.message.header.request.cas= memcached_htonll(rsp.plain.message.header.response.cas - 1);
|
|
833
|
+
execute(resend_packet(&cmd));
|
|
834
|
+
execute(send_binary_noop());
|
|
835
|
+
execute(recv_packet(&rsp));
|
|
836
|
+
execute(receive_binary_noop());
|
|
837
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS));
|
|
838
|
+
|
|
839
|
+
return TEST_PASS;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
static enum test_return test_binary_replace(void)
|
|
843
|
+
{
|
|
844
|
+
return test_binary_replace_impl("test_binary_replace", PROTOCOL_BINARY_CMD_REPLACE);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
static enum test_return test_binary_replaceq(void)
|
|
848
|
+
{
|
|
849
|
+
return test_binary_replace_impl("test_binary_replaceq", PROTOCOL_BINARY_CMD_REPLACEQ);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
static enum test_return test_binary_delete_impl(const char *key, uint8_t cc)
|
|
853
|
+
{
|
|
854
|
+
command cmd;
|
|
855
|
+
response rsp;
|
|
856
|
+
raw_command(&cmd, cc, key, strlen(key), NULL, 0);
|
|
857
|
+
|
|
858
|
+
/* The delete shouldn't work the first time, because the item isn't there */
|
|
859
|
+
execute(send_packet(&cmd));
|
|
860
|
+
execute(send_binary_noop());
|
|
861
|
+
execute(recv_packet(&rsp));
|
|
862
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT));
|
|
863
|
+
execute(receive_binary_noop());
|
|
864
|
+
execute(binary_set_item(key, key));
|
|
865
|
+
|
|
866
|
+
/* The item should be present now, resend*/
|
|
867
|
+
execute(resend_packet(&cmd));
|
|
868
|
+
if (cc == PROTOCOL_BINARY_CMD_DELETE)
|
|
869
|
+
{
|
|
870
|
+
execute(recv_packet(&rsp));
|
|
871
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
execute(test_binary_noop());
|
|
875
|
+
|
|
876
|
+
return TEST_PASS;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
static enum test_return test_binary_delete(void)
|
|
880
|
+
{
|
|
881
|
+
return test_binary_delete_impl("test_binary_delete", PROTOCOL_BINARY_CMD_DELETE);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
static enum test_return test_binary_deleteq(void)
|
|
885
|
+
{
|
|
886
|
+
return test_binary_delete_impl("test_binary_deleteq", PROTOCOL_BINARY_CMD_DELETEQ);
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
static enum test_return test_binary_get_impl(const char *key, uint8_t cc)
|
|
890
|
+
{
|
|
891
|
+
command cmd;
|
|
892
|
+
response rsp;
|
|
893
|
+
|
|
894
|
+
raw_command(&cmd, cc, key, strlen(key), NULL, 0);
|
|
895
|
+
execute(send_packet(&cmd));
|
|
896
|
+
execute(send_binary_noop());
|
|
897
|
+
|
|
898
|
+
if (cc == PROTOCOL_BINARY_CMD_GET || cc == PROTOCOL_BINARY_CMD_GETK)
|
|
899
|
+
{
|
|
900
|
+
execute(recv_packet(&rsp));
|
|
901
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT));
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
execute(receive_binary_noop());
|
|
905
|
+
|
|
906
|
+
execute(binary_set_item(key, key));
|
|
907
|
+
execute(resend_packet(&cmd));
|
|
908
|
+
execute(send_binary_noop());
|
|
909
|
+
|
|
910
|
+
execute(recv_packet(&rsp));
|
|
911
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
912
|
+
execute(receive_binary_noop());
|
|
913
|
+
|
|
914
|
+
return TEST_PASS;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
static enum test_return test_binary_get(void)
|
|
918
|
+
{
|
|
919
|
+
return test_binary_get_impl("test_binary_get", PROTOCOL_BINARY_CMD_GET);
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
static enum test_return test_binary_getk(void)
|
|
923
|
+
{
|
|
924
|
+
return test_binary_get_impl("test_binary_getk", PROTOCOL_BINARY_CMD_GETK);
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
static enum test_return test_binary_getq(void)
|
|
928
|
+
{
|
|
929
|
+
return test_binary_get_impl("test_binary_getq", PROTOCOL_BINARY_CMD_GETQ);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
static enum test_return test_binary_getkq(void)
|
|
933
|
+
{
|
|
934
|
+
return test_binary_get_impl("test_binary_getkq", PROTOCOL_BINARY_CMD_GETKQ);
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
static enum test_return test_binary_incr_impl(const char* key, uint8_t cc)
|
|
938
|
+
{
|
|
939
|
+
command cmd;
|
|
940
|
+
response rsp;
|
|
941
|
+
arithmetic_command(&cmd, cc, key, strlen(key), 1, 0, 0);
|
|
942
|
+
|
|
943
|
+
uint64_t ii;
|
|
944
|
+
for (ii= 0; ii < 10; ++ii)
|
|
945
|
+
{
|
|
946
|
+
if (ii == 0)
|
|
947
|
+
execute(send_packet(&cmd));
|
|
948
|
+
else
|
|
949
|
+
execute(resend_packet(&cmd));
|
|
950
|
+
|
|
951
|
+
if (cc == PROTOCOL_BINARY_CMD_INCREMENT)
|
|
952
|
+
{
|
|
953
|
+
execute(recv_packet(&rsp));
|
|
954
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
955
|
+
verify(memcached_ntohll(rsp.incr.message.body.value) == ii);
|
|
956
|
+
}
|
|
957
|
+
else
|
|
958
|
+
execute(test_binary_noop());
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
/* @todo add incorrect CAS */
|
|
962
|
+
return TEST_PASS;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
static enum test_return test_binary_incr(void)
|
|
966
|
+
{
|
|
967
|
+
return test_binary_incr_impl("test_binary_incr", PROTOCOL_BINARY_CMD_INCREMENT);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
static enum test_return test_binary_incrq(void)
|
|
971
|
+
{
|
|
972
|
+
return test_binary_incr_impl("test_binary_incrq", PROTOCOL_BINARY_CMD_INCREMENTQ);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
static enum test_return test_binary_decr_impl(const char* key, uint8_t cc)
|
|
976
|
+
{
|
|
977
|
+
command cmd;
|
|
978
|
+
response rsp;
|
|
979
|
+
arithmetic_command(&cmd, cc, key, strlen(key), 1, 9, 0);
|
|
980
|
+
|
|
981
|
+
int ii;
|
|
982
|
+
for (ii= 9; ii > -1; --ii)
|
|
983
|
+
{
|
|
984
|
+
if (ii == 9)
|
|
985
|
+
execute(send_packet(&cmd));
|
|
986
|
+
else
|
|
987
|
+
execute(resend_packet(&cmd));
|
|
988
|
+
|
|
989
|
+
if (cc == PROTOCOL_BINARY_CMD_DECREMENT)
|
|
990
|
+
{
|
|
991
|
+
execute(recv_packet(&rsp));
|
|
992
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
993
|
+
verify(memcached_ntohll(rsp.decr.message.body.value) == (uint64_t)ii);
|
|
994
|
+
}
|
|
995
|
+
else
|
|
996
|
+
execute(test_binary_noop());
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
/* decr 0 should not wrap */
|
|
1000
|
+
execute(resend_packet(&cmd));
|
|
1001
|
+
if (cc == PROTOCOL_BINARY_CMD_DECREMENT)
|
|
1002
|
+
{
|
|
1003
|
+
execute(recv_packet(&rsp));
|
|
1004
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
1005
|
+
verify(memcached_ntohll(rsp.decr.message.body.value) == 0);
|
|
1006
|
+
}
|
|
1007
|
+
else
|
|
1008
|
+
{
|
|
1009
|
+
/* @todo get the value and verify! */
|
|
1010
|
+
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
/* @todo add incorrect cas */
|
|
1014
|
+
execute(test_binary_noop());
|
|
1015
|
+
return TEST_PASS;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
static enum test_return test_binary_decr(void)
|
|
1019
|
+
{
|
|
1020
|
+
return test_binary_decr_impl("test_binary_decr",
|
|
1021
|
+
PROTOCOL_BINARY_CMD_DECREMENT);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
static enum test_return test_binary_decrq(void)
|
|
1025
|
+
{
|
|
1026
|
+
return test_binary_decr_impl("test_binary_decrq",
|
|
1027
|
+
PROTOCOL_BINARY_CMD_DECREMENTQ);
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
static enum test_return test_binary_version(void)
|
|
1031
|
+
{
|
|
1032
|
+
command cmd;
|
|
1033
|
+
response rsp;
|
|
1034
|
+
raw_command(&cmd, PROTOCOL_BINARY_CMD_VERSION, NULL, 0, NULL, 0);
|
|
1035
|
+
|
|
1036
|
+
execute(send_packet(&cmd));
|
|
1037
|
+
execute(recv_packet(&rsp));
|
|
1038
|
+
verify(validate_response_header(&rsp, PROTOCOL_BINARY_CMD_VERSION,
|
|
1039
|
+
PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
1040
|
+
|
|
1041
|
+
return TEST_PASS;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
static enum test_return test_binary_flush_impl(const char *key, uint8_t cc)
|
|
1045
|
+
{
|
|
1046
|
+
command cmd;
|
|
1047
|
+
response rsp;
|
|
1048
|
+
|
|
1049
|
+
for (int ii= 0; ii < 2; ++ii)
|
|
1050
|
+
{
|
|
1051
|
+
execute(binary_set_item(key, key));
|
|
1052
|
+
flush_command(&cmd, cc, 0, ii == 0);
|
|
1053
|
+
execute(send_packet(&cmd));
|
|
1054
|
+
|
|
1055
|
+
if (cc == PROTOCOL_BINARY_CMD_FLUSH)
|
|
1056
|
+
{
|
|
1057
|
+
execute(recv_packet(&rsp));
|
|
1058
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
1059
|
+
}
|
|
1060
|
+
else
|
|
1061
|
+
execute(test_binary_noop());
|
|
1062
|
+
|
|
1063
|
+
raw_command(&cmd, PROTOCOL_BINARY_CMD_GET, key, strlen(key), NULL, 0);
|
|
1064
|
+
execute(send_packet(&cmd));
|
|
1065
|
+
execute(recv_packet(&rsp));
|
|
1066
|
+
verify(validate_response_header(&rsp, PROTOCOL_BINARY_CMD_GET,
|
|
1067
|
+
PROTOCOL_BINARY_RESPONSE_KEY_ENOENT));
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
return TEST_PASS;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
static enum test_return test_binary_flush(void)
|
|
1074
|
+
{
|
|
1075
|
+
return test_binary_flush_impl("test_binary_flush", PROTOCOL_BINARY_CMD_FLUSH);
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
static enum test_return test_binary_flushq(void)
|
|
1079
|
+
{
|
|
1080
|
+
return test_binary_flush_impl("test_binary_flushq", PROTOCOL_BINARY_CMD_FLUSHQ);
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
static enum test_return test_binary_concat_impl(const char *key, uint8_t cc)
|
|
1084
|
+
{
|
|
1085
|
+
command cmd;
|
|
1086
|
+
response rsp;
|
|
1087
|
+
const char *value;
|
|
1088
|
+
|
|
1089
|
+
if (cc == PROTOCOL_BINARY_CMD_APPEND || cc == PROTOCOL_BINARY_CMD_APPENDQ)
|
|
1090
|
+
value="hello";
|
|
1091
|
+
else
|
|
1092
|
+
value=" world";
|
|
1093
|
+
|
|
1094
|
+
execute(binary_set_item(key, value));
|
|
1095
|
+
|
|
1096
|
+
if (cc == PROTOCOL_BINARY_CMD_APPEND || cc == PROTOCOL_BINARY_CMD_APPENDQ)
|
|
1097
|
+
value=" world";
|
|
1098
|
+
else
|
|
1099
|
+
value="hello";
|
|
1100
|
+
|
|
1101
|
+
raw_command(&cmd, cc, key, strlen(key), value, strlen(value));
|
|
1102
|
+
execute(send_packet(&cmd));
|
|
1103
|
+
if (cc == PROTOCOL_BINARY_CMD_APPEND || cc == PROTOCOL_BINARY_CMD_PREPEND)
|
|
1104
|
+
{
|
|
1105
|
+
execute(recv_packet(&rsp));
|
|
1106
|
+
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
1107
|
+
}
|
|
1108
|
+
else
|
|
1109
|
+
execute(test_binary_noop());
|
|
1110
|
+
|
|
1111
|
+
raw_command(&cmd, PROTOCOL_BINARY_CMD_GET, key, strlen(key), NULL, 0);
|
|
1112
|
+
execute(send_packet(&cmd));
|
|
1113
|
+
execute(recv_packet(&rsp));
|
|
1114
|
+
verify(validate_response_header(&rsp, PROTOCOL_BINARY_CMD_GET,
|
|
1115
|
+
PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
1116
|
+
verify(rsp.plain.message.header.response.bodylen - 4 == 11);
|
|
1117
|
+
verify(memcmp(rsp.bytes + 28, "hello world", 11) == 0);
|
|
1118
|
+
|
|
1119
|
+
return TEST_PASS;
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
static enum test_return test_binary_append(void)
|
|
1123
|
+
{
|
|
1124
|
+
return test_binary_concat_impl("test_binary_append", PROTOCOL_BINARY_CMD_APPEND);
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
static enum test_return test_binary_prepend(void)
|
|
1128
|
+
{
|
|
1129
|
+
return test_binary_concat_impl("test_binary_prepend", PROTOCOL_BINARY_CMD_PREPEND);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
static enum test_return test_binary_appendq(void)
|
|
1133
|
+
{
|
|
1134
|
+
return test_binary_concat_impl("test_binary_appendq", PROTOCOL_BINARY_CMD_APPENDQ);
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
static enum test_return test_binary_prependq(void)
|
|
1138
|
+
{
|
|
1139
|
+
return test_binary_concat_impl("test_binary_prependq", PROTOCOL_BINARY_CMD_PREPENDQ);
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
static enum test_return test_binary_stat(void)
|
|
1143
|
+
{
|
|
1144
|
+
command cmd;
|
|
1145
|
+
response rsp;
|
|
1146
|
+
|
|
1147
|
+
raw_command(&cmd, PROTOCOL_BINARY_CMD_STAT, NULL, 0, NULL, 0);
|
|
1148
|
+
execute(send_packet(&cmd));
|
|
1149
|
+
|
|
1150
|
+
do
|
|
1151
|
+
{
|
|
1152
|
+
execute(recv_packet(&rsp));
|
|
1153
|
+
verify(validate_response_header(&rsp, PROTOCOL_BINARY_CMD_STAT,
|
|
1154
|
+
PROTOCOL_BINARY_RESPONSE_SUCCESS));
|
|
1155
|
+
} while (rsp.plain.message.header.response.keylen != 0);
|
|
1156
|
+
|
|
1157
|
+
return TEST_PASS;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
static enum test_return send_string(const char *cmd)
|
|
1161
|
+
{
|
|
1162
|
+
execute(retry_write(cmd, strlen(cmd)));
|
|
1163
|
+
return TEST_PASS;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
static enum test_return receive_line(char *buffer, size_t size)
|
|
1167
|
+
{
|
|
1168
|
+
size_t offset= 0;
|
|
1169
|
+
while (offset < size)
|
|
1170
|
+
{
|
|
1171
|
+
execute(retry_read(buffer + offset, 1));
|
|
1172
|
+
if (buffer[offset] == '\n')
|
|
1173
|
+
{
|
|
1174
|
+
if (offset + 1 < size)
|
|
1175
|
+
{
|
|
1176
|
+
buffer[offset + 1]= '\0';
|
|
1177
|
+
return TEST_PASS;
|
|
1178
|
+
}
|
|
1179
|
+
else
|
|
1180
|
+
return TEST_FAIL;
|
|
1181
|
+
}
|
|
1182
|
+
++offset;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
return TEST_FAIL;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
static enum test_return receive_response(const char *msg) {
|
|
1189
|
+
char buffer[80];
|
|
1190
|
+
execute(receive_line(buffer, sizeof(buffer)));
|
|
1191
|
+
if (strcmp(msg, buffer) != 0) {
|
|
1192
|
+
fprintf(stderr, "[%s]\n", buffer);
|
|
1193
|
+
}
|
|
1194
|
+
verify(strcmp(msg, buffer) == 0);
|
|
1195
|
+
return TEST_PASS;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
static enum test_return receive_error_response(void)
|
|
1199
|
+
{
|
|
1200
|
+
char buffer[80];
|
|
1201
|
+
execute(receive_line(buffer, sizeof(buffer)));
|
|
1202
|
+
verify(strncmp(buffer, "ERROR", 5) == 0 ||
|
|
1203
|
+
strncmp(buffer, "CLIENT_ERROR", 12) == 0 ||
|
|
1204
|
+
strncmp(buffer, "SERVER_ERROR", 12) == 0);
|
|
1205
|
+
return TEST_PASS;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
static enum test_return test_ascii_quit(void)
|
|
1209
|
+
{
|
|
1210
|
+
/* Verify that quit handles unknown options */
|
|
1211
|
+
execute(send_string("quit foo bar\r\n"));
|
|
1212
|
+
execute(receive_error_response());
|
|
1213
|
+
|
|
1214
|
+
/* quit doesn't support noreply */
|
|
1215
|
+
execute(send_string("quit noreply\r\n"));
|
|
1216
|
+
execute(receive_error_response());
|
|
1217
|
+
|
|
1218
|
+
/* Verify that quit works */
|
|
1219
|
+
execute(send_string("quit\r\n"));
|
|
1220
|
+
|
|
1221
|
+
/* Socket should be closed now, read should return EXIT_SUCCESS */
|
|
1222
|
+
char buffer[80];
|
|
1223
|
+
verify(timeout_io_op(sock, POLLIN, buffer, sizeof(buffer)) == 0);
|
|
1224
|
+
return TEST_PASS_RECONNECT;
|
|
1225
|
+
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
static enum test_return test_ascii_version(void)
|
|
1229
|
+
{
|
|
1230
|
+
/* Verify that version command handles unknown options */
|
|
1231
|
+
execute(send_string("version foo bar\r\n"));
|
|
1232
|
+
execute(receive_error_response());
|
|
1233
|
+
|
|
1234
|
+
/* version doesn't support noreply */
|
|
1235
|
+
execute(send_string("version noreply\r\n"));
|
|
1236
|
+
execute(receive_error_response());
|
|
1237
|
+
|
|
1238
|
+
/* Verify that verify works */
|
|
1239
|
+
execute(send_string("version\r\n"));
|
|
1240
|
+
char buffer[256];
|
|
1241
|
+
execute(receive_line(buffer, sizeof(buffer)));
|
|
1242
|
+
verify(strncmp(buffer, "VERSION ", 8) == 0);
|
|
1243
|
+
|
|
1244
|
+
return TEST_PASS;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
static enum test_return test_ascii_verbosity(void)
|
|
1248
|
+
{
|
|
1249
|
+
/* This command does not adhere to the spec! */
|
|
1250
|
+
execute(send_string("verbosity foo bar my\r\n"));
|
|
1251
|
+
execute(receive_error_response());
|
|
1252
|
+
|
|
1253
|
+
execute(send_string("verbosity noreply\r\n"));
|
|
1254
|
+
execute(receive_error_response());
|
|
1255
|
+
|
|
1256
|
+
execute(send_string("verbosity 0 noreply\r\n"));
|
|
1257
|
+
execute(test_ascii_version());
|
|
1258
|
+
|
|
1259
|
+
execute(send_string("verbosity\r\n"));
|
|
1260
|
+
execute(receive_error_response());
|
|
1261
|
+
|
|
1262
|
+
execute(send_string("verbosity 1\r\n"));
|
|
1263
|
+
execute(receive_response("OK\r\n"));
|
|
1264
|
+
|
|
1265
|
+
execute(send_string("verbosity 0\r\n"));
|
|
1266
|
+
execute(receive_response("OK\r\n"));
|
|
1267
|
+
|
|
1268
|
+
return TEST_PASS;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
|
|
1272
|
+
|
|
1273
|
+
static enum test_return test_ascii_set_impl(const char* key, bool noreply)
|
|
1274
|
+
{
|
|
1275
|
+
/* @todo add tests for bogus format! */
|
|
1276
|
+
char buffer[1024];
|
|
1277
|
+
snprintf(buffer, sizeof(buffer), "set %s 0 0 5%s\r\nvalue\r\n", key, noreply ? " noreply" : "");
|
|
1278
|
+
execute(send_string(buffer));
|
|
1279
|
+
|
|
1280
|
+
if (!noreply)
|
|
1281
|
+
execute(receive_response("STORED\r\n"));
|
|
1282
|
+
|
|
1283
|
+
return test_ascii_version();
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
static enum test_return test_ascii_set(void)
|
|
1287
|
+
{
|
|
1288
|
+
return test_ascii_set_impl("test_ascii_set", false);
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
static enum test_return test_ascii_set_noreply(void)
|
|
1292
|
+
{
|
|
1293
|
+
return test_ascii_set_impl("test_ascii_set_noreply", true);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
static enum test_return test_ascii_add_impl(const char* key, bool noreply)
|
|
1297
|
+
{
|
|
1298
|
+
/* @todo add tests for bogus format! */
|
|
1299
|
+
char buffer[1024];
|
|
1300
|
+
snprintf(buffer, sizeof(buffer), "add %s 0 0 5%s\r\nvalue\r\n", key, noreply ? " noreply" : "");
|
|
1301
|
+
execute(send_string(buffer));
|
|
1302
|
+
|
|
1303
|
+
if (!noreply)
|
|
1304
|
+
execute(receive_response("STORED\r\n"));
|
|
1305
|
+
|
|
1306
|
+
execute(send_string(buffer));
|
|
1307
|
+
|
|
1308
|
+
if (!noreply)
|
|
1309
|
+
execute(receive_response("NOT_STORED\r\n"));
|
|
1310
|
+
|
|
1311
|
+
return test_ascii_version();
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
static enum test_return test_ascii_add(void)
|
|
1315
|
+
{
|
|
1316
|
+
return test_ascii_add_impl("test_ascii_add", false);
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
static enum test_return test_ascii_add_noreply(void)
|
|
1320
|
+
{
|
|
1321
|
+
return test_ascii_add_impl("test_ascii_add_noreply", true);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
static enum test_return ascii_get_unknown_value(char **key, char **value, ssize_t *ndata)
|
|
1325
|
+
{
|
|
1326
|
+
char buffer[1024];
|
|
1327
|
+
|
|
1328
|
+
execute(receive_line(buffer, sizeof(buffer)));
|
|
1329
|
+
verify(strncmp(buffer, "VALUE ", 6) == 0);
|
|
1330
|
+
char *end= strchr(buffer + 6, ' ');
|
|
1331
|
+
verify(end != NULL);
|
|
1332
|
+
*end= '\0';
|
|
1333
|
+
*key= strdup(buffer + 6);
|
|
1334
|
+
verify(*key != NULL);
|
|
1335
|
+
char *ptr= end + 1;
|
|
1336
|
+
|
|
1337
|
+
unsigned long val= strtoul(ptr, &end, 10); /* flags */
|
|
1338
|
+
verify(ptr != end);
|
|
1339
|
+
verify(val == 0);
|
|
1340
|
+
verify(end != NULL);
|
|
1341
|
+
*ndata = (ssize_t)strtoul(end, &end, 10); /* size */
|
|
1342
|
+
verify(ptr != end);
|
|
1343
|
+
verify(end != NULL);
|
|
1344
|
+
while (*end != '\n' && isspace(*end))
|
|
1345
|
+
++end;
|
|
1346
|
+
verify(*end == '\n');
|
|
1347
|
+
|
|
1348
|
+
*value= static_cast<char*>(malloc((size_t)*ndata));
|
|
1349
|
+
verify(*value != NULL);
|
|
1350
|
+
|
|
1351
|
+
execute(retry_read(*value, (size_t)*ndata));
|
|
1352
|
+
|
|
1353
|
+
execute(retry_read(buffer, 2));
|
|
1354
|
+
verify(memcmp(buffer, "\r\n", 2) == 0);
|
|
1355
|
+
|
|
1356
|
+
return TEST_PASS;
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
static enum test_return ascii_get_value(const char *key, const char *value)
|
|
1360
|
+
{
|
|
1361
|
+
|
|
1362
|
+
char buffer[1024];
|
|
1363
|
+
size_t datasize= strlen(value);
|
|
1364
|
+
|
|
1365
|
+
verify(datasize < sizeof(buffer));
|
|
1366
|
+
execute(receive_line(buffer, sizeof(buffer)));
|
|
1367
|
+
verify(strncmp(buffer, "VALUE ", 6) == 0);
|
|
1368
|
+
verify(strncmp(buffer + 6, key, strlen(key)) == 0);
|
|
1369
|
+
char *ptr= buffer + 6 + strlen(key) + 1;
|
|
1370
|
+
char *end;
|
|
1371
|
+
|
|
1372
|
+
unsigned long val= strtoul(ptr, &end, 10); /* flags */
|
|
1373
|
+
verify(ptr != end);
|
|
1374
|
+
verify(val == 0);
|
|
1375
|
+
verify(end != NULL);
|
|
1376
|
+
val= strtoul(end, &end, 10); /* size */
|
|
1377
|
+
verify(ptr != end);
|
|
1378
|
+
verify(val == datasize);
|
|
1379
|
+
verify(end != NULL);
|
|
1380
|
+
while (*end != '\n' && isspace(*end))
|
|
1381
|
+
++end;
|
|
1382
|
+
verify(*end == '\n');
|
|
1383
|
+
|
|
1384
|
+
execute(retry_read(buffer, datasize));
|
|
1385
|
+
verify(memcmp(buffer, value, datasize) == 0);
|
|
1386
|
+
|
|
1387
|
+
execute(retry_read(buffer, 2));
|
|
1388
|
+
verify(memcmp(buffer, "\r\n", 2) == 0);
|
|
1389
|
+
|
|
1390
|
+
return TEST_PASS;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
static enum test_return ascii_get_item(const char *key, const char *value,
|
|
1394
|
+
bool exist)
|
|
1395
|
+
{
|
|
1396
|
+
char buffer[1024];
|
|
1397
|
+
size_t datasize= 0;
|
|
1398
|
+
if (value != NULL)
|
|
1399
|
+
datasize= strlen(value);
|
|
1400
|
+
|
|
1401
|
+
verify(datasize < sizeof(buffer));
|
|
1402
|
+
snprintf(buffer, sizeof(buffer), "get %s\r\n", key);
|
|
1403
|
+
execute(send_string(buffer));
|
|
1404
|
+
|
|
1405
|
+
if (exist)
|
|
1406
|
+
execute(ascii_get_value(key, value));
|
|
1407
|
+
|
|
1408
|
+
execute(retry_read(buffer, 5));
|
|
1409
|
+
verify(memcmp(buffer, "END\r\n", 5) == 0);
|
|
1410
|
+
|
|
1411
|
+
return TEST_PASS;
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
static enum test_return ascii_gets_value(const char *key, const char *value,
|
|
1415
|
+
unsigned long *cas)
|
|
1416
|
+
{
|
|
1417
|
+
|
|
1418
|
+
char buffer[1024];
|
|
1419
|
+
size_t datasize= strlen(value);
|
|
1420
|
+
|
|
1421
|
+
verify(datasize < sizeof(buffer));
|
|
1422
|
+
execute(receive_line(buffer, sizeof(buffer)));
|
|
1423
|
+
verify(strncmp(buffer, "VALUE ", 6) == 0);
|
|
1424
|
+
verify(strncmp(buffer + 6, key, strlen(key)) == 0);
|
|
1425
|
+
char *ptr= buffer + 6 + strlen(key) + 1;
|
|
1426
|
+
char *end;
|
|
1427
|
+
|
|
1428
|
+
unsigned long val= strtoul(ptr, &end, 10); /* flags */
|
|
1429
|
+
verify(ptr != end);
|
|
1430
|
+
verify(val == 0);
|
|
1431
|
+
verify(end != NULL);
|
|
1432
|
+
val= strtoul(end, &end, 10); /* size */
|
|
1433
|
+
verify(ptr != end);
|
|
1434
|
+
verify(val == datasize);
|
|
1435
|
+
verify(end != NULL);
|
|
1436
|
+
*cas= strtoul(end, &end, 10); /* cas */
|
|
1437
|
+
verify(ptr != end);
|
|
1438
|
+
verify(val == datasize);
|
|
1439
|
+
verify(end != NULL);
|
|
1440
|
+
|
|
1441
|
+
while (*end != '\n' && isspace(*end))
|
|
1442
|
+
++end;
|
|
1443
|
+
verify(*end == '\n');
|
|
1444
|
+
|
|
1445
|
+
execute(retry_read(buffer, datasize));
|
|
1446
|
+
verify(memcmp(buffer, value, datasize) == 0);
|
|
1447
|
+
|
|
1448
|
+
execute(retry_read(buffer, 2));
|
|
1449
|
+
verify(memcmp(buffer, "\r\n", 2) == 0);
|
|
1450
|
+
|
|
1451
|
+
return TEST_PASS;
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
static enum test_return ascii_gets_item(const char *key, const char *value,
|
|
1455
|
+
bool exist, unsigned long *cas)
|
|
1456
|
+
{
|
|
1457
|
+
char buffer[1024];
|
|
1458
|
+
size_t datasize= 0;
|
|
1459
|
+
if (value != NULL)
|
|
1460
|
+
datasize= strlen(value);
|
|
1461
|
+
|
|
1462
|
+
verify(datasize < sizeof(buffer));
|
|
1463
|
+
snprintf(buffer, sizeof(buffer), "gets %s\r\n", key);
|
|
1464
|
+
execute(send_string(buffer));
|
|
1465
|
+
|
|
1466
|
+
if (exist)
|
|
1467
|
+
execute(ascii_gets_value(key, value, cas));
|
|
1468
|
+
|
|
1469
|
+
execute(retry_read(buffer, 5));
|
|
1470
|
+
verify(memcmp(buffer, "END\r\n", 5) == 0);
|
|
1471
|
+
|
|
1472
|
+
return TEST_PASS;
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
static enum test_return ascii_set_item(const char *key, const char *value)
|
|
1476
|
+
{
|
|
1477
|
+
char buffer[300];
|
|
1478
|
+
size_t len= strlen(value);
|
|
1479
|
+
snprintf(buffer, sizeof(buffer), "set %s 0 0 %u\r\n", key, (unsigned int)len);
|
|
1480
|
+
execute(send_string(buffer));
|
|
1481
|
+
execute(retry_write(value, len));
|
|
1482
|
+
execute(send_string("\r\n"));
|
|
1483
|
+
execute(receive_response("STORED\r\n"));
|
|
1484
|
+
return TEST_PASS;
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
static enum test_return test_ascii_replace_impl(const char* key, bool noreply)
|
|
1488
|
+
{
|
|
1489
|
+
char buffer[1024];
|
|
1490
|
+
snprintf(buffer, sizeof(buffer), "replace %s 0 0 5%s\r\nvalue\r\n", key, noreply ? " noreply" : "");
|
|
1491
|
+
execute(send_string(buffer));
|
|
1492
|
+
|
|
1493
|
+
if (noreply)
|
|
1494
|
+
execute(test_ascii_version());
|
|
1495
|
+
else
|
|
1496
|
+
execute(receive_response("NOT_STORED\r\n"));
|
|
1497
|
+
|
|
1498
|
+
execute(ascii_set_item(key, "value"));
|
|
1499
|
+
execute(ascii_get_item(key, "value", true));
|
|
1500
|
+
|
|
1501
|
+
|
|
1502
|
+
execute(send_string(buffer));
|
|
1503
|
+
|
|
1504
|
+
if (noreply)
|
|
1505
|
+
execute(test_ascii_version());
|
|
1506
|
+
else
|
|
1507
|
+
execute(receive_response("STORED\r\n"));
|
|
1508
|
+
|
|
1509
|
+
return test_ascii_version();
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
static enum test_return test_ascii_replace(void)
|
|
1513
|
+
{
|
|
1514
|
+
return test_ascii_replace_impl("test_ascii_replace", false);
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
static enum test_return test_ascii_replace_noreply(void)
|
|
1518
|
+
{
|
|
1519
|
+
return test_ascii_replace_impl("test_ascii_replace_noreply", true);
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
static enum test_return test_ascii_cas_impl(const char* key, bool noreply)
|
|
1523
|
+
{
|
|
1524
|
+
char buffer[1024];
|
|
1525
|
+
unsigned long cas;
|
|
1526
|
+
|
|
1527
|
+
execute(ascii_set_item(key, "value"));
|
|
1528
|
+
execute(ascii_gets_item(key, "value", true, &cas));
|
|
1529
|
+
|
|
1530
|
+
snprintf(buffer, sizeof(buffer), "cas %s 0 0 6 %lu%s\r\nvalue2\r\n", key, cas, noreply ? " noreply" : "");
|
|
1531
|
+
execute(send_string(buffer));
|
|
1532
|
+
|
|
1533
|
+
if (noreply)
|
|
1534
|
+
execute(test_ascii_version());
|
|
1535
|
+
else
|
|
1536
|
+
execute(receive_response("STORED\r\n"));
|
|
1537
|
+
|
|
1538
|
+
/* reexecute the same command should fail due to illegal cas */
|
|
1539
|
+
execute(send_string(buffer));
|
|
1540
|
+
|
|
1541
|
+
if (noreply)
|
|
1542
|
+
execute(test_ascii_version());
|
|
1543
|
+
else
|
|
1544
|
+
execute(receive_response("EXISTS\r\n"));
|
|
1545
|
+
|
|
1546
|
+
return test_ascii_version();
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
static enum test_return test_ascii_cas(void)
|
|
1550
|
+
{
|
|
1551
|
+
return test_ascii_cas_impl("test_ascii_cas", false);
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
static enum test_return test_ascii_cas_noreply(void)
|
|
1555
|
+
{
|
|
1556
|
+
return test_ascii_cas_impl("test_ascii_cas_noreply", true);
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
static enum test_return test_ascii_delete_impl(const char *key, bool noreply)
|
|
1560
|
+
{
|
|
1561
|
+
execute(ascii_set_item(key, "value"));
|
|
1562
|
+
|
|
1563
|
+
execute(send_string("delete\r\n"));
|
|
1564
|
+
execute(receive_error_response());
|
|
1565
|
+
/* BUG: the server accepts delete a b */
|
|
1566
|
+
execute(send_string("delete a b c d e\r\n"));
|
|
1567
|
+
execute(receive_error_response());
|
|
1568
|
+
|
|
1569
|
+
char buffer[1024];
|
|
1570
|
+
snprintf(buffer, sizeof(buffer), "delete %s%s\r\n", key, noreply ? " noreply" : "");
|
|
1571
|
+
execute(send_string(buffer));
|
|
1572
|
+
|
|
1573
|
+
if (noreply)
|
|
1574
|
+
execute(test_ascii_version());
|
|
1575
|
+
else
|
|
1576
|
+
execute(receive_response("DELETED\r\n"));
|
|
1577
|
+
|
|
1578
|
+
execute(ascii_get_item(key, "value", false));
|
|
1579
|
+
execute(send_string(buffer));
|
|
1580
|
+
if (noreply)
|
|
1581
|
+
execute(test_ascii_version());
|
|
1582
|
+
else
|
|
1583
|
+
execute(receive_response("NOT_FOUND\r\n"));
|
|
1584
|
+
|
|
1585
|
+
return TEST_PASS;
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
static enum test_return test_ascii_delete(void)
|
|
1589
|
+
{
|
|
1590
|
+
return test_ascii_delete_impl("test_ascii_delete", false);
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
static enum test_return test_ascii_delete_noreply(void)
|
|
1594
|
+
{
|
|
1595
|
+
return test_ascii_delete_impl("test_ascii_delete_noreply", true);
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
static enum test_return test_ascii_get(void)
|
|
1599
|
+
{
|
|
1600
|
+
execute(ascii_set_item("test_ascii_get", "value"));
|
|
1601
|
+
|
|
1602
|
+
execute(send_string("get\r\n"));
|
|
1603
|
+
execute(receive_error_response());
|
|
1604
|
+
execute(ascii_get_item("test_ascii_get", "value", true));
|
|
1605
|
+
execute(ascii_get_item("test_ascii_get_notfound", "value", false));
|
|
1606
|
+
|
|
1607
|
+
return TEST_PASS;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
static enum test_return test_ascii_gets(void)
|
|
1611
|
+
{
|
|
1612
|
+
execute(ascii_set_item("test_ascii_gets", "value"));
|
|
1613
|
+
|
|
1614
|
+
execute(send_string("gets\r\n"));
|
|
1615
|
+
execute(receive_error_response());
|
|
1616
|
+
unsigned long cas;
|
|
1617
|
+
execute(ascii_gets_item("test_ascii_gets", "value", true, &cas));
|
|
1618
|
+
execute(ascii_gets_item("test_ascii_gets_notfound", "value", false, &cas));
|
|
1619
|
+
|
|
1620
|
+
return TEST_PASS;
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
static enum test_return test_ascii_mget(void)
|
|
1624
|
+
{
|
|
1625
|
+
const uint32_t nkeys= 5;
|
|
1626
|
+
const char * const keys[]= {
|
|
1627
|
+
"test_ascii_mget1",
|
|
1628
|
+
"test_ascii_mget2",
|
|
1629
|
+
/* test_ascii_mget_3 does not exist :) */
|
|
1630
|
+
"test_ascii_mget4",
|
|
1631
|
+
"test_ascii_mget5",
|
|
1632
|
+
"test_ascii_mget6"
|
|
1633
|
+
};
|
|
1634
|
+
|
|
1635
|
+
for (uint32_t x= 0; x < nkeys; ++x)
|
|
1636
|
+
execute(ascii_set_item(keys[x], "value"));
|
|
1637
|
+
|
|
1638
|
+
/* Ask for a key that doesn't exist as well */
|
|
1639
|
+
execute(send_string("get test_ascii_mget1 test_ascii_mget2 test_ascii_mget3 "
|
|
1640
|
+
"test_ascii_mget4 test_ascii_mget5 "
|
|
1641
|
+
"test_ascii_mget6\r\n"));
|
|
1642
|
+
|
|
1643
|
+
char *returned[nkeys];
|
|
1644
|
+
|
|
1645
|
+
for (uint32_t x= 0; x < nkeys; ++x)
|
|
1646
|
+
{
|
|
1647
|
+
ssize_t nbytes = 0;
|
|
1648
|
+
char *v= NULL;
|
|
1649
|
+
execute(ascii_get_unknown_value(&returned[x], &v, &nbytes));
|
|
1650
|
+
verify(nbytes == 5);
|
|
1651
|
+
verify(memcmp(v, "value", 5) == 0);
|
|
1652
|
+
free(v);
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
char buffer[5];
|
|
1656
|
+
execute(retry_read(buffer, 5));
|
|
1657
|
+
verify(memcmp(buffer, "END\r\n", 5) == 0);
|
|
1658
|
+
|
|
1659
|
+
/* verify that we got all the keys we expected */
|
|
1660
|
+
for (uint32_t x= 0; x < nkeys; ++x)
|
|
1661
|
+
{
|
|
1662
|
+
bool found= false;
|
|
1663
|
+
for (uint32_t y= 0; y < nkeys; ++y)
|
|
1664
|
+
{
|
|
1665
|
+
if (strcmp(keys[x], returned[y]) == 0)
|
|
1666
|
+
{
|
|
1667
|
+
found = true;
|
|
1668
|
+
break;
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
verify(found);
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
for (uint32_t x= 0; x < nkeys; ++x)
|
|
1675
|
+
free(returned[x]);
|
|
1676
|
+
|
|
1677
|
+
return TEST_PASS;
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
static enum test_return test_ascii_incr_impl(const char* key, bool noreply)
|
|
1681
|
+
{
|
|
1682
|
+
char cmd[300];
|
|
1683
|
+
snprintf(cmd, sizeof(cmd), "incr %s 1%s\r\n", key, noreply ? " noreply" : "");
|
|
1684
|
+
|
|
1685
|
+
execute(ascii_set_item(key, "0"));
|
|
1686
|
+
for (int x= 1; x < 11; ++x)
|
|
1687
|
+
{
|
|
1688
|
+
execute(send_string(cmd));
|
|
1689
|
+
|
|
1690
|
+
if (noreply)
|
|
1691
|
+
execute(test_ascii_version());
|
|
1692
|
+
else
|
|
1693
|
+
{
|
|
1694
|
+
char buffer[80];
|
|
1695
|
+
execute(receive_line(buffer, sizeof(buffer)));
|
|
1696
|
+
int val= atoi(buffer);
|
|
1697
|
+
verify(val == x);
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
execute(ascii_get_item(key, "10", true));
|
|
1702
|
+
|
|
1703
|
+
return TEST_PASS;
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
static enum test_return test_ascii_incr(void)
|
|
1707
|
+
{
|
|
1708
|
+
return test_ascii_incr_impl("test_ascii_incr", false);
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
static enum test_return test_ascii_incr_noreply(void)
|
|
1712
|
+
{
|
|
1713
|
+
return test_ascii_incr_impl("test_ascii_incr_noreply", true);
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
static enum test_return test_ascii_decr_impl(const char* key, bool noreply)
|
|
1717
|
+
{
|
|
1718
|
+
char cmd[300];
|
|
1719
|
+
snprintf(cmd, sizeof(cmd), "decr %s 1%s\r\n", key, noreply ? " noreply" : "");
|
|
1720
|
+
|
|
1721
|
+
execute(ascii_set_item(key, "9"));
|
|
1722
|
+
for (int x= 8; x > -1; --x)
|
|
1723
|
+
{
|
|
1724
|
+
execute(send_string(cmd));
|
|
1725
|
+
|
|
1726
|
+
if (noreply)
|
|
1727
|
+
execute(test_ascii_version());
|
|
1728
|
+
else
|
|
1729
|
+
{
|
|
1730
|
+
char buffer[80];
|
|
1731
|
+
execute(receive_line(buffer, sizeof(buffer)));
|
|
1732
|
+
int val= atoi(buffer);
|
|
1733
|
+
verify(val == x);
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
execute(ascii_get_item(key, "0", true));
|
|
1738
|
+
|
|
1739
|
+
/* verify that it doesn't wrap */
|
|
1740
|
+
execute(send_string(cmd));
|
|
1741
|
+
if (noreply)
|
|
1742
|
+
execute(test_ascii_version());
|
|
1743
|
+
else
|
|
1744
|
+
{
|
|
1745
|
+
char buffer[80];
|
|
1746
|
+
execute(receive_line(buffer, sizeof(buffer)));
|
|
1747
|
+
}
|
|
1748
|
+
execute(ascii_get_item(key, "0", true));
|
|
1749
|
+
|
|
1750
|
+
return TEST_PASS;
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
static enum test_return test_ascii_decr(void)
|
|
1754
|
+
{
|
|
1755
|
+
return test_ascii_decr_impl("test_ascii_decr", false);
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
static enum test_return test_ascii_decr_noreply(void)
|
|
1759
|
+
{
|
|
1760
|
+
return test_ascii_decr_impl("test_ascii_decr_noreply", true);
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
|
|
1764
|
+
static enum test_return test_ascii_flush_impl(const char *key, bool noreply)
|
|
1765
|
+
{
|
|
1766
|
+
#if 0
|
|
1767
|
+
/* Verify that the flush_all command handles unknown options */
|
|
1768
|
+
/* Bug in the current memcached server! */
|
|
1769
|
+
execute(send_string("flush_all foo bar\r\n"));
|
|
1770
|
+
execute(receive_error_response());
|
|
1771
|
+
#endif
|
|
1772
|
+
|
|
1773
|
+
execute(ascii_set_item(key, key));
|
|
1774
|
+
execute(ascii_get_item(key, key, true));
|
|
1775
|
+
|
|
1776
|
+
if (noreply)
|
|
1777
|
+
{
|
|
1778
|
+
execute(send_string("flush_all noreply\r\n"));
|
|
1779
|
+
execute(test_ascii_version());
|
|
1780
|
+
}
|
|
1781
|
+
else
|
|
1782
|
+
{
|
|
1783
|
+
execute(send_string("flush_all\r\n"));
|
|
1784
|
+
execute(receive_response("OK\r\n"));
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
execute(ascii_get_item(key, key, false));
|
|
1788
|
+
|
|
1789
|
+
return TEST_PASS;
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
static enum test_return test_ascii_flush(void)
|
|
1793
|
+
{
|
|
1794
|
+
return test_ascii_flush_impl("test_ascii_flush", false);
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
static enum test_return test_ascii_flush_noreply(void)
|
|
1798
|
+
{
|
|
1799
|
+
return test_ascii_flush_impl("test_ascii_flush_noreply", true);
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
static enum test_return test_ascii_concat_impl(const char *key,
|
|
1803
|
+
bool append,
|
|
1804
|
+
bool noreply)
|
|
1805
|
+
{
|
|
1806
|
+
const char *value;
|
|
1807
|
+
|
|
1808
|
+
if (append)
|
|
1809
|
+
value="hello";
|
|
1810
|
+
else
|
|
1811
|
+
value=" world";
|
|
1812
|
+
|
|
1813
|
+
execute(ascii_set_item(key, value));
|
|
1814
|
+
|
|
1815
|
+
if (append)
|
|
1816
|
+
value=" world";
|
|
1817
|
+
else
|
|
1818
|
+
value="hello";
|
|
1819
|
+
|
|
1820
|
+
char cmd[400];
|
|
1821
|
+
snprintf(cmd, sizeof(cmd), "%s %s 0 0 %u%s\r\n%s\r\n",
|
|
1822
|
+
append ? "append" : "prepend",
|
|
1823
|
+
key, (unsigned int)strlen(value), noreply ? " noreply" : "",
|
|
1824
|
+
value);
|
|
1825
|
+
execute(send_string(cmd));
|
|
1826
|
+
|
|
1827
|
+
if (noreply)
|
|
1828
|
+
execute(test_ascii_version());
|
|
1829
|
+
else
|
|
1830
|
+
execute(receive_response("STORED\r\n"));
|
|
1831
|
+
|
|
1832
|
+
execute(ascii_get_item(key, "hello world", true));
|
|
1833
|
+
|
|
1834
|
+
snprintf(cmd, sizeof(cmd), "%s %s_notfound 0 0 %u%s\r\n%s\r\n",
|
|
1835
|
+
append ? "append" : "prepend",
|
|
1836
|
+
key, (unsigned int)strlen(value), noreply ? " noreply" : "",
|
|
1837
|
+
value);
|
|
1838
|
+
execute(send_string(cmd));
|
|
1839
|
+
|
|
1840
|
+
if (noreply)
|
|
1841
|
+
execute(test_ascii_version());
|
|
1842
|
+
else
|
|
1843
|
+
execute(receive_response("NOT_STORED\r\n"));
|
|
1844
|
+
|
|
1845
|
+
return TEST_PASS;
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
static enum test_return test_ascii_append(void)
|
|
1849
|
+
{
|
|
1850
|
+
return test_ascii_concat_impl("test_ascii_append", true, false);
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
static enum test_return test_ascii_prepend(void)
|
|
1854
|
+
{
|
|
1855
|
+
return test_ascii_concat_impl("test_ascii_prepend", false, false);
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
static enum test_return test_ascii_append_noreply(void)
|
|
1859
|
+
{
|
|
1860
|
+
return test_ascii_concat_impl("test_ascii_append_noreply", true, true);
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
static enum test_return test_ascii_prepend_noreply(void)
|
|
1864
|
+
{
|
|
1865
|
+
return test_ascii_concat_impl("test_ascii_prepend_noreply", false, true);
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
static enum test_return test_ascii_stat(void)
|
|
1869
|
+
{
|
|
1870
|
+
execute(send_string("stats noreply\r\n"));
|
|
1871
|
+
execute(receive_error_response());
|
|
1872
|
+
execute(send_string("stats\r\n"));
|
|
1873
|
+
char buffer[1024];
|
|
1874
|
+
do {
|
|
1875
|
+
execute(receive_line(buffer, sizeof(buffer)));
|
|
1876
|
+
} while (strcmp(buffer, "END\r\n") != 0);
|
|
1877
|
+
|
|
1878
|
+
return TEST_PASS_RECONNECT;
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
typedef enum test_return(*TEST_FUNC)(void);
|
|
1882
|
+
|
|
1883
|
+
struct testcase
|
|
1884
|
+
{
|
|
1885
|
+
const char *description;
|
|
1886
|
+
TEST_FUNC function;
|
|
1887
|
+
};
|
|
1888
|
+
|
|
1889
|
+
struct testcase testcases[]= {
|
|
1890
|
+
{ "ascii quit", test_ascii_quit },
|
|
1891
|
+
{ "ascii version", test_ascii_version },
|
|
1892
|
+
{ "ascii verbosity", test_ascii_verbosity },
|
|
1893
|
+
{ "ascii set", test_ascii_set },
|
|
1894
|
+
{ "ascii set noreply", test_ascii_set_noreply },
|
|
1895
|
+
{ "ascii get", test_ascii_get },
|
|
1896
|
+
{ "ascii gets", test_ascii_gets },
|
|
1897
|
+
{ "ascii mget", test_ascii_mget },
|
|
1898
|
+
{ "ascii flush", test_ascii_flush },
|
|
1899
|
+
{ "ascii flush noreply", test_ascii_flush_noreply },
|
|
1900
|
+
{ "ascii add", test_ascii_add },
|
|
1901
|
+
{ "ascii add noreply", test_ascii_add_noreply },
|
|
1902
|
+
{ "ascii replace", test_ascii_replace },
|
|
1903
|
+
{ "ascii replace noreply", test_ascii_replace_noreply },
|
|
1904
|
+
{ "ascii cas", test_ascii_cas },
|
|
1905
|
+
{ "ascii cas noreply", test_ascii_cas_noreply },
|
|
1906
|
+
{ "ascii delete", test_ascii_delete },
|
|
1907
|
+
{ "ascii delete noreply", test_ascii_delete_noreply },
|
|
1908
|
+
{ "ascii incr", test_ascii_incr },
|
|
1909
|
+
{ "ascii incr noreply", test_ascii_incr_noreply },
|
|
1910
|
+
{ "ascii decr", test_ascii_decr },
|
|
1911
|
+
{ "ascii decr noreply", test_ascii_decr_noreply },
|
|
1912
|
+
{ "ascii append", test_ascii_append },
|
|
1913
|
+
{ "ascii append noreply", test_ascii_append_noreply },
|
|
1914
|
+
{ "ascii prepend", test_ascii_prepend },
|
|
1915
|
+
{ "ascii prepend noreply", test_ascii_prepend_noreply },
|
|
1916
|
+
{ "ascii stat", test_ascii_stat },
|
|
1917
|
+
{ "binary noop", test_binary_noop },
|
|
1918
|
+
{ "binary quit", test_binary_quit },
|
|
1919
|
+
{ "binary quitq", test_binary_quitq },
|
|
1920
|
+
{ "binary set", test_binary_set },
|
|
1921
|
+
{ "binary setq", test_binary_setq },
|
|
1922
|
+
{ "binary flush", test_binary_flush },
|
|
1923
|
+
{ "binary flushq", test_binary_flushq },
|
|
1924
|
+
{ "binary add", test_binary_add },
|
|
1925
|
+
{ "binary addq", test_binary_addq },
|
|
1926
|
+
{ "binary replace", test_binary_replace },
|
|
1927
|
+
{ "binary replaceq", test_binary_replaceq },
|
|
1928
|
+
{ "binary delete", test_binary_delete },
|
|
1929
|
+
{ "binary deleteq", test_binary_deleteq },
|
|
1930
|
+
{ "binary get", test_binary_get },
|
|
1931
|
+
{ "binary getq", test_binary_getq },
|
|
1932
|
+
{ "binary getk", test_binary_getk },
|
|
1933
|
+
{ "binary getkq", test_binary_getkq },
|
|
1934
|
+
{ "binary incr", test_binary_incr },
|
|
1935
|
+
{ "binary incrq", test_binary_incrq },
|
|
1936
|
+
{ "binary decr", test_binary_decr },
|
|
1937
|
+
{ "binary decrq", test_binary_decrq },
|
|
1938
|
+
{ "binary version", test_binary_version },
|
|
1939
|
+
{ "binary append", test_binary_append },
|
|
1940
|
+
{ "binary appendq", test_binary_appendq },
|
|
1941
|
+
{ "binary prepend", test_binary_prepend },
|
|
1942
|
+
{ "binary prependq", test_binary_prependq },
|
|
1943
|
+
{ "binary stat", test_binary_stat },
|
|
1944
|
+
{ NULL, NULL}
|
|
1945
|
+
};
|
|
1946
|
+
|
|
1947
|
+
const int ascii_tests = 1;
|
|
1948
|
+
const int binary_tests = 2;
|
|
1949
|
+
|
|
1950
|
+
struct test_type_st
|
|
1951
|
+
{
|
|
1952
|
+
bool ascii;
|
|
1953
|
+
bool binary;
|
|
1954
|
+
};
|
|
1955
|
+
|
|
1956
|
+
int main(int argc, char **argv)
|
|
1957
|
+
{
|
|
1958
|
+
static const char * const status_msg[]= {"[skip]", "[pass]", "[pass]", "[FAIL]"};
|
|
1959
|
+
struct test_type_st tests= { true, true };
|
|
1960
|
+
int total= 0;
|
|
1961
|
+
int failed= 0;
|
|
1962
|
+
const char *hostname= "localhost";
|
|
1963
|
+
const char *port= "11211";
|
|
1964
|
+
int cmd;
|
|
1965
|
+
bool prompt= false;
|
|
1966
|
+
const char *testname= NULL;
|
|
1967
|
+
|
|
1968
|
+
|
|
1969
|
+
|
|
1970
|
+
while ((cmd= getopt(argc, argv, "t:vch:p:PT:?ab")) != EOF)
|
|
1971
|
+
{
|
|
1972
|
+
switch (cmd) {
|
|
1973
|
+
case 'a':
|
|
1974
|
+
tests.ascii= true;
|
|
1975
|
+
tests.binary= false;
|
|
1976
|
+
break;
|
|
1977
|
+
case 'b':
|
|
1978
|
+
tests.ascii= false;
|
|
1979
|
+
tests.binary= true;
|
|
1980
|
+
break;
|
|
1981
|
+
case 't':
|
|
1982
|
+
timeout= atoi(optarg);
|
|
1983
|
+
if (timeout == 0)
|
|
1984
|
+
{
|
|
1985
|
+
fprintf(stderr, "Invalid timeout. Please specify a number for -t\n");
|
|
1986
|
+
return EXIT_FAILURE;
|
|
1987
|
+
}
|
|
1988
|
+
break;
|
|
1989
|
+
case 'v': verbose= true;
|
|
1990
|
+
break;
|
|
1991
|
+
case 'c': do_core= true;
|
|
1992
|
+
break;
|
|
1993
|
+
case 'h': hostname= optarg;
|
|
1994
|
+
break;
|
|
1995
|
+
case 'p': port= optarg;
|
|
1996
|
+
break;
|
|
1997
|
+
case 'P': prompt= true;
|
|
1998
|
+
break;
|
|
1999
|
+
case 'T': testname= optarg;
|
|
2000
|
+
break;
|
|
2001
|
+
default:
|
|
2002
|
+
fprintf(stderr, "Usage: %s [-h hostname] [-p port] [-c] [-v] [-t n] [-P] [-T testname]'\n"
|
|
2003
|
+
"\t-c\tGenerate coredump if a test fails\n"
|
|
2004
|
+
"\t-v\tVerbose test output (print out the assertion)\n"
|
|
2005
|
+
"\t-t n\tSet the timeout for io-operations to n seconds\n"
|
|
2006
|
+
"\t-P\tPrompt the user before starting a test.\n"
|
|
2007
|
+
"\t\t\t\"skip\" will skip the test\n"
|
|
2008
|
+
"\t\t\t\"quit\" will terminate memcapable\n"
|
|
2009
|
+
"\t\t\tEverything else will start the test\n"
|
|
2010
|
+
"\t-T n\tJust run the test named n\n"
|
|
2011
|
+
"\t-a\tOnly test the ascii protocol\n"
|
|
2012
|
+
"\t-b\tOnly test the binary protocol\n",
|
|
2013
|
+
argv[0]);
|
|
2014
|
+
return EXIT_FAILURE;
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
initialize_sockets();
|
|
2019
|
+
sock= connect_server(hostname, port);
|
|
2020
|
+
if (sock == INVALID_SOCKET)
|
|
2021
|
+
{
|
|
2022
|
+
fprintf(stderr, "Failed to connect to <%s:%s>: %s\n",
|
|
2023
|
+
hostname, port, strerror(get_socket_errno()));
|
|
2024
|
+
return EXIT_FAILURE;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
for (int ii= 0; testcases[ii].description != NULL; ++ii)
|
|
2028
|
+
{
|
|
2029
|
+
if (testname != NULL && strcmp(testcases[ii].description, testname) != 0)
|
|
2030
|
+
continue;
|
|
2031
|
+
|
|
2032
|
+
if ((testcases[ii].description[0] == 'a' && (tests.ascii) == 0) ||
|
|
2033
|
+
(testcases[ii].description[0] == 'b' && (tests.binary) == 0))
|
|
2034
|
+
{
|
|
2035
|
+
continue;
|
|
2036
|
+
}
|
|
2037
|
+
++total;
|
|
2038
|
+
fprintf(stdout, "%-40s", testcases[ii].description);
|
|
2039
|
+
fflush(stdout);
|
|
2040
|
+
|
|
2041
|
+
if (prompt)
|
|
2042
|
+
{
|
|
2043
|
+
fprintf(stdout, "\nPress <return> when you are ready? ");
|
|
2044
|
+
char buffer[80] = {0};
|
|
2045
|
+
if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
|
|
2046
|
+
if (strncmp(buffer, "skip", 4) == 0)
|
|
2047
|
+
{
|
|
2048
|
+
fprintf(stdout, "%-40s%s\n", testcases[ii].description,
|
|
2049
|
+
status_msg[TEST_SKIP]);
|
|
2050
|
+
fflush(stdout);
|
|
2051
|
+
continue;
|
|
2052
|
+
}
|
|
2053
|
+
if (strncmp(buffer, "quit", 4) == 0)
|
|
2054
|
+
exit(0);
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2057
|
+
fprintf(stdout, "%-40s", testcases[ii].description);
|
|
2058
|
+
fflush(stdout);
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
bool reconnect= false;
|
|
2062
|
+
enum test_return ret= testcases[ii].function();
|
|
2063
|
+
if (ret == TEST_FAIL)
|
|
2064
|
+
{
|
|
2065
|
+
reconnect= true;
|
|
2066
|
+
++failed;
|
|
2067
|
+
if (verbose)
|
|
2068
|
+
fprintf(stderr, "\n");
|
|
2069
|
+
}
|
|
2070
|
+
else if (ret == TEST_PASS_RECONNECT)
|
|
2071
|
+
reconnect= true;
|
|
2072
|
+
|
|
2073
|
+
fprintf(stderr, "%s\n", status_msg[ret]);
|
|
2074
|
+
if (reconnect)
|
|
2075
|
+
{
|
|
2076
|
+
closesocket(sock);
|
|
2077
|
+
if ((sock= connect_server(hostname, port)) == INVALID_SOCKET)
|
|
2078
|
+
{
|
|
2079
|
+
fprintf(stderr, "Failed to connect to <%s:%s>: %s\n",
|
|
2080
|
+
hostname, port, strerror(get_socket_errno()));
|
|
2081
|
+
fprintf(stderr, "%d of %d tests failed\n", failed, total);
|
|
2082
|
+
return EXIT_FAILURE;
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
closesocket(sock);
|
|
2088
|
+
if (failed == 0)
|
|
2089
|
+
fprintf(stdout, "All tests passed\n");
|
|
2090
|
+
else
|
|
2091
|
+
fprintf(stderr, "%d of %d tests failed\n", failed, total);
|
|
2092
|
+
|
|
2093
|
+
return (failed == 0) ? 0 : 1;
|
|
2094
|
+
}
|