8635f5c965af5f55b9e22e67cb74aa560b720243
[oweals/gnunet.git] / src / identity / test_identity.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2013, 2016 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your 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      Affero General Public License for more details.
14 */
15
16 /**
17  * @file identity/test_identity.c
18  * @brief testcase for identity service
19  * @author Christian Grothoff
20  */
21 #include "platform.h"
22 #include "gnunet_util_lib.h"
23 #include "gnunet_identity_service.h"
24 #include "gnunet_testing_lib.h"
25
26
27 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
28
29
30 /**
31  * Return value from 'main'.
32  */
33 static int res;
34
35 /**
36  * Handle to identity service.
37  */
38 static struct GNUNET_IDENTITY_Handle *h;
39
40 /**
41  * Handle to identity operation.
42  */
43 static struct GNUNET_IDENTITY_Operation *op;
44
45 /**
46  * Handle for task for timeout termination.
47  */
48 static struct GNUNET_SCHEDULER_Task *endbadly_task;
49
50
51 /**
52  * Clean up all resources used.
53  */
54 static void
55 cleanup ()
56 {
57   if (NULL != op)
58   {
59     GNUNET_IDENTITY_cancel (op);
60     op = NULL;
61   }
62   if (NULL != h)
63   {
64     GNUNET_IDENTITY_disconnect (h);
65     h = NULL;
66   }
67   GNUNET_SCHEDULER_shutdown ();
68 }
69
70
71 /**
72  * Termiante the testcase (failure).
73  *
74  * @param cls NULL
75  */
76 static void
77 endbadly (void *cls)
78 {
79   cleanup ();
80   res = 1;
81 }
82
83
84 /**
85  * Termiante the testcase (success).
86  *
87  * @param cls NULL
88  */
89 static void
90 end_normally (void *cls)
91 {
92   cleanup ();
93   res = 0;
94 }
95
96
97 /**
98  * Finish the testcase (successfully).
99  */
100 static void
101 end ()
102 {
103   if (NULL != endbadly_task)
104   {
105     GNUNET_SCHEDULER_cancel (endbadly_task);
106     endbadly_task = NULL;
107   }
108   GNUNET_SCHEDULER_shutdown ();
109 }
110
111
112 /**
113  * Called with events about egos.
114  *
115  * @param cls NULL
116  * @param ego ego handle
117  * @param ego_ctx context for application to store data for this ego
118  *                 (during the lifetime of this process, initially NULL)
119  * @param identifier identifier assigned by the user for this ego,
120  *                   NULL if the user just deleted the ego and it
121  *                   must thus no longer be used
122  */
123 static void
124 notification_cb (void *cls,
125                  struct GNUNET_IDENTITY_Ego *ego,
126                  void **ctx,
127                  const char *identifier)
128 {
129   static struct GNUNET_IDENTITY_Ego *my_ego;
130   static int round;
131
132   switch (round)
133   {
134   case 0: /* end of initial iteration */
135     GNUNET_assert (NULL == ego);
136     GNUNET_assert (NULL == identifier);
137     break;
138   case 1: /* create */
139     GNUNET_assert (NULL != ego);
140     GNUNET_assert (0 == strcmp (identifier,
141                                 "test-id"));
142     my_ego = ego;
143     *ctx = &round;
144     break;
145   case 2: /* rename */
146     GNUNET_assert (my_ego == ego);
147     GNUNET_assert (0 == strcmp (identifier,
148                                 "test"));
149     GNUNET_assert (*ctx == &round);
150     break;
151   case 3: /* reconnect-down */
152     GNUNET_assert (my_ego == ego);
153     GNUNET_assert (NULL == identifier);
154     GNUNET_assert (*ctx == &round);
155     *ctx = NULL;
156     break;
157   case 4: /* reconnect-up */
158     GNUNET_assert (0 == strcmp (identifier,
159                                 "test"));
160     my_ego = ego;
161     *ctx = &round;
162     break;
163   case 5: /* end of iteration after reconnect */
164     GNUNET_assert (NULL == ego);
165     GNUNET_assert (NULL == identifier);
166     break;
167   case 6: /* delete */
168     GNUNET_assert (my_ego == ego);
169     GNUNET_assert (*ctx == &round);
170     *ctx = NULL;
171     break;
172   default:
173     GNUNET_break (0);
174   }
175   round++;
176 }
177
178
179 /**
180  * Continuation called from successful delete operation.
181  *
182  * @param cls NULL
183  * @param emsg (should also be NULL)
184  */
185 static void
186 delete_cont (void *cls,
187              const char *emsg)
188 {
189   op = NULL;
190   GNUNET_assert (NULL == emsg);
191   end ();
192 }
193
194
195 /**
196  * Continue by deleting the "test" identity.
197  *
198  * @param cls NULL
199  */
200 static void
201 finally_delete (void *cls)
202 {
203   op = GNUNET_IDENTITY_delete (h,
204                                "test",
205                                &delete_cont,
206                                NULL);
207 }
208
209
210 /**
211  * Continuation called from expected-to-fail rename operation.
212  *
213  * @param cls NULL
214  * @param emsg (should also be NULL)
215  */
216 static void
217 fail_rename_cont (void *cls,
218                   const char *emsg)
219 {
220   GNUNET_assert (NULL != emsg);
221   op = NULL;
222   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
223                                 &finally_delete,
224                                 NULL);
225 }
226
227
228 /**
229  * Continuation called from successful rename operation.
230  *
231  * @param cls NULL
232  * @param emsg (should also be NULL)
233  */
234 static void
235 success_rename_cont (void *cls,
236                      const char *emsg)
237 {
238   GNUNET_assert (NULL == emsg);
239   op = GNUNET_IDENTITY_rename (h,
240                                "test-id",
241                                "test",
242                                &fail_rename_cont,
243                                NULL);
244 }
245
246
247 /**
248  * Called with events about created ego.
249  *
250  * @param cls NULL
251  * @param emsg error message
252  */
253 static void
254 create_cb (void *cls,
255            const char *emsg)
256 {
257   GNUNET_assert (NULL == emsg);
258   op = GNUNET_IDENTITY_rename (h,
259                                "test-id",
260                                "test",
261                                &success_rename_cont,
262                                NULL);
263 }
264
265
266 /**
267  * Main function of the test, run from scheduler.
268  *
269  * @param cls NULL
270  * @param cfg configuration we use (also to connect to identity service)
271  * @param peer handle to access more of the peer (not used)
272  */
273 static void
274 run (void *cls,
275      const struct GNUNET_CONFIGURATION_Handle *cfg,
276      struct GNUNET_TESTING_Peer *peer)
277 {
278   endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
279                                                 &endbadly,
280                                                 NULL);
281   GNUNET_SCHEDULER_add_shutdown (&end_normally,
282                                  NULL);
283   h = GNUNET_IDENTITY_connect (cfg,
284                                &notification_cb,
285                                NULL);
286   GNUNET_assert (NULL != h);
287   op = GNUNET_IDENTITY_create (h,
288                                "test-id",
289                                &create_cb,
290                                NULL);
291
292 }
293
294
295 int
296 main (int argc, char *argv[])
297 {
298   GNUNET_DISK_directory_remove ("/tmp/test-identity-service");
299   res = 1;
300   if (0 !=
301       GNUNET_TESTING_service_run ("test-identity",
302                                   "identity",
303                                   "test_identity.conf",
304                                   &run,
305                                   NULL))
306     return 1;
307   return res;
308 }
309
310
311 /* end of test_identity.c */