From: Christian Grothoff Date: Mon, 27 Feb 2017 01:32:07 +0000 (+0100) Subject: first sketch for libgnuentsq test X-Git-Tag: taler-0.2.1~15 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=eee83a35971446034ac26b9272d9db9bbe7633ee;p=oweals%2Fgnunet.git first sketch for libgnuentsq test --- diff --git a/src/include/gnunet_sq_lib.h b/src/include/gnunet_sq_lib.h index 1606d1129..4484c2851 100644 --- a/src/include/gnunet_sq_lib.h +++ b/src/include/gnunet_sq_lib.h @@ -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); /** diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c index 49705103f..b54318110 100644 --- a/src/pq/test_pq.c +++ b/src/pq/test_pq.c @@ -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 index 000000000..951587047 --- /dev/null +++ b/src/sq/.gitignore @@ -0,0 +1 @@ +test_sq diff --git a/src/sq/sq.c b/src/sq/sq.c index 74ab7beb5..47fcaf24e 100644 --- a/src/sq/sq.c +++ b/src/sq/sq.c @@ -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 index 000000000..e6896861e --- /dev/null +++ b/src/sq/test_sq.c @@ -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 +*/ +/** + * @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 */