do not start mesh
[oweals/gnunet.git] / src / datastore / test_datastore_api.c
index 7eaa09262c035c2186ae5edfe1909b3627844f72..91350f2033c2c2660f8e0b2cb914dd2550ead91b 100644 (file)
@@ -4,7 +4,7 @@
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      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
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
 */
 /*
  * @file datastore/test_datastore_api.c
 */
 /*
  * @file datastore/test_datastore_api.c
- * @brief Test for the datastore implementation.
+ * @brief Test for the basic datastore API.
  * @author Christian Grothoff
  *
  * TODO:
  * @author Christian Grothoff
  *
  * TODO:
- * - test multiple values under same key
- * - test "update"
- * - test storage reservations
+ * - test reservation failure
  */
 
 #include "platform.h"
  */
 
 #include "platform.h"
@@ -35,6 +33,8 @@
 
 #define VERBOSE GNUNET_NO
 
 
 #define VERBOSE GNUNET_NO
 
+#define START_DATASTORE GNUNET_YES
+
 /**
  * How long until we give up on transmitting the message?
  */
 /**
  * How long until we give up on transmitting the message?
  */
@@ -48,6 +48,10 @@ static struct GNUNET_TIME_Absolute now;
 
 static int ok;
 
 
 static int ok;
 
+/**
+ * Name of plugin under test.
+ */
+static const char *plugin_name;
 
 static size_t
 get_size (int i)
 
 static size_t
 get_size (int i)
@@ -59,333 +63,447 @@ get_size (int i)
 static const void *
 get_data (int i)
 {
 static const void *
 get_data (int i)
 {
-  static char buf[60000]; 
+  static char buf[60000];
+
   memset (buf, i, 8 * i);
   return buf;
 }
 
 
 static int
   memset (buf, i, 8 * i);
   return buf;
 }
 
 
 static int
-get_type(int i)
+get_type (int i)
 {
 {
-  return i+1;
+  return i + 1;
 }
 
 
 }
 
 
-static int 
+static int
 get_priority (int i)
 {
 get_priority (int i)
 {
-  return i+1;
+  return i + 1;
 }
 
 
 static int
 }
 
 
 static int
-get_anonymity(int i)
+get_anonymity (int i)
 {
   return i;
 }
 
 
 {
   return i;
 }
 
 
-static struct GNUNET_TIME_Absolute 
+static struct GNUNET_TIME_Absolute
 get_expiration (int i)
 {
   struct GNUNET_TIME_Absolute av;
 
 get_expiration (int i)
 {
   struct GNUNET_TIME_Absolute av;
 
-  av.value = now.value - i * 1000;
+  av.abs_value = now.abs_value + 20000000 - i * 1000;
   return av;
 }
 
 enum RunPhase
   return av;
 }
 
 enum RunPhase
-  {
-    RP_DONE = 0,
-    RP_PUT,
-    RP_GET,
-    RP_DEL,
-    RP_DO_DEL,
-    RP_DELVALIDATE
-  };
+{
+  RP_DONE = 0,
+  RP_PUT = 1,
+  RP_GET = 2,
+  RP_DEL = 3,
+  RP_DO_DEL = 4,
+  RP_DELVALIDATE = 5,
+  RP_RESERVE = 6,
+  RP_PUT_MULTIPLE = 7,
+  RP_PUT_MULTIPLE_NEXT = 8,
+  RP_GET_MULTIPLE = 9,
+  RP_GET_MULTIPLE_NEXT = 10,
+  RP_UPDATE = 11,
+  RP_UPDATE_VALIDATE = 12,
+  RP_ERROR
+};
 
 
 struct CpsRunContext
 {
   GNUNET_HashCode key;
   int i;
 
 
 struct CpsRunContext
 {
   GNUNET_HashCode key;
   int i;
-  int *iptr;
-  struct GNUNET_SCHEDULER_Handle *sched;
-  struct GNUNET_CONFIGURATION_Handle *cfg;
+  int rid;
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
   void *data;
   size_t size;
   enum RunPhase phase;
   void *data;
   size_t size;
   enum RunPhase phase;
+  uint64_t uid;
+  uint64_t offset;
+  uint64_t first_uid;
 };
 
 
 static void
 };
 
 
 static void
-run_continuation (void *cls,
-                 const struct GNUNET_SCHEDULER_TaskContext *tc);
+run_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
 
 
 static void
 
 
 static void
-check_success (void *cls,
-              int success,
-              const char *msg)
+check_success (void *cls, int success, const char *msg)
 {
   struct CpsRunContext *crc = cls;
 {
   struct CpsRunContext *crc = cls;
+
   if (GNUNET_OK != success)
   if (GNUNET_OK != success)
+  {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-               "%s\n", msg);
-  GNUNET_assert (GNUNET_OK == success);
+                "Operation %d/%d not successfull: `%s'\n", crc->phase, crc->i,
+                msg);
+    crc->phase = RP_ERROR;
+  }
   GNUNET_free_non_null (crc->data);
   crc->data = NULL;
   GNUNET_free_non_null (crc->data);
   crc->data = NULL;
-  GNUNET_SCHEDULER_add_continuation (crc->sched,
-                                    GNUNET_NO,
-                                    &run_continuation,
-                                    crc,
-                                    GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
+                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
 }
 
 
 }
 
 
-static void 
-check_value (void *cls,
-            const GNUNET_HashCode * key,
-            uint32_t size,
-            const void *data,
-            uint32_t type,
-            uint32_t priority,
-            uint32_t anonymity,
-            struct GNUNET_TIME_Absolute
-            expiration, uint64_t uid)
+static void
+get_reserved (void *cls, int success, const char *msg)
+{
+  struct CpsRunContext *crc = cls;
+
+  if (0 >= success)
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error obtaining reservation: `%s'\n",
+                msg);
+  GNUNET_assert (0 < success);
+  crc->rid = success;
+  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
+                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+}
+
+
+static void
+check_value (void *cls, const GNUNET_HashCode * key, size_t size,
+             const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority,
+             uint32_t anonymity, struct GNUNET_TIME_Absolute expiration,
+             uint64_t uid)
 {
   struct CpsRunContext *crc = cls;
   int i;
 
 {
   struct CpsRunContext *crc = cls;
   int i;
 
-  if (key == NULL)
-    {
-      if (crc->i == 0)
-       {
-         crc->phase = RP_DEL;
-         crc->i = ITERATIONS;
-       }
-      GNUNET_SCHEDULER_add_continuation (crc->sched,
-                                        GNUNET_NO,
-                                        &run_continuation,
-                                        crc,
-                                        GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-      return;
-    }
   i = crc->i;
   i = crc->i;
+#if 0
+  fprintf (stderr, "Check value got `%s' of size %u, type %d, expire %llu\n",
+           GNUNET_h2s (key), (unsigned int) size, type,
+           (unsigned long long) expiration.abs_value);
+  fprintf (stderr,
+           "Check value iteration %d wants size %u, type %d, expire %llu\n", i,
+           (unsigned int) get_size (i), get_type (i),
+           (unsigned long long) get_expiration (i).abs_value);
+#endif
   GNUNET_assert (size == get_size (i));
   GNUNET_assert (size == get_size (i));
-  GNUNET_assert (0 == memcmp (data, get_data(i), size));
+  GNUNET_assert (0 == memcmp (data, get_data (i), size));
   GNUNET_assert (type == get_type (i));
   GNUNET_assert (priority == get_priority (i));
   GNUNET_assert (type == get_type (i));
   GNUNET_assert (priority == get_priority (i));
-  GNUNET_assert (anonymity == get_anonymity(i));
-  GNUNET_assert (expiration.value == get_expiration(i).value);
+  GNUNET_assert (anonymity == get_anonymity (i));
+  GNUNET_assert (expiration.abs_value == get_expiration (i).abs_value);
+  crc->offset++;
+  if (crc->i == 0)
+  {
+    crc->phase = RP_DEL;
+    crc->i = ITERATIONS;
+  }
+  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
+                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
 }
 
 
 }
 
 
-static void 
-delete_value (void *cls,
-            const GNUNET_HashCode * key,
-            uint32_t size,
-            const void *data,
-            uint32_t type,
-            uint32_t priority,
-            uint32_t anonymity,
-            struct GNUNET_TIME_Absolute
-            expiration, uint64_t uid)
+static void
+delete_value (void *cls, const GNUNET_HashCode * key, size_t size,
+              const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority,
+              uint32_t anonymity, struct GNUNET_TIME_Absolute expiration,
+              uint64_t uid)
 {
   struct CpsRunContext *crc = cls;
 {
   struct CpsRunContext *crc = cls;
-  if (key == NULL)
-    {
-      crc->phase = RP_DO_DEL;
-      GNUNET_SCHEDULER_add_continuation (crc->sched,
-                                        GNUNET_NO,
-                                        &run_continuation,
-                                        crc,
-                                        GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-      return;
-    }
+
   GNUNET_assert (crc->data == NULL);
   GNUNET_assert (crc->data == NULL);
+  GNUNET_assert (NULL != key);
   crc->size = size;
   crc->key = *key;
   crc->data = GNUNET_malloc (size);
   memcpy (crc->data, data, size);
   crc->size = size;
   crc->key = *key;
   crc->data = GNUNET_malloc (size);
   memcpy (crc->data, data, size);
+  crc->phase = RP_DO_DEL;
+  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
+                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
 }
 
 
 }
 
 
-static void 
-check_nothing (void *cls,
-            const GNUNET_HashCode * key,
-            uint32_t size,
-            const void *data,
-            uint32_t type,
-            uint32_t priority,
-            uint32_t anonymity,
-            struct GNUNET_TIME_Absolute
-            expiration, uint64_t uid)
+static void
+check_nothing (void *cls, const GNUNET_HashCode * key, size_t size,
+               const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority,
+               uint32_t anonymity, struct GNUNET_TIME_Absolute expiration,
+               uint64_t uid)
 {
   struct CpsRunContext *crc = cls;
 {
   struct CpsRunContext *crc = cls;
+
   GNUNET_assert (key == NULL);
   if (crc->i == 0)
   GNUNET_assert (key == NULL);
   if (crc->i == 0)
-    {
-      crc->phase = RP_DONE;      
-    }
-  GNUNET_SCHEDULER_add_continuation (crc->sched,
-                                    GNUNET_NO,
-                                    &run_continuation,
-                                    crc,
-                                    GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+    crc->phase = RP_RESERVE;
+  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
+                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
 }
 
 
 static void
 }
 
 
 static void
-run_continuation (void *cls,
-                 const struct GNUNET_SCHEDULER_TaskContext *tc)
+check_multiple (void *cls, const GNUNET_HashCode * key, size_t size,
+                const void *data, enum GNUNET_BLOCK_Type type,
+                uint32_t priority, uint32_t anonymity,
+                struct GNUNET_TIME_Absolute expiration, uint64_t uid)
 {
   struct CpsRunContext *crc = cls;
 {
   struct CpsRunContext *crc = cls;
+
+  GNUNET_assert (key != NULL);
+  switch (crc->phase)
+  {
+  case RP_GET_MULTIPLE:
+    crc->phase = RP_GET_MULTIPLE_NEXT;
+    crc->first_uid = uid;
+    crc->offset++;
+    break;
+  case RP_GET_MULTIPLE_NEXT:
+    GNUNET_assert (uid != crc->first_uid);
+    crc->phase = RP_UPDATE;
+    break;
+  default:
+    GNUNET_break (0);
+    crc->phase = RP_ERROR;
+    break;
+  }
+  if (priority == get_priority (42))
+    crc->uid = uid;
+  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
+                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+}
+
+
+static void
+check_update (void *cls, const GNUNET_HashCode * key, size_t size,
+              const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority,
+              uint32_t anonymity, struct GNUNET_TIME_Absolute expiration,
+              uint64_t uid)
+{
+  struct CpsRunContext *crc = cls;
+
+  GNUNET_assert (key != NULL);
+  if ((anonymity == get_anonymity (42)) && (size == get_size (42)) &&
+      (priority == get_priority (42) + 100))
+    crc->phase = RP_DONE;
+  else
+  {
+    GNUNET_assert (size == get_size (43));
+    crc->offset++;
+  }
+  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
+                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+}
+
+
+static void
+run_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct CpsRunContext *crc = cls;
+
   ok = (int) crc->phase;
   ok = (int) crc->phase;
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test in phase %u\n", crc->phase);
+#endif
   switch (crc->phase)
   switch (crc->phase)
-    {
-    case RP_PUT:
+  {
+  case RP_PUT:
 #if VERBOSE
 #if VERBOSE
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "Executing `%s' number %u\n",
-                 "PUT",
-                 crc->i);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "PUT",
+                crc->i);
 #endif
 #endif
-      GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
-      GNUNET_DATASTORE_put (datastore,
-                           0,
-                           &crc->key,
-                           get_size (crc->i),
-                           get_data (crc->i),
-                           get_type (crc->i),
-                           get_priority (crc->i),
-                           get_anonymity (crc->i),
-                           get_expiration (crc->i),
-                           TIMEOUT,
-                           &check_success,
-                           crc);
-      crc->i++;
-      if (crc->i == ITERATIONS)
-       crc->phase = RP_GET;
-      break;
-    case RP_GET:
-      crc->i--;
+    GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
+    GNUNET_DATASTORE_put (datastore, 0, &crc->key, get_size (crc->i),
+                          get_data (crc->i), get_type (crc->i),
+                          get_priority (crc->i), get_anonymity (crc->i), 0,
+                          get_expiration (crc->i), 1, 1, TIMEOUT,
+                          &check_success, crc);
+    crc->i++;
+    if (crc->i == ITERATIONS)
+      crc->phase = RP_GET;
+    break;
+  case RP_GET:
+    crc->i--;
 #if VERBOSE
 #if VERBOSE
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "Executing `%s' number %u\n",
-                 "GET",
-                 crc->i);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET",
+                crc->i);
 #endif
 #endif
-      GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
-      GNUNET_DATASTORE_get (datastore, 
-                           &crc->key,
-                           get_type (crc->i),
-                           &check_value,
-                           crc,
-                           TIMEOUT);
-      break;
-    case RP_DEL:
-      crc->i--;
+    GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
+    GNUNET_DATASTORE_get_key (datastore, crc->offset, &crc->key,
+                              get_type (crc->i), 1, 1, TIMEOUT, &check_value,
+                              crc);
+    break;
+  case RP_DEL:
+    crc->i--;
 #if VERBOSE
 #if VERBOSE
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "Executing `%s' number %u\n",
-                 "DEL",
-                 crc->i);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "DEL",
+                crc->i);
 #endif
 #endif
-      GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
-      GNUNET_DATASTORE_get (datastore, 
-                           &crc->key,
-                           get_type (crc->i),
-                           &delete_value,
-                           crc,
-                           TIMEOUT);
-      break;
-    case RP_DO_DEL:
+    crc->data = NULL;
+    GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
+    GNUNET_assert (NULL !=
+                   GNUNET_DATASTORE_get_key (datastore, crc->offset, &crc->key,
+                                             get_type (crc->i), 1, 1, TIMEOUT,
+                                             &delete_value, crc));
+    break;
+  case RP_DO_DEL:
 #if VERBOSE
 #if VERBOSE
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "Executing `%s' number %u\n",
-                 "DO_DEL",
-                 crc->i);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "DO_DEL",
+                crc->i);
 #endif
 #endif
-      if (crc->i == 0)
-       {
-         crc->i = ITERATIONS;   
-         crc->phase = RP_DELVALIDATE;
-       }      
-      else
-       {
-         crc->phase = RP_DEL;
-       }
-      GNUNET_DATASTORE_remove (datastore,
-                              &crc->key,
-                              crc->size,
-                              crc->data,
-                              &check_success,
-                              crc,
-                              TIMEOUT);
-      break;   
-    case RP_DELVALIDATE:
-      crc->i--;
+    if (crc->i == 0)
+    {
+      crc->i = ITERATIONS;
+      crc->phase = RP_DELVALIDATE;
+    }
+    else
+    {
+      crc->phase = RP_DEL;
+    }
+    GNUNET_assert (NULL !=
+                   GNUNET_DATASTORE_remove (datastore, &crc->key, crc->size,
+                                            crc->data, 1, 1, TIMEOUT,
+                                            &check_success, crc));
+    break;
+  case RP_DELVALIDATE:
+    crc->i--;
 #if VERBOSE
 #if VERBOSE
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "Executing `%s' number %u\n",
-                 "DEL-VALIDATE",
-                 crc->i);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n",
+                "DEL-VALIDATE", crc->i);
 #endif
 #endif
-      GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
-      GNUNET_DATASTORE_get (datastore, 
-                           &crc->key,
-                           get_type (crc->i),
-                           &check_nothing,
-                           crc,
-                           TIMEOUT);
-      break;
-  /* check reservations */
-  /* check update */
-  /* test multiple results */
-    case RP_DONE:
+    GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
+    GNUNET_assert (NULL !=
+                   GNUNET_DATASTORE_get_key (datastore, crc->offset, &crc->key,
+                                             get_type (crc->i), 1, 1, TIMEOUT,
+                                             &check_nothing, crc));
+    break;
+  case RP_RESERVE:
+    crc->phase = RP_PUT_MULTIPLE;
+    GNUNET_DATASTORE_reserve (datastore, 128 * 1024, 2, 1, 1, TIMEOUT,
+                              &get_reserved, crc);
+    break;
+  case RP_PUT_MULTIPLE:
+    crc->phase = RP_PUT_MULTIPLE_NEXT;
+    GNUNET_DATASTORE_put (datastore, crc->rid, &crc->key, get_size (42),
+                          get_data (42), get_type (42), get_priority (42),
+                          get_anonymity (42), 0, get_expiration (42), 1, 1,
+                          TIMEOUT, &check_success, crc);
+    break;
+  case RP_PUT_MULTIPLE_NEXT:
+    crc->phase = RP_GET_MULTIPLE;
+    GNUNET_DATASTORE_put (datastore, crc->rid, &crc->key, get_size (43),
+                          get_data (43), get_type (42), get_priority (43),
+                          get_anonymity (43), 0, get_expiration (43), 1, 1,
+                          TIMEOUT, &check_success, crc);
+    break;
+  case RP_GET_MULTIPLE:
+    GNUNET_assert (NULL !=
+                   GNUNET_DATASTORE_get_key (datastore, crc->offset, &crc->key,
+                                             get_type (42), 1, 1, TIMEOUT,
+                                             &check_multiple, crc));
+    break;
+  case RP_GET_MULTIPLE_NEXT:
+    GNUNET_assert (NULL !=
+                   GNUNET_DATASTORE_get_key (datastore, crc->offset, &crc->key,
+                                             get_type (42), 1, 1, TIMEOUT,
+                                             &check_multiple, crc));
+    break;
+  case RP_UPDATE:
+    GNUNET_assert (crc->uid > 0);
+    crc->phase = RP_UPDATE_VALIDATE;
+    GNUNET_DATASTORE_update (datastore, crc->uid, 100, get_expiration (42), 1,
+                             1, TIMEOUT, &check_success, crc);
+    break;
+  case RP_UPDATE_VALIDATE:
+    GNUNET_assert (NULL !=
+                   GNUNET_DATASTORE_get_key (datastore, crc->offset, &crc->key,
+                                             get_type (42), 1, 1, TIMEOUT,
+                                             &check_update, crc));
+    break;
+  case RP_DONE:
 #if VERBOSE
 #if VERBOSE
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "Finished, disconnecting\n");
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished, disconnecting\n");
 #endif
 #endif
-      GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES);
-      ok = 0;
-    }
+    GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES);
+    GNUNET_free (crc);
+    ok = 0;
+    break;
+  case RP_ERROR:
+    GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES);
+    GNUNET_free (crc);
+    ok = 43;
+    break;
+  }
 }
 
 
 static void
 }
 
 
 static void
-run (void *cls,
-     struct GNUNET_SCHEDULER_Handle *sched,
-     char *const *args,
-     const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
+run_tests (void *cls, int32_t success, const char *msg)
+{
+  struct CpsRunContext *crc = cls;
+
+  switch (success)
+  {
+  case GNUNET_YES:
+    GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
+                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+    return;
+  case GNUNET_NO:
+    fprintf (stderr, "Test 'put' operation failed, key already exists (!?)\n");
+    GNUNET_free (crc);
+    return;
+  case GNUNET_SYSERR:
+    fprintf (stderr,
+             "Test 'put' operation failed with error `%s' database likely not setup, skipping test.\n",
+             msg);
+    GNUNET_free (crc);
+    return;
+  default:
+    GNUNET_assert (0);
+  }
+}
+
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
   struct CpsRunContext *crc;
 {
   struct CpsRunContext *crc;
+  static GNUNET_HashCode zkey;
 
 
-  crc = GNUNET_malloc(sizeof(struct CpsRunContext));
-  crc->sched = sched;
+  crc = GNUNET_malloc (sizeof (struct CpsRunContext));
   crc->cfg = cfg;
   crc->phase = RP_PUT;
   crc->cfg = cfg;
   crc->phase = RP_PUT;
-  now.value = 1000000;
-  datastore = GNUNET_DATASTORE_connect (cfg, sched);
-  GNUNET_SCHEDULER_add_continuation (crc->sched,
-                                    GNUNET_NO,
-                                    &run_continuation,
-                                    crc,
-                                    GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-
+  now = GNUNET_TIME_absolute_get ();
+  datastore = GNUNET_DATASTORE_connect (cfg);
+  if (NULL ==
+      GNUNET_DATASTORE_put (datastore, 0, &zkey, 4, "TEST",
+                            GNUNET_BLOCK_TYPE_TEST, 0, 0, 0,
+                            GNUNET_TIME_relative_to_absolute
+                            (GNUNET_TIME_UNIT_SECONDS), 0, 1,
+                            GNUNET_TIME_UNIT_MINUTES, &run_tests, crc))
+  {
+    fprintf (stderr, "Test 'put' operation failed.\n");
+    ok = 1;
+    GNUNET_free (crc);
+  }
 }
 
 
 }
 
 
-
 static int
 check ()
 {
 static int
 check ()
 {
-  pid_t pid;
-  char *const argv[] = { "test-datastore-api",
+  char cfg_name[128];
+
+#if START_DATASTORE
+  struct GNUNET_OS_Process *proc;
+#endif
+  char *const argv[] = {
+    "test-datastore-api",
     "-c",
     "-c",
-    "test_datastore_api_data.conf",
+    cfg_name,
 #if VERBOSE
     "-L", "DEBUG",
 #endif
 #if VERBOSE
     "-L", "DEBUG",
 #endif
@@ -394,22 +512,31 @@ check ()
   struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
   struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
-  pid = GNUNET_OS_start_process ("gnunet-service-datastore",
-                                 "gnunet-service-datastore",
+  GNUNET_snprintf (cfg_name, sizeof (cfg_name),
+                   "test_datastore_api_data_%s.conf", plugin_name);
+#if START_DATASTORE
+  proc =
+      GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+                               "gnunet-service-arm",
 #if VERBOSE
 #if VERBOSE
-                                 "-L", "DEBUG",
+                               "-L", "DEBUG",
+#endif
+                               "-c", cfg_name, NULL);
+#endif
+  GNUNET_assert (NULL != proc);
+  GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv,
+                      "test-datastore-api", "nohelp", options, &run, NULL);
+#if START_DATASTORE
+  sleep (1);                    /* give datastore chance to receive 'DROP' request */
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+    ok = 1;
+  }
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
 #endif
 #endif
-                                 "-c", "test_datastore_api_data.conf", NULL);
-  sleep (1);
-  GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
-                      argv, "test-datastore-api", "nohelp",
-                      options, &run, NULL);
-  if (0 != PLIBC_KILL (pid, SIGTERM))
-    {
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-      ok = 1;
-    }
-  GNUNET_OS_process_wait(pid);
   if (ok != 0)
     fprintf (stderr, "Missed some testcases: %u\n", ok);
   return ok;
   if (ok != 0)
     fprintf (stderr, "Missed some testcases: %u\n", ok);
   return ok;
@@ -419,8 +546,22 @@ int
 main (int argc, char *argv[])
 {
   int ret;
 main (int argc, char *argv[])
 {
   int ret;
-  
-  GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-datastore");
+  char *pos;
+  char dir_name[128];
+
+  sleep (1);
+  /* determine name of plugin to use */
+  plugin_name = argv[0];
+  while (NULL != (pos = strstr (plugin_name, "_")))
+    plugin_name = pos + 1;
+  if (NULL != (pos = strstr (plugin_name, ".")))
+    pos[0] = 0;
+  else
+    pos = (char *) plugin_name;
+
+  GNUNET_snprintf (dir_name, sizeof (dir_name), "/tmp/test-gnunet-datastore-%s",
+                   plugin_name);
+  GNUNET_DISK_directory_remove (dir_name);
   GNUNET_log_setup ("test-datastore-api",
 #if VERBOSE
                     "DEBUG",
   GNUNET_log_setup ("test-datastore-api",
 #if VERBOSE
                     "DEBUG",
@@ -429,10 +570,10 @@ main (int argc, char *argv[])
 #endif
                     NULL);
   ret = check ();
 #endif
                     NULL);
   ret = check ();
-
+  if (pos != plugin_name)
+    pos[0] = '.';
+  GNUNET_DISK_directory_remove (dir_name);
   return ret;
 }
 
   return ret;
 }
 
-
-
 /* end of test_datastore_api.c */
 /* end of test_datastore_api.c */