Fixed testcase and small bugs in tree
[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 + 1 == GNUNET_PEER_intern(pi[i]));
105       GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Peer %u: %s\n",
106                  i + 1,
107                  GNUNET_h2s(&pi[i]->hashPubKey));
108   }
109   tree = GNUNET_malloc(sizeof(struct MeshTunnelTree));
110   tree->first_hops = GNUNET_CONTAINER_multihashmap_create(32);
111   tree->root = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode));
112   tree->root->peer = 1;
113   tree->me = tree->root;
114   path = path_new (4);
115   path->peers[0] = 1;
116   path->peers[1] = 2;
117   path->peers[2] = 3;
118   path->peers[3] = 4;
119   path->length = 4;
120
121   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding first path: 1 2 3 4\n");
122   tree_add_path(tree, path, &cb);
123   tree_debug(tree);
124   path1 = tree_get_path_to_peer(tree, 4);
125   if (path->length != path1->length ||
126       memcmp(path->peers, path1->peers, path->length) != 0)
127   {
128     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved path != original\n");
129     failed++;
130   }
131   path_destroy(path1);
132   node = tree_find_peer(tree->root, 4);
133   if (node->peer != 4)
134   {
135     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
136     failed++;
137   }
138   if (node->status != MESH_PEER_SEARCHING)
139   {
140     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
141     failed++;
142   }
143   if (GNUNET_PEER_search(path_get_first_hop(tree, 4)) != 2)
144   {
145     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
146     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "4 GOT: %u\n", GNUNET_PEER_search(path_get_first_hop(tree, 4)));
147     failed++;
148   }
149
150   node = tree_find_peer(tree->root, 3);
151   if (node->peer != 3)
152   {
153     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
154     failed++;
155   }
156   if (node->status != MESH_PEER_RELAY)
157   {
158     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
159     failed++;
160   }
161   if (node->children_head != node->children_tail)
162   {
163     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
164     failed++;
165   }
166   if (GNUNET_PEER_search(path_get_first_hop(tree, 4)) != 2)
167   {
168     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
169     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "4 GOT: %u\n", GNUNET_PEER_search(path_get_first_hop(tree, 4)));
170     failed++;
171   }
172
173   node = tree_find_peer(tree->root, 2);
174   if (node->peer != 2)
175   {
176     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
177     failed++;
178   }
179   if (node->status != MESH_PEER_RELAY)
180   {
181     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
182     failed++;
183   }
184   if (node->children_head != node->children_tail)
185   {
186     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
187     failed++;
188   }
189
190   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding second path: 1 2 3\n");
191   path->length--;
192   tree_add_path(tree, path, &cb);
193   tree_debug(tree);
194
195   node = tree_find_peer(tree->root, 4);
196   if (node->peer != 4)
197   {
198     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
199     failed++;
200   }
201   if (node->status != MESH_PEER_SEARCHING)
202   {
203     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
204     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "  expected SEARCHING, got %u\n", node->status);
205     failed++;
206   }
207   if (node->children_head != node->children_tail)
208   {
209     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
210     failed++;
211   }
212   if (GNUNET_PEER_search(path_get_first_hop(tree, 4)) != 2)
213   {
214     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
215     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "4 GOT: %u\n", GNUNET_PEER_search(path_get_first_hop(tree, 4)));
216     failed++;
217   }
218   if (GNUNET_PEER_search(path_get_first_hop(tree, 3)) != 2)
219   {
220     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
221     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "3 GOT: %u\n", GNUNET_PEER_search(path_get_first_hop(tree, 3)));
222     failed++;
223   }
224
225   node = tree_find_peer(tree->root, 2);
226   if (node->peer != 2)
227   {
228     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
229     failed++;
230   }
231   if (node->status != MESH_PEER_RELAY)
232   {
233     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
234     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "  expected RELAY\n");
235     failed++;
236   }
237   if (node->children_head != node->children_tail)
238   {
239     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
240     failed++;
241   }
242
243   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding third path...\n");
244   path->length++;
245   path->peers[3] = 5;
246   tree_add_path(tree, path, &cb);
247   tree_debug(tree);
248
249   node = tree_find_peer(tree->root, 3);
250   if (node->peer != 3)
251   {
252     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
253     failed++;
254   }
255   if (node->status != MESH_PEER_SEARCHING)
256   {
257     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
258     failed++;
259   }
260   if (node->children_head->next != node->children_tail)
261   {
262     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
263     failed++;
264   }
265   if (GNUNET_PEER_search(path_get_first_hop(tree, 3)) != 2)
266   {
267     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
268     failed++;
269   }
270   if (GNUNET_PEER_search(path_get_first_hop(tree, 4)) != 2)
271   {
272     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
273     failed++;
274   }
275
276   node = tree_find_peer(tree->root, 2);
277   if (node->peer != 2)
278   {
279     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
280     failed++;
281   }
282   if (node->status != MESH_PEER_RELAY)
283   {
284     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
285     failed++;
286   }
287   if (node->children_head != node->children_tail)
288   {
289     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
290     failed++;
291   }
292
293   node = tree_find_peer(tree->root, 5);
294   if (node->peer != 5)
295   {
296     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
297     failed++;
298   }
299
300   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Deleting third path...\n");
301   node->status = MESH_PEER_READY;
302   cb_call = 1;
303   node2 = tree_del_path(tree, 5, &cb);
304   tree_debug(tree);
305   if (cb_call != 0)
306   {
307     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call);
308     failed++;
309   }
310   if (node2->peer != 5)
311   {
312     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
313     failed++;
314   }
315   
316   node = tree_find_peer(tree->root, 3);
317   if (node->peer != 3)
318   {
319     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
320     failed++;
321   }
322   if (node->status != MESH_PEER_SEARCHING)
323   {
324     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
325     failed++;
326   }
327   if (node->children_head != node->children_tail)
328   {
329     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
330     failed++;
331   }
332
333   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Destroying node copy...\n");
334   GNUNET_free (node2);
335
336   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding new shorter first path...\n");
337   path->length = 2;
338   path->peers[1] = 4;
339   cb_call = 1;
340   tree_find_peer(tree->root, 4)->status = MESH_PEER_READY;
341   tree_add_path(tree, path, cb);
342   tree_debug(tree);
343   if (cb_call != 0)
344   {
345     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call);
346     failed++;
347   }  
348   node = tree_find_peer(tree->root, 3);
349   if (node->peer != 3)
350   {
351     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
352     failed++;
353   }
354   if (node->status != MESH_PEER_SEARCHING)
355   {
356     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
357     failed++;
358   }
359   if (node->children_head != NULL)
360   {
361     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
362     failed++;
363   }
364   node = tree_find_peer(tree->root, 4);
365   if (node->peer != 4)
366   {
367     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
368     failed++;
369   }
370   if (node->status != MESH_PEER_SEARCHING)
371   {
372     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong status!\n");
373     failed++;
374   }
375   if (node->children_head != NULL)
376   {
377     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n");
378     failed++;
379   }
380   if (GNUNET_PEER_search(path_get_first_hop(tree, 3)) != 2)
381   {
382     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
383     failed++;
384   }
385   if (GNUNET_PEER_search(path_get_first_hop(tree, 4)) != 4)
386   {
387     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n");
388     failed++;
389   }
390
391
392   if (failed > 0)
393   {
394     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%u tests failed\n", failed);
395     return 1;
396   }
397   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: OK\n");
398   GNUNET_free (path);
399   finish();
400
401   return 0;
402 }