diff options
Diffstat (limited to 'src/pq/test_pq.c')
-rw-r--r-- | src/pq/test_pq.c | 421 |
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 | */ | ||
31 | static struct GNUNET_PQ_Context *db; | ||
32 | |||
33 | /** | ||
34 | * Global return value, 0 on success. | ||
35 | */ | ||
36 | static int ret; | ||
37 | |||
38 | /** | ||
39 | * An event handler. | ||
40 | */ | ||
41 | static struct GNUNET_DB_EventHandler *eh; | ||
42 | |||
43 | /** | ||
44 | * Timeout task. | ||
45 | */ | ||
46 | static 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 | */ | ||
55 | static int | ||
56 | postgres_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 | */ | ||
105 | static int | ||
106 | run_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 | */ | ||
248 | static void | ||
249 | event_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 | */ | ||
267 | static void | ||
268 | timeout_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 | */ | ||
282 | static void | ||
283 | event_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 | */ | ||
301 | static void | ||
302 | sched_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 | |||
328 | int | ||
329 | main (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 */ | ||