geoip2_c 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/geoip2/libmaxminddb/.gitignore +35 -0
- data/ext/geoip2/libmaxminddb/.gitmodules +9 -0
- data/ext/geoip2/libmaxminddb/.perltidyrc +11 -0
- data/ext/geoip2/libmaxminddb/.travis.yml +48 -0
- data/ext/geoip2/libmaxminddb/.uncrustify.cfg +78 -0
- data/ext/geoip2/libmaxminddb/AUTHORS +0 -0
- data/ext/geoip2/libmaxminddb/Changes.md +238 -0
- data/ext/geoip2/libmaxminddb/LICENSE +202 -0
- data/ext/geoip2/libmaxminddb/Makefile.am +41 -0
- data/ext/geoip2/libmaxminddb/NOTICE +13 -0
- data/ext/geoip2/libmaxminddb/README.dev.md +58 -0
- data/ext/geoip2/libmaxminddb/README.md +122 -0
- data/ext/geoip2/libmaxminddb/appveyor.yml +33 -0
- data/ext/geoip2/libmaxminddb/bin/Makefile.am +5 -0
- data/ext/geoip2/libmaxminddb/bin/mmdblookup.c +397 -0
- data/ext/geoip2/libmaxminddb/bootstrap +21 -0
- data/ext/geoip2/libmaxminddb/common.mk +7 -0
- data/ext/geoip2/libmaxminddb/configure.ac +132 -0
- data/ext/geoip2/libmaxminddb/dev-bin/make-man-pages.pl +76 -0
- data/ext/geoip2/libmaxminddb/dev-bin/ppa-release.sh +50 -0
- data/ext/geoip2/libmaxminddb/dev-bin/regen-prototypes.pl +136 -0
- data/ext/geoip2/libmaxminddb/dev-bin/regen-win32-test-projs.pl +54 -0
- data/ext/geoip2/libmaxminddb/dev-bin/release.sh +106 -0
- data/ext/geoip2/libmaxminddb/dev-bin/uncrustify-all.sh +21 -0
- data/ext/geoip2/libmaxminddb/dev-bin/valgrind-all.pl +46 -0
- data/ext/geoip2/libmaxminddb/doc/libmaxminddb.md +889 -0
- data/ext/geoip2/libmaxminddb/doc/mmdblookup.md +103 -0
- data/ext/geoip2/libmaxminddb/include/maxminddb.h +232 -0
- data/ext/geoip2/libmaxminddb/include/maxminddb_config.h.in +14 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/README.md +59 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb-release.props +32 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb-x64.props +14 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.props +32 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.sln +150 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj +141 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj.filters +26 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/maxminddb_config.h +14 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/bad_pointers.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/basic_lookup.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/data_entry_list.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/data_types.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/dump.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/get_value.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/get_value_pointer_bug.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/ipv4_start_cache.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/ipv6_lookup_in_ipv4.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/libtap.vcxproj +85 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/maxminddb_test_helper.vcxproj +107 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/metadata.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/metadata_pointers.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/no_map_get_value.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/read_node.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/shared.vcxproj +104 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/threads.vcxproj +103 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/version.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/test.vcxproj.template +105 -0
- data/ext/geoip2/libmaxminddb/src/Makefile.am +9 -0
- data/ext/geoip2/libmaxminddb/src/libmaxminddb.pc.in +11 -0
- data/ext/geoip2/libmaxminddb/src/maxminddb-compat-util.h +167 -0
- data/ext/geoip2/libmaxminddb/src/maxminddb.c +2171 -0
- data/ext/geoip2/libmaxminddb/t/Makefile.am +23 -0
- data/ext/geoip2/libmaxminddb/t/bad_databases_t.c +66 -0
- data/ext/geoip2/libmaxminddb/t/bad_pointers_t.c +53 -0
- data/ext/geoip2/libmaxminddb/t/basic_lookup_t.c +172 -0
- data/ext/geoip2/libmaxminddb/t/compile_c++_t.pl +107 -0
- data/ext/geoip2/libmaxminddb/t/data_entry_list_t.c +353 -0
- data/ext/geoip2/libmaxminddb/t/data_types_t.c +439 -0
- data/ext/geoip2/libmaxminddb/t/dump_t.c +103 -0
- data/ext/geoip2/libmaxminddb/t/get_value_pointer_bug_t.c +66 -0
- data/ext/geoip2/libmaxminddb/t/get_value_t.c +249 -0
- data/ext/geoip2/libmaxminddb/t/ipv4_start_cache_t.c +36 -0
- data/ext/geoip2/libmaxminddb/t/ipv6_lookup_in_ipv4_t.c +48 -0
- data/ext/geoip2/libmaxminddb/t/maxminddb_test_helper.c +255 -0
- data/ext/geoip2/libmaxminddb/t/maxminddb_test_helper.h +69 -0
- data/ext/geoip2/libmaxminddb/t/metadata_pointers_t.c +32 -0
- data/ext/geoip2/libmaxminddb/t/metadata_t.c +226 -0
- data/ext/geoip2/libmaxminddb/t/mmdblookup_t.pl +158 -0
- data/ext/geoip2/libmaxminddb/t/no_map_get_value_t.c +32 -0
- data/ext/geoip2/libmaxminddb/t/read_node_t.c +157 -0
- data/ext/geoip2/libmaxminddb/t/threads_t.c +196 -0
- data/ext/geoip2/libmaxminddb/t/version_t.c +10 -0
- data/geoip2_c.gemspec +1 -1
- data/lib/geoip2/version.rb +1 -1
- metadata +82 -1
@@ -0,0 +1,23 @@
|
|
1
|
+
include $(top_srcdir)/common.mk
|
2
|
+
|
3
|
+
all-local:
|
4
|
+
cd libtap && $(MAKE) $(AM_MAKEFLAGS) all
|
5
|
+
clean-local:
|
6
|
+
cd libtap && $(MAKE) $(AM_MAKEFLAGS) clean
|
7
|
+
|
8
|
+
AM_LDFLAGS = $(top_builddir)/src/libmaxminddb.la
|
9
|
+
|
10
|
+
noinst_LTLIBRARIES = libmmdbtest.la
|
11
|
+
libmmdbtest_la_SOURCES = maxminddb_test_helper.c
|
12
|
+
|
13
|
+
check_PROGRAMS = \
|
14
|
+
bad_pointers_t bad_databases_t basic_lookup_t data_entry_list_t \
|
15
|
+
data_types_t dump_t get_value_t get_value_pointer_bug_t \
|
16
|
+
ipv4_start_cache_t ipv6_lookup_in_ipv4_t metadata_t metadata_pointers_t \
|
17
|
+
no_map_get_value_t read_node_t threads_t version_t
|
18
|
+
|
19
|
+
threads_t_CFLAGS = $(CFLAGS) -pthread
|
20
|
+
|
21
|
+
TESTS = $(check_PROGRAMS) compile_c++_t.pl mmdblookup_t.pl
|
22
|
+
|
23
|
+
LDADD = libmmdbtest.la libtap/libtap.a
|
@@ -0,0 +1,66 @@
|
|
1
|
+
// This test currently does not work on Windows as nftw is
|
2
|
+
// not available.
|
3
|
+
#define _XOPEN_SOURCE 500
|
4
|
+
#include <ftw.h>
|
5
|
+
|
6
|
+
#include <libgen.h>
|
7
|
+
#include <unistd.h>
|
8
|
+
|
9
|
+
#include "maxminddb_test_helper.h"
|
10
|
+
|
11
|
+
int test_read(const char *path, const struct stat *UNUSED(
|
12
|
+
sbuf), int flags, struct FTW *UNUSED(ftw))
|
13
|
+
{
|
14
|
+
// Check if path is a regular file)
|
15
|
+
if (flags != FTW_F) {
|
16
|
+
return 0;
|
17
|
+
}
|
18
|
+
|
19
|
+
MMDB_s *mmdb = (MMDB_s *)calloc(1, sizeof(MMDB_s));
|
20
|
+
|
21
|
+
if (NULL == mmdb) {
|
22
|
+
BAIL_OUT("could not allocate memory for our MMDB_s struct");
|
23
|
+
}
|
24
|
+
|
25
|
+
int status = MMDB_open(path, MMDB_MODE_MMAP, mmdb);
|
26
|
+
|
27
|
+
if (status != MMDB_SUCCESS) {
|
28
|
+
ok(1, "received error when opening %s", path);
|
29
|
+
return 0;
|
30
|
+
}
|
31
|
+
|
32
|
+
int gai_error, mmdb_error;
|
33
|
+
MMDB_lookup_string(mmdb, "1.1.1.1", &gai_error, &mmdb_error);
|
34
|
+
if (gai_error != 0) {
|
35
|
+
BAIL_OUT("could not parse IP address");
|
36
|
+
}
|
37
|
+
|
38
|
+
cmp_ok(mmdb_error, "!=", MMDB_SUCCESS, "opening %s returned an error",
|
39
|
+
path);
|
40
|
+
|
41
|
+
MMDB_close(mmdb);
|
42
|
+
free(mmdb);
|
43
|
+
return 0;
|
44
|
+
}
|
45
|
+
|
46
|
+
int main(void)
|
47
|
+
{
|
48
|
+
char *test_db_dir;
|
49
|
+
#ifdef _WIN32
|
50
|
+
test_db_dir = "./t/maxmind-db/bad-data";
|
51
|
+
#else
|
52
|
+
char cwd[500];
|
53
|
+
char *UNUSED(tmp) = getcwd(cwd, 500);
|
54
|
+
|
55
|
+
if (strcmp(basename(cwd), "t") == 0) {
|
56
|
+
test_db_dir = "./maxmind-db/bad-data";
|
57
|
+
} else {
|
58
|
+
test_db_dir = "./t/maxmind-db/bad-data";
|
59
|
+
}
|
60
|
+
#endif
|
61
|
+
plan(NO_PLAN);
|
62
|
+
if (nftw(test_db_dir, test_read, 10, FTW_PHYS) != 0) {
|
63
|
+
BAIL_OUT("nftw failed");
|
64
|
+
}
|
65
|
+
done_testing();
|
66
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#include "maxminddb_test_helper.h"
|
2
|
+
|
3
|
+
void run_tests(int mode, const char *mode_desc)
|
4
|
+
{
|
5
|
+
const char *filename = "MaxMind-DB-test-broken-pointers-24.mmdb";
|
6
|
+
const char *path = test_database_path(filename);
|
7
|
+
MMDB_s *mmdb = open_ok(path, mode, mode_desc);
|
8
|
+
free((void *)path);
|
9
|
+
|
10
|
+
{
|
11
|
+
const char *ip = "1.1.1.16";
|
12
|
+
MMDB_lookup_result_s result =
|
13
|
+
lookup_string_ok(mmdb, ip, filename, mode_desc);
|
14
|
+
|
15
|
+
MMDB_entry_data_s entry_data;
|
16
|
+
int status = MMDB_get_value(&result.entry, &entry_data, NULL);
|
17
|
+
|
18
|
+
cmp_ok(
|
19
|
+
status, "==", MMDB_INVALID_DATA_ERROR,
|
20
|
+
"MMDB_get_value returns MMDB_INVALID_DATA_ERROR for bad pointer in data section");
|
21
|
+
|
22
|
+
MMDB_entry_data_list_s *entry_data_list;
|
23
|
+
status = MMDB_get_entry_data_list(&result.entry, &entry_data_list);
|
24
|
+
|
25
|
+
cmp_ok(
|
26
|
+
status, "==", MMDB_INVALID_DATA_ERROR,
|
27
|
+
"MMDB_get_entry_data_list returns MMDB_INVALID_DATA_ERROR for bad pointer in data section");
|
28
|
+
|
29
|
+
MMDB_free_entry_data_list(entry_data_list);
|
30
|
+
}
|
31
|
+
|
32
|
+
{
|
33
|
+
const char *ip = "1.1.1.32";
|
34
|
+
|
35
|
+
int gai_error, mmdb_error;
|
36
|
+
MMDB_lookup_result_s UNUSED(result) =
|
37
|
+
MMDB_lookup_string(mmdb, ip, &gai_error, &mmdb_error);
|
38
|
+
|
39
|
+
cmp_ok(
|
40
|
+
mmdb_error, "==", MMDB_CORRUPT_SEARCH_TREE_ERROR,
|
41
|
+
"MMDB_lookup_string sets mmdb_error to MMDB_CORRUPT_SEARCH_TREE_ERROR when a search tree record points outside the data section");
|
42
|
+
}
|
43
|
+
|
44
|
+
MMDB_close(mmdb);
|
45
|
+
free(mmdb);
|
46
|
+
}
|
47
|
+
|
48
|
+
int main(void)
|
49
|
+
{
|
50
|
+
plan(NO_PLAN);
|
51
|
+
for_all_modes(&run_tests);
|
52
|
+
done_testing();
|
53
|
+
}
|
@@ -0,0 +1,172 @@
|
|
1
|
+
#include "maxminddb_test_helper.h"
|
2
|
+
|
3
|
+
/* These globals are gross but it's the easiest way to mix calling
|
4
|
+
* for_all_modes() and for_all_record_sizes() */
|
5
|
+
static int Current_Mode;
|
6
|
+
static const char *Current_Mode_Description;
|
7
|
+
|
8
|
+
void test_one_result(MMDB_s *mmdb, MMDB_lookup_result_s result,
|
9
|
+
const char *ip, const char *expect,
|
10
|
+
const char *function, const char *filename,
|
11
|
+
const char *mode_desc)
|
12
|
+
{
|
13
|
+
int is_ok = ok(result.found_entry,
|
14
|
+
"got a result for an IP in the database - %s - %s - %s - %s",
|
15
|
+
function, ip, filename, mode_desc);
|
16
|
+
|
17
|
+
if (!is_ok) {
|
18
|
+
return;
|
19
|
+
}
|
20
|
+
|
21
|
+
MMDB_entry_data_s data =
|
22
|
+
data_ok(&result, MMDB_DATA_TYPE_UTF8_STRING, "result{ip}", "ip", NULL);
|
23
|
+
|
24
|
+
char *string = strndup(data.utf8_string, data.data_size);
|
25
|
+
|
26
|
+
char *real_expect;
|
27
|
+
if (mmdb->metadata.ip_version == 4 || strncmp(expect, "::", 2) == 0) {
|
28
|
+
real_expect = strndup(expect, strlen(expect));
|
29
|
+
} else {
|
30
|
+
// When looking up IPv4 addresses in a mixed DB the result will be
|
31
|
+
// something like "::1.2.3.4", not just "1.2.3.4".
|
32
|
+
int maxlen = strlen(expect) + 3;
|
33
|
+
real_expect = malloc(maxlen);
|
34
|
+
snprintf(real_expect, maxlen, "::%s", expect);
|
35
|
+
}
|
36
|
+
|
37
|
+
is(string, real_expect,
|
38
|
+
"found expected result for ip key - %s - %s - %s - %s", function, ip,
|
39
|
+
filename, mode_desc);
|
40
|
+
|
41
|
+
free(real_expect);
|
42
|
+
free(string);
|
43
|
+
}
|
44
|
+
|
45
|
+
void test_one_ip(MMDB_s *mmdb, const char *ip, const char *expect,
|
46
|
+
const char *filename, const char *mode_desc)
|
47
|
+
{
|
48
|
+
MMDB_lookup_result_s result =
|
49
|
+
lookup_string_ok(mmdb, ip, filename, mode_desc);
|
50
|
+
|
51
|
+
test_one_result(mmdb, result, ip, expect, "MMDB_lookup_string", filename,
|
52
|
+
mode_desc);
|
53
|
+
|
54
|
+
result = lookup_sockaddr_ok(mmdb, ip, filename, mode_desc);
|
55
|
+
test_one_result(mmdb, result, ip, expect, "MMDB_lookup_addrinfo", filename,
|
56
|
+
mode_desc);
|
57
|
+
}
|
58
|
+
|
59
|
+
void run_ipX_tests(const char *filename, const char **missing_ips,
|
60
|
+
int missing_ips_length, const char *pairs[][2],
|
61
|
+
int pairs_rows)
|
62
|
+
{
|
63
|
+
const char *path = test_database_path(filename);
|
64
|
+
int mode = Current_Mode;
|
65
|
+
const char *mode_desc = Current_Mode_Description;
|
66
|
+
|
67
|
+
MMDB_s *mmdb = open_ok(path, mode, mode_desc);
|
68
|
+
free((void *)path);
|
69
|
+
|
70
|
+
char desc_suffix[500];
|
71
|
+
snprintf(desc_suffix, 500, "%s - %s", filename, mode_desc);
|
72
|
+
|
73
|
+
for (int i = 0; i < missing_ips_length; i++) {
|
74
|
+
const char *ip = missing_ips[i];
|
75
|
+
|
76
|
+
MMDB_lookup_result_s result =
|
77
|
+
lookup_string_ok(mmdb, ip, filename, mode_desc);
|
78
|
+
|
79
|
+
ok(
|
80
|
+
!result.found_entry,
|
81
|
+
"no result entry struct returned for IP address not in the database (string lookup) - %s - %s - %s",
|
82
|
+
ip, filename, mode_desc);
|
83
|
+
|
84
|
+
result = lookup_sockaddr_ok(mmdb, ip, filename, mode_desc);
|
85
|
+
|
86
|
+
ok(
|
87
|
+
!result.found_entry,
|
88
|
+
"no result entry struct returned for IP address not in the database (ipv4 lookup) - %s - %s - %s",
|
89
|
+
ip, filename, mode_desc);
|
90
|
+
}
|
91
|
+
|
92
|
+
for (int i = 0; i < pairs_rows; i += 1) {
|
93
|
+
const char *ip_to_lookup = pairs[i][0];
|
94
|
+
const char *expect = pairs[i][1];
|
95
|
+
|
96
|
+
test_one_ip(mmdb, ip_to_lookup, expect, filename, mode_desc);
|
97
|
+
}
|
98
|
+
|
99
|
+
MMDB_close(mmdb);
|
100
|
+
free(mmdb);
|
101
|
+
}
|
102
|
+
|
103
|
+
void run_ipv4_tests(int UNUSED(
|
104
|
+
record_size), const char *filename, const char *UNUSED(
|
105
|
+
ignored))
|
106
|
+
{
|
107
|
+
const char *pairs[9][2] = {
|
108
|
+
{ "1.1.1.1", "1.1.1.1" },
|
109
|
+
{ "1.1.1.2", "1.1.1.2" },
|
110
|
+
{ "1.1.1.3", "1.1.1.2" },
|
111
|
+
{ "1.1.1.7", "1.1.1.4" },
|
112
|
+
{ "1.1.1.9", "1.1.1.8" },
|
113
|
+
{ "1.1.1.15", "1.1.1.8" },
|
114
|
+
{ "1.1.1.17", "1.1.1.16" },
|
115
|
+
{ "1.1.1.31", "1.1.1.16" },
|
116
|
+
{ "1.1.1.32", "1.1.1.32" },
|
117
|
+
};
|
118
|
+
|
119
|
+
const char *missing[1] = { "2.3.4.5" };
|
120
|
+
run_ipX_tests(filename, missing, 1, pairs, 9);
|
121
|
+
}
|
122
|
+
|
123
|
+
void run_ipv6_tests(int UNUSED(
|
124
|
+
record_size), const char *filename, const char *UNUSED(
|
125
|
+
ignored))
|
126
|
+
{
|
127
|
+
const char *pairs[9][2] = {
|
128
|
+
{ "::1:ffff:ffff", "::1:ffff:ffff" },
|
129
|
+
{ "::2:0:0", "::2:0:0" },
|
130
|
+
{ "::2:0:1a", "::2:0:0" },
|
131
|
+
{ "::2:0:40", "::2:0:40" },
|
132
|
+
{ "::2:0:4f", "::2:0:40" },
|
133
|
+
{ "::2:0:50", "::2:0:50" },
|
134
|
+
{ "::2:0:52", "::2:0:50" },
|
135
|
+
{ "::2:0:58", "::2:0:58" },
|
136
|
+
{ "::2:0:59", "::2:0:58" },
|
137
|
+
};
|
138
|
+
|
139
|
+
const char *missing[2] = { "2.3.4.5", "::abcd" };
|
140
|
+
run_ipX_tests(filename, missing, 2, pairs, 9);
|
141
|
+
}
|
142
|
+
|
143
|
+
void all_record_sizes(int mode, const char *description)
|
144
|
+
{
|
145
|
+
const char *ipv4_filename_fmts[] = {
|
146
|
+
"MaxMind-DB-test-ipv4-%i.mmdb",
|
147
|
+
"MaxMind-DB-test-mixed-%i.mmdb"
|
148
|
+
};
|
149
|
+
|
150
|
+
Current_Mode = mode;
|
151
|
+
Current_Mode_Description = description;
|
152
|
+
|
153
|
+
for (int i = 0; i < 2; i++) {
|
154
|
+
for_all_record_sizes(ipv4_filename_fmts[i], &run_ipv4_tests);
|
155
|
+
}
|
156
|
+
|
157
|
+
const char *ipv6_filename_fmts[] = {
|
158
|
+
"MaxMind-DB-test-ipv6-%i.mmdb",
|
159
|
+
"MaxMind-DB-test-mixed-%i.mmdb"
|
160
|
+
};
|
161
|
+
|
162
|
+
for (int i = 0; i < 2; i++) {
|
163
|
+
for_all_record_sizes(ipv6_filename_fmts[i], &run_ipv6_tests);
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
int main(void)
|
168
|
+
{
|
169
|
+
plan(NO_PLAN);
|
170
|
+
for_all_modes(&all_record_sizes);
|
171
|
+
done_testing();
|
172
|
+
}
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#!/usr/bin/env perl
|
2
|
+
|
3
|
+
use strict;
|
4
|
+
use warnings;
|
5
|
+
|
6
|
+
use Cwd qw( abs_path );
|
7
|
+
use FindBin qw( $Bin );
|
8
|
+
|
9
|
+
eval <<'EOF';
|
10
|
+
use Test::More 0.88;
|
11
|
+
use File::Temp qw( tempdir );
|
12
|
+
use IPC::Run3 qw( run3 );
|
13
|
+
EOF
|
14
|
+
|
15
|
+
if ($@) {
|
16
|
+
print
|
17
|
+
"1..0 # skip all tests skipped - these tests need the Test::More 0.88, File::Temp, and IPC::Run3 modules:\n";
|
18
|
+
print "$@";
|
19
|
+
exit 0;
|
20
|
+
}
|
21
|
+
|
22
|
+
my $test_db = "$Bin/maxmind-db/test-data/GeoIP2-City-Test.mmdb";
|
23
|
+
|
24
|
+
my $cpp_code = <<"EOF";
|
25
|
+
#include <maxminddb.h>
|
26
|
+
|
27
|
+
int main(int argc, char *argv[])
|
28
|
+
{
|
29
|
+
const char *fname = "$test_db";
|
30
|
+
MMDB_s mmdb;
|
31
|
+
return MMDB_open(fname, MMDB_MODE_MMAP, &mmdb);
|
32
|
+
}
|
33
|
+
EOF
|
34
|
+
|
35
|
+
my $tempdir = tempdir(CLEANUP => 1 );
|
36
|
+
|
37
|
+
my $file = "$tempdir/open.cpp";
|
38
|
+
open my $fh, '>', $file or die $!;
|
39
|
+
print {$fh} $cpp_code or die $!;
|
40
|
+
close $fh or die $!;
|
41
|
+
|
42
|
+
my $exe = "$tempdir/open";
|
43
|
+
|
44
|
+
my $include_dir = abs_path("$Bin/../include");
|
45
|
+
my $lib_dir = abs_path("$Bin/../src/.libs");
|
46
|
+
|
47
|
+
my $cxx = $ENV{CXX} || 'c++';
|
48
|
+
_test_cmd(
|
49
|
+
[ $cxx, $file, "-I$include_dir", "-L$lib_dir", "-lmaxminddb", "-o$exe" ],
|
50
|
+
qr/^$/,
|
51
|
+
q{},
|
52
|
+
0,
|
53
|
+
'compile C++ program which links against libmaxminddb',
|
54
|
+
);
|
55
|
+
|
56
|
+
# DYLD_LIBRARY_PATH is for Mac OS X
|
57
|
+
$ENV{LD_LIBRARY_PATH} = $ENV{DYLD_LIBRARY_PATH} = $lib_dir;
|
58
|
+
|
59
|
+
_test_cmd(
|
60
|
+
[$exe],
|
61
|
+
qr/^$/,
|
62
|
+
q{},
|
63
|
+
0,
|
64
|
+
'compiled C++ program executes without errors'
|
65
|
+
);
|
66
|
+
|
67
|
+
done_testing();
|
68
|
+
|
69
|
+
sub _test_cmd {
|
70
|
+
my $cmd = shift;
|
71
|
+
my $expect_stdout = shift;
|
72
|
+
my $expect_stderr = shift;
|
73
|
+
my $expect_status = shift;
|
74
|
+
my $desc = shift;
|
75
|
+
|
76
|
+
my $stdout;
|
77
|
+
my $stderr;
|
78
|
+
run3(
|
79
|
+
$cmd,
|
80
|
+
\undef,
|
81
|
+
\$stdout,
|
82
|
+
\$stderr,
|
83
|
+
);
|
84
|
+
|
85
|
+
my $exit_status = $? >> 8;
|
86
|
+
|
87
|
+
# We don't need to retest that the help output shows up for all errors
|
88
|
+
if ( defined $expect_stdout ) {
|
89
|
+
like(
|
90
|
+
$stdout,
|
91
|
+
$expect_stdout,
|
92
|
+
"stdout for @{$cmd}"
|
93
|
+
);
|
94
|
+
}
|
95
|
+
|
96
|
+
if ( ref $expect_stderr ) {
|
97
|
+
like( $stderr, $expect_stderr, "stderr for @{$cmd}" );
|
98
|
+
}
|
99
|
+
else {
|
100
|
+
is( $stderr, $expect_stderr, "stderr for @{$cmd}" );
|
101
|
+
}
|
102
|
+
|
103
|
+
is(
|
104
|
+
$exit_status, $expect_status,
|
105
|
+
"exit status was $expect_status for @{$cmd}"
|
106
|
+
);
|
107
|
+
}
|