ignore in lint/
[oweals/gnunet.git] / src / set / test_set_intersection_result_full.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2012-2014 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_intersection_result_full.c
23  * @brief testcase for full result mode of the intersection set operation
24  * @author Christian Fuchs
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 static int ret;
34
35 static struct GNUNET_PeerIdentity local_id;
36
37 static struct GNUNET_HashCode app_id;
38
39 static struct GNUNET_SET_Handle *set1;
40
41 static struct GNUNET_SET_Handle *set2;
42
43 static struct GNUNET_SET_ListenHandle *listen_handle;
44
45 static const struct GNUNET_CONFIGURATION_Handle *config;
46
47 static int iter_count;
48
49 static struct GNUNET_SCHEDULER_Task *tt;
50
51 static struct GNUNET_SET_OperationHandle *oh1;
52
53 static struct GNUNET_SET_OperationHandle *oh2;
54
55
56 static void
57 result_cb_set1 (void *cls,
58                 const struct GNUNET_SET_Element *element,
59                 uint64_t current_size,
60                 enum GNUNET_SET_Status status)
61 {
62   static int count;
63
64   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
65               "Processing result set 1 (%d)\n",
66               status);
67   switch (status)
68   {
69   case GNUNET_SET_STATUS_OK:
70     count++;
71     break;
72   case GNUNET_SET_STATUS_FAILURE:
73     oh1 = NULL;
74     ret = 1;
75     break;
76   case GNUNET_SET_STATUS_DONE:
77     oh1 = NULL;
78     GNUNET_assert (1 == count);
79     GNUNET_SET_destroy (set1);
80     set1 = NULL;
81     if (NULL == set2)
82       GNUNET_SCHEDULER_shutdown ();
83     break;
84   default:
85     GNUNET_assert (0);
86   }
87 }
88
89
90 static void
91 result_cb_set2 (void *cls,
92                 const struct GNUNET_SET_Element *element,
93                 uint64_t current_size,
94                 enum GNUNET_SET_Status status)
95 {
96   static int count;
97
98   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
99               "Processing result set 2 (%d)\n",
100               status);
101   switch (status)
102   {
103   case GNUNET_SET_STATUS_OK:
104     count++;
105     break;
106   case GNUNET_SET_STATUS_FAILURE:
107     oh2 = NULL;
108     ret = 1;
109     break;
110   case GNUNET_SET_STATUS_DONE:
111     oh2 = NULL;
112     GNUNET_assert (1 == count);
113     GNUNET_SET_destroy (set2);
114     set2 = NULL;
115     if (NULL == set1)
116       GNUNET_SCHEDULER_shutdown ();
117     break;
118   default:
119     GNUNET_assert (0);
120   }
121 }
122
123
124 static void
125 listen_cb (void *cls,
126            const struct GNUNET_PeerIdentity *other_peer,
127            const struct GNUNET_MessageHeader *context_msg,
128            struct GNUNET_SET_Request *request)
129 {
130   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
131               "starting intersection by accepting and committing\n");
132   GNUNET_assert (NULL != context_msg);
133   GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY);
134   oh2 = GNUNET_SET_accept (request,
135                            GNUNET_SET_RESULT_FULL,
136                            (struct GNUNET_SET_Option[]) { 0 },
137                            &result_cb_set2,
138                            NULL);
139   GNUNET_SET_commit (oh2,
140                      set2);
141 }
142
143
144 /**
145  * Start the set operation.
146  *
147  * @param cls closure, unused
148  */
149 static void
150 start (void *cls)
151 {
152   struct GNUNET_MessageHeader context_msg;
153
154   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
155               "starting listener\n");
156   context_msg.size = htons (sizeof context_msg);
157   context_msg.type = htons (GNUNET_MESSAGE_TYPE_DUMMY);
158   listen_handle = GNUNET_SET_listen (config,
159                                      GNUNET_SET_OPERATION_INTERSECTION,
160                                      &app_id,
161                                      &listen_cb,
162                                      NULL);
163   oh1 = GNUNET_SET_prepare (&local_id,
164                             &app_id,
165                             &context_msg,
166                             GNUNET_SET_RESULT_FULL,
167                             (struct GNUNET_SET_Option[]) { 0 },
168                             &result_cb_set1,
169                             NULL);
170   GNUNET_SET_commit (oh1,
171                      set1);
172 }
173
174
175 /**
176  * Initialize the second set, continue
177  *
178  * @param cls closure, unused
179  */
180 static void
181 init_set2 (void *cls)
182 {
183   struct GNUNET_SET_Element element;
184
185   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
186               "initializing set 2\n");
187   element.element_type = 0;
188   element.data = "hello";
189   element.size = strlen(element.data);
190   GNUNET_SET_add_element (set2,
191                           &element,
192                           NULL,
193                           NULL);
194   element.data = "quux";
195   element.size = strlen(element.data);
196   GNUNET_SET_add_element (set2,
197                           &element,
198                           NULL,
199                           NULL);
200   element.data = "baz";
201   element.size = strlen(element.data);
202   GNUNET_SET_add_element (set2,
203                           &element,
204                           &start,
205                           NULL);
206 }
207
208
209 /**
210  * Initialize the first set, continue.
211  */
212 static void
213 init_set1 (void)
214 {
215   struct GNUNET_SET_Element element;
216
217   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
218               "initializing set 1\n");
219   element.element_type = 0;
220   element.data = "hello";
221   element.size = strlen(element.data);
222   GNUNET_SET_add_element (set1,
223                           &element,
224                           NULL,
225                           NULL);
226   element.data = "bar";
227   element.size = strlen(element.data);
228   GNUNET_SET_add_element (set1,
229                           &element,
230                           &init_set2,
231                           NULL);
232 }
233
234
235 static int
236 iter_cb (void *cls,
237          const struct GNUNET_SET_Element *element)
238 {
239   if (NULL == element)
240   {
241     GNUNET_assert (iter_count == 3);
242     GNUNET_SET_destroy (cls);
243     return GNUNET_YES;
244   }
245   iter_count++;
246   return GNUNET_YES;
247 }
248
249
250 static void
251 test_iter ()
252 {
253   struct GNUNET_SET_Element element;
254   struct GNUNET_SET_Handle *iter_set;
255
256   iter_set = GNUNET_SET_create (config,
257                                 GNUNET_SET_OPERATION_INTERSECTION);
258   element.element_type = 0;
259   element.data = "hello";
260   element.size = strlen(element.data);
261   GNUNET_SET_add_element (iter_set,
262                           &element,
263                           NULL,
264                           NULL);
265   element.data = "bar";
266   element.size = strlen(element.data);
267   GNUNET_SET_add_element (iter_set,
268                           &element,
269                           NULL,
270                           NULL);
271   element.data = "quux";
272   element.size = strlen(element.data);
273   GNUNET_SET_add_element (iter_set,
274                           &element,
275                           NULL,
276                           NULL);
277   GNUNET_SET_iterate (iter_set,
278                       &iter_cb,
279                       iter_set);
280 }
281
282
283 /**
284  * Function run on shutdown.
285  *
286  * @param cls closure
287  */
288 static void
289 do_shutdown (void *cls)
290 {
291   if (NULL != tt)
292   {
293     GNUNET_SCHEDULER_cancel (tt);
294     tt = NULL;
295   }
296   if (NULL != oh1)
297   {
298     GNUNET_SET_operation_cancel (oh1);
299     oh1 = NULL;
300   }
301   if (NULL != oh2)
302   {
303     GNUNET_SET_operation_cancel (oh2);
304     oh2 = NULL;
305   }
306   if (NULL != set1)
307   {
308     GNUNET_SET_destroy (set1);
309     set1 = NULL;
310   }
311   if (NULL != set2)
312   {
313     GNUNET_SET_destroy (set2);
314     set2 = NULL;
315   }
316   if (NULL != listen_handle)
317   {
318     GNUNET_SET_listen_cancel (listen_handle);
319     listen_handle = NULL;
320   }
321 }
322
323
324 /**
325  * Function run on timeout.
326  *
327  * @param cls closure
328  */
329 static void
330 timeout_fail (void *cls)
331 {
332   tt = NULL;
333   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
334               "Testcase failed with timeout\n");
335   GNUNET_SCHEDULER_shutdown ();
336   ret = 1;
337 }
338
339
340 /**
341  * Signature of the 'main' function for a (single-peer) testcase that
342  * is run using 'GNUNET_TESTING_peer_run'.
343  *
344  * @param cls closure
345  * @param cfg configuration of the peer that was started
346  * @param peer identity of the peer that was created
347  */
348 static void
349 run (void *cls,
350      const struct GNUNET_CONFIGURATION_Handle *cfg,
351      struct GNUNET_TESTING_Peer *peer)
352 {
353   config = cfg;
354   GNUNET_TESTING_peer_get_identity (peer,
355                                     &local_id);
356   if (0)
357     test_iter ();
358
359   tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
360                                      &timeout_fail,
361                                      NULL);
362   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
363                                  NULL);
364
365   set1 = GNUNET_SET_create (cfg,
366                             GNUNET_SET_OPERATION_INTERSECTION);
367   set2 = GNUNET_SET_create (cfg,
368                             GNUNET_SET_OPERATION_INTERSECTION);
369   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
370                                     &app_id);
371
372   /* test the real set reconciliation */
373   init_set1 ();
374 }
375
376
377 int
378 main (int argc,
379       char **argv)
380 {
381   if (0 != GNUNET_TESTING_peer_run ("test_set_intersection_result_full",
382                                     "test_set.conf",
383                                     &run, NULL))
384     return 1;
385   return ret;
386 }