use c99
[oweals/gnunet.git] / src / set / test_set_union_result_symmetric.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2012 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file set/test_set_union_result_smmetric
23  * @brief testcase for symmetric result mode of the union set operation
24  */
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27 #include "gnunet_testing_lib.h"
28 #include "gnunet_set_service.h"
29
30
31 /**
32  * Value to return from #main().
33  */
34 static int ret;
35
36 static struct GNUNET_PeerIdentity local_id;
37
38 static struct GNUNET_HashCode app_id;
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 /**
50  * Are we testing correctness for the empty set union?
51  */
52 static int empty;
53
54 /**
55  * Number of elements found in set 1
56  */
57 static unsigned int count_set1;
58
59 /**
60  * Number of elements found in set 2
61  */
62 static unsigned int count_set2;
63
64
65 static void
66 result_cb_set1 (void *cls,
67                 const struct GNUNET_SET_Element *element,
68                 enum GNUNET_SET_Status status)
69 {
70   switch (status)
71   {
72     case GNUNET_SET_STATUS_ADD_LOCAL:
73       count_set1++;
74       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
75                   "set 1: got element\n");
76       break;
77     case GNUNET_SET_STATUS_FAILURE:
78       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
79                   "set 1: failure\n");
80       ret = 1;
81       GNUNET_SCHEDULER_shutdown ();
82       break;
83     case GNUNET_SET_STATUS_DONE:
84       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
85                   "set 1: done\n");
86       GNUNET_SET_destroy (set1);
87       set1 = NULL;
88       if (NULL == set2)
89         GNUNET_SCHEDULER_shutdown ();
90       break;
91     case GNUNET_SET_STATUS_ADD_REMOTE:
92       break;
93     default:
94       GNUNET_assert (0);
95   }
96 }
97
98
99 static void
100 result_cb_set2 (void *cls,
101                 const struct GNUNET_SET_Element *element,
102                 enum GNUNET_SET_Status status)
103 {
104   switch (status)
105   {
106     case GNUNET_SET_STATUS_ADD_LOCAL:
107       count_set2++;
108       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
109                   "set 2: got element\n");
110       break;
111     case GNUNET_SET_STATUS_FAILURE:
112       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
113                   "set 2: failure\n");
114       ret = 1;
115       GNUNET_SCHEDULER_shutdown ();
116       break;
117     case GNUNET_SET_STATUS_DONE:
118       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
119                   "set 2: done\n");
120       GNUNET_SET_destroy (set2);
121       set2 = NULL;
122       if (NULL == set1)
123         GNUNET_SCHEDULER_shutdown ();
124       break;
125     case GNUNET_SET_STATUS_ADD_REMOTE:
126       break;
127     default:
128       GNUNET_assert (0);
129   }
130 }
131
132
133 static void
134 listen_cb (void *cls,
135            const struct GNUNET_PeerIdentity *other_peer,
136            const struct GNUNET_MessageHeader *context_msg,
137            struct GNUNET_SET_Request *request)
138 {
139   struct GNUNET_SET_OperationHandle *oh;
140
141   GNUNET_assert (NULL != context_msg);
142   GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_TEST);
143   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
144               "listen cb called\n");
145   GNUNET_SET_listen_cancel (listen_handle);
146   oh = GNUNET_SET_accept (request,
147                           GNUNET_SET_RESULT_SYMMETRIC,
148                           &result_cb_set2,
149                           NULL);
150   GNUNET_SET_commit (oh, set2);
151 }
152
153
154 /**
155  * Start the set operation.
156  *
157  * @param cls closure, unused
158  */
159 static void
160 start (void *cls)
161 {
162   struct GNUNET_SET_OperationHandle *oh;
163   struct GNUNET_MessageHeader context_msg;
164
165   context_msg.size = htons (sizeof context_msg);
166   context_msg.type = htons (GNUNET_MESSAGE_TYPE_TEST);
167
168   listen_handle = GNUNET_SET_listen (config,
169                                      GNUNET_SET_OPERATION_UNION,
170                                      &app_id,
171                                      &listen_cb, NULL);
172   oh = GNUNET_SET_prepare (&local_id,
173                            &app_id,
174                            &context_msg,
175                            GNUNET_SET_RESULT_SYMMETRIC,
176                            &result_cb_set1, NULL);
177   GNUNET_SET_commit (oh, set1);
178 }
179
180
181 /**
182  * Initialize the second set, continue
183  *
184  * @param cls closure, unused
185  */
186 static void
187 init_set2 (void *cls)
188 {
189   struct GNUNET_SET_Element element;
190
191   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
192               "initializing set 2\n");
193   if (empty)
194   {
195     start (NULL);
196     return;
197   }
198   element.element_type = 0;
199   element.data = "hello";
200   element.size = strlen(element.data);
201   GNUNET_SET_add_element (set2,
202                           &element,
203                           NULL,
204                           NULL);
205   element.data = "quux";
206   element.size = strlen(element.data);
207   GNUNET_SET_add_element (set2,
208                           &element,
209                           NULL,
210                           NULL);
211   element.data = "baz";
212   element.size = strlen(element.data);
213   GNUNET_SET_add_element (set2,
214                           &element,
215                           &start, NULL);
216 }
217
218
219 /**
220  * Initialize the first set, continue.
221  */
222 static void
223 init_set1 (void)
224 {
225   struct GNUNET_SET_Element element;
226
227   if (empty)
228   {
229     init_set2 (NULL);
230     return;
231   }
232   element.element_type = 0;
233   element.data = "hello";
234   element.size = strlen(element.data);
235   GNUNET_SET_add_element (set1,
236                           &element,
237                           NULL,
238                           NULL);
239   element.data = "bar";
240   element.size = strlen(element.data);
241   GNUNET_SET_add_element (set1,
242                           &element,
243                           &init_set2,
244                           NULL);
245   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
246               "initialized set 1\n");
247 }
248
249
250 static int
251 iter_cb (void *cls,
252          const struct GNUNET_SET_Element *element)
253 {
254   if (NULL == element)
255   {
256     GNUNET_assert (iter_count == 3);
257     GNUNET_SET_destroy (cls);
258     return GNUNET_YES;
259   }
260   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
261               "iter: got element\n");
262   iter_count++;
263   return GNUNET_YES;
264 }
265
266
267 static void
268 test_iter ()
269 {
270   struct GNUNET_SET_Element element;
271   struct GNUNET_SET_Handle *iter_set;
272
273   iter_count = 0;
274   iter_set = GNUNET_SET_create (config, GNUNET_SET_OPERATION_UNION);
275   element.element_type = 0;
276   element.data = "hello";
277   element.size = strlen(element.data);
278   GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
279   element.data = "bar";
280   element.size = strlen(element.data);
281   GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
282   element.data = "quux";
283   element.size = strlen(element.data);
284   GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
285
286   GNUNET_SET_iterate (iter_set,
287                       &iter_cb,
288                       iter_set);
289 }
290
291
292 /**
293  * Signature of the main function of a task.
294  *
295  * @param cls closure
296  */
297 static void
298 timeout_fail (void *cls)
299 {
300   GNUNET_SCHEDULER_shutdown ();
301   ret = 1;
302 }
303
304
305 /**
306  * Signature of the 'main' function for a (single-peer) testcase that
307  * is run using 'GNUNET_TESTING_peer_run'.
308  *
309  * @param cls closure
310  * @param cfg configuration of the peer that was started
311  * @param peer identity of the peer that was created
312  */
313 static void
314 run (void *cls,
315      const struct GNUNET_CONFIGURATION_Handle *cfg,
316      struct GNUNET_TESTING_Peer *peer)
317 {
318   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
319                                 &timeout_fail,
320                                 NULL);
321
322   config = cfg;
323   GNUNET_TESTING_peer_get_identity (peer,
324                                     &local_id);
325
326   test_iter ();
327
328   set1 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION);
329   set2 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION);
330   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &app_id);
331
332   /* test the real set reconciliation */
333   init_set1 ();
334 }
335
336
337 int
338 main (int argc, char **argv)
339 {
340   empty = 1;
341   if (0 != GNUNET_TESTING_peer_run ("test_set_api",
342                                     "test_set.conf",
343                                     &run, NULL))
344   {
345     return 1;
346   }
347   GNUNET_assert (0 == count_set1);
348   GNUNET_assert (0 == count_set2);
349   empty = 0;
350   if (0 != GNUNET_TESTING_peer_run ("test_set_api",
351                                     "test_set.conf",
352                                     &run, NULL))
353   {
354     return 1;
355   }
356   GNUNET_assert (2 == count_set1);
357   GNUNET_assert (1 == count_set2);
358   return ret;
359 }