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