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