--- /dev/null
+/* LibMemcached
+ * Copyright (C) 2010 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license. See
+ * the COPYING file in the parent directory for full text.
+ *
+ * Summary: connect to all hosts, and make sure they meet a minimum version
+ *
+ */
+
+/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+#include "libmemcached/common.h"
+#include "libmemcached/memcached_util.h"
+
+struct local_context
+{
+ uint8_t major_version;
+ uint8_t micro_version;
+ uint8_t minor_version;
+
+ bool truth;
+};
+
+static memcached_return_t check_server_version(const memcached_st *ptr __attribute__((unused)),
+ const memcached_server_st *instance,
+ void *context)
+{
+ /* Do Nothing */
+ struct local_context *check= (struct local_context *)context;
+
+ if (instance->major_version >= check->major_version &&
+ instance->micro_version >= check->micro_version &&
+ instance->minor_version >= check->minor_version)
+ {
+ return MEMCACHED_SUCCESS;
+ }
+
+ check->truth= false;
+
+ return MEMCACHED_FAILURE;
+}
+
+bool libmemcached_util_version_check(memcached_st *memc,
+ uint8_t major_version,
+ uint8_t micro_version,
+ uint8_t minor_version)
+{
+ memcached_server_fn callbacks[1];
+ memcached_version(memc);
+
+ struct local_context check= { .major_version= major_version, .micro_version= micro_version, .minor_version= minor_version, .truth= true };
+
+ callbacks[0]= check_server_version;
+ memcached_server_cursor(memc, callbacks, (void *)&check, 1);
+
+ return check.truth;
+}
{
memcached_return_t rc= MEMCACHED_FAILURE;
memcached_st *memc_clone;
- memcached_server_instance_st instance;
memc_clone= memcached_clone(NULL, memc);
test_true(memc_clone);
// will not toggle protocol on an connection.
memcached_version(memc_clone);
- instance= memcached_server_instance_by_position(memc_clone, 0);
-
- if (instance->major_version >= 1 && instance->minor_version > 2)
+ if (libmemcached_util_version_check(memc_clone, 1, 2, 0))
{
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
{
memcached_return_t rc= MEMCACHED_FAILURE;
memcached_st *memc_clone;
- memcached_server_instance_st instance;
memc_clone= memcached_clone(NULL, memc);
test_true(memc_clone);
// will not toggle protocol on an connection.
memcached_version(memc_clone);
- instance= memcached_server_instance_by_position(memc_clone, 0);
-
- if (instance->major_version >= 1 && instance->minor_version > 2)
+ if (libmemcached_util_version_check(memc_clone, 1, 2, 0))
{
rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
test_true(rc == MEMCACHED_SUCCESS);
{
unsigned int set= 1;
- memcached_server_instance_st instance=
- memcached_server_instance_by_position(memc, 0);
-
- memcached_version(memc);
-
- if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
- || instance->minor_version > 2)
+ if (libmemcached_util_version_check(memc, 1, 2, 4))
{
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
|| instance->minor_version > 2)
+ {
return TEST_SUCCESS;
+ }
return TEST_SKIPPED;
}
return TEST_SUCCESS;
}
+static test_return_t util_version_test(memcached_st *memc)
+{
+ bool if_successful;
+
+ if_successful= libmemcached_util_version_check(memc, 0, 0, 0);
+ test_true(if_successful == true);
+
+ if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
+ test_true(if_successful == false);
+
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc, 0);
+
+ memcached_version(memc);
+
+ // We only use one binary when we test, so this should be just fine.
+ if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version, instance->minor_version);
+ test_true(if_successful == true);
+
+ if (instance->minor_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version, instance->minor_version -1);
+ else if (instance->micro_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version - 1, instance->minor_version);
+ else if (instance->major_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version -1, instance->micro_version, instance->minor_version);
+
+ test_true(if_successful == true);
+
+ if (instance->minor_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version, instance->minor_version +1);
+ else if (instance->micro_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version +1, instance->minor_version);
+ else if (instance->major_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version +1, instance->micro_version, instance->minor_version);
+
+ test_true(if_successful == false);
+
+ return TEST_SUCCESS;
+}
+
static test_return_t ping_test(memcached_st *memc)
{
memcached_return_t rc;
memcached_server_instance_by_position(memc, 0);
// Test both the version that returns a code, and the one that does not.
- test_true(libmemcached_ping(memcached_server_name(instance),
- memcached_server_port(instance), NULL));
+ test_true(libmemcached_util_ping(memcached_server_name(instance),
+ memcached_server_port(instance), NULL));
- test_true(libmemcached_ping(memcached_server_name(instance),
- memcached_server_port(instance), &rc));
+ test_true(libmemcached_util_ping(memcached_server_name(instance),
+ memcached_server_port(instance), &rc));
test_true(rc == MEMCACHED_SUCCESS);
test_true(memc_clone != NULL);
test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
- memcached_server_instance_st instance=
- memcached_server_instance_by_position(memc_clone, 0);
- if (instance->major_version > 1 ||
- (instance->major_version == 1 &&
- instance->minor_version > 2))
+ if (libmemcached_util_version_check(memc_clone, 1, 1, 2))
{
/* Binary protocol doesn't support deferred delete */
memcached_st *bin_clone= memcached_clone(NULL, memc);
#ifdef HAVE_LIBMEMCACHEDUTIL
{"connectionpool", 1, (test_callback_fn)connection_pool_test },
{"ping", 1, (test_callback_fn)ping_test },
+ {"util_version", 1, (test_callback_fn)util_version_test },
#endif
{"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
{"verbosity", 1, (test_callback_fn)test_verbosity},