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