added logging
[oweals/gnunet.git] / src / social / test_social.c
1 /*
2  * This file is part of GNUnet
3  * Copyright (C) 2013 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 /**
21  * @file social/test_social.c
22  * @brief Tests for the Social API.
23  * @author Gabor X Toth
24  */
25
26 #include <inttypes.h>
27
28 #include "platform.h"
29 #include "gnunet_crypto_lib.h"
30 #include "gnunet_common.h"
31 #include "gnunet_util_lib.h"
32 #include "gnunet_testing_lib.h"
33 #include "gnunet_psyc_util_lib.h"
34 #include "gnunet_social_service.h"
35 #include "gnunet_identity_service.h"
36
37 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
38
39 #define DATA2ARG(data) data, sizeof (data)
40
41 /**
42  * Return value from 'main'.
43  */
44 int res;
45
46 struct GNUNET_SOCIAL_App *app;
47 const char *app_id = "test";
48
49 /**
50  * Handle for task for timeout termination.
51  */
52 struct GNUNET_SCHEDULER_Task *end_badly_task;
53
54 const struct GNUNET_CONFIGURATION_Handle *cfg;
55
56 struct GNUNET_PeerIdentity this_peer;
57
58 struct GNUNET_IDENTITY_Handle *id;
59
60 const struct GNUNET_IDENTITY_Ego *identity_host_ego;
61 const struct GNUNET_IDENTITY_Ego *identity_guest_ego;
62
63 const struct GNUNET_SOCIAL_Ego *host_ego;
64 const struct GNUNET_SOCIAL_Ego *guest_ego;
65
66 const char *host_name = "Host One";
67 const char *guest_name = "Guest One";
68
69 struct GNUNET_CRYPTO_EddsaPrivateKey *place_key;
70 struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_key;
71
72 struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key;
73 struct GNUNET_HashCode place_pub_hash;
74
75 const struct GNUNET_CRYPTO_EcdsaPublicKey *guest_pub_key;
76 const struct GNUNET_CRYPTO_EcdsaPublicKey *host_pub_key;
77
78 struct GNUNET_PSYC_Slicer *host_slicer;
79 struct GNUNET_PSYC_Slicer *guest_slicer;
80
81 struct GNUNET_SOCIAL_Host *hst;
82 struct GNUNET_SOCIAL_Guest *gst;
83
84 struct GNUNET_SOCIAL_Place *hst_plc;
85 struct GNUNET_SOCIAL_Place *gst_plc;
86
87 struct GNUNET_SOCIAL_Nym *nym_eject;
88
89 struct GuestEnterMessage
90 {
91   struct GNUNET_PSYC_Message *msg;
92   const char *method_name;
93   struct GNUNET_PSYC_Environment *env;
94   void *data;
95   uint16_t data_size;
96 } guest_enter_msg;
97
98 struct TransmitClosure
99 {
100   struct GNUNET_SOCIAL_Announcement *host_ann;
101   struct GNUNET_SOCIAL_TalkRequest *guest_talk;
102   struct GNUNET_PSYC_Environment *env;
103   char *data[16];
104   uint8_t data_delay[16];
105   uint8_t data_count;
106   uint8_t paused;
107   uint8_t n;
108 } tmit;
109
110 struct ResultClosure {
111   uint32_t n;
112 } mod_foo_bar_rcls;
113
114 uint8_t join_req_count;
115 struct GNUNET_PSYC_Message *join_resp;
116
117 uint32_t counter;
118
119 uint8_t is_guest_nym_added = GNUNET_NO;
120 uint8_t is_host_reconnected = GNUNET_NO;
121 uint8_t is_guest_reconnected = GNUNET_NO;
122
123 enum
124 {
125   TEST_NONE                         =  0,
126   TEST_IDENTITIES_CREATE            =  1,
127   TEST_HOST_ENTER                   =  2,
128   TEST_GUEST_ENTER                  =  3,
129   TEST_HOST_ANSWER_DOOR_REFUSE      =  4,
130   TEST_GUEST_RECV_ENTRY_DCSN_REFUSE =  5,
131   TEST_HOST_ANSWER_DOOR_ADMIT       =  6,
132   TEST_GUEST_RECV_ENTRY_DCSN_ADMIT  =  7,
133   TEST_HOST_ANNOUNCE                =  8,
134   TEST_HOST_ANNOUNCE_END            =  9,
135   TEST_GUEST_TALK                   = 10,
136   TEST_HOST_ANNOUNCE2               = 11,
137   TEST_HOST_ANNOUNCE2_END           = 12,
138   TEST_GUEST_HISTORY_REPLAY         = 13,
139   TEST_GUEST_HISTORY_REPLAY_LATEST  = 14,
140   TEST_GUEST_LOOK_AT                = 15,
141   TEST_GUEST_LOOK_FOR               = 16,
142   TEST_GUEST_LEAVE                  = 17,
143   TEST_ZONE_ADD_PLACE               = 18,
144   TEST_GUEST_ENTER_BY_NAME          = 19,
145   TEST_RECONNECT                    = 20,
146   TEST_GUEST_LEAVE2                 = 21,
147   TEST_HOST_LEAVE                   = 22,
148 } test;
149
150
151 static void
152 schedule_guest_leave (void *cls);
153
154
155 static void
156 host_answer_door (void *cls,
157                   struct GNUNET_SOCIAL_Nym *nym,
158                   const char *method_name,
159                   struct GNUNET_PSYC_Environment *env,
160                   const void *data,
161                   size_t data_size);
162
163 static void
164 host_enter ();
165
166 static void
167 guest_init ();
168
169 static void
170 guest_enter ();
171
172 static void
173 guest_enter_by_name ();
174
175 static void
176 guest_talk ();
177
178 static void
179 host_announce2 ();
180
181
182 /**
183  * Clean up all resources used.
184  */
185 static void
186 cleanup ()
187 {
188   if (NULL != id)
189   {
190     GNUNET_IDENTITY_disconnect (id);
191     id = NULL;
192   }
193
194   if (NULL != guest_slicer)
195   {
196     GNUNET_PSYC_slicer_destroy (guest_slicer);
197     guest_slicer = NULL;
198   }
199
200   if (NULL != host_slicer)
201   {
202     GNUNET_PSYC_slicer_destroy (host_slicer);
203     host_slicer = NULL;
204   }
205
206   if (NULL != gst)
207   {
208     GNUNET_SOCIAL_guest_leave (gst, NULL, NULL, NULL);
209     gst = NULL;
210     gst_plc = NULL;
211   }
212   if (NULL != hst)
213   {
214     GNUNET_SOCIAL_host_leave (hst, NULL, NULL, NULL);
215     hst = NULL;
216     hst_plc = NULL;
217   }
218   GNUNET_SOCIAL_app_disconnect (app, NULL, NULL);
219   GNUNET_SCHEDULER_shutdown ();
220 }
221
222
223 /**
224  * Terminate the test case (failure).
225  *
226  * @param cls NULL
227  */
228 static void
229 end_badly (void *cls)
230 {
231   res = 1;
232   cleanup ();
233   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test FAILED.\n");
234 }
235
236
237 /**
238  * Terminate the test case (success).
239  *
240  * @param cls NULL
241  */
242 static void
243 end_normally (void *cls)
244 {
245   res = 0;
246   cleanup ();
247   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Test PASSED.\n");
248 }
249
250
251 /**
252  * Finish the test case (successfully).
253  */
254 static void
255 end ()
256 {
257   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
258               "Test #%u: Ending tests.\n", test);
259
260   if (end_badly_task != NULL)
261   {
262     GNUNET_SCHEDULER_cancel (end_badly_task);
263     end_badly_task = NULL;
264   }
265   GNUNET_SCHEDULER_add_now (&end_normally, NULL);
266 }
267
268
269 static void
270 transmit_resume (void *cls)
271 {
272   struct TransmitClosure *tmit = cls;
273
274   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
275               "Test #%u: Transmission resumed.\n", test);
276   if (NULL != tmit->host_ann)
277     GNUNET_SOCIAL_host_announce_resume (tmit->host_ann);
278   else
279     GNUNET_SOCIAL_guest_talk_resume (tmit->guest_talk);
280 }
281
282
283 static int
284 notify_data (void *cls, uint16_t *data_size, void *data)
285 {
286   struct TransmitClosure *tmit = cls;
287   if (NULL != tmit->env)
288   {
289     GNUNET_PSYC_env_destroy (tmit->env);
290     tmit->env = NULL;
291   }
292   if (0 == tmit->data_count)
293   {
294     *data_size = 0;
295     return GNUNET_YES;
296   }
297
298   uint16_t size = strlen (tmit->data[tmit->n]);
299   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
300               "Test #%u: Transmit notify data: %u bytes available, "
301               "processing fragment %u/%u (size %u).\n",
302               test, *data_size, tmit->n + 1, tmit->data_count, size);
303   if (*data_size < size)
304   {
305     *data_size = 0;
306     GNUNET_assert (0);
307     return GNUNET_SYSERR;
308   }
309
310   if (GNUNET_YES != tmit->paused && 0 < tmit->data_delay[tmit->n])
311   {
312     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
313                 "Test #%u: Transmission paused.\n", test);
314     tmit->paused = GNUNET_YES;
315     GNUNET_SCHEDULER_add_delayed (
316       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
317                                      tmit->data_delay[tmit->n]),
318       &transmit_resume, tmit);
319     *data_size = 0;
320     return GNUNET_NO;
321   }
322   tmit->paused = GNUNET_NO;
323
324   *data_size = size;
325   GNUNET_memcpy (data, tmit->data[tmit->n], size);
326
327   return ++tmit->n < tmit->data_count ? GNUNET_NO : GNUNET_YES;
328 }
329
330
331 static void
332 host_left ()
333 {
334   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
335               "Test #%u: The host has left the place.\n", test);
336   end ();
337 }
338
339
340 static void
341 schedule_host_leave (void *cls)
342 {
343   test = TEST_HOST_LEAVE;
344   GNUNET_SOCIAL_host_leave (hst, NULL, &host_left, NULL);
345   hst = NULL;
346   hst_plc = NULL;
347 }
348
349
350 static void
351 host_farewell2 (void *cls,
352                const struct GNUNET_SOCIAL_Nym *nym,
353                struct GNUNET_PSYC_Environment *env)
354 {
355   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
356               "Nym left the place again.\n");
357   GNUNET_SCHEDULER_add_now (&schedule_host_leave, NULL);
358 }
359
360
361 static void
362 host_reconnected (void *cls, int result,
363                   const struct GNUNET_CRYPTO_EddsaPublicKey *home_pub_key,
364                   uint64_t max_message_id)
365 {
366   place_pub_key = *home_pub_key;
367   GNUNET_CRYPTO_hash (&place_pub_key, sizeof (place_pub_key), &place_pub_hash);
368   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
369               "Test #%u: Host reconnected to place %s\n",
370               test, GNUNET_h2s (&place_pub_hash));
371
372   is_host_reconnected = GNUNET_YES;
373   if (GNUNET_YES == is_guest_reconnected)
374   {
375     GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
376   }
377 }
378
379
380 static void
381 guest_reconnected (void *cls, int result,
382                    const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key,
383                    uint64_t max_message_id)
384 {
385   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
386               "Test #%u: Guest reconnected to place: %d\n",
387               test, result);
388   GNUNET_assert (0 <= result);
389
390   is_guest_reconnected = GNUNET_YES;
391   if (GNUNET_YES == is_host_reconnected)
392   {
393     GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
394   }
395 }
396
397
398 static void
399 app_connected (void *cls)
400 {
401   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
402               "Test #%u: App connected: %p\n", test, cls);
403 }
404
405
406 static void
407 app_recv_host (void *cls,
408                struct GNUNET_SOCIAL_HostConnection *hconn,
409                struct GNUNET_SOCIAL_Ego *ego,
410                const struct GNUNET_CRYPTO_EddsaPublicKey *host_pub_key,
411                enum GNUNET_SOCIAL_AppPlaceState place_state)
412 {
413   struct GNUNET_HashCode host_pub_hash;
414   GNUNET_CRYPTO_hash (host_pub_key, sizeof (*host_pub_key), &host_pub_hash);
415
416   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
417               "Test #%u: Got app host place notification: %s\n",
418               test, GNUNET_h2s (&host_pub_hash));
419
420   if (test == TEST_RECONNECT)
421   {
422     if (0 == memcmp (&place_pub_key, host_pub_key, sizeof (*host_pub_key)))
423     {
424       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
425                   "Test #%u: Reconnecting to host place: %s\n",
426                   test, GNUNET_h2s (&host_pub_hash));
427       hst = GNUNET_SOCIAL_host_enter_reconnect (hconn, host_slicer, host_reconnected,
428                                                 host_answer_door, host_farewell2, NULL);
429     }
430   }
431 }
432
433
434 static void
435 app_recv_guest (void *cls,
436                 struct GNUNET_SOCIAL_GuestConnection *gconn,
437                 struct GNUNET_SOCIAL_Ego *ego,
438                 const struct GNUNET_CRYPTO_EddsaPublicKey *guest_pub_key,
439                 enum GNUNET_SOCIAL_AppPlaceState place_state)
440 {
441   struct GNUNET_HashCode guest_pub_hash;
442   GNUNET_CRYPTO_hash (guest_pub_key, sizeof (*guest_pub_key), &guest_pub_hash);
443
444   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
445               "Test #%u: Got app guest place notification: %s\n",
446               test, GNUNET_h2s (&guest_pub_hash));
447
448   if (test == TEST_RECONNECT)
449   {
450     if (0 == memcmp (&place_pub_key, guest_pub_key, sizeof (*guest_pub_key)))
451     {
452       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
453                   "Test #%u: Reconnecting to guest place: %s\n",
454                   test, GNUNET_h2s (&guest_pub_hash));
455       gst = GNUNET_SOCIAL_guest_enter_reconnect (gconn, GNUNET_PSYC_SLAVE_JOIN_NONE,
456                                                  guest_slicer, guest_reconnected, NULL);
457     }
458   }
459 }
460
461
462 static void
463 enter_if_ready ()
464 {
465   if (NULL == host_ego || NULL == guest_ego)
466   {
467     return;
468   }
469   host_enter ();
470   guest_init ();
471 }
472
473
474 static void
475 app_recv_ego (void *cls,
476               struct GNUNET_SOCIAL_Ego *ego,
477               const struct GNUNET_CRYPTO_EcdsaPublicKey *ego_pub_key,
478               const char *name)
479 {
480   char *ego_pub_str = GNUNET_CRYPTO_ecdsa_public_key_to_string (ego_pub_key);
481   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
482               "Test #%u: Got app ego notification: %p %s %s\n",
483               test, ego, name, ego_pub_str);
484   GNUNET_free (ego_pub_str);
485
486   if (NULL != strstr (name, host_name))
487   {
488     host_ego = ego;
489     host_pub_key = ego_pub_key;
490     if (TEST_IDENTITIES_CREATE == test)
491     {
492       enter_if_ready ();
493     }
494     else
495     {
496       GNUNET_assert (TEST_RECONNECT == test);
497     }
498   }
499   else if (NULL != strstr (name, guest_name))
500   {
501     guest_ego = ego;
502     guest_pub_key = ego_pub_key;
503     if (TEST_IDENTITIES_CREATE == test)
504     {
505       enter_if_ready ();
506     }
507     else
508     {
509       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
510                   "test = %d\n",
511                   test);
512       GNUNET_assert (TEST_RECONNECT == test);
513     }
514   }
515 }
516
517
518 static void
519 schedule_reconnect (void *cls)
520 {
521   test = TEST_RECONNECT;
522
523   GNUNET_SOCIAL_host_disconnect (hst, NULL, NULL);
524   GNUNET_SOCIAL_guest_disconnect (gst, NULL, NULL);
525   hst = NULL;
526   gst = NULL;
527
528   GNUNET_SOCIAL_app_disconnect (app, NULL, NULL);
529   app = GNUNET_SOCIAL_app_connect (cfg, app_id,
530                                    app_recv_ego,
531                                    app_recv_host,
532                                    app_recv_guest,
533                                    app_connected,
534                                    NULL);
535 }
536
537
538 static void
539 host_recv_zone_add_place_result (void *cls, int64_t result,
540                                  const void *data, uint16_t data_size)
541 {
542   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
543               "Test #%u: Zone add place result: %" PRId64 " (%.*s).\n",
544               test, result, data_size, (const char *) data);
545   GNUNET_assert (GNUNET_YES == result);
546
547   GNUNET_assert (GNUNET_YES == is_guest_nym_added);
548   guest_enter_by_name ();
549 }
550
551
552 static void
553 zone_add_place ()
554 {
555   test = TEST_ZONE_ADD_PLACE;
556   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
557               "Test #%u: Adding place to zone.\n", test);
558
559   GNUNET_SOCIAL_zone_add_place (app, host_ego, "home", "let.me*in!",
560                                 &place_pub_key, &this_peer, 1, &this_peer,
561                                 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES),
562                                 host_recv_zone_add_place_result, app);
563 }
564
565
566 static void
567 host_farewell (void *cls,
568                const struct GNUNET_SOCIAL_Nym *nym,
569                struct GNUNET_PSYC_Environment *env)
570 {
571   const struct GNUNET_CRYPTO_EcdsaPublicKey *
572     nym_key = GNUNET_SOCIAL_nym_get_pub_key (nym);
573
574   char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (nym_key);
575   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
576               "Test #%u: Farewell: nym %s (%s) has left the place.\n",
577               test, GNUNET_h2s (GNUNET_SOCIAL_nym_get_pub_key_hash (nym)), str);
578   GNUNET_free (str);
579   GNUNET_assert (1 == GNUNET_PSYC_env_get_count (env));
580   if (0 != memcmp (guest_pub_key, nym_key, sizeof (*nym_key)))
581   {
582     str = GNUNET_CRYPTO_ecdsa_public_key_to_string (guest_pub_key);
583     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
584                 "Test #%u: Farewell: nym does not match guest: %s\n",
585                 test, str);
586     GNUNET_free (str);
587     GNUNET_assert (0);
588   }
589   zone_add_place ();
590 }
591
592
593 static void
594 guest_left (void *cls)
595 {
596   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
597               "Test #%u: The guest has left the place.\n", test);
598 }
599
600
601 static void
602 guest_leave()
603 {
604   if (test < TEST_RECONNECT)
605     test = TEST_GUEST_LEAVE;
606   else
607     test = TEST_GUEST_LEAVE2;
608
609   struct GNUNET_PSYC_Environment *env = GNUNET_PSYC_env_create ();
610   GNUNET_PSYC_env_add (env, GNUNET_PSYC_OP_SET,
611                        "_notice_place_leave", DATA2ARG ("Leaving."));
612   GNUNET_SOCIAL_guest_leave (gst, env, &guest_left, NULL);
613   GNUNET_PSYC_env_destroy (env);
614   gst = NULL;
615   gst_plc = NULL;
616 }
617
618
619 static void
620 schedule_guest_leave (void *cls)
621 {
622   guest_leave ();
623 }
624
625
626 static void
627 guest_look_for_result (void *cls,
628                        int64_t result_code,
629                        const void *data,
630                        uint16_t data_size)
631 {
632   struct ResultClosure *rcls = cls;
633   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
634               "Test #%u: guest_look_for_result: %" PRId64 "\n",
635               test, result_code);
636   GNUNET_assert (GNUNET_OK == result_code);
637   GNUNET_assert (6 == rcls->n);
638   GNUNET_free (rcls);
639   GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
640 }
641
642
643 static void
644 guest_look_for_var (void *cls,
645                    const struct GNUNET_MessageHeader *mod,
646                    const char *name,
647                    const void *value,
648                    uint32_t value_size,
649                    uint32_t full_value_size)
650 {
651   struct ResultClosure *rcls = cls;
652   rcls->n++;
653   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
654               "Test #%u: guest_look_for_var: %s\n%.*s\n",
655               test, name, value_size, (const char *) value);
656 }
657
658
659 static void
660 guest_look_for ()
661 {
662   test = TEST_GUEST_LOOK_FOR;
663   struct ResultClosure *rcls = GNUNET_malloc (sizeof (*rcls));
664   GNUNET_SOCIAL_place_look_for (gst_plc, "_foo", guest_look_for_var, guest_look_for_result, rcls);
665 }
666
667
668 static void
669 guest_look_at_result (void *cls, int64_t result_code,
670                       const void *data, uint16_t data_size)
671 {
672   struct ResultClosure *rcls = cls;
673
674   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
675               "Test #%u: guest_look_at_result: %" PRId64 "\n",
676               test, result_code);
677   GNUNET_assert (GNUNET_OK == result_code);
678   GNUNET_assert (1 == rcls->n);
679   GNUNET_free (rcls);
680   guest_look_for ();
681 }
682
683
684 static void
685 guest_look_at_var (void *cls,
686                    const struct GNUNET_MessageHeader *mod,
687                    const char *name,
688                    const void *value,
689                    uint32_t value_size,
690                    uint32_t full_value_size)
691 {
692   struct ResultClosure *rcls = cls;
693   rcls->n++;
694
695   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
696               "Test #%u: guest_look_at_var: %s\n%.*s\n",
697               test ,name, value_size, (const char *) value);
698 }
699
700
701 static void
702 guest_look_at ()
703 {
704   test = TEST_GUEST_LOOK_AT;
705   struct ResultClosure *rcls = GNUNET_malloc (sizeof (*rcls));
706   GNUNET_SOCIAL_place_look_at (gst_plc, "_foo_bar", guest_look_at_var, guest_look_at_result, rcls);
707 }
708
709
710 static void
711 guest_recv_history_replay_latest_result (void *cls, int64_t result,
712                                          const void *data, uint16_t data_size)
713 {
714   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
715               "Test #%u: Guest received latest history replay result "
716               "(%" PRIu32 " messages, %" PRId64 " fragments):\n"
717               "%.*s\n",
718               test, counter, result, data_size, (const char *) data);
719   //GNUNET_assert (2 == counter); /* message count */
720   //GNUNET_assert (7 == result); /* fragment count */
721
722   guest_look_at ();
723 }
724
725
726 static void
727 guest_history_replay_latest ()
728 {
729   test = TEST_GUEST_HISTORY_REPLAY_LATEST;
730   counter = 0;
731   GNUNET_SOCIAL_place_history_replay_latest (gst_plc, 3, "",
732                                              GNUNET_PSYC_HISTORY_REPLAY_LOCAL,
733                                              guest_slicer,
734                                              &guest_recv_history_replay_latest_result,
735                                              NULL);
736 }
737
738
739 static void
740 guest_recv_history_replay_result (void *cls, int64_t result,
741                                   const void *data, uint16_t data_size)
742 {
743   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
744               "Test #%u: Guest received history replay result: %" PRId64 "\n"
745               "%.*s\n",
746               test, result, data_size, (const char *) data);
747 //  GNUNET_assert (2 == counter); /* message count */
748 //  GNUNET_assert (7 == result); /* fragment count */
749
750   guest_history_replay_latest ();
751 }
752
753
754 static void
755 guest_history_replay ()
756 {
757   test = TEST_GUEST_HISTORY_REPLAY;
758   counter = 0;
759   GNUNET_SOCIAL_place_history_replay (gst_plc, 1, 3, "",
760                                       GNUNET_PSYC_HISTORY_REPLAY_LOCAL,
761                                       guest_slicer,
762                                       &guest_recv_history_replay_result,
763                                       NULL);
764 }
765
766
767 static void
768 guest_recv_method (void *cls,
769                    const struct GNUNET_PSYC_MessageHeader *msg,
770                    const struct GNUNET_PSYC_MessageMethod *meth,
771                    uint64_t message_id,
772                    const char *method_name)
773 {
774   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
775               "Test #%u: Guest received method for message ID %" PRIu64 ":\n"
776               "%s (flags: %x)\n",
777               test, message_id, method_name, ntohl (meth->flags));
778   /** @todo FIXME: check message */
779 }
780
781
782 static void
783 guest_recv_modifier (void *cls,
784                      const struct GNUNET_PSYC_MessageHeader *msg,
785                      const struct GNUNET_MessageHeader *pmsg,
786                      uint64_t message_id,
787                      enum GNUNET_PSYC_Operator oper,
788                      const char *name,
789                      const void *value,
790                      uint16_t value_size,
791                      uint16_t full_value_size)
792 {
793   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
794               "Test #%u: Guest received modifier for message ID %" PRIu64 ":\n"
795               "%c%s: %.*s (size: %u)\n",
796               test, message_id, oper, name, value_size, (const char *) value, value_size);
797   /** @todo FIXME: check modifier */
798 }
799
800 static void
801 guest_recv_mod_foo_bar (void *cls,
802                         const struct GNUNET_PSYC_MessageHeader *msg,
803                         const struct GNUNET_MessageHeader *pmsg,
804                         uint64_t message_id,
805                         enum GNUNET_PSYC_Operator oper,
806                         const char *name,
807                         const void *value,
808                         uint16_t value_size,
809                         uint16_t full_value_size)
810 {
811   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
812               "Test #%u: Guest received modifier matching _foo_bar for message ID %" PRIu64 ":\n"
813               "%c%s: %.*s (size: %u)\n",
814               test, message_id, oper, name, value_size, (const char *) value, value_size);
815   struct ResultClosure *rc = cls;
816   rc->n++;
817   /** @todo FIXME: check modifier */
818 }
819
820
821 static void
822 guest_recv_data (void *cls,
823                  const struct GNUNET_PSYC_MessageHeader *msg,
824                  const struct GNUNET_MessageHeader *pmsg,
825                  uint64_t message_id,
826                  const void *data,
827                  uint16_t data_size)
828 {
829   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
830               "Test #%u: Guest received data for message ID %" PRIu64 ":\n"
831               "%.*s\n",
832               test, message_id, data_size, (const char *) data);
833   /** @todo FIXME: check data */
834 }
835
836
837 static void
838 guest_recv_eom (void *cls,
839                 const struct GNUNET_PSYC_MessageHeader *msg,
840                 const struct GNUNET_MessageHeader *pmsg,
841                 uint64_t message_id,
842                 uint8_t is_cancelled)
843 {
844   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
845               "Test #%u: Guest received end of message ID %" PRIu64
846               ", cancelled: %u\n",
847               test, message_id, is_cancelled);
848
849   switch (test)
850   {
851   case TEST_HOST_ANNOUNCE:
852     test = TEST_HOST_ANNOUNCE_END;
853     break;
854
855   case TEST_HOST_ANNOUNCE_END:
856     guest_talk ();
857     break;
858
859   case TEST_HOST_ANNOUNCE2:
860     test = TEST_HOST_ANNOUNCE2_END;
861     break;
862
863   case TEST_HOST_ANNOUNCE2_END:
864     guest_history_replay ();
865     break;
866
867   case TEST_GUEST_HISTORY_REPLAY:
868   case TEST_GUEST_HISTORY_REPLAY_LATEST:
869     counter++;
870     break;
871
872   default:
873     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test);
874     GNUNET_assert (0);
875   }
876 }
877
878
879 static void
880 host_recv_method (void *cls,
881                   const struct GNUNET_PSYC_MessageHeader *msg,
882                   const struct GNUNET_PSYC_MessageMethod *meth,
883                   uint64_t message_id,
884                   const char *method_name)
885 {
886   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
887               "Test #%u: Host received method for message ID %" PRIu64 ":\n"
888               "%s\n",
889               test, message_id, method_name);
890   /** @todo FIXME: check message */
891 }
892
893
894 static void
895 host_recv_modifier (void *cls,
896                     const struct GNUNET_PSYC_MessageHeader *msg,
897                     const struct GNUNET_MessageHeader *pmsg,
898                     uint64_t message_id,
899                     enum GNUNET_PSYC_Operator oper,
900                     const char *name,
901                     const void *value,
902                     uint16_t value_size,
903                     uint16_t full_value_size)
904 {
905   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
906               "Test #%u: Host received modifier for message ID %" PRIu64 ":\n"
907               "%c%s: %.*s\n",
908               test, message_id, oper, name, value_size, (const char *) value);
909 }
910
911
912 static void
913 host_recv_data (void *cls,
914                 const struct GNUNET_PSYC_MessageHeader *msg,
915                 const struct GNUNET_MessageHeader *pmsg,
916                 uint64_t message_id,
917                 const void *data,
918                 uint16_t data_size)
919 {
920   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
921               "Test #%u: Host received data for message ID %" PRIu64 ":\n"
922               "%.*s\n",
923               test, message_id, data_size, (const char *) data);
924 }
925
926
927 static void
928 host_recv_eom (void *cls,
929                const struct GNUNET_PSYC_MessageHeader *msg,
930                const struct GNUNET_MessageHeader *pmsg,
931                uint64_t message_id,
932                uint8_t is_cancelled)
933 {
934   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
935               "Test #%u: Host received end of message ID %" PRIu64
936               ", cancelled: %u\n",
937               test, message_id, is_cancelled);
938
939   switch (test)
940   {
941   case TEST_HOST_ANNOUNCE:
942     test = TEST_HOST_ANNOUNCE_END;
943     break;
944
945   case TEST_HOST_ANNOUNCE_END:
946     guest_talk ();
947     break;
948
949   case TEST_HOST_ANNOUNCE2:
950     test = TEST_HOST_ANNOUNCE2_END;
951     break;
952
953   case TEST_HOST_ANNOUNCE2_END:
954     guest_history_replay ();
955     break;
956
957   case TEST_GUEST_TALK:
958     host_announce2 ();
959     break;
960
961   default:
962     if (TEST_GUEST_LEAVE <= test)
963       break;
964     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid test: #%u\n", test);
965     GNUNET_assert (0);
966   }
967 }
968
969
970 static void
971 guest_talk ()
972 {
973   test = TEST_GUEST_TALK;
974
975   tmit = (struct TransmitClosure) {};
976   tmit.env = GNUNET_PSYC_env_create ();
977   GNUNET_PSYC_env_add (tmit.env, GNUNET_PSYC_OP_ASSIGN,
978                        "_bar_foo", DATA2ARG ("one two three"));
979   GNUNET_PSYC_env_add (tmit.env, GNUNET_PSYC_OP_ASSIGN,
980                        "_bar_baz", DATA2ARG ("four five"));
981   tmit.data[0] = "zzz xxx yyy ";
982   tmit.data[1] = "zyx wvu tsr qpo.\n";
983   tmit.data_delay[1] = 1;
984   tmit.data[2] = "testing ten nine eight.\n";
985   tmit.data_count = 3;
986
987   tmit.guest_talk
988     = GNUNET_SOCIAL_guest_talk (gst, "_converse_guest", tmit.env,
989                                 &notify_data, &tmit,
990                                 GNUNET_SOCIAL_TALK_NONE);
991 }
992
993
994 static void
995 host_announce ()
996 {
997   test = TEST_HOST_ANNOUNCE;
998
999   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1000               "Test #%u: Host announcement.\n", test);
1001
1002   tmit = (struct TransmitClosure) {};
1003   tmit.env = GNUNET_PSYC_env_create ();
1004   GNUNET_PSYC_env_add (tmit.env, GNUNET_PSYC_OP_ASSIGN,
1005                        "_foo", DATA2ARG ("bar baz"));
1006   GNUNET_PSYC_env_add (tmit.env, GNUNET_PSYC_OP_ASSIGN,
1007                        "_foo_bar", DATA2ARG ("foo bar"));
1008   GNUNET_PSYC_env_add (tmit.env, GNUNET_PSYC_OP_ASSIGN,
1009                        "_foo_bar_baz", DATA2ARG ("foo bar baz"));
1010   tmit.data[0] = "aaa bbb ccc ";
1011   tmit.data[1] = "abc def ghi jkl.\n";
1012   tmit.data_delay[1] = 1;
1013   tmit.data[2] = "testing one two three ";
1014   tmit.data[3] = "four five.\n";
1015   tmit.data_count = 4;
1016
1017   tmit.host_ann
1018     = GNUNET_SOCIAL_host_announce (hst, "_converse_host", tmit.env,
1019                                    &notify_data, &tmit,
1020                                    GNUNET_SOCIAL_ANNOUNCE_NONE);
1021 }
1022
1023
1024 static void
1025 host_announce2 ()
1026 {
1027   GNUNET_assert (2 == mod_foo_bar_rcls.n);
1028   GNUNET_PSYC_slicer_modifier_remove (guest_slicer, "_foo_bar",
1029                                       guest_recv_mod_foo_bar);
1030
1031   test = TEST_HOST_ANNOUNCE2;
1032
1033   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1034               "Test #%u: Host announcement 2.\n", test);
1035
1036   tmit = (struct TransmitClosure) {};
1037   tmit.env = GNUNET_PSYC_env_create ();
1038   GNUNET_PSYC_env_add (tmit.env, GNUNET_PSYC_OP_ASSIGN,
1039                        "_foo2", DATA2ARG ("BAR BAZ"));
1040   GNUNET_PSYC_env_add (tmit.env, GNUNET_PSYC_OP_ASSIGN,
1041                        "_foo2_bar", DATA2ARG ("FOO BAR"));
1042   GNUNET_PSYC_env_add (tmit.env, GNUNET_PSYC_OP_ASSIGN,
1043                        "_foo2_bar_baz", DATA2ARG ("FOO BAR BAZ"));
1044   tmit.data[0] = "AAA BBB CCC ";
1045   tmit.data[1] = "ABC DEF GHI JKL.\n";
1046   tmit.data[2] = "TESTING ONE TWO THREE.\n";
1047   tmit.data_count = 3;
1048
1049   tmit.host_ann
1050     = GNUNET_SOCIAL_host_announce (hst, "_converse_host_two", tmit.env,
1051                                    &notify_data, &tmit,
1052                                    GNUNET_SOCIAL_ANNOUNCE_NONE);
1053 }
1054
1055
1056 static void
1057 guest_recv_entry_decision (void *cls,
1058                            int is_admitted,
1059                            const struct GNUNET_PSYC_Message *entry_msg)
1060 {
1061   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1062               "Test #%u: Guest received entry decision (try %u): %d.\n",
1063               test, join_req_count, is_admitted);
1064
1065   if (NULL != entry_msg)
1066   {
1067     struct GNUNET_PSYC_Environment *env = GNUNET_PSYC_env_create ();
1068     const char *method_name = NULL;
1069     const void *data = NULL;
1070     uint16_t data_size = 0;
1071     struct GNUNET_PSYC_MessageHeader *
1072       pmsg = GNUNET_PSYC_message_header_create_from_psyc (entry_msg);
1073     GNUNET_PSYC_message_parse (pmsg, &method_name, env, &data, &data_size);
1074     GNUNET_free (pmsg);
1075
1076     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1077                 "%s\n%.*s\n",
1078                 method_name, data_size, (const char *) data);
1079     /** @todo FIXME: check response message */
1080   }
1081
1082   switch (test)
1083   {
1084   case TEST_GUEST_RECV_ENTRY_DCSN_REFUSE:
1085     GNUNET_assert (GNUNET_NO == is_admitted);
1086     guest_enter ();
1087     break;
1088
1089   case TEST_GUEST_RECV_ENTRY_DCSN_ADMIT:
1090     GNUNET_assert (GNUNET_YES == is_admitted);
1091     host_announce ();
1092     break;
1093
1094   case TEST_GUEST_ENTER_BY_NAME:
1095     GNUNET_SCHEDULER_add_now (&schedule_reconnect, NULL);
1096     break;
1097
1098   default:
1099     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test);
1100     GNUNET_assert (0);
1101   }
1102 }
1103
1104
1105 static void
1106 host_answer_door (void *cls,
1107                   struct GNUNET_SOCIAL_Nym *nym,
1108                   const char *method_name,
1109                   struct GNUNET_PSYC_Environment *env,
1110                   const void *data,
1111                   size_t data_size)
1112 {
1113   join_req_count++;
1114
1115   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1116               "Test #%u: Host received entry request from guest (try %u).\n",
1117               (uint8_t) test, join_req_count);
1118   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1119               "%s\n%.*s\n",
1120               method_name, (int) data_size, (const char *) data);
1121
1122   switch (test)
1123   {
1124   case TEST_HOST_ANSWER_DOOR_REFUSE:
1125     test = TEST_GUEST_RECV_ENTRY_DCSN_REFUSE;
1126     join_resp = GNUNET_PSYC_message_create ("_notice_place_refuse", env,
1127                                             DATA2ARG ("Go away!"));
1128     GNUNET_SOCIAL_host_entry_decision (hst, nym, GNUNET_NO, join_resp);
1129     break;
1130
1131   case TEST_HOST_ANSWER_DOOR_ADMIT:
1132     test = TEST_GUEST_RECV_ENTRY_DCSN_ADMIT;
1133     // fall through
1134
1135   case TEST_GUEST_ENTER_BY_NAME:
1136     join_resp = GNUNET_PSYC_message_create ("_notice_place_admit", env,
1137                                             DATA2ARG ("Welcome, nym!"));
1138     GNUNET_SOCIAL_host_entry_decision (hst, nym, GNUNET_YES, join_resp);
1139     break;
1140
1141   default:
1142     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid test: #%u\n", test);
1143     GNUNET_assert (0);
1144   }
1145 }
1146
1147
1148 static void
1149 guest_recv_local_enter (void *cls, int result,
1150                         const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key,
1151                         uint64_t max_message_id)
1152 {
1153   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1154               "Test #%u: Guest entered local place: %d\n",
1155               test, result);
1156   GNUNET_assert (0 <= result);
1157 }
1158
1159
1160 static void
1161 guest_enter ()
1162 {
1163   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1164               "Test #%u: Entering place as guest.\n", test);
1165
1166   struct GuestEnterMessage *emsg = &guest_enter_msg;
1167
1168   emsg->method_name = "_request_enter";
1169   emsg->env = GNUNET_PSYC_env_create ();
1170   GNUNET_PSYC_env_add (emsg->env, GNUNET_PSYC_OP_ASSIGN,
1171                        "_abc", "abc def", 7);
1172   GNUNET_PSYC_env_add (emsg->env, GNUNET_PSYC_OP_ASSIGN,
1173                        "_abc_def", "abc def ghi", 11);
1174   emsg->data = "let me in";
1175   emsg->data_size = strlen (emsg->data) + 1;
1176   emsg->msg = GNUNET_PSYC_message_create (emsg->method_name, emsg->env,
1177                                           emsg->data, emsg->data_size);
1178
1179   gst = GNUNET_SOCIAL_guest_enter (app, guest_ego, &place_pub_key,
1180                                    GNUNET_PSYC_SLAVE_JOIN_NONE,
1181                                    &this_peer, 0, NULL, emsg->msg, guest_slicer,
1182                                    guest_recv_local_enter,
1183                                    guest_recv_entry_decision, NULL);
1184   gst_plc = GNUNET_SOCIAL_guest_get_place (gst);
1185
1186   GNUNET_SOCIAL_place_msg_proc_set (gst_plc, "_converse",
1187                                     GNUNET_SOCIAL_MSG_PROC_SAVE);
1188 }
1189
1190
1191 static void
1192 guest_enter_by_name ()
1193 {
1194   test = TEST_GUEST_ENTER_BY_NAME;
1195   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1196               "Test #%u: Entering place by name as guest.\n", test);
1197
1198   struct GuestEnterMessage *emsg = &guest_enter_msg;
1199
1200   emsg->method_name = "_request_enter";
1201   emsg->env = GNUNET_PSYC_env_create ();
1202   GNUNET_PSYC_env_add (emsg->env, GNUNET_PSYC_OP_ASSIGN,
1203                        "_abc", "abc def", 7);
1204   GNUNET_PSYC_env_add (emsg->env, GNUNET_PSYC_OP_ASSIGN,
1205                        "_abc_def", "abc def ghi", 11);
1206   emsg->data = "let me in";
1207   emsg->data_size = strlen (emsg->data) + 1;
1208   emsg->msg = GNUNET_PSYC_message_create (emsg->method_name, emsg->env,
1209                                           emsg->data, emsg->data_size);
1210
1211   gst = GNUNET_SOCIAL_guest_enter_by_name (app, guest_ego,
1212                                            "home.host.gnu", "let.me*in!",
1213                                            emsg->msg, guest_slicer,
1214                                            guest_recv_local_enter,
1215                                            guest_recv_entry_decision, NULL);
1216   gst_plc = GNUNET_SOCIAL_guest_get_place (gst);
1217 }
1218
1219
1220 static void
1221 app_recv_zone_add_nym_result (void *cls, int64_t result,
1222                               const void *data, uint16_t data_size)
1223 {
1224   GNUNET_assert (GNUNET_YES == result);
1225   is_guest_nym_added = GNUNET_YES;
1226 }
1227
1228
1229 static void
1230 guest_init ()
1231 {
1232   guest_pub_key = GNUNET_SOCIAL_ego_get_pub_key (guest_ego);
1233
1234   guest_slicer = GNUNET_PSYC_slicer_create ();
1235   GNUNET_PSYC_slicer_method_add (guest_slicer, "", NULL,
1236                                  guest_recv_method, guest_recv_modifier,
1237                                  guest_recv_data, guest_recv_eom, NULL);
1238   GNUNET_PSYC_slicer_modifier_add (guest_slicer, "_foo_bar",
1239                                    guest_recv_mod_foo_bar, &mod_foo_bar_rcls);
1240   test = TEST_HOST_ANSWER_DOOR_ADMIT;
1241
1242   GNUNET_SOCIAL_zone_add_nym (app, guest_ego, "host", host_pub_key,
1243                               GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES),
1244                               app_recv_zone_add_nym_result, NULL);
1245 }
1246
1247
1248 static void
1249 id_host_created (void *cls, const char *emsg)
1250 {
1251   if (NULL != emsg)
1252   {
1253     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1254                 "Test #%u: Could not create host identity: %s\n",
1255                 test, emsg);
1256 #if ! DEBUG_TEST_SOCIAL
1257     GNUNET_assert (0);
1258 #endif
1259   }
1260
1261 }
1262
1263
1264 static void
1265 id_guest_created (void *cls, const char *emsg)
1266 {
1267   if (NULL != emsg)
1268   {
1269     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1270                 "Test #%u: Could not create guest identity: %s\n",
1271                 test, emsg);
1272 #if ! DEBUG_TEST_SOCIAL
1273     GNUNET_assert (0);
1274 #endif
1275   }
1276   //if (NULL != guest_ego)
1277   //  guest_init ();
1278 }
1279
1280
1281 static void
1282 host_entered (void *cls, int result,
1283               const struct GNUNET_CRYPTO_EddsaPublicKey *home_pub_key,
1284               uint64_t max_message_id)
1285 {
1286   place_pub_key = *home_pub_key;
1287   GNUNET_CRYPTO_hash (&place_pub_key, sizeof (place_pub_key), &place_pub_hash);
1288   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1289               "Test #%u: Host entered place %s\n",
1290               test, GNUNET_h2s (&place_pub_hash));
1291   guest_enter ();
1292 }
1293
1294
1295 static void
1296 host_enter ()
1297 {
1298   host_slicer = GNUNET_PSYC_slicer_create ();
1299   GNUNET_PSYC_slicer_method_add (host_slicer, "", NULL,
1300                                  host_recv_method, host_recv_modifier,
1301                                  host_recv_data, host_recv_eom, NULL);
1302
1303   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1304               "Test #%u: Entering place as host.\n", test);
1305   test = TEST_HOST_ENTER;
1306   hst = GNUNET_SOCIAL_host_enter (app, host_ego,
1307                                   GNUNET_PSYC_CHANNEL_PRIVATE,
1308                                   host_slicer, host_entered,
1309                                   host_answer_door, host_farewell, NULL);
1310   hst_plc = GNUNET_SOCIAL_host_get_place (hst);
1311
1312   GNUNET_SOCIAL_place_msg_proc_set (hst_plc, "_converse",
1313                                     GNUNET_SOCIAL_MSG_PROC_RELAY);
1314 }
1315
1316
1317 static void
1318 start_app_if_ready ()
1319 {
1320   if (NULL == identity_host_ego || NULL == identity_guest_ego)
1321   {
1322     return;
1323   }
1324   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1325               "starting app...\n");
1326   app = GNUNET_SOCIAL_app_connect (cfg,
1327                                    app_id,
1328                                    app_recv_ego,
1329                                    app_recv_host,
1330                                    app_recv_guest,
1331                                    app_connected,
1332                                    NULL);
1333 }
1334
1335
1336 static void
1337 identity_ego_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego,
1338                  void **ctx, const char *name)
1339 {
1340   if (NULL != ego)
1341   {
1342     if (ego == identity_host_ego)
1343     {
1344       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1345                   "Host ego deleted\n");
1346     }
1347     else if (ego == identity_guest_ego)
1348     {
1349       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1350                   "Guest ego deleted\n");
1351     }
1352     else if (0 == strcmp (name, host_name))
1353     {
1354       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1355                   "Created ego %s\n",
1356                   name);
1357       identity_host_ego = ego;
1358       start_app_if_ready ();
1359     }
1360     else if (0 == strcmp (name, guest_name))
1361     {
1362       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1363                   "Created guest ego %s\n",
1364                   name);
1365       identity_guest_ego = ego;
1366       start_app_if_ready ();
1367     }
1368   }
1369 }
1370
1371
1372 /**
1373  * Main function of the test, run from scheduler.
1374  *
1375  * @param cls NULL
1376  * @param cfg configuration we use (also to connect to Social service)
1377  * @param peer handle to access more of the peer (not used)
1378  */
1379 static void
1380 #if DEBUG_TEST_SOCIAL
1381 run (void *cls, char *const *args, const char *cfgfile,
1382      const struct GNUNET_CONFIGURATION_Handle *c)
1383 #else
1384 run (void *cls,
1385      const struct GNUNET_CONFIGURATION_Handle *c,
1386      struct GNUNET_TESTING_Peer *peer)
1387 #endif
1388 {
1389   cfg = c;
1390   end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
1391                                                  &end_badly, NULL);
1392
1393   GNUNET_CRYPTO_get_peer_identity (cfg, &this_peer);
1394
1395   id = GNUNET_IDENTITY_connect (cfg, &identity_ego_cb, NULL);
1396
1397   test = TEST_IDENTITIES_CREATE;
1398   GNUNET_IDENTITY_create (id, host_name, &id_host_created, NULL);
1399   GNUNET_IDENTITY_create (id, guest_name, &id_guest_created, NULL);
1400 }
1401
1402
1403 int
1404 main (int argc, char *argv[])
1405 {
1406   res = 1;
1407 #if DEBUG_TEST_SOCIAL
1408   const struct GNUNET_GETOPT_CommandLineOption opts[] = {
1409     GNUNET_GETOPT_OPTION_END
1410   };
1411   if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "test-social",
1412                                        "test-social [options]",
1413                                        opts, &run, NULL))
1414     return 1;
1415 #else
1416   if (0 != GNUNET_TESTING_peer_run ("test-social", "test_social.conf", &run, NULL))
1417     return 1;
1418 #endif
1419   return res;
1420 }
1421
1422 /* end of test_social.c */