From fc73a3da5ded1ff8488d7e13ab4ae4a1d0680f96 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Sun, 13 May 2012 17:21:18 +0000 Subject: clean shutdown in lockmanager, test case for lock release and message format checks for incoming msg in lockmanager API --- src/lockmanager/Makefile.am | 9 +- src/lockmanager/gnunet-service-lockmanager.c | 75 ++++- src/lockmanager/lockmanager_api.c | 282 +++++++++---------- src/lockmanager/test_lockmanager_api.conf | 2 +- src/lockmanager/test_lockmanager_api_lockrelease.c | 301 +++++++++++++++++++++ 5 files changed, 507 insertions(+), 162 deletions(-) create mode 100644 src/lockmanager/test_lockmanager_api_lockrelease.c diff --git a/src/lockmanager/Makefile.am b/src/lockmanager/Makefile.am index f86ac72a5..ee6f816f1 100644 --- a/src/lockmanager/Makefile.am +++ b/src/lockmanager/Makefile.am @@ -38,7 +38,8 @@ libgnunetlockmanager_la_LDFLAGS = \ -version-info 0:0:0 check_PROGRAMS = \ - test-lockmanager-api + test-lockmanager-api \ + test-lockmanager-api-lockrelease EXTRA_DIST = \ test_lockmanager_api.conf @@ -52,3 +53,9 @@ test_lockmanager_api_SOURCES = \ test_lockmanager_api_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunetlockmanager.la + +test_lockmanager_api_lockrelease_SOURCES = \ + test_lockmanager_api_lockrelease.c +test_lockmanager_api_lockrelease_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetlockmanager.la \ No newline at end of file diff --git a/src/lockmanager/gnunet-service-lockmanager.c b/src/lockmanager/gnunet-service-lockmanager.c index 3642ca030..974c14be1 100644 --- a/src/lockmanager/gnunet-service-lockmanager.c +++ b/src/lockmanager/gnunet-service-lockmanager.c @@ -217,7 +217,6 @@ find_lock (const char *domain_name, void *value) { matched_lock = value; - if ((lock_num == matched_lock->lock_num) && (0 == strcmp (domain_name, matched_lock->domain_name))) return GNUNET_NO; @@ -266,7 +265,7 @@ add_lock (const char *domain_name, /** - * Removes a lock from the lock map + * Removes a lock from the lock map. The WaitList of the lock should be empty * * @param lock the lock to remove */ @@ -274,7 +273,8 @@ static void remove_lock (struct Lock *lock) { struct GNUNET_HashCode key; - + + GNUNET_assert (NULL == lock->wl_head); get_key (lock->domain_name, lock->lock_num, &key); @@ -468,13 +468,14 @@ cl_add_client (struct GNUNET_SERVER_Client *client) /** - * Delete the given client from the client list + * Delete the given client from the client list. The LockList should be empty * * @param cl_entry the client list entry to delete */ static void cl_remove_client (struct ClientList *cl_entry) { + GNUNET_assert (NULL == cl_entry->ll_head); LOG (GNUNET_ERROR_TYPE_DEBUG, "Removing a client from the client list\n"); GNUNET_SERVER_client_drop (cl_entry->client); @@ -635,7 +636,6 @@ process_lock_release (struct Lock *lock) LOG (GNUNET_ERROR_TYPE_DEBUG, "Giving lock to a client from wait list\n"); lock->cl_entry = wl_entry->cl_entry; - cl_ll_add_lock (wl_entry->cl_entry, lock); lock_wl_remove(lock, wl_entry); send_success_msg (lock->cl_entry->client, lock->domain_name, @@ -750,6 +750,68 @@ client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client) } +/** + * Hashmap Iterator to delete lock entries in hash map + * + * @param cls NULL + * @param key current key code + * @param value value in the hash map + * @return GNUNET_YES if we should continue to + * iterate, + * GNUNET_NO if not. + */ +static int +lock_delete_iterator (void *cls, + const GNUNET_HashCode * key, + void *value) +{ + struct Lock *lock = value; + + GNUNET_assert (NULL != lock); + while (NULL != lock->wl_head) + { + lock_wl_remove (lock, lock->wl_head); + } + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove(lock_map, + key, + lock)); + GNUNET_free (lock->domain_name); + GNUNET_free (lock); + return GNUNET_YES; +} + + +/** + * Task to clean up and shutdown nicely + * + * @param + * @return + */ +static void +shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Shutting down lock manager\n"); + /* Clean the global ClientList */ + while (NULL != cl_head) + { + while (NULL != cl_head->ll_head) /* Clear the LockList */ + { + cl_ll_remove_lock (cl_head, cl_head->ll_head); + } + cl_remove_client (cl_head); + } + /* Clean the global hash table */ + GNUNET_CONTAINER_multihashmap_iterate (lock_map, + &lock_delete_iterator, + NULL); + GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (lock_map)); + GNUNET_CONTAINER_multihashmap_destroy (lock_map); +} + + /** * Lock manager setup * @@ -774,6 +836,9 @@ lockmanager_run (void *cls, &client_disconnect_cb, NULL); lock_map = GNUNET_CONTAINER_multihashmap_create (30); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, + &shutdown_task, + NULL); } diff --git a/src/lockmanager/lockmanager_api.c b/src/lockmanager/lockmanager_api.c index 18f5d0a71..1545717ee 100644 --- a/src/lockmanager/lockmanager_api.c +++ b/src/lockmanager/lockmanager_api.c @@ -98,44 +98,28 @@ struct GNUNET_LOCKMANAGER_LockingRequest * The status of the lock */ enum GNUNET_LOCKMANAGER_Status status; - - /** - * The length of the locking domain string including the trailing NULL - */ - uint16_t domain_name_length; }; /** - * Generate hash with domain name and the lock + * Get the key for the given lock in the 'lock_map'. * - * @param domain NULL terminated domain name - * - * @param domain_length the length of the domain name including the terminating - * NULL if already known; 0 to calculate - * - * @param lock the lock number - * @param ret where to write the generated hash + * @param domain_name + * @param lock_number + * @param key set to the key */ static void -hash_domain_and_lock (const char *domain, - uint16_t domain_length, - uint32_t lock, - GNUNET_HashCode *ret) +get_key (const char *domain_name, + uint32_t lock_number, + struct GNUNET_HashCode *key) { - unsigned int str_len; - uint32_t *block; - size_t block_size; - - str_len = (0 == domain_length) ? strlen (domain) : domain_length - 1; - block_size = sizeof (uint32_t) + str_len; - block = GNUNET_malloc (block_size); - /* Copy data */ - *block = lock; - memcpy (&block[1], domain, str_len); - - GNUNET_CRYPTO_hash (block, block_size, ret); - GNUNET_free (block); + uint32_t *last_32; + + GNUNET_CRYPTO_hash (domain_name, + strlen (domain_name), + key); + last_32 = (uint32_t *) key; + *last_32 ^= lock_number; } @@ -151,15 +135,15 @@ call_status_cb_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) const struct GNUNET_LOCKMANAGER_LockingRequest *r = cls; if (NULL != r->status_cb) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Calling status change callback for lock: %d in domain: %s\n", - r->lock, r->domain); - r->status_cb (r->status_cb_cls, - r->domain, - r->lock, - r->status); - } + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Calling status change callback for lock: %d in domain: %s\n", + r->lock, r->domain); + r->status_cb (r->status_cb_cls, + r->domain, + r->lock, + r->status); + } } @@ -174,67 +158,70 @@ handle_replies (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_LOCKMANAGER_Handle *handle = cls; - + const struct GNUNET_LOCKMANAGER_Message *m; + const char *domain; + struct GNUNET_HashCode hash; + int match_found; + uint32_t lock; + uint16_t msize; + if (NULL == msg) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Lockmanager service not available or went down\n"); + return; + } + if (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS != ntohs(msg->type)) + { + GNUNET_break (0); + return; + } + msize = ntohs (msg->size); + if (msize <= sizeof (struct GNUNET_LOCKMANAGER_Message)) + { + GNUNET_break (0); + return; + } + m = (const struct GNUNET_LOCKMANAGER_Message *) msg; + domain = (const char *) &m[1]; + msize -= sizeof (struct GNUNET_LOCKMANAGER_Message); + if ('\0' != domain[msize-1]) + { + GNUNET_break (0); + return; + } + + lock = ntohl (m->lock); + get_key (domain, lock, &hash); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received SUCCESS message for lock: %d, domain %s\n", + lock, domain); + int match_iterator(void *cls, const GNUNET_HashCode *key, void *value) + { + struct GNUNET_LOCKMANAGER_LockingRequest *r = value; + + if ( !((0 == strcmp (domain, r->domain)) + && (lock == r->lock))) + return GNUNET_YES; + match_found = GNUNET_YES; + if (GNUNET_LOCKMANAGER_SUCCESS != r->status) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "Lockmanager service not available or went down\n"); - return; - } - - switch (ntohs (msg->type)) - { - case GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS: - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Received SUCCESS message\n"); - - const struct GNUNET_LOCKMANAGER_Message *m; - const char *domain; - struct GNUNET_HashCode hash; - uint32_t lock; - int match_found; - - m = (struct GNUNET_LOCKMANAGER_Message *) msg; - domain = (char *) &m[1]; - lock = ntohl (m->lock); - hash_domain_and_lock (domain, 0, lock, &hash); - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "\t on lock: %d in domain %s\n", - lock, domain); - - int match_iterator(void *cls, const GNUNET_HashCode *key, void *value) - { - struct GNUNET_LOCKMANAGER_LockingRequest *r = value; - - if ( !((0 == strcmp (domain, r->domain)) - && (lock == r->lock))) - return GNUNET_YES; - - match_found = GNUNET_YES; - if (GNUNET_LOCKMANAGER_SUCCESS != r->status) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Changing status for lock: %d in domain: %s to SUCCESS\n", - r->lock, r->domain); - r->status = GNUNET_LOCKMANAGER_SUCCESS; - GNUNET_SCHEDULER_add_continuation (&call_status_cb_task, - r, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); - } - return GNUNET_NO; - } - - match_found = GNUNET_NO; - GNUNET_CONTAINER_multihashmap_get_multiple (handle->hashmap, - &hash, - &match_iterator, - NULL); - GNUNET_assert (GNUNET_YES == match_found); - break; - default: - GNUNET_break(0); + "Changing status for lock: %d in domain: %s to SUCCESS\n", + r->lock, r->domain); + r->status = GNUNET_LOCKMANAGER_SUCCESS; + GNUNET_SCHEDULER_add_continuation (&call_status_cb_task, + r, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); } + return GNUNET_NO; + } + match_found = GNUNET_NO; + GNUNET_CONTAINER_multihashmap_get_multiple (handle->hashmap, + &hash, + &match_iterator, + NULL); + GNUNET_break (GNUNET_YES == match_found); } @@ -253,10 +240,10 @@ transmit_notify (void *cls, size_t size, void *buf) uint16_t msg_size; if ((0 == size) || (NULL == buf)) - { - /* FIXME: Timed out -- requeue? */ - return 0; - } + { + /* FIXME: Timed out -- requeue? */ + return 0; + } msg_size = ntohs (msg->header.size); GNUNET_assert (size >= msg_size); memcpy (buf, msg, msg_size); @@ -313,15 +300,13 @@ GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) h = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_Handle)); h->conn = GNUNET_CLIENT_connect ("lockmanager", cfg); if (NULL == h->conn) - { - GNUNET_free (h); - LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); - return NULL; - } - + { + GNUNET_free (h); + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); + return NULL; + } h->hashmap = GNUNET_CONTAINER_multihashmap_create (15); GNUNET_assert (NULL != h->hashmap); - GNUNET_CLIENT_receive (h->conn, &handle_replies, h, @@ -342,18 +327,16 @@ GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle) { LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); GNUNET_CLIENT_disconnect (handle->conn); - if (0 != GNUNET_CONTAINER_multihashmap_size (handle->hashmap)) - { - LOG (GNUNET_ERROR_TYPE_WARNING, - "Some locking requests are still present. Cancel them before " - "calling %s\n", __func__); - GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap, - &free_iterator, - NULL); - } + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Some locking requests are still present. Cancel them before " + "calling %s\n", __func__); + GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap, + &free_iterator, + NULL); + } GNUNET_CONTAINER_multihashmap_destroy (handle->hashmap); - GNUNET_free (handle); LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); } @@ -395,25 +378,24 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, struct GNUNET_LOCKMANAGER_Message *msg; struct GNUNET_HashCode hash; uint16_t msg_size; + size_t domain_name_length; LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); r = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_LockingRequest)); - r->domain_name_length = strlen (domain_name) + 1; + domain_name_length = strlen (domain_name) + 1; r->handle = handle; r->lock = lock; - r->domain = GNUNET_malloc (r->domain_name_length); + r->domain = GNUNET_malloc (domain_name_length); r->status = GNUNET_LOCKMANAGER_RELEASE; r->status_cb = status_cb; r->status_cb_cls = status_cb_cls; - memcpy (r->domain, domain_name, r->domain_name_length); - - msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + r->domain_name_length; + memcpy (r->domain, domain_name, domain_name_length); + msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_length; msg = GNUNET_malloc (msg_size); msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE); msg->header.size = htons (msg_size); msg->lock = htonl (lock); - memcpy (&msg[1], r->domain, r->domain_name_length); - + memcpy (&msg[1], r->domain, domain_name_length); LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n"); r->transmit_handle = GNUNET_CLIENT_notify_transmit_ready (r->handle->conn, @@ -422,15 +404,11 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, GNUNET_YES, &transmit_notify, msg); - hash_domain_and_lock (r->domain, - r->domain_name_length, - r->lock, - &hash); + get_key (r->domain, r->lock, &hash); GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap, &hash, r, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); - LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); return r; } @@ -449,40 +427,34 @@ void GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest *request) { + struct GNUNET_LOCKMANAGER_Message *msg; struct GNUNET_HashCode hash; + uint16_t msg_size; + size_t domain_name_length; LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); /* FIXME: Stop ACQUIRE retransmissions */ if (GNUNET_LOCKMANAGER_SUCCESS == request->status) - { - struct GNUNET_LOCKMANAGER_Message *msg; - uint16_t msg_size; - - msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) - + request->domain_name_length; - msg = GNUNET_malloc (msg_size); - msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE); - msg->header.size = htons (msg_size); - msg->lock = htonl (request->lock); - memcpy (&msg[1], request->domain, request->domain_name_length); - - GNUNET_CLIENT_notify_transmit_ready (request->handle->conn, - msg_size, - TIMEOUT, /* What if this fails */ - GNUNET_NO, - &transmit_notify, - msg); - } - - hash_domain_and_lock (request->domain, - request->domain_name_length, - request->lock, - &hash); - + { + domain_name_length = strlen (request->domain) + 1; + msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + + domain_name_length; + msg = GNUNET_malloc (msg_size); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE); + msg->header.size = htons (msg_size); + msg->lock = htonl (request->lock); + memcpy (&msg[1], request->domain, domain_name_length); + GNUNET_CLIENT_notify_transmit_ready (request->handle->conn, + msg_size, + TIMEOUT, /* What if this fails */ + GNUNET_NO, + &transmit_notify, + msg); + } + get_key (request->domain, request->lock, &hash); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (request->handle->hashmap, &hash, request)); - GNUNET_free (request->domain); GNUNET_free (request); LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); diff --git a/src/lockmanager/test_lockmanager_api.conf b/src/lockmanager/test_lockmanager_api.conf index b6a291730..aa13706cd 100644 --- a/src/lockmanager/test_lockmanager_api.conf +++ b/src/lockmanager/test_lockmanager_api.conf @@ -5,7 +5,7 @@ PORT = 12112 ACCEPT_FROM = 127.0.0.1; HOSTNAME = localhost # PREFIX = valgrind --leak-check=full -# PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args +# PREFIX = xterm -geometry 100x85 -T peer1 -e libtool --mode=execute gdb --args [fs] AUTOSTART = NO diff --git a/src/lockmanager/test_lockmanager_api_lockrelease.c b/src/lockmanager/test_lockmanager_api_lockrelease.c new file mode 100644 index 000000000..8eea5cc22 --- /dev/null +++ b/src/lockmanager/test_lockmanager_api_lockrelease.c @@ -0,0 +1,301 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file lockmanager/test_lockmanager_api_lockrelease.c + * @brief Test cases for lockmanager_api where client disconnects abruptly + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_lockmanager_service.h" + +#define VERBOSE GNUNET_YES + +#define VERBOSE_ARM 1 + +#define LOG(kind,...) \ + GNUNET_log (kind, __VA_ARGS__) + +#define TIME_REL_SECONDS(min) \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, min) + +/** + * Various steps of the test + */ +enum Test + { + /** + * Signal test failure + */ + TEST_FAIL, + + /** + * Testing just began + */ + TEST_INIT, + + /** + * Client 1 has got the lock successfully; Client 2 should try to acquire + * the lock now; after some time client 1 has to release the lock + */ + TEST_CLIENT1_LOCK_SUCCESS, + + /** + * Client 2 has got the lock; Should release it and call shutdown + */ + TEST_CLIENT2_LOCK_SUCCESS, + }; + +/** + * The testing result + */ +static enum Test result; + +/** + * The process id of the GNUNET ARM process + */ +static struct GNUNET_OS_Process *arm_pid = NULL; + +/** + * Configuration Handle + */ +static struct GNUNET_CONFIGURATION_Handle *config; + +/** + * The handle to the lockmanager service + */ +static struct GNUNET_LOCKMANAGER_Handle *handle; + +/** + * A second client handle to the lockmanager service + */ +static struct GNUNET_LOCKMANAGER_Handle *handle2; + +/** + * The locking request + */ +static struct GNUNET_LOCKMANAGER_LockingRequest *request; + +/** + * The locking request of second client + */ +static struct GNUNET_LOCKMANAGER_LockingRequest *request2; + +/** + * Abort task identifier + */ +static GNUNET_SCHEDULER_TaskIdentifier abort_task_id; + + +/** + * Shutdown nicely + * + * @param cls + * @param tc the task context + */ +static void +do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (GNUNET_SCHEDULER_NO_TASK != abort_task_id) + { + GNUNET_SCHEDULER_cancel (abort_task_id); + abort_task_id = GNUNET_SCHEDULER_NO_TASK; + } + + GNUNET_LOCKMANAGER_disconnect (handle); + GNUNET_LOCKMANAGER_disconnect (handle2); + if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Kill gnunet-service-arm manually\n"); + } + GNUNET_OS_process_wait (arm_pid); + GNUNET_OS_process_destroy (arm_pid); + + if (NULL != config) + GNUNET_CONFIGURATION_destroy (config); +} + + +/** + * Abort + * + * @param cls + * @param tc the task context + */ +static void +do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, "Aborting test...\n"); + abort_task_id = GNUNET_SCHEDULER_NO_TASK; + result = TEST_FAIL; + do_shutdown (cls, tc); +} + + +/** + * Callback for lock status changes + * + * @param cls the handle + * + * @param domain_name the locking domain of the lock + * + * @param lock the lock for which this status is relevant + * + * @param status GNUNET_LOCKMANAGER_SUCCESS if the lock has been successfully + * acquired; GNUNET_LOCKMANAGER_RELEASE when the acquired lock is lost + */ +static void +status_cb (void *cls, + const char *domain_name, + uint32_t lock, + enum GNUNET_LOCKMANAGER_Status status) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Status change callback called on lock: %d of domain: %s\n", + lock, domain_name); + GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status); + switch (result) + { + case TEST_INIT: + GNUNET_assert (handle == cls); + result = TEST_CLIENT1_LOCK_SUCCESS; + request2 = GNUNET_LOCKMANAGER_acquire_lock (handle2, + "GNUNET_LOCKMANAGER_TESTING", + 99, + &status_cb, + handle2); + GNUNET_assert (NULL != request2); + GNUNET_LOCKMANAGER_cancel_request (request); + request = NULL; + break; + case TEST_CLIENT1_LOCK_SUCCESS: + GNUNET_assert (handle2 == cls); + result = TEST_CLIENT2_LOCK_SUCCESS; + GNUNET_LOCKMANAGER_cancel_request (request2); + GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1), + &do_shutdown, + NULL); + break; + default: + GNUNET_assert (0); /* We should never reach here */ + } + +} + + +/** + * Testing function + * + * @param cls NULL + * @param tc the task context + */ +static void +test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + result = TEST_INIT; + handle = GNUNET_LOCKMANAGER_connect (config); + GNUNET_assert (NULL != handle); + handle2 = GNUNET_LOCKMANAGER_connect (config); + + request = GNUNET_LOCKMANAGER_acquire_lock (handle, + "GNUNET_LOCKMANAGER_TESTING", + 99, + &status_cb, + handle); + GNUNET_assert (NULL != request); + abort_task_id = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (60), + &do_abort, + NULL); +} + + +/** + * Main point of test execution + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting test...\n"); + config = GNUNET_CONFIGURATION_dup (cfg); + arm_pid = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", +#if VERBOSE_ARM + "-L", "DEBUG", +#endif + "-c", "test_lockmanager_api.conf", NULL); + + GNUNET_assert (NULL != arm_pid); + GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1), + &test, + NULL); +} + + +/** + * Main function + */ +int main (int argc, char **argv) +{ + int ret; + + char *const argv2[] = { "test-lockmanager-api-lockrelease", + "-c", "test_lockmanager_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + GNUNET_log_setup ("test-lockmanager-api-lockrelease", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + + ret = + GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, + "test-lockmanager-api-lockrelease", + "nohelp", options, &run, NULL); + + if (GNUNET_OK != ret) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n", + ret); + return 1; + } + if (TEST_CLIENT2_LOCK_SUCCESS != result) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "test failed\n"); + return 1; + } + LOG (GNUNET_ERROR_TYPE_INFO, "test OK\n"); + return 0; +} -- cgit v1.2.3