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