-not all uris are ksks
[oweals/gnunet.git] / src / fs / test_fs_namespace.c
index 04e82c5d70910eea23e3ed8bc7f6f32bb86603d4..b1221eb82315c2ee1589a56fc920f7221e3f684a 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
  * @brief Test for fs_namespace.c
  * @author Christian Grothoff
  */
  * @brief Test for fs_namespace.c
  * @author Christian Grothoff
  */
-
 #include "platform.h"
 #include "gnunet_util_lib.h"
 #include "gnunet_arm_service.h"
 #include "gnunet_fs_service.h"
 
 #include "platform.h"
 #include "gnunet_util_lib.h"
 #include "gnunet_arm_service.h"
 #include "gnunet_fs_service.h"
 
-#define START_ARM GNUNET_YES
+#define VERBOSE GNUNET_EXTRA_LOGGING
 
 
-static struct GNUNET_SCHEDULER_Handle *sched;
+#define START_ARM GNUNET_YES
 
 static struct PeerContext p1;
 
 
 static struct PeerContext p1;
 
+static GNUNET_HashCode nsid;
+
+static struct GNUNET_FS_Uri *sks_expect_uri;
+
+static struct GNUNET_FS_Uri *ksk_expect_uri;
+
 static struct GNUNET_FS_Handle *fs;
 
 static struct GNUNET_FS_Handle *fs;
 
+static struct GNUNET_FS_SearchContext *sks_search;
+
+static struct GNUNET_FS_SearchContext *ksk_search;
+
+static GNUNET_SCHEDULER_TaskIdentifier kill_task;
+
+static int update_started;
+
+static int err;
 
 struct PeerContext
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 
 struct PeerContext
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
-  struct GNUNET_PeerIdentity id;   
 #if START_ARM
 #if START_ARM
-  pid_t arm_pid;
+  struct GNUNET_OS_Process *arm_proc;
 #endif
 };
 
 
 #endif
 };
 
 
-static void *
-progress_cb (void *cls, 
-            const struct GNUNET_FS_ProgressInfo *event)
-{
-  return NULL;
-}
-
-
 static void
 setup_peer (struct PeerContext *p, const char *cfgname)
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
 static void
 setup_peer (struct PeerContext *p, const char *cfgname)
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process ("gnunet-service-arm",
-                                        "gnunet-service-arm",
+  p->arm_proc =
+      GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+                               "gnunet-service-arm",
 #if VERBOSE
 #if VERBOSE
-                                        "-L", "DEBUG",
+                               "-L", "DEBUG",
 #endif
 #endif
-                                        "-c", cfgname, NULL);
-  sleep (1);                    /* allow ARM to start */
+                               "-c", cfgname, NULL);
 #endif
   GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
 #endif
   GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
-  GNUNET_ARM_start_services (p->cfg, sched, "core", NULL);
 }
 
 
 }
 
 
@@ -78,104 +82,291 @@ static void
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+  if (NULL != p->arm_proc)
+  {
+    if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+    if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK)
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
+                GNUNET_OS_process_get_pid (p->arm_proc));
+    GNUNET_OS_process_close (p->arm_proc);
+    p->arm_proc = NULL;
+  }
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
 
 
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
 
 
-#if 0
 static void
 static void
-spcb (void *cls,
-      const char *name,
-      const GNUNET_HashCode * key)
+abort_ksk_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
 {
+  if (ksk_search != NULL)
+  {
+    GNUNET_FS_search_stop (ksk_search);
+    ksk_search = NULL;
+    if (sks_search == NULL)
+    {
+      GNUNET_FS_stop (fs);
+      if (GNUNET_SCHEDULER_NO_TASK != kill_task)
+        GNUNET_SCHEDULER_cancel (kill_task);
+    }
+  }
 }
 }
-#endif
 
 
 static void
 
 
 static void
-publish_cont (void *cls,
-             const struct GNUNET_FS_Uri *uri,
-             const char *emsg)
+abort_sks_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
 {
-  struct GNUNET_FS_SearchContext *search;
+  struct GNUNET_FS_Namespace *ns;
 
 
-  GNUNET_assert (NULL == emsg);
-  fprintf (stderr, "Starting namespace search...\n");
-  search = GNUNET_FS_search_start (fs, uri, 1);
+  if (sks_search == NULL)
+    return;
+  GNUNET_FS_search_stop (sks_search);
+  sks_search = NULL;
+  ns = GNUNET_FS_namespace_create (fs, "testNamespace");
+  GNUNET_assert (NULL != ns);
+  GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (ns, GNUNET_YES));
+  if (ksk_search == NULL)
+  {
+    GNUNET_FS_stop (fs);
+    if (GNUNET_SCHEDULER_NO_TASK != kill_task)
+      GNUNET_SCHEDULER_cancel (kill_task);
+  }
 }
 
 
 static void
 }
 
 
 static void
-testNamespace ()
+do_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  fprintf (stderr, "Operation timed out\n");
+  kill_task = GNUNET_SCHEDULER_NO_TASK;
+  abort_sks_search_task (NULL, tc);
+  abort_ksk_search_task (NULL, tc);
+}
+
+
+
+static void *
+progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
+{
+  switch (event->status)
+  {
+  case GNUNET_FS_STATUS_SEARCH_RESULT:
+    if (sks_search == event->value.search.sc)
+    {
+      if (!GNUNET_FS_uri_test_equal
+          (sks_expect_uri, event->value.search.specifics.result.uri))
+      {
+        fprintf (stderr, "Wrong result for sks search!\n");
+        err = 1;
+      }
+      /* give system 1ms to initiate update search! */
+      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
+                                    &abort_sks_search_task, NULL);
+    }
+    else if (ksk_search == event->value.search.sc)
+    {
+      if (!GNUNET_FS_uri_test_equal
+          (ksk_expect_uri, event->value.search.specifics.result.uri))
+      {
+        fprintf (stderr, "Wrong result for ksk search!\n");
+        err = 1;
+      }
+      GNUNET_SCHEDULER_add_continuation (&abort_ksk_search_task, NULL,
+                                         GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+    }
+    else
+    {
+      fprintf (stderr, "Unexpected search result received!\n");
+      GNUNET_break (0);
+    }
+    break;
+  case GNUNET_FS_STATUS_SEARCH_ERROR:
+    fprintf (stderr, "Error searching file: %s\n",
+             event->value.search.specifics.error.message);
+    if (sks_search == event->value.search.sc)
+      GNUNET_SCHEDULER_add_continuation (&abort_sks_search_task, NULL,
+                                         GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+    else if (ksk_search == event->value.search.sc)
+      GNUNET_SCHEDULER_add_continuation (&abort_ksk_search_task, NULL,
+                                         GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+    else
+      GNUNET_break (0);
+    break;
+  case GNUNET_FS_STATUS_SEARCH_START:
+    GNUNET_assert ((NULL == event->value.search.cctx) ||
+                   (0 == strcmp ("sks_search", event->value.search.cctx)) ||
+                   (0 == strcmp ("ksk_search", event->value.search.cctx)));
+    if (NULL == event->value.search.cctx)
+    {
+      GNUNET_assert (0 == strcmp ("sks_search", event->value.search.pctx));
+      update_started = GNUNET_YES;
+    }
+    GNUNET_assert (1 == event->value.search.anonymity);
+    break;
+  case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED:
+    return NULL;
+  case GNUNET_FS_STATUS_SEARCH_STOPPED:
+    return NULL;
+  default:
+    fprintf (stderr, "Unexpected event: %d\n", event->status);
+    break;
+  }
+  return event->value.search.cctx;
+}
+
+
+static void
+publish_cont (void *cls, const struct GNUNET_FS_Uri *ksk_uri, const char *emsg)
+{
+  char *msg;
+  struct GNUNET_FS_Uri *sks_uri;
+  char sbuf[1024];
+  struct GNUNET_CRYPTO_HashAsciiEncoded enc;
+
+  if (NULL != emsg)
+  {
+    fprintf (stderr, "Error publishing: %s\n", emsg);
+    err = 1;
+    GNUNET_FS_stop (fs);
+    return;
+  }
+  GNUNET_CRYPTO_hash_to_enc (&nsid, &enc);
+  GNUNET_snprintf (sbuf, sizeof (sbuf), "gnunet://fs/sks/%s/this", &enc);
+  sks_uri = GNUNET_FS_uri_parse (sbuf, &msg);
+  if (msg != NULL)
+  {
+    fprintf (stderr, "failed to parse URI `%s': %s\n", sbuf, msg);
+    err = 1;
+    GNUNET_FS_stop (fs);
+    GNUNET_free (msg);
+    return;
+  }
+  ksk_search =
+      GNUNET_FS_search_start (fs, ksk_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
+                              "ksk_search");
+  sks_search =
+      GNUNET_FS_search_start (fs, sks_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
+                              "sks_search");
+  GNUNET_FS_uri_destroy (sks_uri);
+}
+
+
+static void
+sks_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
 {
 {
-  struct GNUNET_FS_Namespace *ns;
-  struct GNUNET_FS_Uri *adv;
-  struct GNUNET_FS_Uri *rootUri;
   struct GNUNET_CONTAINER_MetaData *meta;
   struct GNUNET_CONTAINER_MetaData *meta;
-  struct GNUNET_TIME_Absolute expiration;
+  struct GNUNET_FS_Uri *ksk_uri;
+  char *msg;
+  struct GNUNET_FS_BlockOptions bo;
 
 
-  expiration = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
   meta = GNUNET_CONTAINER_meta_data_create ();
   meta = GNUNET_CONTAINER_meta_data_create ();
-  adv = GNUNET_FS_uri_ksk_create ("testNamespace", NULL);
-  ns = GNUNET_FS_namespace_create (fs,
-                                  "testNamespace");
-  rootUri = GNUNET_FS_namespace_advertise (fs,
-                                          ns,
-                                          meta,
-                                          1, 1,
-                                          expiration,
-                                          adv,
-                                          "root");
-  GNUNET_assert (NULL != rootUri);
-  GNUNET_FS_publish_sks (fs,
-                        ns,
-                        "this",
-                        "next",
-                        meta,
-                        rootUri,
-                        expiration,
-                        1, 1,
-                        GNUNET_FS_PUBLISH_OPTION_NONE,
-                        &publish_cont,
-                        NULL);
+  msg = NULL;
+  ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/ns-search", &msg);
+  GNUNET_assert (NULL == msg);
+  ksk_expect_uri = GNUNET_FS_uri_dup (uri);
+  bo.content_priority = 1;
+  bo.anonymity_level = 1;
+  bo.replication_level = 0;
+  bo.expiration_time =
+      GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
+  GNUNET_FS_publish_ksk (fs, ksk_uri, meta, uri, &bo,
+                         GNUNET_FS_PUBLISH_OPTION_NONE, &publish_cont, NULL);
+  GNUNET_FS_uri_destroy (ksk_uri);
   GNUNET_CONTAINER_meta_data_destroy (meta);
 }
 
   GNUNET_CONTAINER_meta_data_destroy (meta);
 }
 
-#if 0
-  fprintf (stderr, "Completed namespace search...\n");
-  GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (NULL, cfg, &pid));
-  GNUNET_assert (GNUNET_SYSERR == GNUNET_FS_namespace_delete (NULL, cfg, &pid));
-  GNUNET_FS_uri_destroy (rootURI);
-  GNUNET_FS_uri_destroy (advURI);
-  GNUNET_assert (match == 1);
-  return 0;
+
+static void
+adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
+{
+  struct GNUNET_CONTAINER_MetaData *meta;
+  struct GNUNET_FS_Namespace *ns;
+  struct GNUNET_FS_BlockOptions bo;
+
+  if (NULL != emsg)
+  {
+    fprintf (stderr, "Error publishing: %s\n", emsg);
+    err = 1;
+    GNUNET_FS_stop (fs);
+    return;
+  }
+  ns = GNUNET_FS_namespace_create (fs, "testNamespace");
+  GNUNET_assert (NULL != ns);
+  meta = GNUNET_CONTAINER_meta_data_create ();
+  GNUNET_assert (NULL == emsg);
+  sks_expect_uri = GNUNET_FS_uri_dup (uri);
+  bo.content_priority = 1;
+  bo.anonymity_level = 1;
+  bo.replication_level = 0;
+  bo.expiration_time =
+      GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
+  GNUNET_FS_publish_sks (fs, ns, "this", "next", meta, uri,     /* FIXME: this is non-sense (use CHK URI!?) */
+                         &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont, NULL);
+  GNUNET_CONTAINER_meta_data_destroy (meta);
+  GNUNET_FS_namespace_delete (ns, GNUNET_NO);
 }
 }
-#endif
 
 
 static void
 
 
 static void
-run (void *cls,
-     struct GNUNET_SCHEDULER_Handle *s,
-     char *const *args,
-     const char *cfgfile,
+ns_iterator (void *cls, const char *name, const GNUNET_HashCode * id)
+{
+  int *ok = cls;
+
+  if (0 != strcmp (name, "testNamespace"))
+    return;
+  *ok = GNUNET_YES;
+  nsid = *id;
+}
+
+
+static void
+testNamespace ()
+{
+  struct GNUNET_FS_Namespace *ns;
+  struct GNUNET_FS_BlockOptions bo;
+  struct GNUNET_CONTAINER_MetaData *meta;
+  struct GNUNET_FS_Uri *ksk_uri;
+  int ok;
+
+  ns = GNUNET_FS_namespace_create (fs, "testNamespace");
+  GNUNET_assert (NULL != ns);
+  ok = GNUNET_NO;
+  GNUNET_FS_namespace_list (fs, &ns_iterator, &ok);
+  if (GNUNET_NO == ok)
+  {
+    fprintf (stderr, "namespace_list failed to find namespace!\n");
+    GNUNET_FS_namespace_delete (ns, GNUNET_YES);
+    GNUNET_FS_stop (fs);
+    err = 1;
+    return;
+  }
+  meta = GNUNET_CONTAINER_meta_data_create ();
+  ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL);
+  bo.content_priority = 1;
+  bo.anonymity_level = 1;
+  bo.replication_level = 0;
+  bo.expiration_time =
+      GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
+  GNUNET_FS_namespace_advertise (fs, ksk_uri, ns, meta, &bo, "root", &adv_cont,
+                                 NULL);
+  kill_task =
+      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_timeout,
+                                    NULL);
+  GNUNET_FS_uri_destroy (ksk_uri);
+  GNUNET_FS_namespace_delete (ns, GNUNET_NO);
+  GNUNET_CONTAINER_meta_data_destroy (meta);
+}
+
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
-  sched = s;
-  setup_peer (&p1, "test_fs_download_data.conf");
-  fs = GNUNET_FS_start (sched,
-                       cfg,
-                       "test-fs-namespace",
-                       &progress_cb,
-                       NULL,
-                       GNUNET_FS_FLAGS_NONE,
-                       GNUNET_FS_OPTIONS_END);
+  setup_peer (&p1, "test_fs_namespace_data.conf");
+  fs = GNUNET_FS_start (cfg, "test-fs-namespace", &progress_cb, NULL,
+                        GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END);
   testNamespace ();
 }
 
   testNamespace ();
 }
 
@@ -183,7 +374,7 @@ run (void *cls,
 int
 main (int argc, char *argv[])
 {
 int
 main (int argc, char *argv[])
 {
-  char *const argvx[] = { 
+  char *const argvx[] = {
     "test-fs-namespace",
     "-c",
     "test_fs_namespace_data.conf",
     "test-fs-namespace",
     "-c",
     "test_fs_namespace_data.conf",
@@ -196,21 +387,24 @@ main (int argc, char *argv[])
     GNUNET_GETOPT_OPTION_END
   };
 
     GNUNET_GETOPT_OPTION_END
   };
 
-  GNUNET_log_setup ("test_fs_namespace", 
+  GNUNET_log_setup ("test_fs_namespace",
 #if VERBOSE
 #if VERBOSE
-                   "DEBUG",
+                    "DEBUG",
 #else
 #else
-                   "WARNING",
+                    "WARNING",
 #endif
 #endif
-                   NULL);
-  GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1,
-                      argvx, "test-fs-namespace",
-                     "nohelp", options, &run, NULL);
+                    NULL);
+  GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx,
+                      "test-fs-namespace", "nohelp", options, &run, NULL);
   stop_arm (&p1);
   stop_arm (&p1);
+  if (GNUNET_YES != update_started)
+  {
+    fprintf (stderr, "Update search never started!\n");
+    err = 1;
+  }
   GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-namespace/");
   GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-namespace/");
-  return 0;
+  return err;
 }
 
 
 }
 
 
-
 /* end of test_fs_namespace.c */
 /* end of test_fs_namespace.c */