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