Merge branch 'master' of gnunet.org:gnunet
[oweals/gnunet.git] / src / peerinfo / perf_peerinfo_api.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2004, 2009, 2010, 2017 GNUnet e.V.
4
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.
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      Affero General Public License for more details.
14     
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /**
20  * @file peerinfo/perf_peerinfo_api.c
21  * @brief testcase for peerinfo_api.c, hopefully hammer the peerinfo service,
22  * this performance test adds up to 5000 peers with one address each and checks
23  * over how many peers it can iterate before receiving a timeout after 5 seconds
24  * @author Nathan Evans
25  */
26
27 #include "platform.h"
28 #include "gnunet_hello_lib.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_testing_lib.h"
31 #include "gnunet_peerinfo_service.h"
32 #include "peerinfo.h"
33 #include <gauger.h>
34
35 #define NUM_REQUESTS 5000
36
37 static struct GNUNET_PEERINFO_IteratorContext *ic[NUM_REQUESTS];
38
39 static struct GNUNET_PEERINFO_Handle *h;
40
41 static unsigned int numpeers;
42
43 static struct GNUNET_PeerIdentity pid;
44
45 static struct GNUNET_SCHEDULER_Task *tt;
46
47
48 static void
49 do_shutdown (void *cls)
50 {
51   if (NULL != tt)
52   {
53     GNUNET_SCHEDULER_cancel (tt);
54     tt = NULL;
55   }
56   for (unsigned int i = 0; i < NUM_REQUESTS; i++)
57     if (NULL != ic[i])
58       GNUNET_PEERINFO_iterate_cancel (ic[i]);
59   GNUNET_PEERINFO_disconnect (h);
60   h = NULL;
61 }
62
63
64 static void
65 do_timeout (void *cls)
66 {
67   tt = NULL;
68   GNUNET_SCHEDULER_shutdown ();
69 }
70
71
72 static int
73 check_it (void *cls,
74           const struct GNUNET_HELLO_Address *address,
75           struct GNUNET_TIME_Absolute expiration)
76 {
77   return GNUNET_OK;
78 }
79
80
81 static ssize_t
82 address_generator (void *cls, size_t max, void *buf)
83 {
84   size_t *agc = cls;
85   ssize_t ret;
86   char *caddress;
87   struct GNUNET_HELLO_Address address;
88
89   if (*agc == 0)
90     return GNUNET_SYSERR; /* Done */
91
92   GNUNET_asprintf (&caddress, "Address%d", *agc);
93   address.peer = pid;
94   address.address_length = strlen (caddress) + 1;
95   address.address = caddress;
96   address.transport_name = "peerinfotest";
97   ret =
98       GNUNET_HELLO_add_address (&address,
99                                 GNUNET_TIME_relative_to_absolute
100                                 (GNUNET_TIME_UNIT_HOURS), buf, max);
101   GNUNET_free (caddress);
102   *agc = 0;
103   return ret;
104 }
105
106
107 static void
108 add_peer (size_t i)
109 {
110   struct GNUNET_HELLO_Message *h2;
111
112   memset (&pid, i, sizeof (pid));
113   h2 = GNUNET_HELLO_create (&pid.public_key,
114                             &address_generator,
115                             &i,
116                             GNUNET_NO);
117   GNUNET_PEERINFO_add_peer (h, h2, NULL, NULL);
118   GNUNET_free (h2);
119 }
120
121
122 static void
123 process (void *cls,
124          const struct GNUNET_PeerIdentity *peer,
125          const struct GNUNET_HELLO_Message *hello,
126          const char *err_msg)
127 {
128   struct GNUNET_PEERINFO_IteratorContext **icp = cls;
129
130   if (NULL == peer)
131   {
132     *icp = NULL;
133     return;
134   }
135   numpeers++;
136   if (0 && (NULL != hello) )
137     GNUNET_HELLO_iterate_addresses (hello,
138                                     GNUNET_NO,
139                                     &check_it,
140                                     NULL);
141 }
142
143
144 static void
145 run (void *cls,
146      const struct GNUNET_CONFIGURATION_Handle *cfg,
147      struct GNUNET_TESTING_Peer *peer)
148 {
149   h = GNUNET_PEERINFO_connect (cfg);
150   GNUNET_assert (h != NULL);
151   for (unsigned int i = 0; i < NUM_REQUESTS; i++)
152   {
153     add_peer (i);
154     ic[i] = GNUNET_PEERINFO_iterate (h,
155                                      GNUNET_YES,
156                                      NULL,
157                                      &process,
158                                      &ic[i]);
159   }
160   tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
161                                                                     5),
162                                      &do_timeout,
163                                      NULL);
164   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
165                                  NULL);
166 }
167
168
169 int
170 main (int argc,
171       char *argv[])
172 {
173   if (0 != GNUNET_TESTING_service_run ("perf-gnunet-peerinfo",
174                                        "peerinfo",
175                                        "test_peerinfo_api_data.conf",
176                                        &run, NULL))
177     return 1;
178   FPRINTF (stderr,
179            "Received %u/%u calls before timeout\n",
180            numpeers,
181            NUM_REQUESTS * NUM_REQUESTS / 2);
182   GAUGER ("PEERINFO",
183           "Peerinfo lookups",
184           numpeers / 5,
185           "peers/s");
186   return 0;
187 }
188
189 /* end of perf_peerinfo_api.c */