X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=tests%2Fserver.c;h=84f15de09df4192eaef8641c5b3297e84bb8fdc7;hb=c3992b4a4f0a52704af43fd8da166579caf52a56;hp=e06fbd57e0d66cab5f91544c0b3080f5deb33bee;hpb=ef9ddf55563059fcf3608bab479e15f28e9ceb0f;p=m6w6%2Flibmemcached diff --git a/tests/server.c b/tests/server.c index e06fbd57..84f15de0 100644 --- a/tests/server.c +++ b/tests/server.c @@ -1,25 +1,86 @@ +/* LibMemcached + * Copyright (C) 2006-2009 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: + * + */ + /* Startup, and shutdown the memcached servers. */ -#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT+10 +#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT+10 + +#define PID_FILE_BASE "/tmp/%ulibmemcached_memc.pid" -#include "libmemcached/libmemcached_config.h" +#include "config.h" +#include +#include +#include #include #include #include +#include #include -#include -#include -#include #include + +#include +#include + #include "server.h" -void server_startup(server_startup_st *construct) +static struct timespec global_sleep_value= { .tv_sec= 0, .tv_nsec= 50000 }; + +static void global_sleep(void) { - unsigned int x; +#ifdef WIN32 + sleep(1); +#else + nanosleep(&global_sleep_value, NULL); +#endif +} + +static void kill_file(const char *file_buffer) +{ + FILE *fp= fopen(file_buffer, "r"); + + while ((fp= fopen(file_buffer, "r"))) + { + char pid_buffer[1024]; + + if (fgets(pid_buffer, sizeof(pid_buffer), fp) != NULL) + { + pid_t pid= (pid_t)atoi(pid_buffer); + if (pid != 0) + { + if (kill(pid, SIGTERM) == -1) + { + remove(file_buffer); // If this happens we may be dealing with a dead server that left its pid file. + } + else + { + uint32_t counter= 3; + while ((kill(pid, 0) == 0) && --counter) + { + global_sleep(); + } + } + } + } + + global_sleep(); + fclose(fp); + } +} + +void server_startup(server_startup_st *construct) +{ if ((construct->server_list= getenv("MEMCACHED_SERVERS"))) { printf("servers %s\n", construct->server_list); @@ -34,48 +95,121 @@ void server_startup(server_startup_st *construct) char *end_ptr; end_ptr= server_string_buffer; - for (x= 0; x < construct->count; x++) + for (uint32_t x= 0; x < construct->count; x++) { - char buffer[1024]; /* Nothing special for number */ - int count; int status; + in_port_t port; - sprintf(buffer, "/tmp/%umemc.pid", x); - if (access(buffer, F_OK) == 0) { - FILE *fp= fopen(buffer, "r"); - remove(buffer); + char *var; + char variable_buffer[1024]; - if (fp != NULL) - { - if (fgets(buffer, sizeof(buffer), fp) != NULL) - { - pid_t pid = (pid_t)atol(buffer); - if (pid != 0) - kill(pid, SIGTERM); - } + snprintf(variable_buffer, sizeof(variable_buffer), "LIBMEMCACHED_PORT_%u", x); - fclose(fp); + if ((var= getenv(variable_buffer))) + { + port= (in_port_t)atoi(var); + } + else + { + port= (in_port_t)(x + TEST_PORT_BASE); } } + char buffer[PATH_MAX]; + snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x); + kill_file(buffer); + if (x == 0) { - sprintf(buffer, "%s -d -P /tmp/%umemc.pid -t 1 -p %u -U %u -m 128", - MEMCACHED_BINARY, x, x + TEST_PORT_BASE, x + TEST_PORT_BASE); - } + snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u -m 128", + MEMCACHED_BINARY, x, port, port); + } else { - sprintf(buffer, "%s -d -P /tmp/%umemc.pid -t 1 -p %u -U %u", - MEMCACHED_BINARY, x, x + TEST_PORT_BASE, x + TEST_PORT_BASE); + snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u", + MEMCACHED_BINARY, x, port, port); + } + if (libmemcached_util_ping("localhost", port, NULL)) + { + fprintf(stderr, "Server on port %u already exists\n", port); + } + else + { + status= system(buffer); + fprintf(stderr, "STARTING SERVER: %s status:%d\n", buffer, status); + } + int count; + size_t remaining_length= sizeof(server_string_buffer) - (size_t)(end_ptr -server_string_buffer); + count= snprintf(end_ptr, remaining_length, "localhost:%u,", port); + + if ((size_t)count >= remaining_length || count < 0) + { + fprintf(stderr, "server names grew to be larger then buffer allowed\n"); + abort(); } - fprintf(stderr, "STARTING SERVER: %s\n", buffer); - status= system(buffer); - count= sprintf(end_ptr, "localhost:%u,", x + TEST_PORT_BASE); end_ptr+= count; } *end_ptr= 0; + + int *pids= calloc(construct->count, sizeof(int)); + for (uint32_t x= 0; x < construct->count; x++) + { + char buffer[PATH_MAX]; /* Nothing special for number */ + + snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x); + + uint32_t counter= 3000; // Absurd, just to catch run away process + while (pids[x] <= 0 && --counter) + { + FILE *file= fopen(buffer, "r"); + if (file) + { + char pid_buffer[1024]; + char *found= fgets(pid_buffer, sizeof(pid_buffer), file); + + if (found) + { + pids[x]= atoi(pid_buffer); + fclose(file); + + if (pids[x] > 0) + break; + } + fclose(file); + } + global_sleep(); + } + + bool was_started= false; + if (pids[x] > 0) + { + counter= 30; + while (--counter) + { + if (kill(pids[x], 0) == 0) + { + was_started= true; + break; + } + global_sleep(); + } + } + + if (was_started == false) + { + fprintf(stderr, "Failed to open buffer %s(%d)\n", buffer, pids[x]); + for (uint32_t y= 0; y < construct->count; y++) + { + if (pids[y] > 0) + kill(pids[y], SIGTERM); + } + abort(); + } + } + free(pids); + construct->server_list= strdup(server_string_buffer); } printf("servers %s\n", construct->server_list); @@ -86,9 +220,9 @@ void server_startup(server_startup_st *construct) srandom((unsigned int)time(NULL)); - for (x= 0; x < memcached_server_list_count(construct->servers); x++) + for (uint32_t x= 0; x < memcached_server_list_count(construct->servers); x++) { - printf("\t%s : %u\n", construct->servers[x].hostname, construct->servers[x].port); + printf("\t%s : %d\n", memcached_server_name(&construct->servers[x]), memcached_server_port(&construct->servers[x])); assert(construct->servers[x].fd == -1); assert(construct->servers[x].cursor_active == 0); } @@ -98,19 +232,13 @@ void server_startup(server_startup_st *construct) void server_shutdown(server_startup_st *construct) { - unsigned int x; - if (construct->server_list) { - for (x= 0; x < construct->count; x++) + for (uint32_t x= 0; x < construct->count; x++) { - char buffer[1024]; /* Nothing special for number */ - sprintf(buffer, "cat /tmp/%umemc.pid | xargs kill", x); - /* We have to check the return value of this or the compiler will yell */ - int sys_ret= system(buffer); - assert(sys_ret != -1); - sprintf(buffer, "/tmp/%umemc.pid", x); - unlink(buffer); + char file_buffer[PATH_MAX]; /* Nothing special for number */ + snprintf(file_buffer, sizeof(file_buffer), PID_FILE_BASE, x); + kill_file(file_buffer); } free(construct->server_list);