guix-env: some update.
[oweals/gnunet.git] / src / sq / test_sq.c
1 /*
2   This file is part of GNUnet
3   (C) 2015, 2016, 2017 GNUnet e.V.
4
5   GNUnet is free software; you can redistribute it and/or modify it under the
6   terms of the GNU General Public License as published by the Free Software
7   Foundation; either version 3, or (at your option) any later version.
8
9   GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
13   You should have received a copy of the GNU General Public License along with
14   GNUnet; see the file COPYING.  If not, If not, see <http://www.gnu.org/licenses/>
15 */
16 /**
17  * @file sq/test_sq.c
18  * @brief Tests for sqlite3 convenience API
19  * @author Christian Grothoff
20  */
21 #include "platform.h"
22 #include "gnunet_util_lib.h"
23 #include "gnunet_sq_lib.h"
24
25
26 /**
27  * @brief Prepare a SQL statement
28  *
29  * @param dbh handle to the database
30  * @param zSql SQL statement, UTF-8 encoded
31  * @param[out] ppStmt set to the prepared statement
32  * @return 0 on success
33  */
34 static int
35 sq_prepare (sqlite3 *dbh,
36             const char *zSql,
37             sqlite3_stmt **ppStmt)
38 {
39   char *dummy;
40   int result;
41
42   result = sqlite3_prepare_v2 (dbh,
43                                zSql,
44                                strlen (zSql),
45                                ppStmt,
46                                (const char **) &dummy);
47   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
48               "Prepared `%s' / %p: %d\n",
49               zSql,
50               *ppStmt,
51               result);
52   return result;
53 }
54
55
56 /**
57  * Run actual test queries.
58  *
59  * @return 0 on success
60  */
61 static int
62 run_queries (sqlite3 *dbh)
63 {
64   struct GNUNET_CRYPTO_RsaPublicKey *pub;
65   struct GNUNET_CRYPTO_RsaPublicKey *pub2 = NULL;
66   struct GNUNET_CRYPTO_RsaSignature *sig;
67   struct GNUNET_CRYPTO_RsaSignature *sig2 = NULL;
68   struct GNUNET_TIME_Absolute abs_time = GNUNET_TIME_absolute_get ();
69   struct GNUNET_TIME_Absolute abs_time2;
70   struct GNUNET_TIME_Absolute forever = GNUNET_TIME_UNIT_FOREVER_ABS;
71   struct GNUNET_TIME_Absolute forever2;
72   struct GNUNET_HashCode hc;
73   struct GNUNET_HashCode hc2;
74   sqlite3_stmt *stmt;
75   struct GNUNET_CRYPTO_RsaPrivateKey *priv;
76   const char msg[] = "hello";
77   void *msg2;
78   struct GNUNET_HashCode hmsg;
79   size_t msg2_len;
80   uint16_t u16;
81   uint16_t u162;
82   uint32_t u32;
83   uint32_t u322;
84   uint64_t u64;
85   uint64_t u642;
86
87   priv = GNUNET_CRYPTO_rsa_private_key_create (1024);
88   pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
89   memset (&hmsg, 42, sizeof (hmsg));
90   sig = GNUNET_CRYPTO_rsa_sign_fdh (priv,
91                                     &hmsg);
92   u16 = 16;
93   u32 = 32;
94   u64 = 64;
95   /* FIXME: test GNUNET_SQ_result_spec_variable_size */
96
97   sq_prepare (dbh,
98               "INSERT INTO test_sq ("
99               " pub"
100               ",sig"
101               ",abs_time"
102               ",forever"
103               ",hash"
104               ",vsize"
105               ",u16"
106               ",u32"
107               ",u64"
108               ") VALUES "
109               "($1, $2, $3, $4, $5, $6,"
110               "$7, $8, $9);",
111               &stmt);
112   {
113     struct GNUNET_SQ_QueryParam params_insert[] = {
114       GNUNET_SQ_query_param_rsa_public_key (pub),
115       GNUNET_SQ_query_param_rsa_signature (sig),
116       GNUNET_SQ_query_param_absolute_time (&abs_time),
117       GNUNET_SQ_query_param_absolute_time (&forever),
118       GNUNET_SQ_query_param_auto_from_type (&hc),
119       GNUNET_SQ_query_param_fixed_size (msg, strlen (msg)),
120       GNUNET_SQ_query_param_uint16 (&u16),
121       GNUNET_SQ_query_param_uint32 (&u32),
122       GNUNET_SQ_query_param_uint64 (&u64),
123       GNUNET_SQ_query_param_end
124     };
125
126     GNUNET_assert (GNUNET_OK ==
127                    GNUNET_SQ_bind (stmt,
128                                    params_insert));
129     if (SQLITE_DONE !=
130         sqlite3_step (stmt))
131     {
132       GNUNET_CRYPTO_rsa_signature_free (sig);
133       GNUNET_CRYPTO_rsa_private_key_free (priv);
134       GNUNET_CRYPTO_rsa_public_key_free (pub);
135       return 1;
136     }
137   }
138   sqlite3_finalize (stmt);
139
140   sq_prepare (dbh,
141               "SELECT"
142               " pub"
143               ",sig"
144               ",abs_time"
145               ",forever"
146               ",hash"
147               ",vsize"
148               ",u16"
149               ",u32"
150               ",u64"
151               " FROM test_sq"
152               " ORDER BY abs_time DESC "
153               " LIMIT 1;",
154               &stmt);
155   {
156     struct GNUNET_SQ_QueryParam params_select[] = {
157       GNUNET_SQ_query_param_end
158     };
159     struct GNUNET_SQ_ResultSpec results_select[] = {
160       GNUNET_SQ_result_spec_rsa_public_key (&pub2),
161       GNUNET_SQ_result_spec_rsa_signature (&sig2),
162       GNUNET_SQ_result_spec_absolute_time (&abs_time2),
163       GNUNET_SQ_result_spec_absolute_time (&forever2),
164       GNUNET_SQ_result_spec_auto_from_type (&hc2),
165       GNUNET_SQ_result_spec_variable_size (&msg2, &msg2_len),
166       GNUNET_SQ_result_spec_uint16 (&u162),
167       GNUNET_SQ_result_spec_uint32 (&u322),
168       GNUNET_SQ_result_spec_uint64 (&u642),
169       GNUNET_SQ_result_spec_end
170     };
171
172     GNUNET_assert (GNUNET_OK ==
173                    GNUNET_SQ_bind (stmt,
174                                    params_select));
175     if (SQLITE_ROW !=
176         sqlite3_step (stmt))
177     {
178       GNUNET_break (0);
179       sqlite3_finalize (stmt);
180       GNUNET_CRYPTO_rsa_signature_free (sig);
181       GNUNET_CRYPTO_rsa_private_key_free (priv);
182       GNUNET_CRYPTO_rsa_public_key_free (pub);
183       return 1;
184     }
185     GNUNET_assert (GNUNET_OK ==
186                    GNUNET_SQ_extract_result (stmt,
187                                              results_select));
188     GNUNET_break (abs_time.abs_value_us == abs_time2.abs_value_us);
189     GNUNET_break (forever.abs_value_us == forever2.abs_value_us);
190     GNUNET_break (0 ==
191                   memcmp (&hc,
192                           &hc2,
193                           sizeof (struct GNUNET_HashCode)));
194     GNUNET_break (0 ==
195                   GNUNET_CRYPTO_rsa_signature_cmp (sig,
196                                                    sig2));
197     GNUNET_break (0 ==
198                   GNUNET_CRYPTO_rsa_public_key_cmp (pub,
199                                                     pub2));
200     GNUNET_break (strlen (msg) == msg2_len);
201     GNUNET_break (0 ==
202                   strncmp (msg,
203                            msg2,
204                            msg2_len));
205     GNUNET_break (16 == u162);
206     GNUNET_break (32 == u322);
207     GNUNET_break (64 == u642);
208     GNUNET_SQ_cleanup_result (results_select);
209   }
210   sqlite3_finalize (stmt);
211
212   GNUNET_CRYPTO_rsa_signature_free (sig);
213   GNUNET_CRYPTO_rsa_private_key_free (priv);
214   GNUNET_CRYPTO_rsa_public_key_free (pub);
215   return 0;
216 }
217
218
219 int
220 main(int argc,
221      const char *const argv[])
222 {
223   sqlite3 *dbh;
224   int ret;
225
226   GNUNET_log_setup ("test-sq",
227                     "WARNING",
228                     NULL);
229   if (SQLITE_OK !=
230       sqlite3_open ("test.db",
231                     &dbh))
232   {
233     fprintf (stderr,
234              "Cannot run test, sqlite3 initialization failed\n");
235     GNUNET_break (0);
236     return 77; /* Signal test was skipped... */
237   }
238
239   if (SQLITE_OK !=
240       sqlite3_exec (dbh,
241                     "CREATE TEMPORARY TABLE IF NOT EXISTS test_sq ("
242                     " pub BYTEA NOT NULL"
243                     ",sig BYTEA NOT NULL"
244                     ",abs_time INT8 NOT NULL"
245                     ",forever INT8 NOT NULL"
246                     ",hash BYTEA NOT NULL"
247                     ",vsize VARCHAR NOT NULL"
248                     ",u16 INT2 NOT NULL"
249                     ",u32 INT4 NOT NULL"
250                     ",u64 INT8 NOT NULL"
251                     ")",
252                     NULL, NULL, NULL))
253   {
254     fprintf (stderr,
255              "Failed to create table\n");
256     GNUNET_break (SQLITE_OK ==
257                   sqlite3_close (dbh));
258     if (0 != unlink ("test.db"))
259       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
260                                 "unlink",
261                                 "test.db");
262     return 1;
263   }
264
265   ret = run_queries (dbh);
266   if (SQLITE_OK !=
267       sqlite3_exec (dbh,
268                     "DROP TABLE test_sq",
269                     NULL, NULL, NULL))
270   {
271     fprintf (stderr,
272              "Failed to drop table\n");
273     ret = 1;
274   }
275   GNUNET_break (SQLITE_OK ==
276                 sqlite3_close (dbh));
277   if (0 != unlink ("test.db"))
278     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
279                               "unlink",
280                               "test.db");
281   return ret;
282 }
283
284
285 /* end of test_sq.c */