dirvote: Handling adding vote and signature if module is disabled
[tor.git] / src / test / test_geoip.c
blob0711a113eb418fc7c1e09e8f22fd169ef32535f0
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2018, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 #include "orconfig.h"
8 /* These macros pull in declarations for some functions and structures that
9 * are typically file-private. */
10 #define GEOIP_PRIVATE
11 #include "or.h"
12 #include "config.h"
13 #include "geoip.h"
14 #include "test.h"
16 /* Record odd numbered fake-IPs using ipv6, even numbered fake-IPs
17 * using ipv4. Since our fake geoip database is the same between
18 * ipv4 and ipv6, we should get the same result no matter which
19 * address family we pick for each IP. */
20 #define SET_TEST_ADDRESS(i) do { \
21 if ((i) & 1) { \
22 SET_TEST_IPV6(i); \
23 tor_addr_from_in6(&addr, &in6); \
24 } else { \
25 tor_addr_from_ipv4h(&addr, (uint32_t) i); \
26 } \
27 } while (0)
29 /* Make sure that country ID actually works. */
30 #define SET_TEST_IPV6(i) \
31 do { \
32 set_uint32(in6.s6_addr + 12, htonl((uint32_t) (i))); \
33 } while (0)
34 #define CHECK_COUNTRY(country, val) do { \
35 /* test ipv4 country lookup */ \
36 tt_str_op(country, OP_EQ, \
37 geoip_get_country_name(geoip_get_country_by_ipv4(val))); \
38 /* test ipv6 country lookup */ \
39 SET_TEST_IPV6(val); \
40 tt_str_op(country, OP_EQ, \
41 geoip_get_country_name(geoip_get_country_by_ipv6(&in6))); \
42 } while (0)
44 /** Run unit tests for GeoIP code. */
45 static void
46 test_geoip(void *arg)
48 int i, j;
49 time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
50 char *s = NULL, *v = NULL;
51 const char *bridge_stats_1 =
52 "bridge-stats-end 2010-08-12 13:27:30 (86400 s)\n"
53 "bridge-ips zz=24,xy=8\n"
54 "bridge-ip-versions v4=16,v6=16\n"
55 "bridge-ip-transports <OR>=24\n",
56 *dirreq_stats_1 =
57 "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
58 "dirreq-v3-ips ab=8\n"
59 "dirreq-v3-reqs ab=8\n"
60 "dirreq-v3-resp ok=0,not-enough-sigs=0,unavailable=0,not-found=0,"
61 "not-modified=0,busy=0\n"
62 "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
63 "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
64 *dirreq_stats_2 =
65 "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
66 "dirreq-v3-ips \n"
67 "dirreq-v3-reqs \n"
68 "dirreq-v3-resp ok=0,not-enough-sigs=0,unavailable=0,not-found=0,"
69 "not-modified=0,busy=0\n"
70 "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
71 "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
72 *dirreq_stats_3 =
73 "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
74 "dirreq-v3-ips \n"
75 "dirreq-v3-reqs \n"
76 "dirreq-v3-resp ok=8,not-enough-sigs=0,unavailable=0,not-found=0,"
77 "not-modified=0,busy=0\n"
78 "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
79 "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
80 *dirreq_stats_4 =
81 "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
82 "dirreq-v3-ips \n"
83 "dirreq-v3-reqs \n"
84 "dirreq-v3-resp ok=8,not-enough-sigs=0,unavailable=0,not-found=0,"
85 "not-modified=0,busy=0\n"
86 "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
87 "dirreq-v3-tunneled-dl complete=0,timeout=0,running=4\n",
88 *entry_stats_1 =
89 "entry-stats-end 2010-08-12 13:27:30 (86400 s)\n"
90 "entry-ips ab=8\n",
91 *entry_stats_2 =
92 "entry-stats-end 2010-08-12 13:27:30 (86400 s)\n"
93 "entry-ips \n";
94 tor_addr_t addr;
95 struct in6_addr in6;
97 /* Populate the DB a bit. Add these in order, since we can't do the final
98 * 'sort' step. These aren't very good IP addresses, but they're perfectly
99 * fine uint32_t values. */
100 (void)arg;
101 tt_int_op(0,OP_EQ, geoip_parse_entry("10,50,AB", AF_INET));
102 tt_int_op(0,OP_EQ, geoip_parse_entry("52,90,XY", AF_INET));
103 tt_int_op(0,OP_EQ, geoip_parse_entry("95,100,AB", AF_INET));
104 tt_int_op(0,OP_EQ, geoip_parse_entry("\"105\",\"140\",\"ZZ\"", AF_INET));
105 tt_int_op(0,OP_EQ, geoip_parse_entry("\"150\",\"190\",\"XY\"", AF_INET));
106 tt_int_op(0,OP_EQ, geoip_parse_entry("\"200\",\"250\",\"AB\"", AF_INET));
108 /* Populate the IPv6 DB equivalently with fake IPs in the same range */
109 tt_int_op(0,OP_EQ, geoip_parse_entry("::a,::32,AB", AF_INET6));
110 tt_int_op(0,OP_EQ, geoip_parse_entry("::34,::5a,XY", AF_INET6));
111 tt_int_op(0,OP_EQ, geoip_parse_entry("::5f,::64,AB", AF_INET6));
112 tt_int_op(0,OP_EQ, geoip_parse_entry("::69,::8c,ZZ", AF_INET6));
113 tt_int_op(0,OP_EQ, geoip_parse_entry("::96,::be,XY", AF_INET6));
114 tt_int_op(0,OP_EQ, geoip_parse_entry("::c8,::fa,AB", AF_INET6));
116 /* We should have 4 countries: ??, ab, xy, zz. */
117 tt_int_op(4,OP_EQ, geoip_get_n_countries());
118 memset(&in6, 0, sizeof(in6));
120 CHECK_COUNTRY("??", 3);
121 CHECK_COUNTRY("ab", 32);
122 CHECK_COUNTRY("??", 5);
123 CHECK_COUNTRY("??", 51);
124 CHECK_COUNTRY("xy", 150);
125 CHECK_COUNTRY("xy", 190);
126 CHECK_COUNTRY("??", 2000);
128 tt_int_op(0,OP_EQ, geoip_get_country_by_ipv4(3));
129 SET_TEST_IPV6(3);
130 tt_int_op(0,OP_EQ, geoip_get_country_by_ipv6(&in6));
132 get_options_mutable()->BridgeRelay = 1;
133 get_options_mutable()->BridgeRecordUsageByCountry = 1;
134 /* Put 9 observations in AB... */
135 for (i=32; i < 40; ++i) {
136 SET_TEST_ADDRESS(i);
137 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200);
139 SET_TEST_ADDRESS(225);
140 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200);
141 /* and 3 observations in XY, several times. */
142 for (j=0; j < 10; ++j)
143 for (i=52; i < 55; ++i) {
144 SET_TEST_ADDRESS(i);
145 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-3600);
147 /* and 17 observations in ZZ... */
148 for (i=110; i < 127; ++i) {
149 SET_TEST_ADDRESS(i);
150 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
152 geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v);
153 tt_assert(s);
154 tt_assert(v);
155 tt_str_op("zz=24,ab=16,xy=8",OP_EQ, s);
156 tt_str_op("v4=16,v6=16",OP_EQ, v);
157 tor_free(s);
158 tor_free(v);
160 /* Now clear out all the AB observations. */
161 geoip_remove_old_clients(now-6000);
162 geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v);
163 tt_assert(s);
164 tt_assert(v);
165 tt_str_op("zz=24,xy=8",OP_EQ, s);
166 tt_str_op("v4=16,v6=16",OP_EQ, v);
167 tor_free(s);
168 tor_free(v);
170 /* Start testing bridge statistics by making sure that we don't output
171 * bridge stats without initializing them. */
172 s = geoip_format_bridge_stats(now + 86400);
173 tt_ptr_op(s, OP_EQ, NULL);
175 /* Initialize stats and generate the bridge-stats history string out of
176 * the connecting clients added above. */
177 geoip_bridge_stats_init(now);
178 s = geoip_format_bridge_stats(now + 86400);
179 tt_assert(s);
180 tt_str_op(bridge_stats_1,OP_EQ, s);
181 tor_free(s);
183 /* Stop collecting bridge stats and make sure we don't write a history
184 * string anymore. */
185 geoip_bridge_stats_term();
186 s = geoip_format_bridge_stats(now + 86400);
187 tt_ptr_op(s, OP_EQ, NULL);
189 /* Stop being a bridge and start being a directory mirror that gathers
190 * directory request statistics. */
191 geoip_bridge_stats_term();
192 get_options_mutable()->BridgeRelay = 0;
193 get_options_mutable()->BridgeRecordUsageByCountry = 0;
194 get_options_mutable()->DirReqStatistics = 1;
196 /* Start testing dirreq statistics by making sure that we don't collect
197 * dirreq stats without initializing them. */
198 SET_TEST_ADDRESS(100);
199 geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
200 s = geoip_format_dirreq_stats(now + 86400);
201 tt_ptr_op(s, OP_EQ, NULL);
203 /* Initialize stats, note one connecting client, and generate the
204 * dirreq-stats history string. */
205 geoip_dirreq_stats_init(now);
206 SET_TEST_ADDRESS(100);
207 geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
208 s = geoip_format_dirreq_stats(now + 86400);
209 tt_str_op(dirreq_stats_1,OP_EQ, s);
210 tor_free(s);
212 /* Stop collecting stats, add another connecting client, and ensure we
213 * don't generate a history string. */
214 geoip_dirreq_stats_term();
215 SET_TEST_ADDRESS(101);
216 geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
217 s = geoip_format_dirreq_stats(now + 86400);
218 tt_ptr_op(s, OP_EQ, NULL);
220 /* Re-start stats, add a connecting client, reset stats, and make sure
221 * that we get an all empty history string. */
222 geoip_dirreq_stats_init(now);
223 SET_TEST_ADDRESS(100);
224 geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
225 geoip_reset_dirreq_stats(now);
226 s = geoip_format_dirreq_stats(now + 86400);
227 tt_str_op(dirreq_stats_2,OP_EQ, s);
228 tor_free(s);
230 /* Note a successful network status response and make sure that it
231 * appears in the history string. */
232 geoip_note_ns_response(GEOIP_SUCCESS);
233 s = geoip_format_dirreq_stats(now + 86400);
234 tt_str_op(dirreq_stats_3,OP_EQ, s);
235 tor_free(s);
237 /* Start a tunneled directory request. */
238 geoip_start_dirreq((uint64_t) 1, 1024, DIRREQ_TUNNELED);
239 s = geoip_format_dirreq_stats(now + 86400);
240 tt_str_op(dirreq_stats_4,OP_EQ, s);
241 tor_free(s);
243 /* Stop collecting directory request statistics and start gathering
244 * entry stats. */
245 geoip_dirreq_stats_term();
246 get_options_mutable()->DirReqStatistics = 0;
247 get_options_mutable()->EntryStatistics = 1;
249 /* Start testing entry statistics by making sure that we don't collect
250 * anything without initializing entry stats. */
251 SET_TEST_ADDRESS(100);
252 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
253 s = geoip_format_entry_stats(now + 86400);
254 tt_ptr_op(s, OP_EQ, NULL);
256 /* Initialize stats, note one connecting client, and generate the
257 * entry-stats history string. */
258 geoip_entry_stats_init(now);
259 SET_TEST_ADDRESS(100);
260 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
261 s = geoip_format_entry_stats(now + 86400);
262 tt_str_op(entry_stats_1,OP_EQ, s);
263 tor_free(s);
265 /* Stop collecting stats, add another connecting client, and ensure we
266 * don't generate a history string. */
267 geoip_entry_stats_term();
268 SET_TEST_ADDRESS(101);
269 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
270 s = geoip_format_entry_stats(now + 86400);
271 tt_ptr_op(s, OP_EQ, NULL);
273 /* Re-start stats, add a connecting client, reset stats, and make sure
274 * that we get an all empty history string. */
275 geoip_entry_stats_init(now);
276 SET_TEST_ADDRESS(100);
277 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
278 geoip_reset_entry_stats(now);
279 s = geoip_format_entry_stats(now + 86400);
280 tt_str_op(entry_stats_2,OP_EQ, s);
281 tor_free(s);
283 /* Test the OOM handler. Add a client, run the OOM. */
284 geoip_entry_stats_init(now);
285 SET_TEST_ADDRESS(100);
286 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL,
287 now - (12 * 60 * 60));
288 /* We've seen this 12 hours ago. Run the OOM, it should clean the entry
289 * because it is above the minimum cutoff of 4 hours. */
290 size_t bytes_removed = geoip_client_cache_handle_oom(now, 1000);
291 tt_size_op(bytes_removed, OP_GT, 0);
293 /* Do it again but this time with an entry with a lower cutoff. */
294 geoip_entry_stats_init(now);
295 SET_TEST_ADDRESS(100);
296 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL,
297 now - (3 * 60 * 60));
298 bytes_removed = geoip_client_cache_handle_oom(now, 1000);
299 tt_size_op(bytes_removed, OP_EQ, 0);
301 /* Stop collecting entry statistics. */
302 geoip_entry_stats_term();
303 get_options_mutable()->EntryStatistics = 0;
305 done:
306 tor_free(s);
307 tor_free(v);
310 static void
311 test_geoip_with_pt(void *arg)
313 time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
314 char *s = NULL;
315 int i;
316 tor_addr_t addr;
317 struct in6_addr in6;
319 (void)arg;
320 get_options_mutable()->BridgeRelay = 1;
321 get_options_mutable()->BridgeRecordUsageByCountry = 1;
323 memset(&in6, 0, sizeof(in6));
325 /* No clients seen yet. */
326 s = geoip_get_transport_history();
327 tor_assert(!s);
329 /* 4 connections without a pluggable transport */
330 for (i=0; i < 4; ++i) {
331 SET_TEST_ADDRESS(i);
332 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200);
335 /* 9 connections with "alpha" */
336 for (i=4; i < 13; ++i) {
337 SET_TEST_ADDRESS(i);
338 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "alpha", now-7200);
341 /* one connection with "beta" */
342 SET_TEST_ADDRESS(13);
343 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "beta", now-7200);
345 /* 14 connections with "charlie" */
346 for (i=14; i < 28; ++i) {
347 SET_TEST_ADDRESS(i);
348 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "charlie", now-7200);
351 /* 131 connections with "ddr" */
352 for (i=28; i < 159; ++i) {
353 SET_TEST_ADDRESS(i);
354 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "ddr", now-7200);
357 /* 8 connections with "entropy" */
358 for (i=159; i < 167; ++i) {
359 SET_TEST_ADDRESS(i);
360 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "entropy", now-7200);
363 /* 2 connections from the same IP with two different transports. */
364 SET_TEST_ADDRESS(++i);
365 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "fire", now-7200);
366 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "google", now-7200);
368 /* Test the transport history string. */
369 s = geoip_get_transport_history();
370 tor_assert(s);
371 tt_str_op(s,OP_EQ, "<OR>=8,alpha=16,beta=8,charlie=16,ddr=136,"
372 "entropy=8,fire=8,google=8");
374 /* Stop collecting entry statistics. */
375 geoip_entry_stats_term();
376 get_options_mutable()->EntryStatistics = 0;
378 done:
379 tor_free(s);
382 #undef SET_TEST_ADDRESS
383 #undef SET_TEST_IPV6
384 #undef CHECK_COUNTRY
386 static void
387 test_geoip_load_file(void *arg)
389 (void)arg;
390 char *contents = NULL;
391 char *dhex = NULL;
393 /* A nonexistant filename should fail. */
394 tt_int_op(-1, OP_EQ,
395 geoip_load_file(AF_INET, "/you/did/not/put/a/file/here/I/hope"));
397 /* We start out with only "Ningunpartia" in the database. */
398 tt_int_op(1, OP_EQ, geoip_get_n_countries());
399 tt_str_op("??", OP_EQ, geoip_get_country_name(0));
400 /* Any lookup attempt should say "-1" because we have no info */
401 tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv4(0x01020304));
402 /* There should be no 'digest' for a nonexistant file */
403 tt_str_op("0000000000000000000000000000000000000000", OP_EQ,
404 geoip_db_digest(AF_INET));
406 const char FNAME[] = SRCDIR "/src/config/geoip";
407 int rv = geoip_load_file(AF_INET, FNAME);
408 if (rv != 0) {
409 TT_GRIPE(("Unable to load geoip from %s", escaped(FNAME)));
411 tt_int_op(0, OP_EQ, rv);
413 /* Check that we loaded some countries; this will fail if there are ever
414 * fewer than 50 countries in the world. */
415 tt_int_op(geoip_get_n_countries(), OP_GE, 50);
417 /* Let's see where 8.8.8.8 is. */
418 int country = geoip_get_country_by_ipv4(0x08080808);
419 tt_int_op(country, OP_GE, 1); /* It shouldn't be 'unknown' or 'nowhere' */
420 const char *cc = geoip_get_country_name(country);
421 tt_int_op(strlen(cc), OP_EQ, 2);
423 /* The digest should be set.... */
424 tt_str_op("0000000000000000000000000000000000000000", OP_NE,
425 geoip_db_digest(AF_INET));
427 /* And it should be set correctly */
428 contents = read_file_to_str(FNAME, RFTS_BIN, NULL);
429 uint8_t d[DIGEST_LEN];
430 crypto_digest((char*)d, contents, strlen(contents));
431 dhex = tor_strdup(hex_str((char*)d, DIGEST_LEN));
432 tt_str_op(dhex, OP_EQ, geoip_db_digest(AF_INET));
434 /* Make sure geoip_free_all() works. */
435 geoip_free_all();
436 tt_int_op(1, OP_EQ, geoip_get_n_countries());
437 tt_str_op("??", OP_EQ, geoip_get_country_name(0));
438 tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv4(0x01020304));
439 tt_str_op("0000000000000000000000000000000000000000", OP_EQ,
440 geoip_db_digest(AF_INET)); // <--- nick bets this will fail.
442 done:
443 tor_free(contents);
444 tor_free(dhex);
447 static void
448 test_geoip6_load_file(void *arg)
450 (void)arg;
451 struct in6_addr iaddr6;
452 char *contents = NULL;
453 char *dhex = NULL;
455 /* A nonexistant filename should fail. */
456 tt_int_op(-1, OP_EQ,
457 geoip_load_file(AF_INET6, "/you/did/not/put/a/file/here/I/hope"));
459 /* Any lookup attempt should say "-1" because we have no info */
460 tor_inet_pton(AF_INET6, "2001:4860:4860::8888", &iaddr6);
461 tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv6(&iaddr6));
463 /* Load geiop6 file */
464 const char FNAME6[] = SRCDIR "/src/config/geoip6";
465 tt_int_op(0, OP_EQ, geoip_load_file(AF_INET6, FNAME6));
467 /* Check that we loaded some countries; this will fail if there are ever
468 * fewer than 50 countries in the world. */
469 tt_int_op(geoip_get_n_countries(), OP_GE, 50);
471 /* Let's see where 2001:4860:4860::8888 (google dns) is. */
472 const char *caddr6 = "2001:4860:4860::8888";
473 tor_inet_pton(AF_INET6, caddr6, &iaddr6);
474 int country6 = geoip_get_country_by_ipv6(&iaddr6);
475 tt_int_op(country6, OP_GE, 1);
477 const char *cc6 = geoip_get_country_name(country6);
478 tt_int_op(strlen(cc6), OP_EQ, 2);
480 /* The digest should be set.... */
481 tt_str_op("0000000000000000000000000000000000000000", OP_NE,
482 geoip_db_digest(AF_INET6));
484 /* And it should be set correctly */
485 contents = read_file_to_str(FNAME6, RFTS_BIN, NULL);
486 uint8_t d[DIGEST_LEN];
487 crypto_digest((char*)d, contents, strlen(contents));
488 dhex = tor_strdup(hex_str((char*)d, DIGEST_LEN));
489 tt_str_op(dhex, OP_EQ, geoip_db_digest(AF_INET6));
491 /* Make sure geoip_free_all() works. */
492 geoip_free_all();
493 tt_int_op(1, OP_EQ, geoip_get_n_countries());
494 tt_str_op("??", OP_EQ, geoip_get_country_name(0));
495 tor_inet_pton(AF_INET6, "::1:2:3:4", &iaddr6);
496 tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv6(&iaddr6));
497 tt_str_op("0000000000000000000000000000000000000000", OP_EQ,
498 geoip_db_digest(AF_INET6));
500 done:
501 tor_free(contents);
502 tor_free(dhex);
505 static void
506 test_geoip_load_2nd_file(void *arg)
508 (void)arg;
510 /* Load 1st geoip file */
511 const char FNAME[] = SRCDIR "/src/config/geoip";
512 tt_int_op(0, OP_EQ, geoip_load_file(AF_INET, FNAME));
514 /* Load 2nd geoip (empty) file */
515 /* It has to be the same IP address family */
516 const char FNAME2[] = SRCDIR "/src/test/geoip_dummy";
517 tt_int_op(0, OP_EQ, geoip_load_file(AF_INET, FNAME2));
519 /* Check that there is no geoip information for 8.8.8.8, */
520 /* since loading the empty 2nd file should have delete it. */
521 int country = geoip_get_country_by_ipv4(0x08080808);
522 tt_int_op(country, OP_EQ, 0);
524 done: ;
527 #define ENT(name) \
528 { #name, test_ ## name , 0, NULL, NULL }
529 #define FORK(name) \
530 { #name, test_ ## name , TT_FORK, NULL, NULL }
532 #ifdef _WIN32
533 #define SKIP_ON_WINDOWS TT_SKIP
534 #else
535 #define SKIP_ON_WINDOWS 0
536 #endif
538 struct testcase_t geoip_tests[] = {
539 { "geoip", test_geoip, TT_FORK, NULL, NULL },
540 { "geoip_with_pt", test_geoip_with_pt, TT_FORK, NULL, NULL },
541 { "load_file", test_geoip_load_file, TT_FORK|SKIP_ON_WINDOWS, NULL, NULL },
542 { "load_file6", test_geoip6_load_file, TT_FORK | SKIP_ON_WINDOWS,
543 NULL, NULL },
544 { "load_2nd_file", test_geoip_load_2nd_file, TT_FORK | SKIP_ON_WINDOWS,
545 NULL, NULL },
547 END_OF_TESTCASES