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