making the new mesh the default
[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.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 static 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 /**
56  * Check if a node has all expected properties.
57  *
58  * @param peer_id Short ID of the peer to test.
59  * @param status Expected status of the peer.
60  * @param children Expected number of children of the peer.
61  * @param first_hop Short ID of the expected first hop towards the peer.
62  */
63 static void
64 test_assert (GNUNET_PEER_Id peer_id,
65              enum MeshPeerState status,
66              unsigned int children,
67              GNUNET_PEER_Id first_hop)
68 {
69   struct MeshTunnelTreeNode *n;
70   struct MeshTunnelTreeNode *c;
71   unsigned int i;
72   int pre_failed;
73
74   pre_failed = failed;
75   n = tree_find_peer(tree->root, peer_id);
76   if (n->peer != peer_id)
77   {
78     GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
79                "Retrieved peer != original (%u, %u)\n",
80                n->peer, peer_id);
81     failed++;
82   }
83   if (n->status != status)
84   {
85     GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
86                "Retrieved peer has wrong status! (%u, %u)\n",
87                n->status, status);
88     failed++;
89   }
90   for (c = n->children_head, i = 0; NULL != c; c = c->next, i++);
91   if (i != children)
92   {
93     GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
94                "Retrieved peer wrong has number of children! (%u, %u)\n",
95                i, children);
96     failed++;
97   }
98   if (0 != first_hop &&
99       GNUNET_PEER_search(path_get_first_hop(tree, peer_id)) != first_hop)
100   {
101     GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
102                "Wrong first hop! (%u, %u)\n",
103                GNUNET_PEER_search(path_get_first_hop(tree, peer_id)),
104                first_hop);
105     failed++;
106   }
107   if (pre_failed != failed)
108   {
109     struct GNUNET_PeerIdentity id;
110     GNUNET_PEER_resolve (peer_id, &id);
111     GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
112                "*** Peer %s (%u) has failed %d checks! (real, expected)\n",
113                GNUNET_i2s (&id), peer_id,  failed - pre_failed);
114   }
115 }
116
117
118 static void
119 finish(void)
120 {
121   unsigned int i;
122
123   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Finishing...\n");
124   for (i = 0; i < 10; i++)
125   {
126     GNUNET_free(pi[i]);
127   }
128   tree_destroy(tree);
129   exit(0);
130 }
131
132 /**
133  * Convert an integer int to a peer identity
134  */
135 static struct GNUNET_PeerIdentity *
136 get_pi (uint32_t id)
137 {
138   struct GNUNET_PeerIdentity *pi;
139
140   pi = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
141   pi->hashPubKey.bits[0] = id + 1;
142   return pi;
143 }
144
145
146 int
147 main (int argc, char *argv[])
148 {
149   struct MeshTunnelTreeNode *node;
150   struct MeshTunnelTreeNode *node2;
151   struct MeshPeerPath *path;
152   struct MeshPeerPath *path1;
153   unsigned int i;
154
155   failed = 0;
156   cb_call = 0;
157   GNUNET_log_setup ("test_mesh_api_path",
158 #if VERBOSE
159                     "DEBUG",
160 #else
161                     "WARNING",
162 #endif
163                     NULL);
164   for (i = 0; i < 10; i++)
165   {
166       pi[i] = get_pi(i);
167       GNUNET_break (i + 1 == GNUNET_PEER_intern(pi[i]));
168       GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Peer %u: %s\n",
169                  i + 1,
170                  GNUNET_h2s(&pi[i]->hashPubKey));
171   }
172   tree = GNUNET_malloc(sizeof(struct MeshTunnelTree));
173   tree->first_hops = GNUNET_CONTAINER_multihashmap_create(32);
174   tree->root = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode));
175   tree->root->peer = 1;
176   tree->me = tree->root;
177   path = path_new (4);
178   path->peers[0] = 1;
179   path->peers[1] = 2;
180   path->peers[2] = 3;
181   path->peers[3] = 4;
182   path->length = 4;
183
184   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding first path: 1 2 3 4\n");
185   tree_add_path(tree, path, &cb);
186   tree_debug(tree);
187   path1 = tree_get_path_to_peer(tree, 4);
188   if (path->length != path1->length ||
189       memcmp(path->peers, path1->peers, path->length) != 0)
190   {
191     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved path != original\n");
192     failed++;
193   }
194   path_destroy(path1);
195   test_assert (4, MESH_PEER_SEARCHING, 0, 2);
196   test_assert (3, MESH_PEER_RELAY, 1, 0);
197   test_assert (2, MESH_PEER_RELAY, 1, 0);
198   test_assert (1, MESH_PEER_ROOT, 1, 0);
199
200   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding second path: 1 2 3\n");
201   path->length--;
202   tree_add_path(tree, path, &cb);
203   tree_debug(tree);
204
205   test_assert (4, MESH_PEER_SEARCHING, 0, 2);
206   test_assert (3, MESH_PEER_SEARCHING, 1, 2);
207   test_assert (2, MESH_PEER_RELAY, 1, 0);
208   test_assert (1, MESH_PEER_ROOT, 1, 0);
209
210   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding third path...\n");
211   path->length++;
212   path->peers[3] = 5;
213   tree_add_path(tree, path, &cb);
214   tree_debug(tree);
215
216   test_assert (5, MESH_PEER_SEARCHING, 0, 2);
217   test_assert (4, MESH_PEER_SEARCHING, 0, 2);
218   test_assert (3, MESH_PEER_SEARCHING, 2, 2);
219   test_assert (2, MESH_PEER_RELAY, 1, 0);
220   test_assert (1, MESH_PEER_ROOT, 1, 0);
221
222   node = tree_find_peer(tree->root, 5);
223   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Deleting third path...\n");
224   node->status = MESH_PEER_READY;
225   cb_call = 1;
226   node2 = tree_del_path(tree, 5, &cb);
227   tree_debug(tree);
228   if (cb_call != 0)
229   {
230     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call);
231     failed++;
232   }
233   if (node2->peer != 5)
234   {
235     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
236     failed++;
237   }
238
239   test_assert (4, MESH_PEER_SEARCHING, 0, 2);
240   test_assert (3, MESH_PEER_SEARCHING, 1, 2);
241   test_assert (2, MESH_PEER_RELAY, 1, 0);
242   test_assert (1, MESH_PEER_ROOT, 1, 0);
243
244   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Destroying node copy...\n");
245   GNUNET_free (node2);
246
247   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding new shorter first path...\n");
248   path->length = 2;
249   path->peers[1] = 4;
250   cb_call = 1;
251   tree_find_peer(tree->root, 4)->status = MESH_PEER_READY;
252   tree_add_path(tree, path, cb);
253   tree_debug(tree);
254   if (cb_call != 0)
255   {
256     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call);
257     failed++;
258   }
259
260   test_assert (4, MESH_PEER_SEARCHING, 0, 4);
261   test_assert (3, MESH_PEER_SEARCHING, 0, 2);
262   test_assert (2, MESH_PEER_RELAY, 1, 0);
263   test_assert (1, MESH_PEER_ROOT, 2, 0);
264
265   if (failed > 0)
266   {
267     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%u tests failed\n", failed);
268     return 1;
269   }
270   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: OK\n");
271   GNUNET_free (path->peers);
272   GNUNET_free (path);
273   finish();
274
275   return 0;
276 }