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