summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpyruvate <d.pyruvate.kinase@gmail.com>2014-08-08 15:40:21 +0300
committerpyruvate <d.pyruvate.kinase@gmail.com>2014-08-09 11:33:20 +0300
commita460b9fbd0bd262b7e9c6d2b3f8d835a6b973093 (patch)
tree508b6eee0524725065cb610ee1388982e1d78d4c
parentec9082f2c382741c07fdbd81ed7362a99c747256 (diff)
Added tests for addto_lists function
-rw-r--r--auto_tests/Makefile.inc10
-rw-r--r--auto_tests/dht_test.c349
2 files changed, 357 insertions, 2 deletions
diff --git a/auto_tests/Makefile.inc b/auto_tests/Makefile.inc
index ecf3f31f..c68f313b 100644
--- a/auto_tests/Makefile.inc
+++ b/auto_tests/Makefile.inc
@@ -1,7 +1,7 @@
1if BUILD_TESTS 1if BUILD_TESTS
2 2
3TESTS = messenger_autotest crypto_test network_test assoc_test onion_test TCP_test tox_test 3TESTS = messenger_autotest crypto_test network_test assoc_test onion_test TCP_test tox_test dht_autotest
4check_PROGRAMS = messenger_autotest crypto_test network_test assoc_test onion_test TCP_test tox_test 4check_PROGRAMS = messenger_autotest crypto_test network_test assoc_test onion_test TCP_test tox_test dht_autotest
5 5
6AUTOTEST_CFLAGS = \ 6AUTOTEST_CFLAGS = \
7 $(LIBSODIUM_CFLAGS) \ 7 $(LIBSODIUM_CFLAGS) \
@@ -74,6 +74,12 @@ tox_test_CFLAGS = $(AUTOTEST_CFLAGS)
74tox_test_LDADD = $(AUTOTEST_LDADD) 74tox_test_LDADD = $(AUTOTEST_LDADD)
75 75
76 76
77dht_autotest_SOURCES = ../auto_tests/dht_test.c
78
79dht_autotest_CFLAGS = $(AUTOTEST_CFLAGS)
80
81dht_autotest_LDADD = $(AUTOTEST_LDADD)
82
77 83
78if BUILD_AV 84if BUILD_AV
79toxav_basic_test_SOURCES = ../auto_tests/toxav_basic_test.c 85toxav_basic_test_SOURCES = ../auto_tests/toxav_basic_test.c
diff --git a/auto_tests/dht_test.c b/auto_tests/dht_test.c
new file mode 100644
index 00000000..a5a97233
--- /dev/null
+++ b/auto_tests/dht_test.c
@@ -0,0 +1,349 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <sys/param.h>
6#include <time.h>
7
8#include "../toxcore/tox.h"
9#include "../toxcore/DHT.c"
10
11#include "helpers.h"
12
13#define swap(x,y) do \
14 { unsigned char swap_temp[sizeof(x) == sizeof(y) ? (signed)sizeof(x) : -1]; \
15 memcpy(swap_temp,&y,sizeof(x)); \
16 memcpy(&y,&x, sizeof(x)); \
17 memcpy(&x,swap_temp,sizeof(x)); \
18 } while(0)
19
20
21void mark_bad(IPPTsPng *ipptp)
22{
23 ipptp->timestamp = unix_time() - 2 * BAD_NODE_TIMEOUT;
24 ipptp->hardening.routes_requests_ok = 0;
25 ipptp->hardening.send_nodes_ok = 0;
26 ipptp->hardening.testing_requests = 0;
27}
28
29void mark_possible_bad(IPPTsPng *ipptp)
30{
31 ipptp->timestamp = unix_time();
32 ipptp->hardening.routes_requests_ok = 0;
33 ipptp->hardening.send_nodes_ok = 0;
34 ipptp->hardening.testing_requests = 0;
35}
36
37void mark_good(IPPTsPng *ipptp)
38{
39 ipptp->timestamp = unix_time();
40 ipptp->hardening.routes_requests_ok = (HARDENING_ALL_OK >> 0) & 1;
41 ipptp->hardening.send_nodes_ok = (HARDENING_ALL_OK >> 1) & 1;
42 ipptp->hardening.testing_requests = (HARDENING_ALL_OK >> 2) & 1;
43}
44
45void mark_all_good(Client_data *list, uint32_t length, uint8_t ipv6)
46{
47 int i;
48 for (i = 0; i < length; ++i) {
49 if (ipv6)
50 mark_good(&list[i].assoc6);
51 else
52 mark_good(&list[i].assoc4);
53 }
54}
55
56/* Returns 1 if client_id has a furthest distance to comp_client_id
57 than all client_id's in the list */
58uint8_t is_furthest(const uint8_t *comp_client_id, Client_data *list, uint32_t length, const uint8_t *client_id)
59{
60 int i;
61 for (i = 0; i < length; ++i)
62 if (id_closest(comp_client_id, client_id, list[i].client_id) == 1)
63 return 0;
64 return 1;
65}
66
67int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id)
68{
69 int i;
70 for (i = 0; i < length; ++i)
71 if (id_equal(client_id, list[i].client_id))
72 return i;
73 return -1;
74}
75
76void test_addto_lists_update(DHT *dht,
77 Client_data *list,
78 uint32_t length,
79 IP_Port *ip_port)
80{
81 int used, test = rand() % length, test1 = rand() % (length / 2), test2 = rand() % (length / 2) + length / 2;
82 uint8_t test_id[CLIENT_ID_SIZE];
83 IP_Port test_ipp;
84 uint8_t ipv6 = ip_port->ip.family == AF_INET6 ? 1 : 0;
85
86 ipport_copy(&test_ipp, ipv6 ? &list[test].assoc6.ip_port : &list[test].assoc4.ip_port);
87
88 // check id update for existing ip_port
89 randombytes(test_id, sizeof(test_id));
90 used = addto_lists(dht, test_ipp, test_id);
91 ck_assert_msg(used >= 1, "Wrong number of added clients");
92 ck_assert_msg(client_in_list(list, length, test_id) == test, "Client id is not in the list");
93 ck_assert_msg(ipport_equal(&test_ipp, ipv6 ? &list[test].assoc6.ip_port : &list[test].assoc4.ip_port), "Client IP_Port is incorrect");
94
95 // check ip_port update for existing id
96 test_ipp.port = rand() % TOX_PORT_DEFAULT;
97 used = addto_lists(dht, test_ipp, test_id);
98 ck_assert_msg(used >= 1, "Wrong number of added clients");
99 ck_assert_msg(client_in_list(list, length, test_id) == test, "Client id is not in the list");
100 ck_assert_msg(ipport_equal(&test_ipp, ipv6 ? &list[test].assoc6.ip_port : &list[test].assoc4.ip_port), "Client IP_Port is incorrect");
101
102 // check ip_port update for existing id and ip_port (... port ... id ...)
103 ipport_copy(&test_ipp, ipv6 ? &list[test1].assoc6.ip_port : &list[test1].assoc4.ip_port);
104 id_copy(test_id, list[test2].client_id);
105 if (ipv6) list[test2].assoc6.ip_port.port = -1; else list[test2].assoc4.ip_port.port = -1;
106 used = addto_lists(dht, test_ipp, test_id);
107 ck_assert_msg(used >= 1, "Wrong number of added clients");
108 ck_assert_msg(client_in_list(list, length, test_id) == test2, "Client id is not in the list");
109 ck_assert_msg(ipport_equal(&test_ipp, ipv6 ? &list[test2].assoc6.ip_port : &list[test2].assoc4.ip_port), "Client IP_Port is incorrect");
110
111 // check ip_port update for existing id and ip_port (... id ... port ...)
112 ipport_copy(&test_ipp, ipv6 ? &list[test2].assoc6.ip_port : &list[test2].assoc4.ip_port);
113 id_copy(test_id, list[test1].client_id);
114 if (ipv6) list[test1].assoc6.ip_port.port = -1; else list[test1].assoc4.ip_port.port = -1;
115 used = addto_lists(dht, test_ipp, test_id);
116 ck_assert_msg(used >= 1, "Wrong number of added clients");
117 ck_assert_msg(client_in_list(list, length, test_id) == test1, "Client id is not in the list");
118 ck_assert_msg(ipport_equal(&test_ipp, ipv6 ? &list[test1].assoc6.ip_port : &list[test1].assoc4.ip_port), "Client IP_Port is incorrect");
119}
120
121void test_addto_lists_bad(DHT *dht,
122 Client_data *list,
123 uint32_t length,
124 IP_Port *ip_port)
125{
126 // check "bad" clients replacement
127 uint8_t client_id[CLIENT_ID_SIZE], test_id1[CLIENT_ID_SIZE], test_id2[CLIENT_ID_SIZE], test_id3[CLIENT_ID_SIZE];
128 int test1, test2, test3;
129 uint8_t ipv6 = ip_port->ip.family == AF_INET6 ? 1 : 0;
130
131 randombytes(client_id, sizeof(client_id));
132 mark_all_good(list, length, ipv6);
133
134 test1 = rand() % (length / 3);
135 test2 = rand() % (length / 3) + length / 3;
136 test3 = rand() % (length / 3) + 2 * length / 3;
137 ck_assert_msg(!(test1 == test2 || test1 == test3 || test2 == test3), "Wrong test indices are chosen");
138
139 id_copy((uint8_t*)&test_id1, list[test1].client_id);
140 id_copy((uint8_t*)&test_id2, list[test2].client_id);
141 id_copy((uint8_t*)&test_id3, list[test3].client_id);
142
143 // mark nodes as "bad"
144 if (ipv6) {
145 mark_bad(&list[test1].assoc6);
146 mark_bad(&list[test2].assoc6);
147 mark_bad(&list[test3].assoc6);
148 } else {
149 mark_bad(&list[test1].assoc4);
150 mark_bad(&list[test2].assoc4);
151 mark_bad(&list[test3].assoc4);
152 }
153
154 ip_port->port += 1;
155 int used = addto_lists(dht, *ip_port, client_id);
156 ck_assert_msg(used >= 1, "Wrong number of added clients");
157
158 ck_assert_msg(client_in_list(list, length, client_id) >= 0, "Client id is not in the list");
159 ck_assert_msg(id_equal(client_id, list[test1].client_id), "Wrong bad client removed");
160 ck_assert_msg(id_equal(test_id2, list[test2].client_id), "Wrong bad client removed");
161 ck_assert_msg(id_equal(test_id3, list[test3].client_id), "Wrong bad client removed");
162}
163
164void test_addto_lists_possible_bad(DHT *dht,
165 Client_data *list,
166 uint32_t length,
167 IP_Port *ip_port,
168 const uint8_t *comp_client_id)
169{
170 // check "possibly bad" clients replacement
171 uint8_t client_id[CLIENT_ID_SIZE], test_id1[CLIENT_ID_SIZE], test_id2[CLIENT_ID_SIZE], test_id3[CLIENT_ID_SIZE];
172 int test1, test2, test3;
173 uint8_t ipv6 = ip_port->ip.family == AF_INET6 ? 1 : 0;
174
175 randombytes(client_id, sizeof(client_id));
176 mark_all_good(list, length, ipv6);
177
178 test1 = rand() % (length / 3);
179 test2 = rand() % (length / 3) + length / 3;
180 test3 = rand() % (length / 3) + 2 * length / 3;
181 ck_assert_msg(!(test1 == test2 || test1 == test3 || test2 == test3), "Wrong test indices are chosen");
182
183 id_copy((uint8_t*)&test_id1, list[test1].client_id);
184 id_copy((uint8_t*)&test_id2, list[test2].client_id);
185 id_copy((uint8_t*)&test_id3, list[test3].client_id);
186
187 // mark nodes as "possibly bad"
188 if (ipv6) {
189 mark_possible_bad(&list[test1].assoc6);
190 mark_possible_bad(&list[test2].assoc6);
191 mark_possible_bad(&list[test3].assoc6);
192 } else {
193 mark_possible_bad(&list[test1].assoc4);
194 mark_possible_bad(&list[test2].assoc4);
195 mark_possible_bad(&list[test3].assoc4);
196 }
197
198 ip_port->port += 1;
199 int used = addto_lists(dht, *ip_port, client_id);
200 ck_assert_msg(used >= 1, "Wrong number of added clients");
201
202 ck_assert_msg(client_in_list(list, length, client_id) >= 0, "Client id is not in the list");
203
204 int inlist_id1 = client_in_list(list, length, test_id1) >= 0;
205 int inlist_id2 = client_in_list(list, length, test_id2) >= 0;
206 int inlist_id3 = client_in_list(list, length, test_id3) >= 0;
207
208 ck_assert_msg(inlist_id1 + inlist_id2 + inlist_id3 == 2, "Wrong client removed");
209
210 if (!inlist_id1) {
211 ck_assert_msg(id_closest(comp_client_id, test_id2, test_id1) == 1, "Id has been removed but is closer to than another one");
212 ck_assert_msg(id_closest(comp_client_id, test_id3, test_id1) == 1, "Id has been removed but is closer to than another one");
213 } else if (!inlist_id2) {
214 ck_assert_msg(id_closest(comp_client_id, test_id1, test_id2) == 1, "Id has been removed but is closer to than another one");
215 ck_assert_msg(id_closest(comp_client_id, test_id3, test_id2) == 1, "Id has been removed but is closer to than another one");
216 } else if (!inlist_id3) {
217 ck_assert_msg(id_closest(comp_client_id, test_id1, test_id3) == 1, "Id has been removed but is closer to than another one");
218 ck_assert_msg(id_closest(comp_client_id, test_id2, test_id3) == 1, "Id has been removed but is closer to than another one");
219 }
220}
221
222void test_addto_lists_good(DHT *dht,
223 Client_data *list,
224 uint32_t length,
225 IP_Port *ip_port,
226 const uint8_t *comp_client_id)
227{
228 uint8_t client_id[CLIENT_ID_SIZE];
229 uint8_t ipv6 = ip_port->ip.family == AF_INET6 ? 1 : 0;
230
231 mark_all_good(list, length, ipv6);
232
233 // check "good" client id replacement
234 do {
235 randombytes(client_id, sizeof(client_id));
236 } while (is_furthest(comp_client_id, list, length, client_id));
237 ip_port->port += 1;
238 addto_lists(dht, *ip_port, client_id);
239 ck_assert_msg(client_in_list(list, length, client_id) >= 0, "Good client id is not in the list");
240
241 // check "good" client id skip
242 do {
243 randombytes(client_id, sizeof(client_id));
244 } while (!is_furthest(comp_client_id, list, length, client_id));
245
246 ip_port->port += 1;
247 addto_lists(dht, *ip_port, client_id);
248 ck_assert_msg(client_in_list(list, length, client_id) == -1, "Good client id is in the list");
249}
250
251void test_addto_lists(IP ip)
252{
253 Networking_Core* net = new_networking(ip, TOX_PORT_DEFAULT);
254 ck_assert_msg(net != 0, "Failed to create Networking_Core");
255
256 DHT* dht = new_DHT(net);
257 ck_assert_msg(dht != 0, "Failed to create DHT");
258
259 IP_Port ip_port = { .ip = ip, .port = TOX_PORT_DEFAULT };
260 uint8_t client_id[CLIENT_ID_SIZE];
261 int i;
262
263 // check lists filling
264 for (i = 0; i < MAX(LCLIENT_LIST, MAX_FRIEND_CLIENTS); ++i) {
265 randombytes(client_id, sizeof(client_id));
266 int used = addto_lists(dht, ip_port, client_id);
267 ck_assert_msg(used == dht->num_friends + 1, "Wrong number of added clients with existing ip_port");
268 }
269
270 for (i = 0; i < MAX(LCLIENT_LIST, MAX_FRIEND_CLIENTS); ++i) {
271 ip_port.port += 1;
272 int used = addto_lists(dht, ip_port, client_id);
273 ck_assert_msg(used == dht->num_friends + 1, "Wrong number of added clients with existing client_id");
274 }
275
276 for (i = 0; i < MAX(LCLIENT_LIST, MAX_FRIEND_CLIENTS); ++i) {
277 ip_port.port += 1;
278 randombytes(client_id, sizeof(client_id));
279 int used = addto_lists(dht, ip_port, client_id);
280 ck_assert_msg(used >= 1, "Wrong number of added clients");
281 }
282
283 /*check: Current behavior if there are two clients with the same id is
284 * to replace the first ip by the second. */
285 test_addto_lists_update(dht, dht->close_clientlist, LCLIENT_LIST, &ip_port);
286 for (i = 0; i < dht->num_friends; ++i)
287 test_addto_lists_update(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &ip_port);
288
289 // check "bad" entries
290 test_addto_lists_bad(dht, dht->close_clientlist, LCLIENT_LIST, &ip_port);
291 for (i = 0; i < dht->num_friends; ++i)
292 test_addto_lists_bad(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &ip_port);
293
294 // check "possibly bad" entries
295 test_addto_lists_possible_bad(dht, dht->close_clientlist, LCLIENT_LIST, &ip_port, dht->self_public_key);
296 // for (i = 0; i < dht->num_friends; ++i)
297 // test_addto_lists_possible_bad(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &ip_port, dht->friends_list[i].client_id);
298
299 // check "good" entries
300 test_addto_lists_good(dht, dht->close_clientlist, LCLIENT_LIST, &ip_port, dht->self_public_key);
301 for (i = 0; i < dht->num_friends; ++i)
302 test_addto_lists_good(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &ip_port, dht->friends_list[i].client_id);
303
304 kill_DHT(dht);
305 kill_networking(net);
306}
307
308START_TEST(test_addto_lists_ipv4)
309{
310 IP ip;
311 ip_init(&ip, 0);
312 test_addto_lists(ip);
313
314}
315END_TEST
316
317START_TEST(test_addto_lists_ipv6)
318{
319 IP ip;
320 ip_init(&ip, 1);
321 test_addto_lists(ip);
322
323}
324END_TEST
325
326Suite *dht_suite(void)
327{
328 Suite *s = suite_create("DHT");
329
330 DEFTESTCASE(addto_lists_ipv4);
331 DEFTESTCASE(addto_lists_ipv6);
332 return s;
333}
334
335int main(int argc, char *argv[])
336{
337 srand((unsigned int) time(NULL));
338
339 Suite *dht = dht_suite();
340 SRunner *test_runner = srunner_create(dht);
341
342 int number_failed = 0;
343 srunner_run_all(test_runner, CK_NORMAL);
344 number_failed = srunner_ntests_failed(test_runner);
345
346 srunner_free(test_runner);
347
348 return number_failed;
349}