mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-14 11:47:15 +01:00
197 lines
5.2 KiB
C
197 lines
5.2 KiB
C
|
#include "maxminddb_test_helper.h"
|
||
|
#include <pthread.h>
|
||
|
|
||
|
typedef struct thread_arg {
|
||
|
int thread_id;
|
||
|
MMDB_s *mmdb;
|
||
|
const char *ip_to_lookup;
|
||
|
} thread_arg_s;
|
||
|
|
||
|
typedef struct test_result {
|
||
|
const char *ip_looked_up;
|
||
|
int lookup_string_gai_error;
|
||
|
int lookup_string_mmdb_error;
|
||
|
int found_entry;
|
||
|
int get_value_status;
|
||
|
int data_type_ok;
|
||
|
char *data_value;
|
||
|
} test_result_s;
|
||
|
|
||
|
void test_one_ip(MMDB_s *mmdb, const char *ip, test_result_s *test_result)
|
||
|
{
|
||
|
|
||
|
test_result->ip_looked_up = ip;
|
||
|
|
||
|
int gai_error = 0;
|
||
|
int mmdb_error = 0;
|
||
|
MMDB_lookup_result_s result =
|
||
|
MMDB_lookup_string(mmdb, ip, &gai_error, &mmdb_error);
|
||
|
|
||
|
test_result->lookup_string_gai_error = gai_error;
|
||
|
if (gai_error) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
test_result->lookup_string_mmdb_error = mmdb_error;
|
||
|
if (mmdb_error) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
test_result->found_entry = result.found_entry;
|
||
|
if (!result.found_entry) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
MMDB_entry_data_s data;
|
||
|
int status = MMDB_get_value(&result.entry, &data, "ip", NULL);
|
||
|
|
||
|
test_result->get_value_status = status;
|
||
|
if (status) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
test_result->data_type_ok = data.type == MMDB_DATA_TYPE_UTF8_STRING;
|
||
|
if (!test_result->data_type_ok) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
test_result->data_value = mmdb_strndup(data.utf8_string, data.data_size);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void *run_one_thread(void *arg)
|
||
|
{
|
||
|
thread_arg_s *thread_arg = (thread_arg_s *)arg;
|
||
|
|
||
|
MMDB_s *mmdb = thread_arg->mmdb;
|
||
|
const char *ip = thread_arg->ip_to_lookup;
|
||
|
|
||
|
test_result_s *result = malloc(sizeof(test_result_s));
|
||
|
test_one_ip(mmdb, ip, result);
|
||
|
|
||
|
pthread_exit((void *)result);
|
||
|
}
|
||
|
|
||
|
void process_result(test_result_s *result, const char *expect,
|
||
|
const char *mode_desc)
|
||
|
{
|
||
|
int is_ok;
|
||
|
is_ok =
|
||
|
ok(!result->lookup_string_gai_error, "no getaddrinfo error for %s - %s",
|
||
|
result->ip_looked_up, mode_desc);
|
||
|
if (!is_ok) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
is_ok = ok(!result->lookup_string_mmdb_error, "no mmdb error for %s - %s",
|
||
|
result->ip_looked_up, mode_desc);
|
||
|
if (!is_ok) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
is_ok = ok(result->found_entry, "got a result for %s in the database - %s",
|
||
|
result->ip_looked_up, mode_desc);
|
||
|
if (!is_ok) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
is_ok =
|
||
|
ok(!result->get_value_status,
|
||
|
"no error from MMDB_get_value for %s - %s",
|
||
|
result->ip_looked_up,
|
||
|
mode_desc);
|
||
|
if (!is_ok) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
is_ok = ok(result->data_type_ok,
|
||
|
"MMDB_get_value found a utf8_string at 'ip' key for %s - %s",
|
||
|
result->ip_looked_up, mode_desc);
|
||
|
if (!is_ok) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
is(result->data_value, expect,
|
||
|
"found expected result for 'ip' key for %s - %s",
|
||
|
result->ip_looked_up, mode_desc);
|
||
|
}
|
||
|
|
||
|
void run_ipX_tests(MMDB_s *mmdb, const char *pairs[][2], int pairs_rows,
|
||
|
int mode, const char *mode_desc)
|
||
|
{
|
||
|
pthread_t threads[pairs_rows];
|
||
|
struct thread_arg thread_args[pairs_rows];
|
||
|
|
||
|
for (int i = 0; i < pairs_rows; i += 1) {
|
||
|
thread_args[i].thread_id = i;
|
||
|
thread_args[i].mmdb = mmdb;
|
||
|
thread_args[i].ip_to_lookup = pairs[i][0];
|
||
|
|
||
|
int error = pthread_create(&threads[i], NULL, run_one_thread,
|
||
|
&thread_args[i]);
|
||
|
if (error) {
|
||
|
BAIL_OUT("pthread_create failed");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < pairs_rows; i += 1) {
|
||
|
void *thread_return;
|
||
|
int error = pthread_join(threads[i], &thread_return);
|
||
|
if (error) {
|
||
|
BAIL_OUT("pthread_join failed");
|
||
|
}
|
||
|
|
||
|
test_result_s *test_result = (test_result_s *)thread_return;
|
||
|
if (NULL != test_result) {
|
||
|
process_result(test_result, pairs[i][1], mode_desc);
|
||
|
if (test_result->data_type_ok) {
|
||
|
free(test_result->data_value);
|
||
|
}
|
||
|
free(test_result);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void run_tests(int mode, const char *mode_desc)
|
||
|
{
|
||
|
const char *filename = "MaxMind-DB-test-mixed-32.mmdb";
|
||
|
const char *path = test_database_path(filename);
|
||
|
MMDB_s *mmdb = open_ok(path, mode, mode_desc);
|
||
|
free((void *)path);
|
||
|
|
||
|
const char *pairs[18][2] = {
|
||
|
{ "1.1.1.1", "::1.1.1.1" },
|
||
|
{ "1.1.1.2", "::1.1.1.2" },
|
||
|
{ "1.1.1.3", "::1.1.1.2" },
|
||
|
{ "1.1.1.7", "::1.1.1.4" },
|
||
|
{ "1.1.1.9", "::1.1.1.8" },
|
||
|
{ "1.1.1.15", "::1.1.1.8" },
|
||
|
{ "1.1.1.17", "::1.1.1.16" },
|
||
|
{ "1.1.1.31", "::1.1.1.16" },
|
||
|
{ "1.1.1.32", "::1.1.1.32" },
|
||
|
{ "::1:ffff:ffff", "::1:ffff:ffff" },
|
||
|
{ "::2:0:0", "::2:0:0" },
|
||
|
{ "::2:0:1a", "::2:0:0" },
|
||
|
{ "::2:0:40", "::2:0:40" },
|
||
|
{ "::2:0:4f", "::2:0:40" },
|
||
|
{ "::2:0:50", "::2:0:50" },
|
||
|
{ "::2:0:52", "::2:0:50" },
|
||
|
{ "::2:0:58", "::2:0:58" },
|
||
|
{ "::2:0:59", "::2:0:58" },
|
||
|
};
|
||
|
|
||
|
run_ipX_tests(mmdb, pairs, 18, mode, mode_desc);
|
||
|
|
||
|
MMDB_close(mmdb);
|
||
|
free(mmdb);
|
||
|
}
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
plan(NO_PLAN);
|
||
|
for_all_modes(&run_tests);
|
||
|
done_testing();
|
||
|
pthread_exit(NULL);
|
||
|
}
|