first sketch for libgnuentsq test
authorChristian Grothoff <christian@grothoff.org>
Mon, 27 Feb 2017 01:32:07 +0000 (02:32 +0100)
committerChristian Grothoff <christian@grothoff.org>
Mon, 27 Feb 2017 01:32:07 +0000 (02:32 +0100)
src/include/gnunet_sq_lib.h
src/pq/test_pq.c
src/sq/.gitignore [new file with mode: 0644]
src/sq/sq.c
src/sq/test_sq.c [new file with mode: 0644]

index 1606d11293c5861f4357758c8469f7f8ebad2087..4484c28515e03b04d0e1feb470e367ac9d77c803 100644 (file)
@@ -186,7 +186,6 @@ GNUNET_SQ_query_param_uint64 (const uint64_t *x);
  *
  * @param cls closure
  * @param result where to extract data from
- * @param row row to extract data from
  * @param column column to extract data from
  * @param[in,out] dst_size where to store size of result, may be NULL
  * @param[out] dst where to store the result
@@ -197,7 +196,6 @@ GNUNET_SQ_query_param_uint64 (const uint64_t *x);
 typedef int
 (*GNUNET_SQ_ResultConverter)(void *cls,
                             sqlite3_stmt *result,
-                            int row,
                              unsigned int column,
                             size_t *dst_size,
                             void *dst);
@@ -304,7 +302,7 @@ GNUNET_SQ_result_spec_fixed_size (void *dst,
  * @param dst point to where to store the result, type fits expected result size
  * @return array entry for the result specification to use
  */
-#define GNUNET_SQ_result_spec_auto_from_type(dst) GNUNET_SQ_result_spec_fixed_size (name, (dst), sizeof (*(dst)))
+#define GNUNET_SQ_result_spec_auto_from_type(dst) GNUNET_SQ_result_spec_fixed_size ((dst), sizeof (*(dst)))
 
 
 /**
@@ -416,15 +414,13 @@ GNUNET_SQ_bind (sqlite3_stmt *stmt,
  *
  * @param result result to process
  * @param[in,out] rs result specification to extract for
- * @param row row from the result to extract
  * @return
  *   #GNUNET_OK if all results could be extracted
  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
  */
 int
 GNUNET_SQ_extract_result (sqlite3_stmt *result,
-                         struct GNUNET_SQ_ResultSpec *rs,
-                         int row);
+                         struct GNUNET_SQ_ResultSpec *rs);
 
 
 /**
index 49705103fb66856f9371f6ad679bd8d450e73bdf..b543181103758eb05b3d09f2df8633217bc6c6cf 100644 (file)
@@ -218,8 +218,8 @@ run_queries (PGconn *conn)
 
 
 int
-main(int argc,
-     const char *const argv[])
+main (int argc,
+      const char *const argv[])
 {
   PGconn *conn;
   PGresult *result;
@@ -236,7 +236,7 @@ main(int argc,
             PQerrorMessage (conn));
     GNUNET_break (0);
     PQfinish (conn);
-    return 0; /* We ignore this type of error... */
+    return 77; /* signal test was skipped */
   }
 
   result = PQexec (conn,
diff --git a/src/sq/.gitignore b/src/sq/.gitignore
new file mode 100644 (file)
index 0000000..9515870
--- /dev/null
@@ -0,0 +1 @@
+test_sq
index 74ab7beb5480b6f85c7f4dd7b063872357144f85..47fcaf24ea13e6217c9c1ecc6d28b513901e595c 100644 (file)
@@ -63,15 +63,13 @@ GNUNET_SQ_bind (sqlite3_stmt *stmt,
  *
  * @param result result to process
  * @param[in,out] rs result specification to extract for
- * @param row row from the result to extract
  * @return
  *   #GNUNET_OK if all results could be extracted
  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
  */
 int
 GNUNET_SQ_extract_result (sqlite3_stmt *result,
-                         struct GNUNET_SQ_ResultSpec *rs,
-                         int row)
+                         struct GNUNET_SQ_ResultSpec *rs)
 {
   unsigned int j = 0;
 
@@ -80,7 +78,6 @@ GNUNET_SQ_extract_result (sqlite3_stmt *result,
     if (GNUNET_OK !=
         rs[i].conv (rs[i].cls,
                     result,
-                    row,
                     j,
                     rs[i].result_size,
                     rs[i].dst))
diff --git a/src/sq/test_sq.c b/src/sq/test_sq.c
new file mode 100644 (file)
index 0000000..e689686
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+  This file is part of GNUnet
+  (C) 2015, 2016, 2017 GNUnet e.V.
+
+  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, If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file sq/test_sq.c
+ * @brief Tests for sqlite3 convenience API
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_sq_lib.h"
+
+
+/**
+ * @brief Prepare a SQL statement
+ *
+ * @param dbh handle to the database
+ * @param zSql SQL statement, UTF-8 encoded
+ * @param[out] ppStmt set to the prepared statement
+ * @return 0 on success
+ */
+static int
+sq_prepare (sqlite3 *dbh,
+            const char *zSql,
+            sqlite3_stmt **ppStmt)
+{
+  char *dummy;
+  int result;
+
+  result = sqlite3_prepare_v2 (dbh,
+                               zSql,
+                               strlen (zSql),
+                               ppStmt,
+                               (const char **) &dummy);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Prepared `%s' / %p: %d\n",
+              zSql,
+              *ppStmt,
+              result);
+  return result;
+}
+
+
+/**
+ * Run actual test queries.
+ *
+ * @return 0 on success
+ */
+static int
+run_queries (sqlite3 *dbh)
+{
+  struct GNUNET_CRYPTO_RsaPublicKey *pub;
+  struct GNUNET_CRYPTO_RsaPublicKey *pub2 = NULL;
+  struct GNUNET_CRYPTO_RsaSignature *sig;
+  struct GNUNET_CRYPTO_RsaSignature *sig2 = NULL;
+  struct GNUNET_TIME_Absolute abs_time = GNUNET_TIME_absolute_get ();
+  struct GNUNET_TIME_Absolute abs_time2;
+  struct GNUNET_TIME_Absolute forever = GNUNET_TIME_UNIT_FOREVER_ABS;
+  struct GNUNET_TIME_Absolute forever2;
+  struct GNUNET_HashCode hc;
+  struct GNUNET_HashCode hc2;
+  sqlite3_stmt *stmt;
+  struct GNUNET_CRYPTO_RsaPrivateKey *priv;
+  const char msg[] = "hello";
+  void *msg2;
+  struct GNUNET_HashCode hmsg;
+  size_t msg2_len;
+  uint16_t u16;
+  uint16_t u162;
+  uint32_t u32;
+  uint32_t u322;
+  uint64_t u64;
+  uint64_t u642;
+
+  priv = GNUNET_CRYPTO_rsa_private_key_create (1024);
+  pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
+  memset (&hmsg, 42, sizeof (hmsg));
+  sig = GNUNET_CRYPTO_rsa_sign_fdh (priv,
+                                    &hmsg);
+  u16 = 16;
+  u32 = 32;
+  u64 = 64;
+  /* FIXME: test GNUNET_SQ_result_spec_variable_size */
+
+  sq_prepare (dbh,
+              "INSERT INTO test_sq ("
+              " pub"
+              ",sig"
+              ",abs_time"
+              ",forever"
+              ",hash"
+              ",vsize"
+              ",u16"
+              ",u32"
+              ",u64"
+              ") VALUES "
+              "($1, $2, $3, $4, $5, $6,"
+              "$7, $8, $9);",
+              &stmt);
+  {
+    struct GNUNET_SQ_QueryParam params_insert[] = {
+      GNUNET_SQ_query_param_rsa_public_key (pub),
+      GNUNET_SQ_query_param_rsa_signature (sig),
+      GNUNET_SQ_query_param_absolute_time (&abs_time),
+      GNUNET_SQ_query_param_absolute_time (&forever),
+      GNUNET_SQ_query_param_auto_from_type (&hc),
+      GNUNET_SQ_query_param_fixed_size (msg, strlen (msg)),
+      GNUNET_SQ_query_param_uint16 (&u16),
+      GNUNET_SQ_query_param_uint32 (&u32),
+      GNUNET_SQ_query_param_uint64 (&u64),
+      GNUNET_SQ_query_param_end
+    };
+
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_SQ_bind (stmt,
+                                   params_insert));
+    if (SQLITE_DONE !=
+        sqlite3_step (stmt))
+    {
+      GNUNET_CRYPTO_rsa_signature_free (sig);
+      GNUNET_CRYPTO_rsa_private_key_free (priv);
+      GNUNET_CRYPTO_rsa_public_key_free (pub);
+      return 1;
+    }
+  }
+  sqlite3_finalize (stmt);
+
+  sq_prepare (dbh,
+              "SELECT"
+              " pub"
+              ",sig"
+              ",abs_time"
+              ",forever"
+              ",hash"
+              ",vsize"
+              ",u16"
+              ",u32"
+              ",u64"
+              " FROM test_sq"
+              " ORDER BY abs_time DESC "
+              " LIMIT 1;",
+              &stmt);
+  {
+    struct GNUNET_SQ_QueryParam params_select[] = {
+      GNUNET_SQ_query_param_end
+    };
+    struct GNUNET_SQ_ResultSpec results_select[] = {
+      GNUNET_SQ_result_spec_rsa_public_key (&pub2),
+      GNUNET_SQ_result_spec_rsa_signature (&sig2),
+      GNUNET_SQ_result_spec_absolute_time (&abs_time2),
+      GNUNET_SQ_result_spec_absolute_time (&forever2),
+      GNUNET_SQ_result_spec_auto_from_type (&hc2),
+      GNUNET_SQ_result_spec_variable_size (&msg2, &msg2_len),
+      GNUNET_SQ_result_spec_uint16 (&u162),
+      GNUNET_SQ_result_spec_uint32 (&u322),
+      GNUNET_SQ_result_spec_uint64 (&u642),
+      GNUNET_SQ_result_spec_end
+    };
+
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_SQ_bind (stmt,
+                                   params_select));
+    if (SQLITE_ROW !=
+        sqlite3_step (stmt))
+    {
+      GNUNET_break (0);
+      sqlite3_finalize (stmt);
+      GNUNET_CRYPTO_rsa_signature_free (sig);
+      GNUNET_CRYPTO_rsa_private_key_free (priv);
+      GNUNET_CRYPTO_rsa_public_key_free (pub);
+      return 1;
+    }
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_SQ_extract_result (stmt,
+                                             results_select));
+    GNUNET_break (abs_time.abs_value_us == abs_time2.abs_value_us);
+    GNUNET_break (forever.abs_value_us == forever2.abs_value_us);
+    GNUNET_break (0 ==
+                 memcmp (&hc,
+                         &hc2,
+                         sizeof (struct GNUNET_HashCode)));
+    GNUNET_break (0 ==
+                 GNUNET_CRYPTO_rsa_signature_cmp (sig,
+                                                  sig2));
+    GNUNET_break (0 ==
+                 GNUNET_CRYPTO_rsa_public_key_cmp (pub,
+                                                   pub2));
+    GNUNET_break (strlen (msg) == msg2_len);
+    GNUNET_break (0 ==
+                 strncmp (msg,
+                          msg2,
+                          msg2_len));
+    GNUNET_break (16 == u162);
+    GNUNET_break (32 == u322);
+    GNUNET_break (64 == u642);
+    GNUNET_SQ_cleanup_result (results_select);
+  }
+  sqlite3_finalize (stmt);
+
+  GNUNET_CRYPTO_rsa_signature_free (sig);
+  GNUNET_CRYPTO_rsa_private_key_free (priv);
+  GNUNET_CRYPTO_rsa_public_key_free (pub);
+  return 0;
+}
+
+
+int
+main(int argc,
+     const char *const argv[])
+{
+  sqlite3 *dbh;
+  int ret;
+
+  GNUNET_log_setup ("test-sq",
+                   "WARNING",
+                   NULL);
+  if (SQLITE_OK !=
+      sqlite3_open ("test.db",
+                    &dbh))
+  {
+    fprintf (stderr,
+            "Cannot run test, sqlite3 initialization failed\n");
+    GNUNET_break (0);
+    return 77; /* Signal test was skipped... */
+  }
+
+  if (SQLITE_OK !=
+      sqlite3_exec (dbh,
+                    "CREATE TEMPORARY TABLE IF NOT EXISTS test_sq ("
+                    " pub BYTEA NOT NULL"
+                    ",sig BYTEA NOT NULL"
+                    ",abs_time INT8 NOT NULL"
+                    ",forever INT8 NOT NULL"
+                    ",hash BYTEA NOT NULL"
+                    ",vsize VARCHAR NOT NULL"
+                    ",u16 INT2 NOT NULL"
+                    ",u32 INT4 NOT NULL"
+                    ",u64 INT8 NOT NULL"
+                    ")",
+                    NULL, NULL, NULL))
+  {
+    fprintf (stderr,
+            "Failed to create table\n");
+    sqlite3_close (dbh);
+    unlink ("test.db");
+    return 1;
+  }
+
+  ret = run_queries (dbh);
+  if (SQLITE_OK !=
+      sqlite3_exec (dbh,
+                    "DROP TABLE test_sq",
+                    NULL, NULL, NULL))
+  {
+    fprintf (stderr,
+            "Failed to drop table\n");
+    sqlite3_close (dbh);
+    unlink ("test.db");
+    return 1;
+  }
+  sqlite3_close (dbh);
+  unlink ("test.db");
+  return ret;
+}
+
+
+/* end of test_sq.c */