remove CYGWIN codeblocks, drop vendored Windows openvpn, drop win32 specific files.
[oweals/gnunet.git] / src / set / test_set_union_result_symmetric.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2012, 2016 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 /**
22  * @file set/test_set_union_result_smmetric
23  * @brief testcase for symmetric result mode of the union set operation
24  * @author Florian Dold
25  * @author Christian Grothoff
26  */
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_testing_lib.h"
30 #include "gnunet_set_service.h"
31
32
33 /**
34  * Value to return from #main().
35  */
36 static int ret;
37
38 static struct GNUNET_PeerIdentity local_id;
39
40 static struct GNUNET_HashCode app_id;
41
42 static struct GNUNET_SET_Handle *set1;
43
44 static struct GNUNET_SET_Handle *set2;
45
46 static struct GNUNET_SET_ListenHandle *listen_handle;
47
48 static const struct GNUNET_CONFIGURATION_Handle *config;
49
50 static struct GNUNET_SET_OperationHandle *oh1;
51
52 static struct GNUNET_SET_OperationHandle *oh2;
53
54 static int iter_count;
55
56 /**
57  * Are we testing correctness for the empty set union?
58  */
59 static int empty;
60
61 /**
62  * Number of elements found in set 1
63  */
64 static unsigned int count_set1;
65
66 /**
67  * Number of elements found in set 2
68  */
69 static unsigned int count_set2;
70
71 /**
72  * Task that is run when the test times out.
73  */
74 static struct GNUNET_SCHEDULER_Task *timeout_task;
75
76
77 static void
78 result_cb_set1(void *cls,
79                const struct GNUNET_SET_Element *element,
80                uint64_t current_size,
81                enum GNUNET_SET_Status status)
82 {
83   switch (status)
84     {
85     case GNUNET_SET_STATUS_ADD_LOCAL:
86       count_set1++;
87       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
88                  "set 1: got element\n");
89       break;
90
91     case GNUNET_SET_STATUS_FAILURE:
92       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
93                  "set 1: failure\n");
94       oh1 = NULL;
95       ret = 1;
96       if (NULL != timeout_task)
97         {
98           GNUNET_SCHEDULER_cancel(timeout_task);
99           timeout_task = NULL;
100         }
101       GNUNET_SCHEDULER_shutdown();
102       break;
103
104     case GNUNET_SET_STATUS_DONE:
105       oh1 = NULL;
106       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
107                  "set 1: done\n");
108       GNUNET_SET_destroy(set1);
109       set1 = NULL;
110       if (NULL == set2)
111         {
112           if (NULL != timeout_task)
113             {
114               GNUNET_SCHEDULER_cancel(timeout_task);
115               timeout_task = NULL;
116             }
117           GNUNET_SCHEDULER_shutdown();
118         }
119       break;
120
121     case GNUNET_SET_STATUS_ADD_REMOTE:
122       break;
123
124     default:
125       GNUNET_assert(0);
126     }
127 }
128
129
130 static void
131 result_cb_set2(void *cls,
132                const struct GNUNET_SET_Element *element,
133                uint64_t current_size,
134                enum GNUNET_SET_Status status)
135 {
136   switch (status)
137     {
138     case GNUNET_SET_STATUS_ADD_LOCAL:
139       count_set2++;
140       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
141                  "set 2: got element\n");
142       break;
143
144     case GNUNET_SET_STATUS_FAILURE:
145       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
146                  "set 2: failure\n");
147       oh2 = NULL;
148       ret = 1;
149       if (NULL != timeout_task)
150         {
151           GNUNET_SCHEDULER_cancel(timeout_task);
152           timeout_task = NULL;
153         }
154       GNUNET_SCHEDULER_shutdown();
155       break;
156
157     case GNUNET_SET_STATUS_DONE:
158       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
159                  "set 2: done\n");
160       oh2 = NULL;
161       GNUNET_SET_destroy(set2);
162       set2 = NULL;
163       if (NULL == set1)
164         {
165           if (NULL != timeout_task)
166             {
167               GNUNET_SCHEDULER_cancel(timeout_task);
168               timeout_task = NULL;
169             }
170           GNUNET_SCHEDULER_shutdown();
171         }
172       break;
173
174     case GNUNET_SET_STATUS_ADD_REMOTE:
175       break;
176
177     default:
178       GNUNET_assert(0);
179     }
180 }
181
182
183 static void
184 listen_cb(void *cls,
185           const struct GNUNET_PeerIdentity *other_peer,
186           const struct GNUNET_MessageHeader *context_msg,
187           struct GNUNET_SET_Request *request)
188 {
189   GNUNET_assert(NULL != context_msg);
190   GNUNET_assert(ntohs(context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY);
191   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
192              "listen cb called\n");
193   oh2 = GNUNET_SET_accept(request,
194                           GNUNET_SET_RESULT_SYMMETRIC,
195                           (struct GNUNET_SET_Option[]) { 0 },
196                           &result_cb_set2,
197                           NULL);
198   GNUNET_SET_commit(oh2,
199                     set2);
200 }
201
202
203 /**
204  * Start the set operation.
205  *
206  * @param cls closure, unused
207  */
208 static void
209 start(void *cls)
210 {
211   struct GNUNET_MessageHeader context_msg;
212
213   context_msg.size = htons(sizeof context_msg);
214   context_msg.type = htons(GNUNET_MESSAGE_TYPE_DUMMY);
215
216   listen_handle = GNUNET_SET_listen(config,
217                                     GNUNET_SET_OPERATION_UNION,
218                                     &app_id,
219                                     &listen_cb, NULL);
220   oh1 = GNUNET_SET_prepare(&local_id,
221                            &app_id,
222                            &context_msg,
223                            GNUNET_SET_RESULT_SYMMETRIC,
224                            (struct GNUNET_SET_Option[]) { 0 },
225                            &result_cb_set1, NULL);
226   GNUNET_SET_commit(oh1, set1);
227 }
228
229
230 /**
231  * Initialize the second set, continue
232  *
233  * @param cls closure, unused
234  */
235 static void
236 init_set2(void *cls)
237 {
238   struct GNUNET_SET_Element element;
239
240   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
241              "initializing set 2\n");
242   if (empty)
243     {
244       start(NULL);
245       return;
246     }
247   element.element_type = 0;
248   element.data = "hello";
249   element.size = strlen(element.data);
250   GNUNET_SET_add_element(set2,
251                          &element,
252                          NULL,
253                          NULL);
254   element.data = "quux";
255   element.size = strlen(element.data);
256   GNUNET_SET_add_element(set2,
257                          &element,
258                          NULL,
259                          NULL);
260   element.data = "baz";
261   element.size = strlen(element.data);
262   GNUNET_SET_add_element(set2,
263                          &element,
264                          &start, NULL);
265 }
266
267
268 /**
269  * Initialize the first set, continue.
270  */
271 static void
272 init_set1(void)
273 {
274   struct GNUNET_SET_Element element;
275
276   if (empty)
277     {
278       init_set2(NULL);
279       return;
280     }
281   element.element_type = 0;
282   element.data = "hello";
283   element.size = strlen(element.data);
284   GNUNET_SET_add_element(set1,
285                          &element,
286                          NULL,
287                          NULL);
288   element.data = "bar";
289   element.size = strlen(element.data);
290   GNUNET_SET_add_element(set1,
291                          &element,
292                          &init_set2,
293                          NULL);
294   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
295              "initialized set 1\n");
296 }
297
298
299 static int
300 iter_cb(void *cls,
301         const struct GNUNET_SET_Element *element)
302 {
303   if (NULL == element)
304     {
305       GNUNET_assert(iter_count == 3);
306       GNUNET_SET_destroy(cls);
307       return GNUNET_YES;
308     }
309   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
310              "iter: got element\n");
311   iter_count++;
312   return GNUNET_YES;
313 }
314
315
316 static void
317 test_iter()
318 {
319   struct GNUNET_SET_Element element;
320   struct GNUNET_SET_Handle *iter_set;
321
322   iter_count = 0;
323   iter_set = GNUNET_SET_create(config, GNUNET_SET_OPERATION_UNION);
324   element.element_type = 0;
325   element.data = "hello";
326   element.size = strlen(element.data);
327   GNUNET_SET_add_element(iter_set, &element, NULL, NULL);
328   element.data = "bar";
329   element.size = strlen(element.data);
330   GNUNET_SET_add_element(iter_set, &element, NULL, NULL);
331   element.data = "quux";
332   element.size = strlen(element.data);
333   GNUNET_SET_add_element(iter_set, &element, NULL, NULL);
334
335   GNUNET_SET_iterate(iter_set,
336                      &iter_cb,
337                      iter_set);
338 }
339
340
341 /**
342  * Signature of the main function of a task.
343  *
344  * @param cls closure
345  */
346 static void
347 timeout_fail(void *cls)
348 {
349   timeout_task = NULL;
350   GNUNET_SCHEDULER_shutdown();
351   GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
352              "test timed out\n");
353   ret = 1;
354 }
355
356
357 /**
358  * Function run on shutdown.
359  *
360  * @param cls closure
361  */
362 static void
363 do_shutdown(void *cls)
364 {
365   if (NULL != timeout_task)
366     {
367       GNUNET_SCHEDULER_cancel(timeout_task);
368       timeout_task = NULL;
369     }
370   if (NULL != oh1)
371     {
372       GNUNET_SET_operation_cancel(oh1);
373       oh1 = NULL;
374     }
375   if (NULL != oh2)
376     {
377       GNUNET_SET_operation_cancel(oh2);
378       oh2 = NULL;
379     }
380   if (NULL != set1)
381     {
382       GNUNET_SET_destroy(set1);
383       set1 = NULL;
384     }
385   if (NULL != set2)
386     {
387       GNUNET_SET_destroy(set2);
388       set2 = NULL;
389     }
390   if (NULL != listen_handle)
391     {
392       GNUNET_SET_listen_cancel(listen_handle);
393       listen_handle = NULL;
394     }
395 }
396
397
398 /**
399  * Signature of the 'main' function for a (single-peer) testcase that
400  * is run using 'GNUNET_TESTING_peer_run'.
401  *
402  * @param cls closure
403  * @param cfg configuration of the peer that was started
404  * @param peer identity of the peer that was created
405  */
406 static void
407 run(void *cls,
408     const struct GNUNET_CONFIGURATION_Handle *cfg,
409     struct GNUNET_TESTING_Peer *peer)
410 {
411   timeout_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5),
412                                               &timeout_fail,
413                                               NULL);
414   GNUNET_SCHEDULER_add_shutdown(&do_shutdown,
415                                 NULL);
416   config = cfg;
417   GNUNET_TESTING_peer_get_identity(peer,
418                                    &local_id);
419
420   if (0)
421     test_iter();
422
423   set1 = GNUNET_SET_create(cfg, GNUNET_SET_OPERATION_UNION);
424   set2 = GNUNET_SET_create(cfg, GNUNET_SET_OPERATION_UNION);
425   GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &app_id);
426
427   /* test the real set reconciliation */
428   init_set1();
429 }
430
431
432 int
433 main(int argc, char **argv)
434 {
435   empty = 1;
436   if (0 != GNUNET_TESTING_peer_run("test_set_api",
437                                    "test_set.conf",
438                                    &run, NULL))
439     {
440       return 1;
441     }
442   GNUNET_assert(0 == count_set1);
443   GNUNET_assert(0 == count_set2);
444   empty = 0;
445   if (0 != GNUNET_TESTING_peer_run("test_set_api",
446                                    "test_set.conf",
447                                    &run, NULL))
448     {
449       return 1;
450     }
451   GNUNET_break(2 == count_set1);
452   GNUNET_break(1 == count_set2);
453   return ret;
454 }