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