aboutsummaryrefslogtreecommitdiff
path: root/src/pq/test_pq.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pq/test_pq.c')
-rw-r--r--src/pq/test_pq.c421
1 files changed, 0 insertions, 421 deletions
diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c
deleted file mode 100644
index 90b5c6489..000000000
--- a/src/pq/test_pq.c
+++ /dev/null
@@ -1,421 +0,0 @@
1/*
2 This file is part of GNUnet
3 (C) 2015, 2016, 2019, 2020 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 pq/test_pq.c
22 * @brief Tests for Postgres convenience API
23 * @author Christian Grothoff <christian@grothoff.org>
24 */
25#include "platform.h"
26#include "pq.h"
27
28/**
29 * Database handle.
30 */
31static struct GNUNET_PQ_Context *db;
32
33/**
34 * Global return value, 0 on success.
35 */
36static int ret;
37
38/**
39 * An event handler.
40 */
41static struct GNUNET_DB_EventHandler *eh;
42
43/**
44 * Timeout task.
45 */
46static struct GNUNET_SCHEDULER_Task *tt;
47
48
49/**
50 * Setup prepared statements.
51 *
52 * @param db database handle to initialize
53 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
54 */
55static int
56postgres_prepare (struct GNUNET_PQ_Context *db)
57{
58 struct GNUNET_PQ_PreparedStatement ps[] = {
59 GNUNET_PQ_make_prepare ("test_insert",
60 "INSERT INTO test_pq ("
61 " pub"
62 ",sig"
63 ",abs_time"
64 ",forever"
65 ",hash"
66 ",vsize"
67 ",u16"
68 ",u32"
69 ",u64"
70 ",unn"
71 ") VALUES "
72 "($1, $2, $3, $4, $5, $6,"
73 "$7, $8, $9, $10);",
74 10),
75 GNUNET_PQ_make_prepare ("test_select",
76 "SELECT"
77 " pub"
78 ",sig"
79 ",abs_time"
80 ",forever"
81 ",hash"
82 ",vsize"
83 ",u16"
84 ",u32"
85 ",u64"
86 ",unn"
87 " FROM test_pq"
88 " ORDER BY abs_time DESC "
89 " LIMIT 1;",
90 0),
91 GNUNET_PQ_PREPARED_STATEMENT_END
92 };
93
94 return GNUNET_PQ_prepare_statements (db,
95 ps);
96}
97
98
99/**
100 * Run actual test queries.
101 *
102 * @param db database handle
103 * @return 0 on success
104 */
105static int
106run_queries (struct GNUNET_PQ_Context *db)
107{
108 struct GNUNET_CRYPTO_RsaPublicKey *pub;
109 struct GNUNET_CRYPTO_RsaPublicKey *pub2 = NULL;
110 struct GNUNET_CRYPTO_RsaSignature *sig;
111 struct GNUNET_CRYPTO_RsaSignature *sig2 = NULL;
112 struct GNUNET_TIME_Absolute abs_time = GNUNET_TIME_absolute_get ();
113 struct GNUNET_TIME_Absolute abs_time2;
114 struct GNUNET_TIME_Absolute forever = GNUNET_TIME_UNIT_FOREVER_ABS;
115 struct GNUNET_TIME_Absolute forever2;
116 struct GNUNET_HashCode hc;
117 struct GNUNET_HashCode hc2;
118 PGresult *result;
119 int ret;
120 struct GNUNET_CRYPTO_RsaPrivateKey *priv;
121 const char msg[] = "hello";
122 void *msg2;
123 struct GNUNET_HashCode hmsg;
124 size_t msg2_len;
125 uint16_t u16;
126 uint16_t u162;
127 uint32_t u32;
128 uint32_t u322;
129 uint64_t u64;
130 uint64_t u642;
131 uint64_t uzzz = 42;
132
133 priv = GNUNET_CRYPTO_rsa_private_key_create (1024);
134 pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
135 memset (&hmsg, 42, sizeof(hmsg));
136 sig = GNUNET_CRYPTO_rsa_sign_fdh (priv,
137 &hmsg);
138 u16 = 16;
139 u32 = 32;
140 u64 = 64;
141 /* FIXME: test GNUNET_PQ_result_spec_variable_size */
142 {
143 struct GNUNET_PQ_QueryParam params_insert[] = {
144 GNUNET_PQ_query_param_rsa_public_key (pub),
145 GNUNET_PQ_query_param_rsa_signature (sig),
146 GNUNET_PQ_query_param_absolute_time (&abs_time),
147 GNUNET_PQ_query_param_absolute_time (&forever),
148 GNUNET_PQ_query_param_auto_from_type (&hc),
149 GNUNET_PQ_query_param_fixed_size (msg, strlen (msg)),
150 GNUNET_PQ_query_param_uint16 (&u16),
151 GNUNET_PQ_query_param_uint32 (&u32),
152 GNUNET_PQ_query_param_uint64 (&u64),
153 GNUNET_PQ_query_param_null (),
154 GNUNET_PQ_query_param_end
155 };
156 struct GNUNET_PQ_QueryParam params_select[] = {
157 GNUNET_PQ_query_param_end
158 };
159 bool got_null = false;
160 struct GNUNET_PQ_ResultSpec results_select[] = {
161 GNUNET_PQ_result_spec_rsa_public_key ("pub", &pub2),
162 GNUNET_PQ_result_spec_rsa_signature ("sig", &sig2),
163 GNUNET_PQ_result_spec_absolute_time ("abs_time", &abs_time2),
164 GNUNET_PQ_result_spec_absolute_time ("forever", &forever2),
165 GNUNET_PQ_result_spec_auto_from_type ("hash", &hc2),
166 GNUNET_PQ_result_spec_variable_size ("vsize", &msg2, &msg2_len),
167 GNUNET_PQ_result_spec_uint16 ("u16", &u162),
168 GNUNET_PQ_result_spec_uint32 ("u32", &u322),
169 GNUNET_PQ_result_spec_uint64 ("u64", &u642),
170 GNUNET_PQ_result_spec_allow_null (
171 GNUNET_PQ_result_spec_uint64 ("unn", &uzzz),
172 &got_null),
173 GNUNET_PQ_result_spec_end
174 };
175
176 result = GNUNET_PQ_exec_prepared (db,
177 "test_insert",
178 params_insert);
179 if (PGRES_COMMAND_OK != PQresultStatus (result))
180 {
181 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
182 "Database failure: %s\n",
183 PQresultErrorMessage (result));
184 PQclear (result);
185 GNUNET_CRYPTO_rsa_signature_free (sig);
186 GNUNET_CRYPTO_rsa_private_key_free (priv);
187 GNUNET_CRYPTO_rsa_public_key_free (pub);
188 return 1;
189 }
190
191 PQclear (result);
192 result = GNUNET_PQ_exec_prepared (db,
193 "test_select",
194 params_select);
195 if (1 !=
196 PQntuples (result))
197 {
198 GNUNET_break (0);
199 PQclear (result);
200 GNUNET_CRYPTO_rsa_signature_free (sig);
201 GNUNET_CRYPTO_rsa_private_key_free (priv);
202 GNUNET_CRYPTO_rsa_public_key_free (pub);
203 return 1;
204 }
205 ret = GNUNET_PQ_extract_result (result,
206 results_select,
207 0);
208 GNUNET_break (GNUNET_YES == ret);
209 GNUNET_break (abs_time.abs_value_us == abs_time2.abs_value_us);
210 GNUNET_break (forever.abs_value_us == forever2.abs_value_us);
211 GNUNET_break (0 ==
212 GNUNET_memcmp (&hc,
213 &hc2));
214 GNUNET_break (0 ==
215 GNUNET_CRYPTO_rsa_signature_cmp (sig,
216 sig2));
217 GNUNET_break (0 ==
218 GNUNET_CRYPTO_rsa_public_key_cmp (pub,
219 pub2));
220 GNUNET_break (strlen (msg) == msg2_len);
221 GNUNET_break (0 ==
222 strncmp (msg,
223 msg2,
224 msg2_len));
225 GNUNET_break (16 == u162);
226 GNUNET_break (32 == u322);
227 GNUNET_break (64 == u642);
228 GNUNET_break (42 == uzzz);
229 GNUNET_break (got_null);
230 GNUNET_PQ_cleanup_result (results_select);
231 PQclear (result);
232 }
233 GNUNET_CRYPTO_rsa_signature_free (sig);
234 GNUNET_CRYPTO_rsa_private_key_free (priv);
235 GNUNET_CRYPTO_rsa_public_key_free (pub);
236 if (GNUNET_OK != ret)
237 return 1;
238
239 return 0;
240}
241
242
243/**
244 * Task called on shutdown.
245 *
246 * @param cls NULL
247 */
248static void
249event_end (void *cls)
250{
251 GNUNET_PQ_event_listen_cancel (eh);
252 eh = NULL;
253 if (NULL != tt)
254 {
255 GNUNET_SCHEDULER_cancel (tt);
256 tt = NULL;
257 }
258}
259
260
261/**
262 * Task called on timeout. Should not happen, means
263 * we did not get the expected event.
264 *
265 * @param cls NULL
266 */
267static void
268timeout_cb (void *cls)
269{
270 ret = 2;
271 GNUNET_break (0);
272 tt = NULL;
273 GNUNET_SCHEDULER_shutdown ();
274}
275
276
277/**
278 * Task called on expected event
279 *
280 * @param cls NULL
281 */
282static void
283event_sched_cb (void *cls,
284 const void *extra,
285 size_t extra_size)
286{
287 GNUNET_assert (5 == extra_size);
288 GNUNET_assert (0 ==
289 memcmp ("hello",
290 extra,
291 5));
292 GNUNET_SCHEDULER_shutdown ();
293}
294
295
296/**
297 * Run tests that need a scheduler.
298 *
299 * @param cls NULL
300 */
301static void
302sched_tests (void *cls)
303{
304 struct GNUNET_DB_EventHeaderP es = {
305 .size = htons (sizeof (es)),
306 .type = htons (42)
307 };
308
309
310 tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
311 &timeout_cb,
312 NULL);
313 eh = GNUNET_PQ_event_listen (db,
314 &es,
315 GNUNET_TIME_UNIT_FOREVER_REL,
316 &event_sched_cb,
317 NULL);
318 GNUNET_PQ_reconnect (db);
319 GNUNET_SCHEDULER_add_shutdown (&event_end,
320 NULL);
321 GNUNET_PQ_event_notify (db,
322 &es,
323 "hello",
324 5);
325}
326
327
328int
329main (int argc,
330 const char *const argv[])
331{
332 struct GNUNET_PQ_ExecuteStatement es[] = {
333 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS test_pq ("
334 " pub BYTEA NOT NULL"
335 ",sig BYTEA NOT NULL"
336 ",abs_time INT8 NOT NULL"
337 ",forever INT8 NOT NULL"
338 ",hash BYTEA NOT NULL CHECK(LENGTH(hash)=64)"
339 ",vsize VARCHAR NOT NULL"
340 ",u16 INT2 NOT NULL"
341 ",u32 INT4 NOT NULL"
342 ",u64 INT8 NOT NULL"
343 ",unn INT8"
344 ")"),
345 GNUNET_PQ_EXECUTE_STATEMENT_END
346 };
347
348 GNUNET_log_setup ("test-pq",
349 "INFO",
350 NULL);
351 db = GNUNET_PQ_connect ("postgres:///gnunetcheck",
352 NULL,
353 es,
354 NULL);
355 if (NULL == db)
356 {
357 fprintf (stderr,
358 "Cannot run test, database connection failed\n");
359 return 77;
360 }
361 if (CONNECTION_OK != PQstatus (db->conn))
362 {
363 fprintf (stderr,
364 "Cannot run test, database connection failed: %s\n",
365 PQerrorMessage (db->conn));
366 GNUNET_break (0);
367 GNUNET_PQ_disconnect (db);
368 return 77; /* signal test was skipped */
369 }
370 if (GNUNET_OK !=
371 postgres_prepare (db))
372 {
373 GNUNET_break (0);
374 GNUNET_PQ_disconnect (db);
375 return 1;
376 }
377 ret = run_queries (db);
378 if (0 != ret)
379 {
380 GNUNET_break (0);
381 GNUNET_PQ_disconnect (db);
382 return ret;
383 }
384 GNUNET_SCHEDULER_run (&sched_tests,
385 NULL);
386 if (0 != ret)
387 {
388 GNUNET_break (0);
389 GNUNET_PQ_disconnect (db);
390 return ret;
391 }
392#if TEST_RESTART
393 fprintf (stderr, "Please restart Postgres database now!\n");
394 sleep (60);
395 ret |= run_queries (db);
396 fprintf (stderr, "Result: %d (expect: 1 -- if you restarted the DB)\n", ret);
397 ret |= run_queries (db);
398 fprintf (stderr, "Result: %d (expect: 0)\n", ret);
399#endif
400 {
401 struct GNUNET_PQ_ExecuteStatement es[] = {
402 GNUNET_PQ_make_execute ("DROP TABLE test_pq"),
403 GNUNET_PQ_EXECUTE_STATEMENT_END
404 };
405
406 if (GNUNET_OK !=
407 GNUNET_PQ_exec_statements (db,
408 es))
409 {
410 fprintf (stderr,
411 "Failed to drop table\n");
412 GNUNET_PQ_disconnect (db);
413 return 1;
414 }
415 }
416 GNUNET_PQ_disconnect (db);
417 return ret;
418}
419
420
421/* end of test_pq.c */