WiP
[oweals/gnunet.git] / src / mesh / test_mesh_path_api.c
1 /*
2      This file is part of GNUnet.
3      (C) 2011 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file mesh/test_mesh_path.c
23  * @brief test mesh path: test of path management api
24  * @author Bartlomiej Polot
25  */
26
27 #include "platform.h"
28 #include "gnunet_common.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_dht_service.h"
31 #include "gnunet_mesh_service_new.h"
32 #include "mesh.h"
33 #include "mesh_tunnel_tree.h"
34
35 #define VERBOSE 1
36
37 int failed;
38 int cb_call;
39 struct GNUNET_PeerIdentity* pi[10];
40 struct MeshTunnelTree *tree;
41
42 void
43 cb (const struct MeshTunnelTreeNode *n)
44 {
45   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: CB: Disconnected %u\n", n->peer);
46   if(0 == cb_call)
47   {
48     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test:      and it shouldn't!\n");
49     failed++;
50   }
51   cb_call--;
52 }
53
54
55 void
56 finish(void)
57 {
58   unsigned int i;
59
60   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Finishing...\n");
61   for (i = 0; i < 10; i++)
62   {
63     GNUNET_free(pi[i]);
64   }
65   tree_destroy(tree);
66   exit(0);
67 }
68
69 /**
70  * Convert an integer int to a peer identity
71  */
72 static struct GNUNET_PeerIdentity *
73 get_pi (uint32_t id)
74 {
75   struct GNUNET_PeerIdentity *pi;
76
77   pi = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
78   pi->hashPubKey.bits[0] = id + 1;
79   return pi;
80 }
81
82
83 int
84 main (int argc, char *argv[])
85 {
86   struct MeshTunnelTreeNode *node;
87   struct MeshTunnelTreeNode *node2;
88   struct MeshPeerPath *path;
89   struct MeshPeerPath *path1;
90   unsigned int i;
91
92   failed = 0;
93   cb_call = 0;
94   GNUNET_log_setup ("test_mesh_api_path",
95 #if VERBOSE
96                     "DEBUG",
97 #else
98                     "WARNING",
99 #endif
100                     NULL);
101   for (i = 0; i < 10; i++)
102   {
103       pi[i] = get_pi(i);
104       GNUNET_break (i != GNUNET_PEER_intern(pi[i]));
105       GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Peer %u: %s\n", i,
106                  GNUNET_h2s(&pi[i]->hashPubKey));
107   }
108   tree = GNUNET_malloc(sizeof(struct MeshTunnelTree));
109   tree->first_hops = GNUNET_CONTAINER_multihashmap_create(32);
110   tree->root = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode));
111   tree->root->peer = 1;
112   tree->me = tree->root;
113   path = path_new (4);
114   path->peers[0] = 1;
115   path->peers[1] = 2;
116   path->peers[2] = 3;
117   path->peers[3] = 4;
118   path->length = 4;
119
120   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding first path: 1 2 3 4\n");
121   tree_add_path(tree, path, &cb);
122   tree_debug(tree);
123   path1 = tree_get_path_to_peer(tree, 4);
124   if (path->length != path1->length ||
125       memcmp(path->peers, path1->peers, path->length) != 0)
126   {
127     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved path != original\n");
128     failed++;
129   }
130   path_destroy(path1);
131   node = tree_find_peer(tree->root, 4);
132   if (node->peer != 4)
133   {
134     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
135     failed++;
136   }
137   if (node->status != MESH_PEER_SEARCHING)
138   {
139     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
140     failed++;
141   }
142   if (GNUNET_PEER_search(path_get_first_hop(tree, 4)) != 2)
143   {
144     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
145     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "4 GOT: %u\n", GNUNET_PEER_search(path_get_first_hop(tree, 4)));
146     failed++;
147   }
148
149   node = tree_find_peer(tree->root, 3);
150   if (node->peer != 3)
151   {
152     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
153     failed++;
154   }
155   if (node->status != MESH_PEER_RELAY)
156   {
157     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
158     failed++;
159   }
160   if (node->children_head != node->children_tail)
161   {
162     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
163     failed++;
164   }
165   if (GNUNET_PEER_search(path_get_first_hop(tree, 4)) != 2)
166   {
167     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
168     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "4 GOT: %u\n", GNUNET_PEER_search(path_get_first_hop(tree, 4)));
169     failed++;
170   }
171
172   node = tree_find_peer(tree->root, 2);
173   if (node->peer != 2)
174   {
175     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
176     failed++;
177   }
178   if (node->status != MESH_PEER_RELAY)
179   {
180     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
181     failed++;
182   }
183   if (node->children_head != node->children_tail)
184   {
185     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
186     failed++;
187   }
188
189   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding second path: 1 2 3\n");
190   path->length--;
191   tree_add_path(tree, path, &cb);
192   tree_debug(tree);
193
194   node = tree_find_peer(tree->root, 4);
195   if (node->peer != 4)
196   {
197     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
198     failed++;
199   }
200   if (node->status != MESH_PEER_SEARCHING)
201   {
202     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
203     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "  expected SEARCHING, got %u\n", node->status);
204     failed++;
205   }
206   if (node->children_head != node->children_tail)
207   {
208     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
209     failed++;
210   }
211   if (GNUNET_PEER_search(path_get_first_hop(tree, 4)) != 2)
212   {
213     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
214     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "4 GOT: %u\n", GNUNET_PEER_search(path_get_first_hop(tree, 4)));
215     failed++;
216   }
217   if (GNUNET_PEER_search(path_get_first_hop(tree, 3)) != 2)
218   {
219     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
220     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "3 GOT: %u\n", GNUNET_PEER_search(path_get_first_hop(tree, 3)));
221     failed++;
222   }
223
224   node = tree_find_peer(tree->root, 2);
225   if (node->peer != 2)
226   {
227     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
228     failed++;
229   }
230   if (node->status != MESH_PEER_RELAY)
231   {
232     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
233     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "  expected RELAY\n");
234     failed++;
235   }
236   if (node->children_head != node->children_tail)
237   {
238     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
239     failed++;
240   }
241
242   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding third path...\n");
243   path->length++;
244   path->peers[3] = 5;
245   tree_add_path(tree, path, &cb);
246   tree_debug(tree);
247
248   node = tree_find_peer(tree->root, 3);
249   if (node->peer != 3)
250   {
251     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
252     failed++;
253   }
254   if (node->status != MESH_PEER_SEARCHING)
255   {
256     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
257     failed++;
258   }
259   if (node->children_head->next != node->children_tail)
260   {
261     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
262     failed++;
263   }
264   if (GNUNET_PEER_search(path_get_first_hop(tree, 3)) != 2)
265   {
266     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
267     failed++;
268   }
269   if (GNUNET_PEER_search(path_get_first_hop(tree, 4)) != 2)
270   {
271     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
272     failed++;
273   }
274
275   node = tree_find_peer(tree->root, 2);
276   if (node->peer != 2)
277   {
278     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
279     failed++;
280   }
281   if (node->status != MESH_PEER_RELAY)
282   {
283     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
284     failed++;
285   }
286   if (node->children_head != node->children_tail)
287   {
288     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
289     failed++;
290   }
291
292   node = tree_find_peer(tree->root, 5);
293   if (node->peer != 5)
294   {
295     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
296     failed++;
297   }
298
299   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Deleting third path...\n");
300   node->status = MESH_PEER_READY;
301   cb_call = 1;
302   node2 = tree_del_path(tree, 5, &cb);
303   tree_debug(tree);
304   if (cb_call != 0)
305   {
306     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call);
307     failed++;
308   }
309   if (node2->peer != 5)
310   {
311     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
312     failed++;
313   }
314   
315   node = tree_find_peer(tree->root, 3);
316   if (node->peer != 3)
317   {
318     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
319     failed++;
320   }
321   if (node->status != MESH_PEER_SEARCHING)
322   {
323     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
324     failed++;
325   }
326   if (node->children_head != node->children_tail)
327   {
328     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
329     failed++;
330   }
331
332   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Destroying node copy...\n");
333   GNUNET_free (node2);
334
335   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding new shorter first path...\n");
336   path->length = 2;
337   path->peers[1] = 4;
338   cb_call = 1;
339   tree_find_peer(tree->root, 4)->status = MESH_PEER_READY;
340   tree_add_path(tree, path, cb);
341   tree_debug(tree);
342   if (cb_call != 0)
343   {
344     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call);
345     failed++;
346   }  
347   node = tree_find_peer(tree->root, 3);
348   if (node->peer != 3)
349   {
350     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
351     failed++;
352   }
353   if (node->status != MESH_PEER_SEARCHING)
354   {
355     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
356     failed++;
357   }
358   if (node->children_head != NULL)
359   {
360     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
361     failed++;
362   }
363   node = tree_find_peer(tree->root, 4);
364   if (node->peer != 4)
365   {
366     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
367     failed++;
368   }
369   if (node->status != MESH_PEER_SEARCHING)
370   {
371     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
372     failed++;
373   }
374   if (node->children_head != NULL)
375   {
376     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
377     failed++;
378   }
379   if (GNUNET_PEER_search(path_get_first_hop(tree, 3)) != 1)
380   {
381     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
382     failed++;
383   }
384   if (GNUNET_PEER_search(path_get_first_hop(tree, 4)) != 4)
385   {
386     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
387     failed++;
388   }
389
390
391   if (failed > 0)
392   {
393     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%u tests failed\n", failed);
394     return 1;
395   }
396   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: OK\n");
397   path_destroy(path);
398   finish();
399
400   return 0;
401 }