-remove debug message
[oweals/gnunet.git] / src / pq / test_pq.c
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 /**
30  * Setup prepared statements.
31  *
32  * @param db database handle to initialize
33  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
34  */
35 static int
36 postgres_prepare (struct GNUNET_PQ_Context *db)
37 {
38   struct GNUNET_PQ_PreparedStatement ps[] = {
39     GNUNET_PQ_make_prepare ("test_insert",
40                             "INSERT INTO test_pq ("
41                             " pub"
42                             ",sig"
43                             ",abs_time"
44                             ",forever"
45                             ",hash"
46                             ",vsize"
47                             ",u16"
48                             ",u32"
49                             ",u64"
50                             ") VALUES "
51                             "($1, $2, $3, $4, $5, $6,"
52                             "$7, $8, $9);",
53                             9),
54     GNUNET_PQ_make_prepare ("test_select",
55                             "SELECT"
56                             " pub"
57                             ",sig"
58                             ",abs_time"
59                             ",forever"
60                             ",hash"
61                             ",vsize"
62                             ",u16"
63                             ",u32"
64                             ",u64"
65                             " FROM test_pq"
66                             " ORDER BY abs_time DESC "
67                             " LIMIT 1;",
68                             0),
69     GNUNET_PQ_PREPARED_STATEMENT_END
70   };
71
72   return GNUNET_PQ_prepare_statements (db,
73                                        ps);
74 }
75
76
77 /**
78  * Run actual test queries.
79  *
80  * @param db database handle
81  * @return 0 on success
82  */
83 static int
84 run_queries (struct GNUNET_PQ_Context *db)
85 {
86   struct GNUNET_CRYPTO_RsaPublicKey *pub;
87   struct GNUNET_CRYPTO_RsaPublicKey *pub2 = NULL;
88   struct GNUNET_CRYPTO_RsaSignature *sig;
89   struct GNUNET_CRYPTO_RsaSignature *sig2 = NULL;
90   struct GNUNET_TIME_Absolute abs_time = GNUNET_TIME_absolute_get ();
91   struct GNUNET_TIME_Absolute abs_time2;
92   struct GNUNET_TIME_Absolute forever = GNUNET_TIME_UNIT_FOREVER_ABS;
93   struct GNUNET_TIME_Absolute forever2;
94   struct GNUNET_HashCode hc;
95   struct GNUNET_HashCode hc2;
96   PGresult *result;
97   int ret;
98   struct GNUNET_CRYPTO_RsaPrivateKey *priv;
99   const char msg[] = "hello";
100   void *msg2;
101   struct GNUNET_HashCode hmsg;
102   size_t msg2_len;
103   uint16_t u16;
104   uint16_t u162;
105   uint32_t u32;
106   uint32_t u322;
107   uint64_t u64;
108   uint64_t u642;
109
110   priv = GNUNET_CRYPTO_rsa_private_key_create (1024);
111   pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
112   memset (&hmsg, 42, sizeof(hmsg));
113   sig = GNUNET_CRYPTO_rsa_sign_fdh (priv,
114                                     &hmsg);
115   u16 = 16;
116   u32 = 32;
117   u64 = 64;
118   /* FIXME: test GNUNET_PQ_result_spec_variable_size */
119   {
120     struct GNUNET_PQ_QueryParam params_insert[] = {
121       GNUNET_PQ_query_param_rsa_public_key (pub),
122       GNUNET_PQ_query_param_rsa_signature (sig),
123       GNUNET_PQ_query_param_absolute_time (&abs_time),
124       GNUNET_PQ_query_param_absolute_time (&forever),
125       GNUNET_PQ_query_param_auto_from_type (&hc),
126       GNUNET_PQ_query_param_fixed_size (msg, strlen (msg)),
127       GNUNET_PQ_query_param_uint16 (&u16),
128       GNUNET_PQ_query_param_uint32 (&u32),
129       GNUNET_PQ_query_param_uint64 (&u64),
130       GNUNET_PQ_query_param_end
131     };
132     struct GNUNET_PQ_QueryParam params_select[] = {
133       GNUNET_PQ_query_param_end
134     };
135     struct GNUNET_PQ_ResultSpec results_select[] = {
136       GNUNET_PQ_result_spec_rsa_public_key ("pub", &pub2),
137       GNUNET_PQ_result_spec_rsa_signature ("sig", &sig2),
138       GNUNET_PQ_result_spec_absolute_time ("abs_time", &abs_time2),
139       GNUNET_PQ_result_spec_absolute_time ("forever", &forever2),
140       GNUNET_PQ_result_spec_auto_from_type ("hash", &hc2),
141       GNUNET_PQ_result_spec_variable_size ("vsize", &msg2, &msg2_len),
142       GNUNET_PQ_result_spec_uint16 ("u16", &u162),
143       GNUNET_PQ_result_spec_uint32 ("u32", &u322),
144       GNUNET_PQ_result_spec_uint64 ("u64", &u642),
145       GNUNET_PQ_result_spec_end
146     };
147
148     result = GNUNET_PQ_exec_prepared (db,
149                                       "test_insert",
150                                       params_insert);
151     if (PGRES_COMMAND_OK != PQresultStatus (result))
152     {
153       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
154                   "Database failure: %s\n",
155                   PQresultErrorMessage (result));
156       PQclear (result);
157       GNUNET_CRYPTO_rsa_signature_free (sig);
158       GNUNET_CRYPTO_rsa_private_key_free (priv);
159       GNUNET_CRYPTO_rsa_public_key_free (pub);
160       return 1;
161     }
162
163     PQclear (result);
164     result = GNUNET_PQ_exec_prepared (db,
165                                       "test_select",
166                                       params_select);
167     if (1 !=
168         PQntuples (result))
169     {
170       GNUNET_break (0);
171       PQclear (result);
172       GNUNET_CRYPTO_rsa_signature_free (sig);
173       GNUNET_CRYPTO_rsa_private_key_free (priv);
174       GNUNET_CRYPTO_rsa_public_key_free (pub);
175       return 1;
176     }
177     ret = GNUNET_PQ_extract_result (result,
178                                     results_select,
179                                     0);
180     GNUNET_break (GNUNET_YES == ret);
181     GNUNET_break (abs_time.abs_value_us == abs_time2.abs_value_us);
182     GNUNET_break (forever.abs_value_us == forever2.abs_value_us);
183     GNUNET_break (0 ==
184                   GNUNET_memcmp (&hc,
185                                  &hc2));
186     GNUNET_break (0 ==
187                   GNUNET_CRYPTO_rsa_signature_cmp (sig,
188                                                    sig2));
189     GNUNET_break (0 ==
190                   GNUNET_CRYPTO_rsa_public_key_cmp (pub,
191                                                     pub2));
192     GNUNET_break (strlen (msg) == msg2_len);
193     GNUNET_break (0 ==
194                   strncmp (msg,
195                            msg2,
196                            msg2_len));
197     GNUNET_break (16 == u162);
198     GNUNET_break (32 == u322);
199     GNUNET_break (64 == u642);
200     GNUNET_PQ_cleanup_result (results_select);
201     PQclear (result);
202   }
203   GNUNET_CRYPTO_rsa_signature_free (sig);
204   GNUNET_CRYPTO_rsa_private_key_free (priv);
205   GNUNET_CRYPTO_rsa_public_key_free (pub);
206   if (GNUNET_OK != ret)
207     return 1;
208
209   return 0;
210 }
211
212
213 int
214 main (int argc,
215       const char *const argv[])
216 {
217   struct GNUNET_PQ_ExecuteStatement es[] = {
218     GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS test_pq ("
219                             " pub BYTEA NOT NULL"
220                             ",sig BYTEA NOT NULL"
221                             ",abs_time INT8 NOT NULL"
222                             ",forever INT8 NOT NULL"
223                             ",hash BYTEA NOT NULL CHECK(LENGTH(hash)=64)"
224                             ",vsize VARCHAR NOT NULL"
225                             ",u16 INT2 NOT NULL"
226                             ",u32 INT4 NOT NULL"
227                             ",u64 INT8 NOT NULL"
228                             ")"),
229     GNUNET_PQ_EXECUTE_STATEMENT_END
230   };
231   struct GNUNET_PQ_Context *db;
232   int ret;
233
234   GNUNET_log_setup ("test-pq",
235                     "WARNING",
236                     NULL);
237   db = GNUNET_PQ_connect ("postgres:///gnunetcheck",
238                           NULL,
239                           es,
240                           NULL);
241   if (NULL == db)
242   {
243     fprintf (stderr,
244              "Cannot run test, database connection failed\n");
245     return 77;
246   }
247   if (CONNECTION_OK != PQstatus (db->conn))
248   {
249     fprintf (stderr,
250              "Cannot run test, database connection failed: %s\n",
251              PQerrorMessage (db->conn));
252     GNUNET_break (0);
253     GNUNET_PQ_disconnect (db);
254     return 77;   /* signal test was skipped */
255   }
256   if (GNUNET_OK !=
257       postgres_prepare (db))
258   {
259     GNUNET_break (0);
260     GNUNET_PQ_disconnect (db);
261     return 1;
262   }
263   ret = run_queries (db);
264 #if TEST_RESTART
265   fprintf (stderr, "Please restart Postgres database now!\n");
266   sleep (60);
267   ret = run_queries (db);
268   fprintf (stderr, "Result: %d (expect: 1 -- if you restarted the DB)\n", ret);
269   ret = run_queries (db);
270   fprintf (stderr, "Result: %d (expect: 0)\n", ret);
271 #endif
272   {
273     struct GNUNET_PQ_ExecuteStatement es[] = {
274       GNUNET_PQ_make_execute ("DROP TABLE test_pq"),
275       GNUNET_PQ_EXECUTE_STATEMENT_END
276     };
277
278     if (GNUNET_OK !=
279         GNUNET_PQ_exec_statements (db,
280                                    es))
281     {
282       fprintf (stderr,
283                "Failed to drop table\n");
284       GNUNET_PQ_disconnect (db);
285       return 1;
286     }
287   }
288   GNUNET_PQ_disconnect (db);
289   return ret;
290 }
291
292
293 /* end of test_pq.c */