2 * This file is part of GNUnet
3 * Copyright (C) 2013 GNUnet e.V.
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.
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.
16 * @file social/test_social.c
17 * @brief Tests for the Social API.
18 * @author Gabor X Toth
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"
32 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
34 #define DATA2ARG(data) data, sizeof (data)
37 * Return value from 'main'.
41 struct GNUNET_SOCIAL_App *app;
42 const char *app_id = "test";
45 * Handle for task for timeout termination.
47 struct GNUNET_SCHEDULER_Task *end_badly_task;
49 const struct GNUNET_CONFIGURATION_Handle *cfg;
51 struct GNUNET_PeerIdentity this_peer;
53 struct GNUNET_IDENTITY_Handle *id;
55 const struct GNUNET_IDENTITY_Ego *identity_host_ego;
56 const struct GNUNET_IDENTITY_Ego *identity_guest_ego;
58 const struct GNUNET_SOCIAL_Ego *host_ego;
59 const struct GNUNET_SOCIAL_Ego *guest_ego;
61 const char *host_name = "Host One";
62 const char *guest_name = "Guest One";
64 struct GNUNET_CRYPTO_EddsaPrivateKey *place_key;
65 struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_key;
67 struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key;
68 struct GNUNET_HashCode place_pub_hash;
70 const struct GNUNET_CRYPTO_EcdsaPublicKey *guest_pub_key;
71 const struct GNUNET_CRYPTO_EcdsaPublicKey *host_pub_key;
73 struct GNUNET_PSYC_Slicer *host_slicer;
74 struct GNUNET_PSYC_Slicer *guest_slicer;
76 struct GNUNET_SOCIAL_Host *hst;
77 struct GNUNET_SOCIAL_Guest *gst;
79 struct GNUNET_SOCIAL_Place *hst_plc;
80 struct GNUNET_SOCIAL_Place *gst_plc;
82 struct GNUNET_SOCIAL_Nym *nym_eject;
84 struct GuestEnterMessage
86 struct GNUNET_PSYC_Message *msg;
87 const char *method_name;
88 struct GNUNET_PSYC_Environment *env;
93 struct TransmitClosure
95 struct GNUNET_SOCIAL_Announcement *host_ann;
96 struct GNUNET_SOCIAL_TalkRequest *guest_talk;
97 struct GNUNET_PSYC_Environment *env;
99 uint8_t data_delay[16];
105 struct ResultClosure {
109 uint8_t join_req_count;
110 struct GNUNET_PSYC_Message *join_resp;
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;
121 TEST_IDENTITIES_CREATE = 1,
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,
141 TEST_GUEST_LEAVE2 = 21,
142 TEST_HOST_LEAVE = 22,
147 schedule_guest_leave (void *cls);
151 host_answer_door (void *cls,
152 struct GNUNET_SOCIAL_Nym *nym,
153 const char *method_name,
154 struct GNUNET_PSYC_Environment *env,
168 guest_enter_by_name ();
178 * Terminate the test case (failure).
183 end_badly (void *cls)
185 end_badly_task = NULL;
186 GNUNET_SCHEDULER_shutdown ();
188 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
194 * Terminate the test case (failure).
199 end_shutdown (void *cls)
203 GNUNET_IDENTITY_disconnect (id);
207 if (NULL != guest_slicer)
209 GNUNET_PSYC_slicer_destroy (guest_slicer);
213 if (NULL != host_slicer)
215 GNUNET_PSYC_slicer_destroy (host_slicer);
218 if (NULL != end_badly_task)
220 GNUNET_SCHEDULER_cancel (end_badly_task);
221 end_badly_task = NULL;
225 GNUNET_SOCIAL_guest_leave (gst, NULL, NULL, NULL);
231 GNUNET_SOCIAL_host_leave (hst, NULL, NULL, NULL);
235 GNUNET_SOCIAL_app_disconnect (app, NULL, NULL);
240 * Terminate the test case (success).
245 end_normally (void *cls)
247 GNUNET_SCHEDULER_shutdown ();
249 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Test PASSED.\n");
254 * Finish the test case (successfully).
259 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
260 "Test #%u: Ending tests.\n", test);
262 if (end_badly_task != NULL)
264 GNUNET_SCHEDULER_cancel (end_badly_task);
265 end_badly_task = NULL;
267 GNUNET_SCHEDULER_add_now (&end_normally, NULL);
272 transmit_resume (void *cls)
274 struct TransmitClosure *tmit = cls;
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);
281 GNUNET_SOCIAL_guest_talk_resume (tmit->guest_talk);
286 notify_data (void *cls, uint16_t *data_size, void *data)
288 struct TransmitClosure *tmit = cls;
289 if (NULL != tmit->env)
291 GNUNET_PSYC_env_destroy (tmit->env);
294 if (0 == tmit->data_count)
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)
309 return GNUNET_SYSERR;
312 if (GNUNET_YES != tmit->paused && 0 < tmit->data_delay[tmit->n])
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);
324 tmit->paused = GNUNET_NO;
327 GNUNET_memcpy (data, tmit->data[tmit->n], size);
329 return ++tmit->n < tmit->data_count ? GNUNET_NO : GNUNET_YES;
336 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
337 "Test #%u: The host has left the place.\n", test);
343 schedule_host_leave (void *cls)
345 test = TEST_HOST_LEAVE;
346 GNUNET_SOCIAL_host_leave (hst, NULL, &host_left, NULL);
353 host_farewell2 (void *cls,
354 const struct GNUNET_SOCIAL_Nym *nym,
355 struct GNUNET_PSYC_Environment *env)
357 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
358 "Nym left the place again.\n");
359 GNUNET_SCHEDULER_add_now (&schedule_host_leave, NULL);
364 host_reconnected (void *cls, int result,
365 const struct GNUNET_CRYPTO_EddsaPublicKey *home_pub_key,
366 uint64_t max_message_id)
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));
374 is_host_reconnected = GNUNET_YES;
375 if (GNUNET_YES == is_guest_reconnected)
377 GNUNET_assert (NULL != gst);
378 GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
384 guest_reconnected (void *cls, int result,
385 const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key,
386 uint64_t max_message_id)
388 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
389 "Test #%u: Guest reconnected to place: %d\n",
391 GNUNET_assert (0 <= result);
393 is_guest_reconnected = GNUNET_YES;
394 if (GNUNET_YES == is_host_reconnected)
396 GNUNET_assert (NULL != gst);
397 GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
403 app_connected (void *cls)
405 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
406 "Test #%u: App connected: %p\n", test, cls);
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)
417 struct GNUNET_HashCode host_pub_hash;
419 GNUNET_CRYPTO_hash (host_pub_key,
420 sizeof (*host_pub_key),
423 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
424 "Test #%u: Got app host place notification: %s\n",
426 GNUNET_h2s (&host_pub_hash));
428 if (test == TEST_RECONNECT)
430 if (0 == memcmp (&place_pub_key, host_pub_key, sizeof (*host_pub_key)))
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,
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)
452 struct GNUNET_HashCode guest_pub_hash;
454 GNUNET_CRYPTO_hash (guest_pub_key,
455 sizeof (*guest_pub_key),
458 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
459 "Test #%u: Got app guest place notification: %s\n",
460 test, GNUNET_h2s (&guest_pub_hash));
462 if (test == TEST_RECONNECT)
464 if (0 == memcmp (&place_pub_key,
466 sizeof (*guest_pub_key)))
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,
476 GNUNET_assert (NULL != gst);
485 if (NULL == host_ego || NULL == guest_ego)
495 app_recv_ego (void *cls,
496 struct GNUNET_SOCIAL_Ego *ego,
497 const struct GNUNET_CRYPTO_EcdsaPublicKey *ego_pub_key,
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);
506 if (NULL != strstr (name, host_name))
509 host_pub_key = ego_pub_key;
510 if (TEST_IDENTITIES_CREATE == test)
516 GNUNET_assert (TEST_RECONNECT == test);
519 else if (NULL != strstr (name, guest_name))
522 guest_pub_key = ego_pub_key;
523 if (TEST_IDENTITIES_CREATE == test)
529 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
532 GNUNET_assert (TEST_RECONNECT == test);
539 schedule_reconnect (void *cls)
541 test = TEST_RECONNECT;
542 GNUNET_SOCIAL_host_disconnect (hst, NULL, NULL);
543 GNUNET_SOCIAL_guest_disconnect (gst, NULL, NULL);
547 GNUNET_SOCIAL_app_disconnect (app, NULL, NULL);
548 app = GNUNET_SOCIAL_app_connect (cfg, app_id,
558 host_recv_zone_add_place_result (void *cls, int64_t result,
559 const void *data, uint16_t data_size)
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);
566 GNUNET_assert (GNUNET_YES == is_guest_nym_added);
567 guest_enter_by_name ();
574 test = TEST_ZONE_ADD_PLACE;
575 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
576 "Test #%u: Adding place to zone.\n", test);
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);
586 host_farewell (void *cls,
587 const struct GNUNET_SOCIAL_Nym *nym,
588 struct GNUNET_PSYC_Environment *env)
590 const struct GNUNET_CRYPTO_EcdsaPublicKey *
591 nym_key = GNUNET_SOCIAL_nym_get_pub_key (nym);
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);
598 GNUNET_assert (1 == GNUNET_PSYC_env_get_count (env));
599 if (0 != memcmp (guest_pub_key, nym_key, sizeof (*nym_key)))
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",
613 guest_left (void *cls)
615 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
616 "Test #%u: The guest has left the place.\n", test);
623 if (test < TEST_RECONNECT)
624 test = TEST_GUEST_LEAVE;
626 test = TEST_GUEST_LEAVE2;
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);
639 schedule_guest_leave (void *cls)
646 guest_look_for_result (void *cls,
651 struct ResultClosure *rcls = cls;
652 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
653 "Test #%u: guest_look_for_result: %" PRId64 "\n",
655 GNUNET_assert (GNUNET_OK == result_code);
656 GNUNET_assert (6 == rcls->n);
658 GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
663 guest_look_for_var (void *cls,
664 const struct GNUNET_MessageHeader *mod,
668 uint32_t full_value_size)
670 struct ResultClosure *rcls = cls;
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);
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);
688 guest_look_at_result (void *cls, int64_t result_code,
689 const void *data, uint16_t data_size)
691 struct ResultClosure *rcls = cls;
693 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
694 "Test #%u: guest_look_at_result: %" PRId64 "\n",
696 GNUNET_assert (GNUNET_OK == result_code);
697 GNUNET_assert (1 == rcls->n);
704 guest_look_at_var (void *cls,
705 const struct GNUNET_MessageHeader *mod,
709 uint32_t full_value_size)
711 struct ResultClosure *rcls = cls;
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);
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);
730 guest_recv_history_replay_latest_result (void *cls, int64_t result,
731 const void *data, uint16_t data_size)
733 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
734 "Test #%u: Guest received latest history replay result "
735 "(%" PRIu32 " messages, %" PRId64 " fragments):\n"
737 test, counter, result, data_size, (const char *) data);
738 //GNUNET_assert (2 == counter); /* message count */
739 //GNUNET_assert (7 == result); /* fragment count */
746 guest_history_replay_latest ()
748 test = TEST_GUEST_HISTORY_REPLAY_LATEST;
750 GNUNET_SOCIAL_place_history_replay_latest (gst_plc, 3, "",
751 GNUNET_PSYC_HISTORY_REPLAY_LOCAL,
753 &guest_recv_history_replay_latest_result,
759 guest_recv_history_replay_result (void *cls, int64_t result,
760 const void *data, uint16_t data_size)
762 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
763 "Test #%u: Guest received history replay result: %" PRId64 "\n"
765 test, result, data_size, (const char *) data);
766 // GNUNET_assert (2 == counter); /* message count */
767 // GNUNET_assert (7 == result); /* fragment count */
769 guest_history_replay_latest ();
774 guest_history_replay ()
776 test = TEST_GUEST_HISTORY_REPLAY;
778 GNUNET_SOCIAL_place_history_replay (gst_plc, 1, 3, "",
779 GNUNET_PSYC_HISTORY_REPLAY_LOCAL,
781 &guest_recv_history_replay_result,
787 guest_recv_method (void *cls,
788 const struct GNUNET_PSYC_MessageHeader *msg,
789 const struct GNUNET_PSYC_MessageMethod *meth,
791 const char *method_name)
793 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
794 "Test #%u: Guest received method for message ID %" PRIu64 ":\n"
796 test, message_id, method_name, ntohl (meth->flags));
797 /** @todo FIXME: check message */
802 guest_recv_modifier (void *cls,
803 const struct GNUNET_PSYC_MessageHeader *msg,
804 const struct GNUNET_MessageHeader *pmsg,
806 enum GNUNET_PSYC_Operator oper,
810 uint16_t full_value_size)
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 */
820 guest_recv_mod_foo_bar (void *cls,
821 const struct GNUNET_PSYC_MessageHeader *msg,
822 const struct GNUNET_MessageHeader *pmsg,
824 enum GNUNET_PSYC_Operator oper,
828 uint16_t full_value_size)
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;
836 /** @todo FIXME: check modifier */
841 guest_recv_data (void *cls,
842 const struct GNUNET_PSYC_MessageHeader *msg,
843 const struct GNUNET_MessageHeader *pmsg,
848 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
849 "Test #%u: Guest received data for message ID %" PRIu64 ":\n"
851 test, message_id, data_size, (const char *) data);
852 /** @todo FIXME: check data */
857 guest_recv_eom (void *cls,
858 const struct GNUNET_PSYC_MessageHeader *msg,
859 const struct GNUNET_MessageHeader *pmsg,
861 uint8_t is_cancelled)
863 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
864 "Test #%u: Guest received end of message ID %" PRIu64
866 test, message_id, is_cancelled);
870 case TEST_HOST_ANNOUNCE:
871 test = TEST_HOST_ANNOUNCE_END;
874 case TEST_HOST_ANNOUNCE_END:
878 case TEST_HOST_ANNOUNCE2:
879 test = TEST_HOST_ANNOUNCE2_END;
882 case TEST_HOST_ANNOUNCE2_END:
883 guest_history_replay ();
886 case TEST_GUEST_HISTORY_REPLAY:
887 case TEST_GUEST_HISTORY_REPLAY_LATEST:
892 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test);
899 host_recv_method (void *cls,
900 const struct GNUNET_PSYC_MessageHeader *msg,
901 const struct GNUNET_PSYC_MessageMethod *meth,
903 const char *method_name)
905 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
906 "Test #%u: Host received method for message ID %" PRIu64 ":\n"
908 test, message_id, method_name);
909 /** @todo FIXME: check message */
914 host_recv_modifier (void *cls,
915 const struct GNUNET_PSYC_MessageHeader *msg,
916 const struct GNUNET_MessageHeader *pmsg,
918 enum GNUNET_PSYC_Operator oper,
922 uint16_t full_value_size)
924 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
925 "Test #%u: Host received modifier for message ID %" PRIu64 ":\n"
927 test, message_id, oper, name, value_size, (const char *) value);
932 host_recv_data (void *cls,
933 const struct GNUNET_PSYC_MessageHeader *msg,
934 const struct GNUNET_MessageHeader *pmsg,
939 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
940 "Test #%u: Host received data for message ID %" PRIu64 ":\n"
942 test, message_id, data_size, (const char *) data);
947 host_recv_eom (void *cls,
948 const struct GNUNET_PSYC_MessageHeader *msg,
949 const struct GNUNET_MessageHeader *pmsg,
951 uint8_t is_cancelled)
953 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
954 "Test #%u: Host received end of message ID %" PRIu64
956 test, message_id, is_cancelled);
960 case TEST_HOST_ANNOUNCE:
961 test = TEST_HOST_ANNOUNCE_END;
964 case TEST_HOST_ANNOUNCE_END:
968 case TEST_HOST_ANNOUNCE2:
969 test = TEST_HOST_ANNOUNCE2_END;
972 case TEST_HOST_ANNOUNCE2_END:
973 guest_history_replay ();
976 case TEST_GUEST_TALK:
981 if (TEST_GUEST_LEAVE <= test)
983 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid test: #%u\n", test);
992 test = TEST_GUEST_TALK;
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;
1007 = GNUNET_SOCIAL_guest_talk (gst, "_converse_guest", tmit.env,
1008 ¬ify_data, &tmit,
1009 GNUNET_SOCIAL_TALK_NONE);
1016 test = TEST_HOST_ANNOUNCE;
1018 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1019 "Test #%u: Host announcement.\n", test);
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;
1037 = GNUNET_SOCIAL_host_announce (hst, "_converse_host", tmit.env,
1038 ¬ify_data, &tmit,
1039 GNUNET_SOCIAL_ANNOUNCE_NONE);
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);
1050 test = TEST_HOST_ANNOUNCE2;
1052 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1053 "Test #%u: Host announcement 2.\n", test);
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;
1069 = GNUNET_SOCIAL_host_announce (hst, "_converse_host_two", tmit.env,
1070 ¬ify_data, &tmit,
1071 GNUNET_SOCIAL_ANNOUNCE_NONE);
1076 guest_recv_entry_decision (void *cls,
1078 const struct GNUNET_PSYC_Message *entry_msg)
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);
1084 if (NULL != entry_msg)
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);
1095 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1097 method_name, data_size, (const char *) data);
1098 /** @todo FIXME: check response message */
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);
1109 case TEST_GUEST_RECV_ENTRY_DCSN_ADMIT:
1110 GNUNET_assert (GNUNET_YES == is_admitted);
1114 case TEST_GUEST_ENTER_BY_NAME:
1115 GNUNET_SCHEDULER_add_now (&schedule_reconnect, NULL);
1119 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test);
1126 host_answer_door (void *cls,
1127 struct GNUNET_SOCIAL_Nym *nym,
1128 const char *method_name,
1129 struct GNUNET_PSYC_Environment *env,
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,
1140 method_name, (int) data_size, (const char *) data);
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);
1151 case TEST_HOST_ANSWER_DOOR_ADMIT:
1152 test = TEST_GUEST_RECV_ENTRY_DCSN_ADMIT;
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);
1162 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid test: #%u\n", test);
1169 guest_recv_local_enter (void *cls, int result,
1170 const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key,
1171 uint64_t max_message_id)
1173 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1174 "Test #%u: Guest entered local place: %d\n",
1176 GNUNET_assert (GNUNET_OK == result);
1183 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1184 "Test #%u: Entering place as guest.\n", test);
1186 struct GuestEnterMessage *emsg = &guest_enter_msg;
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);
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);
1206 GNUNET_SOCIAL_place_msg_proc_set (gst_plc, "_converse",
1207 GNUNET_SOCIAL_MSG_PROC_SAVE);
1212 guest_enter_by_name ()
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);
1218 struct GuestEnterMessage *emsg = &guest_enter_msg;
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);
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);
1241 app_recv_zone_add_nym_result (void *cls, int64_t result,
1242 const void *data, uint16_t data_size)
1244 GNUNET_assert (GNUNET_YES == result);
1245 is_guest_nym_added = GNUNET_YES;
1252 guest_pub_key = GNUNET_SOCIAL_ego_get_pub_key (guest_ego);
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;
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);
1269 id_host_created (void *cls, const char *emsg)
1273 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1274 "Test #%u: Could not create host identity: %s\n",
1276 #if ! DEBUG_TEST_SOCIAL
1285 id_guest_created (void *cls, const char *emsg)
1289 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1290 "Test #%u: Could not create guest identity: %s\n",
1292 #if ! DEBUG_TEST_SOCIAL
1296 //if (NULL != guest_ego)
1302 host_entered (void *cls, int result,
1303 const struct GNUNET_CRYPTO_EddsaPublicKey *home_pub_key,
1304 uint64_t max_message_id)
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));
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);
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);
1332 GNUNET_SOCIAL_place_msg_proc_set (hst_plc, "_converse",
1333 GNUNET_SOCIAL_MSG_PROC_RELAY);
1338 start_app_if_ready ()
1340 if (NULL == identity_host_ego || NULL == identity_guest_ego)
1344 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1345 "starting app...\n");
1346 app = GNUNET_SOCIAL_app_connect (cfg,
1357 identity_ego_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego,
1358 void **ctx, const char *name)
1362 if (ego == identity_host_ego)
1364 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1365 "Host ego deleted\n");
1367 else if (ego == identity_guest_ego)
1369 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1370 "Guest ego deleted\n");
1372 else if (0 == strcmp (name, host_name))
1374 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1377 identity_host_ego = ego;
1378 start_app_if_ready ();
1380 else if (0 == strcmp (name, guest_name))
1382 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1383 "Created guest ego %s\n",
1385 identity_guest_ego = ego;
1386 start_app_if_ready ();
1393 * Main function of the test, run from scheduler.
1396 * @param cfg configuration we use (also to connect to Social service)
1397 * @param peer handle to access more of the peer (not used)
1400 #if DEBUG_TEST_SOCIAL
1401 run (void *cls, char *const *args, const char *cfgfile,
1402 const struct GNUNET_CONFIGURATION_Handle *c)
1405 const struct GNUNET_CONFIGURATION_Handle *c,
1406 struct GNUNET_TESTING_Peer *peer)
1411 end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
1413 GNUNET_SCHEDULER_add_shutdown (&end_shutdown,
1415 GNUNET_CRYPTO_get_peer_identity (cfg, &this_peer);
1417 id = GNUNET_IDENTITY_connect (cfg, &identity_ego_cb, NULL);
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);
1426 main (int argc, char *argv[])
1429 #if DEBUG_TEST_SOCIAL
1430 const struct GNUNET_GETOPT_CommandLineOption opts[] = {
1431 GNUNET_GETOPT_OPTION_END
1433 if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "test-social",
1434 "test-social [options]",
1438 if (0 != GNUNET_TESTING_peer_run ("test-social", "test_social.conf", &run, NULL))
1444 /* end of test_social.c */