small API change: do no longer pass rarely needed GNUNET_SCHEDULER_TaskContext to...
[oweals/gnunet.git] / src / set / test_set_api.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_api.c
23  * @brief testcase for set_api.c
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 static struct GNUNET_PeerIdentity local_id;
32
33 static struct GNUNET_HashCode app_id;
34
35 static struct GNUNET_SET_Handle *set1;
36
37 static struct GNUNET_SET_Handle *set2;
38
39 static struct GNUNET_SET_ListenHandle *listen_handle;
40
41 static const struct GNUNET_CONFIGURATION_Handle *config;
42
43 static unsigned int iter_count;
44
45 static int ret;
46
47
48 static void
49 result_cb_set1 (void *cls,
50                 const struct GNUNET_SET_Element *element,
51                 enum GNUNET_SET_Status status)
52 {
53   switch (status)
54   {
55   case GNUNET_SET_STATUS_OK:
56     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
57                 "set 1: got element\n");
58     break;
59   case GNUNET_SET_STATUS_FAILURE:
60     GNUNET_break (0);
61     fprintf (stderr,
62              "set 1: received failure status!\n");
63     ret = 1;
64     GNUNET_SCHEDULER_shutdown ();
65     break;
66   case GNUNET_SET_STATUS_DONE:
67     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
68                 "set 1: done\n");
69     GNUNET_SET_destroy (set1);
70     set1 = NULL;
71     if (NULL == set2)
72       GNUNET_SCHEDULER_shutdown ();
73     break;
74   default:
75     GNUNET_assert (0);
76   }
77 }
78
79
80 static void
81 result_cb_set2 (void *cls,
82                 const struct GNUNET_SET_Element *element,
83                 enum GNUNET_SET_Status status)
84 {
85   switch (status)
86   {
87   case GNUNET_SET_STATUS_OK:
88     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
89                 "set 2: got element\n");
90     break;
91   case GNUNET_SET_STATUS_FAILURE:
92     GNUNET_break (0);
93     fprintf (stderr,
94              "set 2: received failure status\n");
95     ret = 1;
96     break;
97   case GNUNET_SET_STATUS_DONE:
98     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
99                 "set 2: done\n");
100     GNUNET_SET_destroy (set2);
101     set2 = NULL;
102     if (NULL == set1)
103       GNUNET_SCHEDULER_shutdown ();
104     break;
105   default:
106     GNUNET_assert (0);
107   }
108 }
109
110
111 static void
112 listen_cb (void *cls,
113            const struct GNUNET_PeerIdentity *other_peer,
114            const struct GNUNET_MessageHeader *context_msg,
115            struct GNUNET_SET_Request *request)
116 {
117   struct GNUNET_SET_OperationHandle *oh;
118
119   GNUNET_assert (NULL != context_msg);
120
121   GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_TEST);
122
123   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
124               "listen cb called\n");
125   GNUNET_SET_listen_cancel (listen_handle);
126   oh = GNUNET_SET_accept (request,
127                           GNUNET_SET_RESULT_ADDED,
128                           &result_cb_set2, NULL);
129   GNUNET_SET_commit (oh, set2);
130 }
131
132
133 /**
134  * Start the set operation.
135  *
136  * @param cls closure, unused
137  */
138 static void
139 start (void *cls)
140 {
141   struct GNUNET_SET_OperationHandle *oh;
142   struct GNUNET_MessageHeader context_msg;
143
144   context_msg.size = htons (sizeof context_msg);
145   context_msg.type = htons (GNUNET_MESSAGE_TYPE_TEST);
146
147   listen_handle = GNUNET_SET_listen (config, GNUNET_SET_OPERATION_UNION,
148                                      &app_id, listen_cb, NULL);
149   oh = GNUNET_SET_prepare (&local_id, &app_id, &context_msg,
150                            GNUNET_SET_RESULT_ADDED,
151                            result_cb_set1, NULL);
152   GNUNET_SET_commit (oh, set1);
153 }
154
155
156 /**
157  * Initialize the second set, continue
158  *
159  * @param cls closure, unused
160  */
161 static void
162 init_set2 (void *cls)
163 {
164   struct GNUNET_SET_Element element;
165
166   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initializing set 2\n");
167
168   element.element_type = 0;
169
170   element.data = "hello";
171   element.size = strlen(element.data);
172   GNUNET_SET_add_element (set2, &element, NULL, NULL);
173   element.data = "quux";
174   element.size = strlen(element.data);
175   GNUNET_SET_add_element (set2, &element, NULL, NULL);
176   element.data = "baz";
177   element.size = strlen(element.data);
178   GNUNET_SET_add_element (set2, &element, start, NULL);
179 }
180
181
182 /**
183  * Initialize the first set, continue.
184  */
185 static void
186 init_set1 (void)
187 {
188   struct GNUNET_SET_Element element;
189
190   element.element_type = 0;
191
192   element.data = "hello";
193   element.size = strlen(element.data);
194   GNUNET_SET_add_element (set1, &element, NULL, NULL);
195   element.data = "bar";
196   element.size = strlen(element.data);
197   GNUNET_SET_add_element (set1, &element, init_set2, NULL);
198
199   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized set 1\n");
200 }
201
202
203 static int
204 iter_cb (void *cls,
205          const struct GNUNET_SET_Element *element)
206 {
207   if (NULL == element)
208   {
209     GNUNET_assert (3 == iter_count);
210     GNUNET_SET_destroy (cls);
211     return GNUNET_YES;
212   }
213   iter_count++;
214   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
215               "iter: got element %u\n",
216               iter_count);
217   return GNUNET_YES;
218 }
219
220
221 static void
222 test_iter ()
223 {
224   struct GNUNET_SET_Element element;
225   struct GNUNET_SET_Handle *iter_set;
226
227   iter_set = GNUNET_SET_create (config, GNUNET_SET_OPERATION_UNION);
228
229   element.element_type = 0;
230
231   element.data = "hello";
232   element.size = strlen(element.data);
233   GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
234   element.data = "bar";
235   element.size = strlen(element.data);
236   GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
237   element.data = "quux";
238   element.size = strlen(element.data);
239   GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
240
241   GNUNET_SET_iterate (iter_set, iter_cb, iter_set);
242 }
243
244
245 /**
246  * Signature of the main function of a task.
247  *
248  * @param cls closure
249  */
250 static void
251 timeout_fail (void *cls)
252 {
253   const struct GNUNET_SCHEDULER_TaskContext *tc;
254
255   tc = GNUNET_SCHEDULER_get_task_context ();
256   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
257     return;
258   GNUNET_SCHEDULER_shutdown ();
259   ret = 1;
260 }
261
262
263 /**
264  * Signature of the 'main' function for a (single-peer) testcase that
265  * is run using 'GNUNET_TESTING_peer_run'.
266  *
267  * @param cls closure
268  * @param cfg configuration of the peer that was started
269  * @param peer identity of the peer that was created
270  */
271 static void
272 run (void *cls,
273      const struct GNUNET_CONFIGURATION_Handle *cfg,
274      struct GNUNET_TESTING_Peer *peer)
275 {
276
277   struct GNUNET_SET_OperationHandle *my_oh;
278
279   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
280                                 &timeout_fail, NULL);
281
282   config = cfg;
283   GNUNET_CRYPTO_get_peer_identity (cfg, &local_id);
284   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
285               "my id (from CRYPTO): %s\n",
286               GNUNET_i2s (&local_id));
287   GNUNET_TESTING_peer_get_identity (peer, &local_id);
288   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
289               "my id (from TESTING): %s\n",
290               GNUNET_i2s (&local_id));
291   test_iter ();
292
293   set1 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION);
294   set2 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION);
295   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
296                                     &app_id);
297
298   ///* test if canceling an uncommited request works! */
299   my_oh = GNUNET_SET_prepare (&local_id, &app_id, NULL,
300                               GNUNET_SET_RESULT_ADDED, NULL, NULL);
301
302   GNUNET_SET_operation_cancel (my_oh);
303
304   /* test the real set reconciliation */
305   init_set1 ();
306 }
307
308
309 int
310 main (int argc, char **argv)
311 {
312   if (0 != GNUNET_TESTING_peer_run ("test_set_api",
313                                     "test_set.conf",
314                                     &run, NULL))
315   {
316     return 1;
317   }
318   return ret;
319 }