update test_psyc_api_join
[oweals/gnunet.git] / src / psyc / test_psyc_api_join.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 /**
22  * @file psyc/test_psyc_api_join.c
23  * @brief Testbed test for the PSYC API.
24  * @author xrs
25  */
26
27 /**
28  * Lessons Learned:
29  * - define topology in config
30  * - psyc slave join needs part to end (same with master)
31  * - GNUNET_SCHEDULER_add_delayed return value will outdate at call time
32  * - main can not contain GNUNET_log()
33  */
34
35 #include "platform.h"
36 #include "gnunet_crypto_lib.h"
37 #include "gnunet_common.h"
38 #include "gnunet_util_lib.h"
39 #include "gnunet_testbed_service.h"
40 #include "gnunet_psyc_util_lib.h"
41 #include "gnunet_psyc_service.h"
42 #include "psyc_test_lib.h"
43
44 static struct pctx PEERS[2];
45
46 static int pids;
47
48
49 static void 
50 shutdown_task (void *cls)
51 {
52   if (NULL != timeout_task_id) {
53     GNUNET_SCHEDULER_cancel (timeout_task_id);
54     timeout_task_id = NULL;
55   }
56
57   for (int i=0;i<2;i++) {
58     GNUNET_free (PEERS[i].channel_pub_key);
59
60     if (NULL != PEERS[i].psyc)
61     {
62       if (0 == i) 
63         GNUNET_PSYC_master_stop (PEERS[i].psyc, GNUNET_NO, NULL, NULL);
64       else 
65         GNUNET_PSYC_slave_part (PEERS[i].psyc, GNUNET_NO, NULL, NULL);
66     }
67   }
68
69   for (int i=0;i<MAX_TESTBED_OPS;i++)
70     if (NULL != op[i])
71       GNUNET_TESTBED_operation_done (op[i]);
72
73   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shut down!\n");
74 }
75
76 static void
77 timeout_task (void *cls)
78 {
79   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Timeout!\n");
80
81   timeout_task_id = NULL;
82
83   result = GNUNET_SYSERR;
84   GNUNET_SCHEDULER_shutdown ();
85 }
86
87 static void
88 join_decision_cb (void *cls,
89                   const struct GNUNET_PSYC_JoinDecisionMessage *dcsn,
90                   int is_admitted,
91                   const struct GNUNET_PSYC_Message *join_msg)
92 {
93   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
94               "slave: got join decision: %s\n", 
95               (GNUNET_YES == is_admitted) ? "admitted":"rejected");
96
97   result = (GNUNET_YES == is_admitted) ? GNUNET_OK : GNUNET_SYSERR;
98
99   GNUNET_SCHEDULER_shutdown ();
100 }
101
102 static void
103 join_request_cb (void *cls,
104                  const struct GNUNET_PSYC_JoinRequestMessage *req,
105                  const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
106                  const struct GNUNET_PSYC_Message *join_msg,
107                  struct GNUNET_PSYC_JoinHandle *jh)
108 {
109   struct GNUNET_HashCode slave_key_hash;
110
111   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "master: got join request.\n");
112
113   GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash);
114
115   GNUNET_PSYC_join_decision (jh, GNUNET_YES, 0, NULL, NULL);
116 }
117
118 static void
119 psyc_da ()
120 {
121   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "disconnect form PSYC service\n");
122 }
123
124 static void *
125 psyc_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) 
126 {
127   struct pctx *peer = (struct pctx*) cls;
128
129   // Case: master role
130   if (0 == peer->idx) {
131     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to PSYC as master ...\n");
132
133     peer->psyc = (struct GNUNET_PSYC_Master *) 
134       GNUNET_PSYC_master_start (cfg,
135                                 peer->channel_key,
136                                 GNUNET_PSYC_CHANNEL_PRIVATE,
137                                 NULL,
138                                 join_request_cb,
139                                 NULL,
140                                 NULL,
141                                 cls);
142     return peer->psyc;
143   }
144
145   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to PSYC as slave ...\n");
146
147   struct GNUNET_PSYC_Environment *env = GNUNET_PSYC_env_create ();
148   GNUNET_PSYC_env_add (env, GNUNET_PSYC_OP_ASSIGN, "_foo", "bar baz", 7);
149   GNUNET_PSYC_env_add (env, GNUNET_PSYC_OP_ASSIGN, "_foo_bar", "foo bar baz", 11);
150
151   struct GNUNET_PSYC_Message *
152     join_msg = GNUNET_PSYC_message_create ("_request_join", env, "some data", 40);
153
154   peer->psyc = (struct GNUNET_PSYC_Slave *)
155     GNUNET_PSYC_slave_join (cfg,
156                             peer->channel_pub_key,
157                             peer->id_key,
158                             GNUNET_PSYC_SLAVE_JOIN_NONE,
159                             peer->peer_id_master, 
160                             0,
161                             NULL,
162                             NULL,
163                             NULL,
164                             NULL,
165                             join_decision_cb,
166                             cls,
167                             join_msg);
168
169   GNUNET_free (join_msg);
170   peer->channel = GNUNET_PSYC_slave_get_channel (peer->psyc);
171   GNUNET_PSYC_env_destroy (env);
172
173   return peer->psyc;
174 }
175
176 static void
177 service_connect (void *cls,
178                  struct GNUNET_TESTBED_Operation *op,
179                  void *ca_result,
180                  const char *emsg)
181 {
182   GNUNET_assert (NULL != ca_result);
183
184   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to the service\n");
185 }
186
187 static void 
188 connect_to_services (void *cls)
189 {
190   for (int i = 0; i < 2; i++)
191   {
192     PEERS[i].peer_id_master = PEERS[0].peer_id;
193
194     op[op_cnt++] = 
195       GNUNET_TESTBED_service_connect (NULL, PEERS[i].testbed_peer, "psyc", 
196                                       &service_connect, &PEERS[i], &psyc_ca, 
197                                       &psyc_da, &PEERS[i]);
198   }
199 }
200
201 static void
202 pinfo_cb (void *cls,
203           struct GNUNET_TESTBED_Operation *operation,
204           const struct GNUNET_TESTBED_PeerInformation *pinfo,
205           const char *emsg)
206 {
207   struct pctx *peer = (struct pctx*) cls;
208
209   peer->peer_id = pinfo->result.id;
210
211   pids++;
212   if (pids < 2)
213     return;
214   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got all IDs, starting test\n");
215
216   GNUNET_SCHEDULER_add_now (&connect_to_services, NULL);
217 }
218
219 static void
220 testbed_master (void *cls,
221      struct GNUNET_TESTBED_RunHandle *h,
222      unsigned int num_peers,
223      struct GNUNET_TESTBED_Peer **p,
224      unsigned int links_succeeded,
225      unsigned int links_failed)
226 {
227   struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key = NULL;
228
229   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to testbed_master\n");
230
231   // Set up shutdown logic
232   GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); 
233   timeout_task_id = 
234     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 15),
235                                   &timeout_task, NULL);
236   GNUNET_assert (NULL != timeout_task_id);
237
238   // Set up channel key
239   channel_key = GNUNET_CRYPTO_eddsa_key_create ();
240   GNUNET_assert (NULL != channel_key);
241   
242   // Set up information contexts for peers
243   for (int i=0 ; i < 2 ; i++)
244   {
245     PEERS[i].idx = i;
246     PEERS[i].testbed_peer = p[i];
247
248     // Create "egos"
249     PEERS[i].id_key = GNUNET_CRYPTO_ecdsa_key_create ();
250
251     // Set up channel keys shared by master and slave
252     PEERS[i].channel_key = channel_key; 
253
254     PEERS[i].channel_pub_key = 
255       GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
256     // Get public key 
257     GNUNET_CRYPTO_eddsa_key_get_public (PEERS[i].channel_key, 
258                                         PEERS[i].channel_pub_key);
259     // Get peerinfo
260     op[op_cnt++] = 
261       GNUNET_TESTBED_peer_get_information (p[i], 
262                                            GNUNET_TESTBED_PIT_IDENTITY, 
263                                            pinfo_cb, &PEERS[i]);
264   }
265 }
266
267 int 
268 main (int argc, char *argv[])
269 {
270   int ret; 
271
272   ret = GNUNET_TESTBED_test_run ("test_psyc_api_join", "test_psyc.conf",
273                                  2, 0LL, NULL, NULL, 
274                                  &testbed_master, NULL);
275
276   if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
277     return 1;
278
279   return 0;
280 }
281
282 /* end of test_psyc_api_join.c */