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
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.
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.
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.
21 * @file social/test_social.c
22 * @brief Tests for the Social API.
23 * @author Gabor X Toth
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"
37 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
39 #define DATA2ARG(data) data, sizeof (data)
42 * Return value from 'main'.
46 struct GNUNET_SOCIAL_App *app;
47 const char *app_id = "test";
50 * Handle for task for timeout termination.
52 struct GNUNET_SCHEDULER_Task *end_badly_task;
54 const struct GNUNET_CONFIGURATION_Handle *cfg;
56 struct GNUNET_PeerIdentity this_peer;
58 struct GNUNET_IDENTITY_Handle *id;
60 const struct GNUNET_IDENTITY_Ego *identity_host_ego;
61 const struct GNUNET_IDENTITY_Ego *identity_guest_ego;
63 const struct GNUNET_SOCIAL_Ego *host_ego;
64 const struct GNUNET_SOCIAL_Ego *guest_ego;
66 const char *host_name = "Host One";
67 const char *guest_name = "Guest One";
69 struct GNUNET_CRYPTO_EddsaPrivateKey *place_key;
70 struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_key;
72 struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key;
73 struct GNUNET_HashCode place_pub_hash;
75 const struct GNUNET_CRYPTO_EcdsaPublicKey *guest_pub_key;
76 const struct GNUNET_CRYPTO_EcdsaPublicKey *host_pub_key;
78 struct GNUNET_PSYC_Slicer *host_slicer;
79 struct GNUNET_PSYC_Slicer *guest_slicer;
81 struct GNUNET_SOCIAL_Host *hst;
82 struct GNUNET_SOCIAL_Guest *gst;
84 struct GNUNET_SOCIAL_Place *hst_plc;
85 struct GNUNET_SOCIAL_Place *gst_plc;
87 struct GNUNET_SOCIAL_Nym *nym_eject;
89 struct GuestEnterMessage
91 struct GNUNET_PSYC_Message *msg;
92 const char *method_name;
93 struct GNUNET_PSYC_Environment *env;
98 struct TransmitClosure
100 struct GNUNET_SOCIAL_Announcement *host_ann;
101 struct GNUNET_SOCIAL_TalkRequest *guest_talk;
102 struct GNUNET_PSYC_Environment *env;
104 uint8_t data_delay[16];
110 struct ResultClosure {
114 uint8_t join_req_count;
115 struct GNUNET_PSYC_Message *join_resp;
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;
126 TEST_IDENTITIES_CREATE = 1,
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,
146 TEST_GUEST_LEAVE2 = 21,
147 TEST_HOST_LEAVE = 22,
152 schedule_guest_leave (void *cls);
156 host_answer_door (void *cls,
157 struct GNUNET_SOCIAL_Nym *nym,
158 const char *method_name,
159 struct GNUNET_PSYC_Environment *env,
173 guest_enter_by_name ();
183 * Terminate the test case (failure).
188 end_badly (void *cls)
190 end_badly_task = NULL;
191 GNUNET_SCHEDULER_shutdown ();
193 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
199 * Terminate the test case (failure).
204 end_shutdown (void *cls)
208 GNUNET_IDENTITY_disconnect (id);
212 if (NULL != guest_slicer)
214 GNUNET_PSYC_slicer_destroy (guest_slicer);
218 if (NULL != host_slicer)
220 GNUNET_PSYC_slicer_destroy (host_slicer);
223 if (NULL != end_badly_task)
225 GNUNET_SCHEDULER_cancel (end_badly_task);
226 end_badly_task = NULL;
230 GNUNET_SOCIAL_guest_leave (gst, NULL, NULL, NULL);
236 GNUNET_SOCIAL_host_leave (hst, NULL, NULL, NULL);
240 GNUNET_SOCIAL_app_disconnect (app, NULL, NULL);
245 * Terminate the test case (success).
250 end_normally (void *cls)
252 GNUNET_SCHEDULER_shutdown ();
254 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Test PASSED.\n");
259 * Finish the test case (successfully).
264 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
265 "Test #%u: Ending tests.\n", test);
267 if (end_badly_task != NULL)
269 GNUNET_SCHEDULER_cancel (end_badly_task);
270 end_badly_task = NULL;
272 GNUNET_SCHEDULER_add_now (&end_normally, NULL);
277 transmit_resume (void *cls)
279 struct TransmitClosure *tmit = cls;
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);
286 GNUNET_SOCIAL_guest_talk_resume (tmit->guest_talk);
291 notify_data (void *cls, uint16_t *data_size, void *data)
293 struct TransmitClosure *tmit = cls;
294 if (NULL != tmit->env)
296 GNUNET_PSYC_env_destroy (tmit->env);
299 if (0 == tmit->data_count)
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)
314 return GNUNET_SYSERR;
317 if (GNUNET_YES != tmit->paused && 0 < tmit->data_delay[tmit->n])
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);
329 tmit->paused = GNUNET_NO;
332 GNUNET_memcpy (data, tmit->data[tmit->n], size);
334 return ++tmit->n < tmit->data_count ? GNUNET_NO : GNUNET_YES;
341 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
342 "Test #%u: The host has left the place.\n", test);
348 schedule_host_leave (void *cls)
350 test = TEST_HOST_LEAVE;
351 GNUNET_SOCIAL_host_leave (hst, NULL, &host_left, NULL);
358 host_farewell2 (void *cls,
359 const struct GNUNET_SOCIAL_Nym *nym,
360 struct GNUNET_PSYC_Environment *env)
362 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
363 "Nym left the place again.\n");
364 GNUNET_SCHEDULER_add_now (&schedule_host_leave, NULL);
369 host_reconnected (void *cls, int result,
370 const struct GNUNET_CRYPTO_EddsaPublicKey *home_pub_key,
371 uint64_t max_message_id)
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));
379 is_host_reconnected = GNUNET_YES;
380 if (GNUNET_YES == is_guest_reconnected)
382 GNUNET_assert (NULL != gst);
383 GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
389 guest_reconnected (void *cls, int result,
390 const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key,
391 uint64_t max_message_id)
393 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
394 "Test #%u: Guest reconnected to place: %d\n",
396 GNUNET_assert (0 <= result);
398 is_guest_reconnected = GNUNET_YES;
399 if (GNUNET_YES == is_host_reconnected)
401 GNUNET_assert (NULL != gst);
402 GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
408 app_connected (void *cls)
410 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
411 "Test #%u: App connected: %p\n", test, cls);
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)
422 struct GNUNET_HashCode host_pub_hash;
424 GNUNET_CRYPTO_hash (host_pub_key,
425 sizeof (*host_pub_key),
428 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
429 "Test #%u: Got app host place notification: %s\n",
431 GNUNET_h2s (&host_pub_hash));
433 if (test == TEST_RECONNECT)
435 if (0 == memcmp (&place_pub_key, host_pub_key, sizeof (*host_pub_key)))
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,
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)
457 struct GNUNET_HashCode guest_pub_hash;
459 GNUNET_CRYPTO_hash (guest_pub_key,
460 sizeof (*guest_pub_key),
463 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
464 "Test #%u: Got app guest place notification: %s\n",
465 test, GNUNET_h2s (&guest_pub_hash));
467 if (test == TEST_RECONNECT)
469 if (0 == memcmp (&place_pub_key,
471 sizeof (*guest_pub_key)))
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,
481 GNUNET_assert (NULL != gst);
490 if (NULL == host_ego || NULL == guest_ego)
500 app_recv_ego (void *cls,
501 struct GNUNET_SOCIAL_Ego *ego,
502 const struct GNUNET_CRYPTO_EcdsaPublicKey *ego_pub_key,
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);
511 if (NULL != strstr (name, host_name))
514 host_pub_key = ego_pub_key;
515 if (TEST_IDENTITIES_CREATE == test)
521 GNUNET_assert (TEST_RECONNECT == test);
524 else if (NULL != strstr (name, guest_name))
527 guest_pub_key = ego_pub_key;
528 if (TEST_IDENTITIES_CREATE == test)
534 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
537 GNUNET_assert (TEST_RECONNECT == test);
544 schedule_reconnect (void *cls)
546 test = TEST_RECONNECT;
547 GNUNET_SOCIAL_host_disconnect (hst, NULL, NULL);
548 GNUNET_SOCIAL_guest_disconnect (gst, NULL, NULL);
552 GNUNET_SOCIAL_app_disconnect (app, NULL, NULL);
553 app = GNUNET_SOCIAL_app_connect (cfg, app_id,
563 host_recv_zone_add_place_result (void *cls, int64_t result,
564 const void *data, uint16_t data_size)
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);
571 GNUNET_assert (GNUNET_YES == is_guest_nym_added);
572 guest_enter_by_name ();
579 test = TEST_ZONE_ADD_PLACE;
580 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
581 "Test #%u: Adding place to zone.\n", test);
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);
591 host_farewell (void *cls,
592 const struct GNUNET_SOCIAL_Nym *nym,
593 struct GNUNET_PSYC_Environment *env)
595 const struct GNUNET_CRYPTO_EcdsaPublicKey *
596 nym_key = GNUNET_SOCIAL_nym_get_pub_key (nym);
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);
603 GNUNET_assert (1 == GNUNET_PSYC_env_get_count (env));
604 if (0 != memcmp (guest_pub_key, nym_key, sizeof (*nym_key)))
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",
618 guest_left (void *cls)
620 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
621 "Test #%u: The guest has left the place.\n", test);
628 if (test < TEST_RECONNECT)
629 test = TEST_GUEST_LEAVE;
631 test = TEST_GUEST_LEAVE2;
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);
644 schedule_guest_leave (void *cls)
651 guest_look_for_result (void *cls,
656 struct ResultClosure *rcls = cls;
657 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
658 "Test #%u: guest_look_for_result: %" PRId64 "\n",
660 GNUNET_assert (GNUNET_OK == result_code);
661 GNUNET_assert (6 == rcls->n);
663 GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
668 guest_look_for_var (void *cls,
669 const struct GNUNET_MessageHeader *mod,
673 uint32_t full_value_size)
675 struct ResultClosure *rcls = cls;
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);
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);
693 guest_look_at_result (void *cls, int64_t result_code,
694 const void *data, uint16_t data_size)
696 struct ResultClosure *rcls = cls;
698 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
699 "Test #%u: guest_look_at_result: %" PRId64 "\n",
701 GNUNET_assert (GNUNET_OK == result_code);
702 GNUNET_assert (1 == rcls->n);
709 guest_look_at_var (void *cls,
710 const struct GNUNET_MessageHeader *mod,
714 uint32_t full_value_size)
716 struct ResultClosure *rcls = cls;
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);
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);
735 guest_recv_history_replay_latest_result (void *cls, int64_t result,
736 const void *data, uint16_t data_size)
738 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
739 "Test #%u: Guest received latest history replay result "
740 "(%" PRIu32 " messages, %" PRId64 " fragments):\n"
742 test, counter, result, data_size, (const char *) data);
743 //GNUNET_assert (2 == counter); /* message count */
744 //GNUNET_assert (7 == result); /* fragment count */
751 guest_history_replay_latest ()
753 test = TEST_GUEST_HISTORY_REPLAY_LATEST;
755 GNUNET_SOCIAL_place_history_replay_latest (gst_plc, 3, "",
756 GNUNET_PSYC_HISTORY_REPLAY_LOCAL,
758 &guest_recv_history_replay_latest_result,
764 guest_recv_history_replay_result (void *cls, int64_t result,
765 const void *data, uint16_t data_size)
767 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
768 "Test #%u: Guest received history replay result: %" PRId64 "\n"
770 test, result, data_size, (const char *) data);
771 // GNUNET_assert (2 == counter); /* message count */
772 // GNUNET_assert (7 == result); /* fragment count */
774 guest_history_replay_latest ();
779 guest_history_replay ()
781 test = TEST_GUEST_HISTORY_REPLAY;
783 GNUNET_SOCIAL_place_history_replay (gst_plc, 1, 3, "",
784 GNUNET_PSYC_HISTORY_REPLAY_LOCAL,
786 &guest_recv_history_replay_result,
792 guest_recv_method (void *cls,
793 const struct GNUNET_PSYC_MessageHeader *msg,
794 const struct GNUNET_PSYC_MessageMethod *meth,
796 const char *method_name)
798 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
799 "Test #%u: Guest received method for message ID %" PRIu64 ":\n"
801 test, message_id, method_name, ntohl (meth->flags));
802 /** @todo FIXME: check message */
807 guest_recv_modifier (void *cls,
808 const struct GNUNET_PSYC_MessageHeader *msg,
809 const struct GNUNET_MessageHeader *pmsg,
811 enum GNUNET_PSYC_Operator oper,
815 uint16_t full_value_size)
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 */
825 guest_recv_mod_foo_bar (void *cls,
826 const struct GNUNET_PSYC_MessageHeader *msg,
827 const struct GNUNET_MessageHeader *pmsg,
829 enum GNUNET_PSYC_Operator oper,
833 uint16_t full_value_size)
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;
841 /** @todo FIXME: check modifier */
846 guest_recv_data (void *cls,
847 const struct GNUNET_PSYC_MessageHeader *msg,
848 const struct GNUNET_MessageHeader *pmsg,
853 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
854 "Test #%u: Guest received data for message ID %" PRIu64 ":\n"
856 test, message_id, data_size, (const char *) data);
857 /** @todo FIXME: check data */
862 guest_recv_eom (void *cls,
863 const struct GNUNET_PSYC_MessageHeader *msg,
864 const struct GNUNET_MessageHeader *pmsg,
866 uint8_t is_cancelled)
868 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
869 "Test #%u: Guest received end of message ID %" PRIu64
871 test, message_id, is_cancelled);
875 case TEST_HOST_ANNOUNCE:
876 test = TEST_HOST_ANNOUNCE_END;
879 case TEST_HOST_ANNOUNCE_END:
883 case TEST_HOST_ANNOUNCE2:
884 test = TEST_HOST_ANNOUNCE2_END;
887 case TEST_HOST_ANNOUNCE2_END:
888 guest_history_replay ();
891 case TEST_GUEST_HISTORY_REPLAY:
892 case TEST_GUEST_HISTORY_REPLAY_LATEST:
897 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test);
904 host_recv_method (void *cls,
905 const struct GNUNET_PSYC_MessageHeader *msg,
906 const struct GNUNET_PSYC_MessageMethod *meth,
908 const char *method_name)
910 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
911 "Test #%u: Host received method for message ID %" PRIu64 ":\n"
913 test, message_id, method_name);
914 /** @todo FIXME: check message */
919 host_recv_modifier (void *cls,
920 const struct GNUNET_PSYC_MessageHeader *msg,
921 const struct GNUNET_MessageHeader *pmsg,
923 enum GNUNET_PSYC_Operator oper,
927 uint16_t full_value_size)
929 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
930 "Test #%u: Host received modifier for message ID %" PRIu64 ":\n"
932 test, message_id, oper, name, value_size, (const char *) value);
937 host_recv_data (void *cls,
938 const struct GNUNET_PSYC_MessageHeader *msg,
939 const struct GNUNET_MessageHeader *pmsg,
944 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
945 "Test #%u: Host received data for message ID %" PRIu64 ":\n"
947 test, message_id, data_size, (const char *) data);
952 host_recv_eom (void *cls,
953 const struct GNUNET_PSYC_MessageHeader *msg,
954 const struct GNUNET_MessageHeader *pmsg,
956 uint8_t is_cancelled)
958 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
959 "Test #%u: Host received end of message ID %" PRIu64
961 test, message_id, is_cancelled);
965 case TEST_HOST_ANNOUNCE:
966 test = TEST_HOST_ANNOUNCE_END;
969 case TEST_HOST_ANNOUNCE_END:
973 case TEST_HOST_ANNOUNCE2:
974 test = TEST_HOST_ANNOUNCE2_END;
977 case TEST_HOST_ANNOUNCE2_END:
978 guest_history_replay ();
981 case TEST_GUEST_TALK:
986 if (TEST_GUEST_LEAVE <= test)
988 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid test: #%u\n", test);
997 test = TEST_GUEST_TALK;
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;
1012 = GNUNET_SOCIAL_guest_talk (gst, "_converse_guest", tmit.env,
1013 ¬ify_data, &tmit,
1014 GNUNET_SOCIAL_TALK_NONE);
1021 test = TEST_HOST_ANNOUNCE;
1023 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1024 "Test #%u: Host announcement.\n", test);
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;
1042 = GNUNET_SOCIAL_host_announce (hst, "_converse_host", tmit.env,
1043 ¬ify_data, &tmit,
1044 GNUNET_SOCIAL_ANNOUNCE_NONE);
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);
1055 test = TEST_HOST_ANNOUNCE2;
1057 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1058 "Test #%u: Host announcement 2.\n", test);
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;
1074 = GNUNET_SOCIAL_host_announce (hst, "_converse_host_two", tmit.env,
1075 ¬ify_data, &tmit,
1076 GNUNET_SOCIAL_ANNOUNCE_NONE);
1081 guest_recv_entry_decision (void *cls,
1083 const struct GNUNET_PSYC_Message *entry_msg)
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);
1089 if (NULL != entry_msg)
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);
1100 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1102 method_name, data_size, (const char *) data);
1103 /** @todo FIXME: check response message */
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);
1114 case TEST_GUEST_RECV_ENTRY_DCSN_ADMIT:
1115 GNUNET_assert (GNUNET_YES == is_admitted);
1119 case TEST_GUEST_ENTER_BY_NAME:
1120 GNUNET_SCHEDULER_add_now (&schedule_reconnect, NULL);
1124 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test);
1131 host_answer_door (void *cls,
1132 struct GNUNET_SOCIAL_Nym *nym,
1133 const char *method_name,
1134 struct GNUNET_PSYC_Environment *env,
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,
1145 method_name, (int) data_size, (const char *) data);
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);
1156 case TEST_HOST_ANSWER_DOOR_ADMIT:
1157 test = TEST_GUEST_RECV_ENTRY_DCSN_ADMIT;
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);
1167 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid test: #%u\n", test);
1174 guest_recv_local_enter (void *cls, int result,
1175 const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key,
1176 uint64_t max_message_id)
1178 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1179 "Test #%u: Guest entered local place: %d\n",
1181 GNUNET_assert (GNUNET_OK == result);
1188 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1189 "Test #%u: Entering place as guest.\n", test);
1191 struct GuestEnterMessage *emsg = &guest_enter_msg;
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);
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);
1211 GNUNET_SOCIAL_place_msg_proc_set (gst_plc, "_converse",
1212 GNUNET_SOCIAL_MSG_PROC_SAVE);
1217 guest_enter_by_name ()
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);
1223 struct GuestEnterMessage *emsg = &guest_enter_msg;
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);
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);
1246 app_recv_zone_add_nym_result (void *cls, int64_t result,
1247 const void *data, uint16_t data_size)
1249 GNUNET_assert (GNUNET_YES == result);
1250 is_guest_nym_added = GNUNET_YES;
1257 guest_pub_key = GNUNET_SOCIAL_ego_get_pub_key (guest_ego);
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;
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);
1274 id_host_created (void *cls, const char *emsg)
1278 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1279 "Test #%u: Could not create host identity: %s\n",
1281 #if ! DEBUG_TEST_SOCIAL
1290 id_guest_created (void *cls, const char *emsg)
1294 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1295 "Test #%u: Could not create guest identity: %s\n",
1297 #if ! DEBUG_TEST_SOCIAL
1301 //if (NULL != guest_ego)
1307 host_entered (void *cls, int result,
1308 const struct GNUNET_CRYPTO_EddsaPublicKey *home_pub_key,
1309 uint64_t max_message_id)
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));
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);
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);
1337 GNUNET_SOCIAL_place_msg_proc_set (hst_plc, "_converse",
1338 GNUNET_SOCIAL_MSG_PROC_RELAY);
1343 start_app_if_ready ()
1345 if (NULL == identity_host_ego || NULL == identity_guest_ego)
1349 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1350 "starting app...\n");
1351 app = GNUNET_SOCIAL_app_connect (cfg,
1362 identity_ego_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego,
1363 void **ctx, const char *name)
1367 if (ego == identity_host_ego)
1369 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1370 "Host ego deleted\n");
1372 else if (ego == identity_guest_ego)
1374 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1375 "Guest ego deleted\n");
1377 else if (0 == strcmp (name, host_name))
1379 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1382 identity_host_ego = ego;
1383 start_app_if_ready ();
1385 else if (0 == strcmp (name, guest_name))
1387 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1388 "Created guest ego %s\n",
1390 identity_guest_ego = ego;
1391 start_app_if_ready ();
1398 * Main function of the test, run from scheduler.
1401 * @param cfg configuration we use (also to connect to Social service)
1402 * @param peer handle to access more of the peer (not used)
1405 #if DEBUG_TEST_SOCIAL
1406 run (void *cls, char *const *args, const char *cfgfile,
1407 const struct GNUNET_CONFIGURATION_Handle *c)
1410 const struct GNUNET_CONFIGURATION_Handle *c,
1411 struct GNUNET_TESTING_Peer *peer)
1416 end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
1418 GNUNET_SCHEDULER_add_shutdown (&end_shutdown,
1420 GNUNET_CRYPTO_get_peer_identity (cfg, &this_peer);
1422 id = GNUNET_IDENTITY_connect (cfg, &identity_ego_cb, NULL);
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);
1431 main (int argc, char *argv[])
1434 #if DEBUG_TEST_SOCIAL
1435 const struct GNUNET_GETOPT_CommandLineOption opts[] = {
1436 GNUNET_GETOPT_OPTION_END
1438 if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "test-social",
1439 "test-social [options]",
1443 if (0 != GNUNET_TESTING_peer_run ("test-social", "test_social.conf", &run, NULL))
1449 /* end of test_social.c */