-do not run test without sqlite
[oweals/gnunet.git] / src / psycstore / test_plugin_psycstore.c
index b584ed51de535105db884f14531aa57ea2121027..0a7824929e74dc38e47286bab71ee18a9f6bc07a 100644 (file)
@@ -1,25 +1,26 @@
 /*
-     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 3, 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.
-*/
+ * This file is part of GNUnet
+ * Copyright (C) 2013 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 3, 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
 /*
  * @file psycstore/test_plugin_psycstore.c
- * @brief Test for the psycstore plugins
+ * @brief Test for the PSYCstore plugins.
  * @author Gabor X Toth
  * @author Christian Grothoff
  */
@@ -39,9 +40,8 @@
 
 #define C2ARG(str) str, (sizeof (str) - 1)
 
-#define LOG(kind,...) GNUNET_log_from (kind, "test-plugin-psycstore", __VA_ARGS__)
-
-#define ASSERT(x) do { if (! (x)) { printf("Error at %s:%d\n", __FILE__, __LINE__); goto FAILURE;} } while (0)
+#define LOG(kind,...)                                                          \
+  GNUNET_log_from (kind, "test-plugin-psycstore", __VA_ARGS__)
 
 static int ok;
 
@@ -50,11 +50,11 @@ static int ok;
  */
 static const char *plugin_name;
 
-static struct GNUNET_CRYPTO_EccPrivateKey *channel_key;
-static struct GNUNET_CRYPTO_EccPrivateKey *slave_key;
+static struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key;
+static struct GNUNET_CRYPTO_EcdsaPrivateKey *slave_key;
 
-static struct GNUNET_CRYPTO_EccPublicSignKey channel_pub_key;
-static struct GNUNET_CRYPTO_EccPublicSignKey slave_pub_key;
+static struct GNUNET_CRYPTO_EddsaPublicKey channel_pub_key;
+static struct GNUNET_CRYPTO_EcdsaPublicKey slave_pub_key;
 
 /**
  * Function called when the service shuts down.  Unloads our psycstore
@@ -85,7 +85,7 @@ load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg)
   struct GNUNET_PSYCSTORE_PluginFunctions *ret;
   char *libname;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' psycstore plugin\n"),
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Loading `%s' psycstore plugin\n"),
               plugin_name);
   GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name);
   if (NULL == (ret = GNUNET_PLUGIN_load (libname, (void*) cfg)))
@@ -118,13 +118,13 @@ fragment_cb (void *cls, struct GNUNET_MULTICAST_MessageHeader *msg2,
       && 0 == memcmp (msg1, msg2, ntohs (msg1->header.size)))
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Fragment %llu matches\n",
-         msg1->fragment_id);
+         GNUNET_ntohll (msg1->fragment_id));
     ret = GNUNET_YES;
   }
   else
   {
     LOG (GNUNET_ERROR_TYPE_ERROR, "Fragment %llu differs\n",
-         msg1->fragment_id);
+         GNUNET_ntohll (msg1->fragment_id));
     ret = GNUNET_SYSERR;
   }
 
@@ -135,6 +135,7 @@ fragment_cb (void *cls, struct GNUNET_MULTICAST_MessageHeader *msg2,
 
 struct StateClosure {
   size_t n;
+  char *name[16];
   void *value[16];
   size_t value_size[16];
 };
@@ -146,6 +147,8 @@ state_cb (void *cls, const char *name, const void *value, size_t value_size)
   const void *val = scls->value[scls->n];
   size_t val_size = scls->value_size[scls->n++];
 
+  /* FIXME: check name */
+
   return value_size == val_size && 0 == memcmp (value, val, val_size)
     ? GNUNET_YES
     : GNUNET_SYSERR;
@@ -157,55 +160,62 @@ run (void *cls, char *const *args, const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
   struct GNUNET_PSYCSTORE_PluginFunctions *db;
-  
+
   ok = 1;
   db = load_plugin (cfg);
   if (NULL == db)
   {
     FPRINTF (stderr,
-             "%s", 
+             "%s",
             "Failed to initialize PSYCstore.  "
              "Database likely not setup, skipping test.\n");
     return;
   }
 
-  /* Membership */
+  /* Store & test membership */
 
-  channel_key = GNUNET_CRYPTO_ecc_key_create ();
-  slave_key = GNUNET_CRYPTO_ecc_key_create ();
+  channel_key = GNUNET_CRYPTO_eddsa_key_create ();
+  slave_key = GNUNET_CRYPTO_ecdsa_key_create ();
 
-  GNUNET_CRYPTO_ecc_key_get_public_for_signature (channel_key, &channel_pub_key);
-  GNUNET_CRYPTO_ecc_key_get_public_for_signature (slave_key, &slave_pub_key);
+  GNUNET_CRYPTO_eddsa_key_get_public (channel_key,
+                                                  &channel_pub_key);
+  GNUNET_CRYPTO_ecdsa_key_get_public (slave_key, &slave_pub_key);
 
-  ASSERT (GNUNET_OK == db->membership_store(db->cls, &channel_pub_key,
-                                            &slave_pub_key, GNUNET_YES,
-                                            4, 2, 1));
+  GNUNET_assert (GNUNET_OK == db->membership_store (db->cls, &channel_pub_key,
+                                                    &slave_pub_key, GNUNET_YES,
+                                                    4, 2, 1));
 
-  ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key,
-                                            &slave_pub_key, 4));
+  GNUNET_assert (GNUNET_YES == db->membership_test (db->cls, &channel_pub_key,
+                                                    &slave_pub_key, 4));
 
-  ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key,
-                                            &slave_pub_key, 2));
+  GNUNET_assert (GNUNET_YES == db->membership_test (db->cls, &channel_pub_key,
+                                                    &slave_pub_key, 2));
 
-  ASSERT (GNUNET_NO == db->membership_test(db->cls, &channel_pub_key,
-                                           &slave_pub_key, 1));
+  GNUNET_assert (GNUNET_NO == db->membership_test (db->cls, &channel_pub_key,
+                                                   &slave_pub_key, 1));
 
 
-  /* Messages */
+  /* Store & get messages */
 
   struct GNUNET_MULTICAST_MessageHeader *msg
     = GNUNET_malloc (sizeof (*msg) + sizeof (channel_pub_key));
-  ASSERT (msg != NULL);
+  GNUNET_assert (msg != NULL);
 
   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE);
   msg->header.size = htons (sizeof (*msg) + sizeof (channel_pub_key));
 
-  msg->hop_counter = 9;
-  msg->fragment_id = INT64_MAX - 1;
-  msg->fragment_offset = 0;
-  msg->message_id = INT64_MAX - 2;
-  msg->group_generation = INT64_MAX - 3;
-  msg->flags = GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT;
+  uint64_t fragment_id = INT64_MAX - 1;
+  msg->fragment_id = GNUNET_htonll (fragment_id);
+
+  uint64_t message_id = INT64_MAX - 10;
+  msg->message_id = GNUNET_htonll (message_id);
+
+  uint64_t group_generation = INT64_MAX - 3;
+  msg->group_generation = GNUNET_htonll (group_generation);
+
+  msg->hop_counter = htonl (9);
+  msg->fragment_offset = GNUNET_htonll (0);
+  msg->flags = htonl (GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT);
 
   memcpy (&msg[1], &channel_pub_key, sizeof (channel_pub_key));
 
@@ -214,116 +224,197 @@ run (void *cls, char *const *args, const char *cfgfile,
                              - sizeof (msg->hop_counter)
                              - sizeof (msg->signature));
   msg->purpose.purpose = htonl (234);
-  GNUNET_CRYPTO_ecc_sign (slave_key, &msg->purpose, &msg->signature);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CRYPTO_eddsa_sign (channel_key, &msg->purpose, &msg->signature));
 
   struct FragmentClosure fcls = { 0 };
   fcls.n = 0;
   fcls.msg[0] = msg;
   fcls.flags[0] = GNUNET_PSYCSTORE_MESSAGE_STATE;
 
-  ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg,
-                                           fcls.flags[0]));
+  GNUNET_assert (
+    GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg,
+                                     fcls.flags[0]));
+
+  uint64_t ret_frags = 0;
+  GNUNET_assert (
+    GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key,
+                                   fragment_id, fragment_id,
+                                   &ret_frags, fragment_cb, &fcls));
+  GNUNET_assert (fcls.n == 1);
 
-  ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key,
-                                         msg->fragment_id,
-                                         fragment_cb, &fcls));
-  ASSERT (fcls.n == 1);
+  // FIXME: test fragment_get_latest and message_get_latest
 
   fcls.n = 0;
 
-  ASSERT (GNUNET_OK == db->message_get_fragment (db->cls, &channel_pub_key,
-                                                 msg->message_id,
-                                                 msg->fragment_offset,
-                                                 fragment_cb, &fcls));
-  ASSERT (fcls.n == 1);
+  GNUNET_assert (
+    GNUNET_OK == db->message_get_fragment (db->cls, &channel_pub_key,
+                                           GNUNET_ntohll (msg->message_id),
+                                           GNUNET_ntohll (msg->fragment_offset),
+                                           fragment_cb, &fcls));
+  GNUNET_assert (fcls.n == 1);
 
-  ASSERT (GNUNET_OK == db->message_add_flags (
-            db->cls, &channel_pub_key, msg->message_id,
-            GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED));
+  GNUNET_assert (
+    GNUNET_OK == db->message_add_flags (db->cls, &channel_pub_key,
+                                        GNUNET_ntohll (msg->message_id),
+                                        GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED));
 
   fcls.n = 0;
   fcls.flags[0] |= GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED;
 
-  ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key,
-                                         msg->fragment_id,
-                                         fragment_cb, &fcls));
-  ASSERT (fcls.n == 1);
+  GNUNET_assert (
+    GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key,
+                                   fragment_id, fragment_id,
+                                   &ret_frags, fragment_cb, &fcls));
+  GNUNET_assert (fcls.n == 1);
 
   struct GNUNET_MULTICAST_MessageHeader *msg1
     = GNUNET_malloc (sizeof (*msg1) + sizeof (channel_pub_key));
 
   memcpy (msg1, msg, sizeof (*msg1) + sizeof (channel_pub_key));
 
-  msg1->fragment_id++;
-  msg1->fragment_offset += 32768;
+  msg1->fragment_id = GNUNET_htonll (INT64_MAX);
+  msg1->fragment_offset = GNUNET_htonll (32768);
 
   fcls.n = 0;
   fcls.msg[1] = msg1;
   fcls.flags[1] = GNUNET_PSYCSTORE_MESSAGE_STATE_HASH;
 
-  ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg1,
-                                           fcls.flags[1]));
+  GNUNET_assert (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg1,
+                                                  fcls.flags[1]));
 
-  ASSERT (GNUNET_OK == db->message_get (db->cls, &channel_pub_key,
-                                        msg->message_id,
-                                        fragment_cb, &fcls));
-  ASSERT (fcls.n == 2);
+  GNUNET_assert (
+    GNUNET_OK == db->message_get (db->cls, &channel_pub_key,
+                                  message_id, message_id,
+                                  &ret_frags, fragment_cb, &fcls));
+  GNUNET_assert (fcls.n == 2 && ret_frags == 2);
 
-  uint64_t max_state_msg_id = 0;
-  ASSERT (GNUNET_OK == db->counters_get_slave (db->cls, &channel_pub_key,
-                                               &max_state_msg_id)
-          && max_state_msg_id == msg->message_id);
+  /* Message counters */
 
-  uint64_t fragment_id = 0, message_id = 0, group_generation = 0;
-  ASSERT (GNUNET_OK == db->counters_get_master (db->cls, &channel_pub_key,
-                                                &fragment_id, &message_id,
-                                                &group_generation)
-          && fragment_id == msg1->fragment_id
-          && message_id == msg1->message_id
-          && group_generation == msg1->group_generation);
+  fragment_id = 0;
+  message_id = 0;
+  group_generation = 0;
+  GNUNET_assert (
+    GNUNET_OK == db->counters_message_get (db->cls, &channel_pub_key,
+                                           &fragment_id, &message_id,
+                                           &group_generation)
+    && fragment_id == GNUNET_ntohll (msg1->fragment_id)
+    && message_id == GNUNET_ntohll (msg1->message_id)
+    && group_generation == GNUNET_ntohll (msg1->group_generation));
 
+  /* Modify state */
 
-  /* State */
+  message_id = GNUNET_ntohll (fcls.msg[0]->message_id) + 1;
+  GNUNET_assert (GNUNET_OK == db->state_modify_begin (db->cls, &channel_pub_key,
+                                                      message_id, 0));
 
-  ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo",
-                                      C2ARG("one two three")));
+  GNUNET_assert (GNUNET_OK == db->state_modify_op (db->cls, &channel_pub_key,
+                                                   GNUNET_ENV_OP_ASSIGN,
+                                                   "_foo",
+                                                   C2ARG("one two three")));
 
-  ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo_bar",
-                                      slave_key,
-                                      sizeof (*slave_key)));
+  GNUNET_assert (GNUNET_OK == db->state_modify_op (db->cls, &channel_pub_key,
+                                                   GNUNET_ENV_OP_ASSIGN,
+                                                   "_foo_bar", slave_key,
+                                                   sizeof (*slave_key)));
+
+  GNUNET_assert (GNUNET_OK == db->state_modify_end (db->cls, &channel_pub_key,
+                                                    message_id));
 
   struct StateClosure scls = { 0 };
   scls.n = 0;
   scls.value[0] = "one two three";
   scls.value_size[0] = strlen ("one two three");
 
-  ASSERT (GNUNET_OK == db->state_get (db->cls, &channel_pub_key, "_foo",
-                                      state_cb, &scls));
-  ASSERT (scls.n == 1);
+  GNUNET_assert (GNUNET_OK == db->state_get (db->cls, &channel_pub_key, "_foo",
+                                             state_cb, &scls));
+  GNUNET_assert (scls.n == 1);
 
   scls.n = 0;
   scls.value[1] = slave_key;
   scls.value_size[1] = sizeof (*slave_key);
 
-  ASSERT (GNUNET_OK == db->state_get_all (db->cls, &channel_pub_key, "_foo",
-                                          state_cb, &scls));
-  ASSERT (scls.n == 2);
+  GNUNET_assert (GNUNET_OK == db->state_get_prefix (db->cls, &channel_pub_key,
+                                                    "_foo", state_cb, &scls));
+  GNUNET_assert (scls.n == 2);
 
   scls.n = 0;
-  ASSERT (GNUNET_NO == db->state_get_signed (db->cls, &channel_pub_key,
-                                             state_cb, &scls));
-  ASSERT (scls.n == 0);
+  GNUNET_assert (GNUNET_NO == db->state_get_signed (db->cls, &channel_pub_key,
+                                                    state_cb, &scls));
+  GNUNET_assert (scls.n == 0);
+
+  GNUNET_assert (GNUNET_OK == db->state_update_signed (db->cls,
+                                                       &channel_pub_key));
+
+  scls.n = 0;
+  GNUNET_assert (GNUNET_YES == db->state_get_signed (db->cls, &channel_pub_key,
+                                                     state_cb, &scls));
+  GNUNET_assert (scls.n == 2);
 
-  ASSERT (GNUNET_OK == db->state_update_signed (db->cls, &channel_pub_key));
+  /* State counters */
+
+  uint64_t max_state_msg_id = 0;
+  GNUNET_assert (GNUNET_OK == db->counters_state_get (db->cls, &channel_pub_key,
+                                                      &max_state_msg_id)
+                 && max_state_msg_id == message_id);
+
+  /* State sync */
 
   scls.n = 0;
-  ASSERT (GNUNET_YES == db->state_get_signed (db->cls, &channel_pub_key,
-                                              state_cb, &scls));
-  ASSERT (scls.n == 2);
+  scls.value[0] = channel_key;
+  scls.value_size[0] = sizeof (*channel_key);
+  scls.value[1] = "three two one";
+  scls.value_size[1] = strlen ("three two one");
+
+  GNUNET_assert (GNUNET_OK == db->state_sync_begin (db->cls, &channel_pub_key));
+
+  GNUNET_assert (GNUNET_OK == db->state_sync_assign (db->cls, &channel_pub_key,
+                                                     "_sync_bar", scls.value[0],
+                                                     scls.value_size[0]));
+
+  GNUNET_assert (GNUNET_OK == db->state_sync_assign (db->cls, &channel_pub_key,
+                                                     "_sync_foo", scls.value[1],
+                                                     scls.value_size[1]));
+
+  GNUNET_assert (GNUNET_OK == db->state_sync_end (db->cls, &channel_pub_key,
+                                                  max_state_msg_id,
+                                                  INT64_MAX - 5));
+
+  GNUNET_assert (GNUNET_NO == db->state_get_prefix (db->cls, &channel_pub_key,
+                                                    "_foo", state_cb, &scls));
+  GNUNET_assert (scls.n == 0);
+
+  GNUNET_assert (GNUNET_OK == db->state_get_prefix (db->cls, &channel_pub_key,
+                                                    "_sync", state_cb, &scls));
+  GNUNET_assert (scls.n == 2);
+
+  scls.n = 0;
+  GNUNET_assert (GNUNET_OK == db->state_get_signed (db->cls, &channel_pub_key,
+                                                    state_cb, &scls));
+  GNUNET_assert (scls.n == 2);
+
+  /* Modify state after sync */
+
+  message_id = GNUNET_ntohll (fcls.msg[0]->message_id) + 6;
+  GNUNET_assert (GNUNET_OK == db->state_modify_begin (db->cls, &channel_pub_key,
+                                                      message_id,
+                                                      message_id - max_state_msg_id));
+
+  GNUNET_assert (GNUNET_OK == db->state_modify_op (db->cls, &channel_pub_key,
+                                                   GNUNET_ENV_OP_ASSIGN,
+                                                   "_sync_foo",
+                                                   C2ARG("five six seven")));
+
+  GNUNET_assert (GNUNET_OK == db->state_modify_end (db->cls, &channel_pub_key,
+                                                    message_id));
+
+  /* Reset state */
+
+  scls.n = 0;
+  GNUNET_assert (GNUNET_OK == db->state_reset (db->cls, &channel_pub_key));
+  GNUNET_assert (scls.n == 0);
 
   ok = 0;
-  
-FAILURE:
 
   if (NULL != channel_key)
   {
@@ -353,7 +444,6 @@ main (int argc, char *argv[])
   struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
-
   GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite");
   GNUNET_log_setup ("test-plugin-psycstore", LOG_LEVEL, NULL);
   plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]);