psyc/social: get state from psycstore
[oweals/gnunet.git] / src / social / test_social.c
1 /*
2  * This file is part of GNUnet
3  * Copyright (C) 2013 Christian Grothoff (and other contributing authors)
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_env_lib.h"
34 #include "gnunet_psyc_util_lib.h"
35 #include "gnunet_social_service.h"
36 #include "gnunet_core_service.h"
37 #include "gnunet_identity_service.h"
38
39 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
40
41 #define DATA2ARG(data) data, sizeof (data)
42
43 /**
44  * Return value from 'main'.
45  */
46 int res;
47
48 /**
49  * Handle for task for timeout termination.
50  */
51 struct GNUNET_SCHEDULER_Task * end_badly_task;
52
53 const struct GNUNET_CONFIGURATION_Handle *cfg;
54
55 struct GNUNET_CORE_Handle *core;
56 struct GNUNET_PeerIdentity this_peer;
57
58 struct GNUNET_IDENTITY_Handle *id;
59
60 const struct GNUNET_IDENTITY_Ego *host_ego;
61 const struct GNUNET_IDENTITY_Ego *guest_ego;
62
63 const char *host_name = "Host One";
64 const char *guest_name = "Guest One";
65
66 struct GNUNET_CRYPTO_EddsaPrivateKey *place_key;
67 struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_key;
68
69 struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key;
70 struct GNUNET_CRYPTO_EcdsaPublicKey guest_pub_key;
71
72 struct GNUNET_SOCIAL_Slicer *host_slicer;
73 struct GNUNET_SOCIAL_Slicer *guest_slicer;
74
75 struct GNUNET_SOCIAL_Host *hst;
76 struct GNUNET_SOCIAL_Guest *gst;
77
78 struct GNUNET_SOCIAL_Place *hst_plc;
79 struct GNUNET_SOCIAL_Place *gst_plc;
80
81 struct GuestEnterMessage
82 {
83   struct GNUNET_PSYC_Message *msg;
84   const char *method_name;
85   struct GNUNET_ENV_Environment *env;
86   void *data;
87   uint16_t data_size;
88 } guest_enter_msg;
89
90 struct TransmitClosure
91 {
92   struct GNUNET_SOCIAL_Announcement *host_ann;
93   struct GNUNET_SOCIAL_TalkRequest *guest_talk;
94   struct GNUNET_ENV_Environment *env;
95   char *data[16];
96   uint8_t data_delay[16];
97   uint8_t data_count;
98   uint8_t paused;
99   uint8_t n;
100 } tmit;
101
102 struct ResultClosure {
103   uint32_t n;
104 };
105
106 uint8_t join_req_count;
107 struct GNUNET_PSYC_Message *join_resp;
108
109 uint32_t counter;
110
111 enum
112 {
113   TEST_NONE = 0,
114   TEST_HOST_ANSWER_DOOR_REFUSE      =  1,
115   TEST_GUEST_RECV_ENTRY_DCSN_REFUSE =  2,
116   TEST_HOST_ANSWER_DOOR_ADMIT       =  3,
117   TEST_GUEST_RECV_ENTRY_DCSN_ADMIT  =  4,
118   TEST_HOST_ANNOUNCE                =  5,
119   TEST_HOST_ANNOUNCE_END            =  6,
120   TEST_HOST_ANNOUNCE2               =  7,
121   TEST_HOST_ANNOUNCE2_END           =  8,
122   TEST_GUEST_TALK                   =  9,
123   TEST_GUEST_HISTORY_REPLAY         = 10,
124   TEST_GUEST_HISTORY_REPLAY_LATEST  = 11,
125   TEST_GUEST_LOOK_AT                = 12,
126   TEST_GUEST_LOOK_FOR               = 13,
127   TEST_GUEST_LEAVE                  = 14,
128   TEST_HOST_LEAVE                   = 15,
129 } test;
130
131
132 static void
133 guest_enter ();
134
135
136 static void
137 guest_talk ();
138
139
140 static void
141 host_announce2 ();
142
143
144 /**
145  * Clean up all resources used.
146  */
147 static void
148 cleanup ()
149 {
150   if (NULL != core)
151   {
152     GNUNET_CORE_disconnect (core);
153     core = NULL;
154   }
155
156   if (NULL != id)
157   {
158     GNUNET_IDENTITY_disconnect (id);
159     id = NULL;
160   }
161
162   if (NULL != gst)
163   {
164     GNUNET_SOCIAL_guest_leave (gst, GNUNET_NO, NULL, NULL);
165     gst = NULL;
166     gst_plc = NULL;
167   }
168   if (NULL != hst)
169   {
170     GNUNET_SOCIAL_host_leave (hst, GNUNET_NO, NULL, NULL);
171     hst = NULL;
172     hst_plc = NULL;
173   }
174   GNUNET_SCHEDULER_shutdown ();
175 }
176
177
178 /**
179  * Terminate the test case (failure).
180  *
181  * @param cls NULL
182  * @param tc scheduler context
183  */
184 static void
185 end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
186 {
187   res = 1;
188   cleanup ();
189   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test FAILED.\n");
190 }
191
192
193 /**
194  * Terminate the test case (success).
195  *
196  * @param cls NULL
197  * @param tc scheduler context
198  */
199 static void
200 end_normally (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
201 {
202   res = 0;
203   cleanup ();
204   GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Test PASSED.\n");
205 }
206
207
208 /**
209  * Finish the test case (successfully).
210  */
211 static void
212 end ()
213 {
214   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending tests.\n");
215
216   if (end_badly_task != NULL)
217   {
218     GNUNET_SCHEDULER_cancel (end_badly_task);
219     end_badly_task = NULL;
220   }
221   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
222                                 &end_normally, NULL);
223 }
224
225
226 static void
227 transmit_resume (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
228 {
229   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission resumed.\n");
230   struct TransmitClosure *tmit = cls;
231   if (NULL != tmit->host_ann)
232     GNUNET_SOCIAL_host_announce_resume (tmit->host_ann);
233   else
234     GNUNET_SOCIAL_guest_talk_resume (tmit->guest_talk);
235 }
236
237
238 static int
239 notify_data (void *cls, uint16_t *data_size, void *data)
240 {
241   struct TransmitClosure *tmit = cls;
242   if (NULL != tmit->env)
243   {
244     GNUNET_ENV_environment_destroy (tmit->env);
245     tmit->env = NULL;
246   }
247   if (0 == tmit->data_count)
248   {
249     *data_size = 0;
250     return GNUNET_YES;
251   }
252
253   uint16_t size = strlen (tmit->data[tmit->n]) + 1;
254   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
255               "Transmit notify data: %u bytes available, "
256               "processing fragment %u/%u (size %u).\n",
257               *data_size, tmit->n + 1, tmit->data_count, size);
258   if (*data_size < size)
259   {
260     *data_size = 0;
261     GNUNET_assert (0);
262     return GNUNET_SYSERR;
263   }
264
265   if (GNUNET_YES != tmit->paused && 0 < tmit->data_delay[tmit->n])
266   {
267     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission paused.\n");
268     tmit->paused = GNUNET_YES;
269     GNUNET_SCHEDULER_add_delayed (
270       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
271                                      tmit->data_delay[tmit->n]),
272       &transmit_resume, tmit);
273     *data_size = 0;
274     return GNUNET_NO;
275   }
276   tmit->paused = GNUNET_NO;
277
278   *data_size = size;
279   memcpy (data, tmit->data[tmit->n], size);
280
281   return ++tmit->n < tmit->data_count ? GNUNET_NO : GNUNET_YES;
282 }
283
284
285 static void
286 host_left ()
287 {
288   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
289               "The host has left the place.\n");
290   GNUNET_SOCIAL_slicer_destroy (host_slicer);
291   host_slicer = NULL;
292   hst = NULL;
293   hst_plc = NULL;
294
295   end ();
296 }
297
298
299 static void
300 schedule_host_leave (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
301 {
302   test = TEST_HOST_LEAVE;
303   GNUNET_SOCIAL_host_leave (hst, GNUNET_NO, &host_left, NULL);
304 }
305
306
307 static void
308 host_farewell (void *cls,
309                struct GNUNET_SOCIAL_Nym *nym,
310                struct GNUNET_ENV_Environment *env,
311                size_t variable_count,
312                struct GNUNET_ENV_Modifier *variables)
313 {
314   // FIXME: this function is not called yet
315   struct GNUNET_CRYPTO_EcdsaPublicKey *nym_key = GNUNET_SOCIAL_nym_get_key (nym);
316   char *str;
317
318   str = GNUNET_CRYPTO_ecdsa_public_key_to_string (nym_key);
319   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
320               "Nym %s has left the place.\n",
321               str);
322   GNUNET_free (str);
323   GNUNET_assert (0 == memcmp (&guest_pub_key, nym_key, sizeof (*nym_key)));
324
325   GNUNET_SCHEDULER_add_now (&schedule_host_leave, NULL);
326 }
327
328
329 static void
330 guest_left (void *cls)
331 {
332   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
333               "The guest has left the place.\n");
334   GNUNET_SOCIAL_slicer_destroy (guest_slicer);
335   guest_slicer = NULL;
336   gst = NULL;
337   gst_plc = NULL;
338
339   GNUNET_SCHEDULER_add_now (&schedule_host_leave, NULL);
340 }
341
342
343 static void
344 guest_leave()
345 {
346   test = TEST_GUEST_LEAVE;
347   /* FIXME test keep_active */
348   GNUNET_SOCIAL_guest_leave (gst, GNUNET_NO, &guest_left, NULL);
349 }
350
351
352 static void
353 schedule_guest_leave (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
354 {
355   guest_leave ();
356 }
357
358
359 static void
360 guest_look_for_result (void *cls, int64_t result_code,
361                       const void *data, uint16_t data_size)
362 {
363   struct ResultClosure *rcls = cls;
364   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
365               "guest_look_for_result: %d\n", result_code);
366   GNUNET_assert (GNUNET_OK == result_code);
367   GNUNET_assert (3 == rcls->n);
368   GNUNET_free (rcls);
369   GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
370 }
371
372
373 static void
374 guest_look_for_var (void *cls,
375                    const struct GNUNET_MessageHeader *mod,
376                    const char *name,
377                    const void *value,
378                    uint32_t value_size,
379                    uint32_t full_value_size)
380 {
381   struct ResultClosure *rcls = cls;
382   rcls->n++;
383   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
384               "guest_look_for_var: %s\n%.*s\n",
385               name, value_size, value);
386 }
387
388
389 static void
390 guest_look_for ()
391 {
392   test = TEST_GUEST_LOOK_FOR;
393   struct ResultClosure *rcls = GNUNET_malloc (sizeof (*rcls));
394   GNUNET_SOCIAL_place_look_for (gst_plc, "_foo", guest_look_for_var, guest_look_for_result, rcls);
395 }
396
397
398 static void
399 guest_look_at_result (void *cls, int64_t result_code,
400                       const void *data, uint16_t data_size)
401 {
402   struct ResultClosure *rcls = cls;
403
404   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
405               "guest_look_at_result: %d\n", result_code);
406   GNUNET_assert (GNUNET_OK == result_code);
407   GNUNET_assert (1 == rcls->n);
408   GNUNET_free (rcls);
409   guest_look_for ();
410 }
411
412
413 static void
414 guest_look_at_var (void *cls,
415                    const struct GNUNET_MessageHeader *mod,
416                    const char *name,
417                    const void *value,
418                    uint32_t value_size,
419                    uint32_t full_value_size)
420 {
421   struct ResultClosure *rcls = cls;
422   rcls->n++;
423
424   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
425               "guest_look_at_var: %s\n%.*s\n",
426               name, value_size, value);
427 }
428
429
430 static void
431 guest_look_at ()
432 {
433   test = TEST_GUEST_LOOK_AT;
434   struct ResultClosure *rcls = GNUNET_malloc (sizeof (*rcls));
435   GNUNET_SOCIAL_place_look_at (gst_plc, "_foo_bar", guest_look_at_var, guest_look_at_result, rcls);
436 }
437
438
439 static void
440 guest_recv_history_replay_latest_result (void *cls, int64_t result,
441                                          const void *data, uint16_t data_size)
442 {
443   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
444               "Test #%u: Guest received latest history replay result: %" PRId64 "\n"
445               "%.*s\n",
446               test, result, data_size, data);
447   GNUNET_assert (2 == counter); /* message count */
448   GNUNET_assert (7 == result); /* fragment count */
449
450   guest_look_at ();
451 }
452
453
454 static void
455 guest_history_replay_latest ()
456 {
457   test = TEST_GUEST_HISTORY_REPLAY_LATEST;
458   counter = 0;
459   GNUNET_SOCIAL_place_history_replay_latest (gst_plc, 3, "",
460                                              GNUNET_PSYC_HISTORY_REPLAY_LOCAL,
461                                              guest_slicer,
462                                              &guest_recv_history_replay_latest_result,
463                                              NULL);
464 }
465
466
467 static void
468 guest_recv_history_replay_result (void *cls, int64_t result,
469                                   const void *data, uint16_t data_size)
470 {
471   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
472               "Test #%u: Guest received history replay result: %" PRId64 "\n"
473               "%.*s\n",
474               test, result, data_size, data);
475   GNUNET_assert (2 == counter); /* message count */
476   GNUNET_assert (7 == result); /* fragment count */
477
478   guest_history_replay_latest ();
479 }
480
481
482 static void
483 guest_history_replay ()
484 {
485   test = TEST_GUEST_HISTORY_REPLAY;
486   counter = 0;
487   GNUNET_SOCIAL_place_history_replay (gst_plc, 1, 3, "",
488                                       GNUNET_PSYC_HISTORY_REPLAY_LOCAL,
489                                       guest_slicer,
490                                       &guest_recv_history_replay_result,
491                                       NULL);
492 }
493
494
495 static void
496 guest_recv_method (void *cls,
497                   const struct GNUNET_PSYC_MessageMethod *meth,
498                   uint64_t message_id,
499                   uint32_t flags,
500                   const struct GNUNET_SOCIAL_Nym *nym,
501                   const char *method_name)
502 {
503   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
504               "Test #%u: Guest received method for message ID %" PRIu64 ":\n"
505               "%s (flags: %x)\n",
506               test, message_id, method_name, flags);
507   /* FIXME: check message */
508 }
509
510
511 static void
512 guest_recv_modifier (void *cls,
513                     const struct GNUNET_PSYC_MessageModifier *mod,
514                     uint64_t message_id,
515                     enum GNUNET_ENV_Operator oper,
516                     const char *name,
517                     const void *value,
518                     uint16_t value_size)
519 {
520   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
521               "Test #%u: Guest received modifier for message ID %" PRIu64 ":\n"
522               "%c%s: %.*s\n",
523               test, message_id, oper, name, value_size, value);
524 }
525
526
527 static void
528 guest_recv_data (void *cls,
529                 const struct GNUNET_MessageHeader *msg,
530                 uint64_t message_id,
531                 uint64_t data_offset,
532                 const void *data,
533                 uint16_t data_size)
534 {
535   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
536               "Test #%u: Guest received data for message ID %" PRIu64 ":\n"
537               "%.*s\n",
538               test, message_id, data_size, data);
539 }
540
541
542 static void
543 guest_recv_eom (void *cls,
544                const struct GNUNET_MessageHeader *msg,
545                uint64_t message_id,
546                uint8_t cancelled)
547 {
548   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
549               "Test #%u: Guest received end of message ID %" PRIu64
550               ", cancelled: %u\n",
551               test, message_id, cancelled);
552
553   switch (test)
554   {
555   case TEST_HOST_ANNOUNCE:
556     test = TEST_HOST_ANNOUNCE_END;
557     break;
558
559   case TEST_HOST_ANNOUNCE_END:
560     host_announce2 ();
561     break;
562
563   case TEST_HOST_ANNOUNCE2:
564     test = TEST_HOST_ANNOUNCE2_END;
565     break;
566
567   case TEST_HOST_ANNOUNCE2_END:
568     guest_talk ();
569     break;
570
571   case TEST_GUEST_HISTORY_REPLAY:
572   case TEST_GUEST_HISTORY_REPLAY_LATEST:
573     counter++;
574     break;
575
576   default:
577     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test);
578     GNUNET_assert (0);
579   }
580 }
581
582
583 static void
584 host_recv_method (void *cls,
585                   const struct GNUNET_PSYC_MessageMethod *meth,
586                   uint64_t message_id,
587                   uint32_t flags,
588                   const struct GNUNET_SOCIAL_Nym *nym,
589                   const char *method_name)
590 {
591   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
592               "Test #%u: Host received method for message ID %" PRIu64 ":\n"
593               "%s\n",
594               test, message_id, method_name);
595   /* FIXME: check message */
596 }
597
598
599 static void
600 host_recv_modifier (void *cls,
601                     const struct GNUNET_PSYC_MessageModifier *mod,
602                     uint64_t message_id,
603                     enum GNUNET_ENV_Operator oper,
604                     const char *name,
605                     const void *value,
606                     uint16_t value_size)
607 {
608   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
609               "Test #%u: Host received modifier for message ID %" PRIu64 ":\n"
610               "%c%s: %.*s\n",
611               test, message_id, oper, name, value_size, value);
612 }
613
614
615 static void
616 host_recv_data (void *cls,
617                 const struct GNUNET_MessageHeader *msg,
618                 uint64_t message_id,
619                 uint64_t data_offset,
620                 const void *data,
621                 uint16_t data_size)
622 {
623   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
624               "Test #%u: Host received data for message ID %" PRIu64 ":\n"
625               "%.*s\n",
626               test, message_id, data_size, data);
627 }
628
629
630 static void
631 host_recv_eom (void *cls,
632                const struct GNUNET_MessageHeader *msg,
633                uint64_t message_id,
634                uint8_t cancelled)
635 {
636   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
637               "Test #%u: Host received end of message ID %" PRIu64
638               ", cancelled: %u\n",
639               test, message_id, cancelled);
640
641   switch (test)
642   {
643   case TEST_HOST_ANNOUNCE:
644     test = TEST_HOST_ANNOUNCE_END;
645     break;
646
647   case TEST_HOST_ANNOUNCE_END:
648     host_announce2 ();
649     break;
650
651   case TEST_HOST_ANNOUNCE2:
652     test = TEST_HOST_ANNOUNCE2_END;
653     break;
654
655   case TEST_HOST_ANNOUNCE2_END:
656     guest_talk ();
657     break;
658
659   case TEST_GUEST_TALK:
660       guest_history_replay ();
661     break;
662
663   default:
664     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test);
665     GNUNET_assert (0);
666   }
667 }
668
669
670 static void
671 guest_talk ()
672 {
673   test = TEST_GUEST_TALK;
674
675   tmit = (struct TransmitClosure) {};
676   tmit.env = GNUNET_ENV_environment_create ();
677   GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN,
678                               "_bar_foo", DATA2ARG ("one two three"));
679   GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN,
680                               "_bar_baz", DATA2ARG ("four five"));
681   tmit.data[0] = "zzz xxx yyy";
682   tmit.data[1] = "zyx wvu tsr qpo";
683   tmit.data[2] = "testing ten nine eight";
684   tmit.data_count = 3;
685
686   tmit.guest_talk
687     = GNUNET_SOCIAL_guest_talk (gst, "_message_guest", tmit.env,
688                                 &notify_data, &tmit,
689                                 GNUNET_SOCIAL_TALK_NONE);
690 }
691
692
693 static void
694 host_announce ()
695 {
696   test = TEST_HOST_ANNOUNCE;
697
698   tmit = (struct TransmitClosure) {};
699   tmit.env = GNUNET_ENV_environment_create ();
700   GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN,
701                               "_foo", DATA2ARG ("bar baz"));
702   GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN,
703                               "_foo_bar", DATA2ARG ("foo bar"));
704   GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN,
705                               "_foo_bar_baz", DATA2ARG ("foo bar baz"));
706   tmit.data[0] = "aaa bbb ccc";
707   tmit.data[1] = "abc def ghi jkl";
708   tmit.data[2] = "testing one two three";
709   tmit.data[3] = "four five";
710   tmit.data_count = 4;
711
712   tmit.host_ann
713     = GNUNET_SOCIAL_host_announce (hst, "_message_host", tmit.env,
714                                    &notify_data, &tmit,
715                                    GNUNET_SOCIAL_ANNOUNCE_NONE
716                                    | GNUNET_PSYC_MASTER_TRANSMIT_STATE_MODIFY);
717 }
718
719
720 static void
721 host_announce2 ()
722 {
723   test = TEST_HOST_ANNOUNCE2;
724
725   tmit = (struct TransmitClosure) {};
726   tmit.env = GNUNET_ENV_environment_create ();
727   GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN,
728                               "_foo2", DATA2ARG ("BAR BAZ"));
729   GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN,
730                               "_foo2_bar", DATA2ARG ("FOO BAR"));
731   GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN,
732                               "_foo2_bar", DATA2ARG ("FOO BAR BAZ"));
733   tmit.data[0] = "AAA BBB CCC";
734   tmit.data[1] = "ABC DEF GHI JKL";
735   tmit.data[2] = "TESTING ONE TWO THREE";
736   tmit.data_count = 3;
737
738   tmit.host_ann
739     = GNUNET_SOCIAL_host_announce (hst, "_message_host_two", tmit.env,
740                                    &notify_data, &tmit,
741                                    GNUNET_SOCIAL_ANNOUNCE_NONE);
742 }
743
744
745 static void
746 guest_recv_entry_decision (void *cls,
747                            int is_admitted,
748                            const struct GNUNET_PSYC_Message *entry_resp)
749 {
750   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
751               "Guest received entry decision (try %u): %d.\n",
752               join_req_count, is_admitted);
753
754   if (NULL != entry_resp)
755   {
756     struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create ();
757     const char *method_name = NULL;
758     const void *data = NULL;
759     uint16_t data_size = 0;
760     GNUNET_PSYC_message_parse (entry_resp, &method_name, env, &data, &data_size);
761
762     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
763                 "%s\n%.*s\n",
764                 method_name, data_size, data);
765     /* FIXME: check response message */
766   }
767
768   switch (test)
769   {
770   case TEST_GUEST_RECV_ENTRY_DCSN_REFUSE:
771     GNUNET_assert (GNUNET_NO == is_admitted);
772     guest_enter ();
773     break;
774
775   case TEST_GUEST_RECV_ENTRY_DCSN_ADMIT:
776     GNUNET_assert (GNUNET_YES == is_admitted);
777     host_announce ();
778     break;
779
780   default:
781     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test);
782     GNUNET_assert (0);
783   }
784 }
785
786
787 static void
788 host_answer_door (void *cls,
789                   struct GNUNET_SOCIAL_Nym *nym,
790                   const char *method_name,
791                   struct GNUNET_ENV_Environment *env,
792                   size_t data_size,
793                   const void *data)
794 {
795   join_req_count++;
796
797   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
798                 "Host received entry request from guest (try %u).\n",
799                 join_req_count);
800   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
801               "%s\n%.*s\n",
802               method_name, data_size, data);
803
804   switch (test)
805   {
806   case TEST_HOST_ANSWER_DOOR_REFUSE:
807     test = TEST_GUEST_RECV_ENTRY_DCSN_REFUSE;
808     join_resp = GNUNET_PSYC_message_create ("_refuse_nym", env,
809                                             DATA2ARG ("Go away!"));
810     GNUNET_SOCIAL_host_entry_decision (hst, nym, GNUNET_NO, join_resp);
811     break;
812
813   case TEST_HOST_ANSWER_DOOR_ADMIT:
814     test = TEST_GUEST_RECV_ENTRY_DCSN_ADMIT;
815     join_resp = GNUNET_PSYC_message_create ("_admit_nym", env,
816                                             DATA2ARG ("Welcome, nym!"));
817     GNUNET_SOCIAL_host_entry_decision (hst, nym, GNUNET_YES, join_resp);
818     break;
819
820   default:
821     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test);
822     GNUNET_assert (0);
823   }
824 }
825
826
827 static void
828 guest_recv_local_enter (void *cls, int result, uint64_t max_message_id)
829 {
830   GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Guest entered to local place.\n");
831
832 }
833
834
835 static void
836 guest_enter ()
837 {
838   GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Entering to place as guest.\n");
839
840   struct GuestEnterMessage *emsg = &guest_enter_msg;
841
842   emsg->method_name = "_request_enter";
843   emsg->env = GNUNET_ENV_environment_create ();
844   GNUNET_ENV_environment_add (emsg->env, GNUNET_ENV_OP_ASSIGN,
845                               "_abc", "abc def", 7);
846   GNUNET_ENV_environment_add (emsg->env, GNUNET_ENV_OP_ASSIGN,
847                               "_abc_def", "abc def ghi", 11);
848   emsg->data = "let me in";
849   emsg->data_size = strlen (emsg->data) + 1;
850   emsg->msg = GNUNET_PSYC_message_create (emsg->method_name, emsg->env,
851                                           emsg->data, emsg->data_size);
852
853   gst = GNUNET_SOCIAL_guest_enter (cfg, guest_ego, &place_pub_key,
854                                    &this_peer, 0, NULL, emsg->msg,
855                                    guest_slicer, &guest_recv_local_enter,
856                                    &guest_recv_entry_decision, NULL);
857   gst_plc = GNUNET_SOCIAL_guest_get_place (gst);
858 }
859
860
861 static void
862 id_guest_ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
863 {
864   GNUNET_assert (NULL != ego);
865   guest_ego = ego;
866
867   guest_slicer = GNUNET_SOCIAL_slicer_create ();
868   GNUNET_SOCIAL_slicer_add (guest_slicer, "",
869                             &guest_recv_method, &guest_recv_modifier,
870                             &guest_recv_data, &guest_recv_eom, NULL);
871   test = TEST_HOST_ANSWER_DOOR_ADMIT;
872   //host_announce ();
873   guest_enter ();
874 }
875
876
877 static void
878 id_guest_created (void *cls, const char *emsg)
879 {
880   if (NULL != emsg)
881   {
882     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
883                 "Could not create guest identity: %s\n", emsg);
884 #if ! DEBUG_TEST_SOCIAL
885     GNUNET_assert (0);
886 #endif
887   }
888
889  GNUNET_IDENTITY_ego_lookup (cfg, guest_name, &id_guest_ego_cb, NULL);
890 }
891
892
893 static void
894 host_entered (void *cls, int result, uint64_t max_message_id)
895 {
896   GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Host entered to place.\n");
897
898   GNUNET_IDENTITY_create (id, guest_name, &id_guest_created, NULL);
899 }
900
901
902 static void
903 id_host_ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
904 {
905   GNUNET_assert (NULL != ego);
906   host_ego = ego;
907
908   host_slicer = GNUNET_SOCIAL_slicer_create ();
909   GNUNET_SOCIAL_slicer_add (host_slicer, "",
910                             &host_recv_method, &host_recv_modifier,
911                             &host_recv_data, &host_recv_eom, NULL);
912
913   GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Entering to place as host.\n");
914   hst = GNUNET_SOCIAL_host_enter (cfg, host_ego, place_key,
915                                   GNUNET_PSYC_CHANNEL_PRIVATE, host_slicer,
916                                   &host_entered, &host_answer_door,
917                                   &host_farewell, NULL);
918   hst_plc = GNUNET_SOCIAL_host_get_place (hst);
919 }
920
921
922 static void
923 id_host_created (void *cls, const char *emsg)
924 {
925   if (NULL != emsg)
926   {
927     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
928                 "Could not create host identity: %s\n", emsg);
929 #if ! DEBUG_TEST_SOCIAL
930     GNUNET_assert (0);
931 #endif
932   }
933
934   GNUNET_IDENTITY_ego_lookup (cfg, host_name, &id_host_ego_cb, NULL);
935 }
936
937
938 static void
939 identity_ego_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego,
940                  void **ctx, const char *name)
941 {
942
943 }
944
945
946 static void
947 core_connected (void *cls, const struct GNUNET_PeerIdentity *my_identity)
948 {
949   this_peer = *my_identity;
950
951   id = GNUNET_IDENTITY_connect (cfg, &identity_ego_cb, NULL);
952   GNUNET_IDENTITY_create (id, host_name, &id_host_created, NULL);
953 }
954
955
956 /**
957  * Main function of the test, run from scheduler.
958  *
959  * @param cls NULL
960  * @param cfg configuration we use (also to connect to Social service)
961  * @param peer handle to access more of the peer (not used)
962  */
963 static void
964 #if DEBUG_TEST_SOCIAL
965 run (void *cls, char *const *args, const char *cfgfile,
966      const struct GNUNET_CONFIGURATION_Handle *c)
967 #else
968 run (void *cls,
969      const struct GNUNET_CONFIGURATION_Handle *c,
970      struct GNUNET_TESTING_Peer *peer)
971 #endif
972 {
973   cfg = c;
974   end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
975
976   place_key = GNUNET_CRYPTO_eddsa_key_create ();
977   guest_key = GNUNET_CRYPTO_ecdsa_key_create ();
978
979   GNUNET_CRYPTO_eddsa_key_get_public (place_key, &place_pub_key);
980   GNUNET_CRYPTO_ecdsa_key_get_public (guest_key, &guest_pub_key);
981
982   core = GNUNET_CORE_connect (cfg, NULL, &core_connected, NULL, NULL,
983                               NULL, GNUNET_NO, NULL, GNUNET_NO, NULL);
984 }
985
986
987 int
988 main (int argc, char *argv[])
989 {
990   res = 1;
991 #if DEBUG_TEST_SOCIAL
992   const struct GNUNET_GETOPT_CommandLineOption opts[] = {
993     GNUNET_GETOPT_OPTION_END
994   };
995   if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "test-social",
996                                        "test-social [options]",
997                                        opts, &run, NULL))
998     return 1;
999 #else
1000   if (0 != GNUNET_TESTING_peer_run ("test-social", "test_social.conf", &run, NULL))
1001     return 1;
1002 #endif
1003   return res;
1004 }
1005
1006 /* end of test_social.c */