diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-11-11 07:39:20 -0500 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-11-11 13:39:20 +0100 |
commit | 9f7672b3bcff200405b722e105b57809781caa3b (patch) | |
tree | 63da251dd1b14fbe83f0e83a31e95444f9c2464c | |
parent | d48bb46b5a8a3a718948789a776d238c065fff88 (diff) |
test-nss: allow the module and names/addresses to be specified (#4258)
Useful for testing a single module. If nothing is specified, behaviour is the
same as before.
$ ./test-nss myhostname 192.168.0.14 localhost
======== myhostname ========
_nss_myhostname_gethostbyname4_r("localhost") → status=NSS_STATUS_SUCCESS
pat=buffer+0x38 errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0
"localhost" AF_INET 127.0.0.1 %lo
"localhost" AF_INET6 ::1 %lo
_nss_myhostname_gethostbyname3_r("localhost", AF_INET) → status=NSS_STATUS_SUCCESS
errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0
"localhost"
AF_INET 127.0.0.1
canonical: "localhost"
_nss_myhostname_gethostbyname3_r("localhost", AF_INET6) → status=NSS_STATUS_SUCCESS
errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0
"localhost"
AF_INET6 ::1
canonical: "localhost"
_nss_myhostname_gethostbyname3_r("localhost", *) → status=NSS_STATUS_SUCCESS
errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0
"localhost"
AF_INET 127.0.0.1
canonical: "localhost"
_nss_myhostname_gethostbyname3_r("localhost", AF_UNIX) → status=NSS_STATUS_UNAVAIL
errno=97/EAFNOSUPPORT h_errno=4/No address associated with name ttl=2147483647
_nss_myhostname_gethostbyname2_r("localhost", AF_INET) → status=NSS_STATUS_SUCCESS
errno=0/--- h_errno=0/Resolver Error 0 (no error)
"localhost"
AF_INET 127.0.0.1
_nss_myhostname_gethostbyname2_r("localhost", AF_INET6) → status=NSS_STATUS_SUCCESS
errno=0/--- h_errno=0/Resolver Error 0 (no error)
"localhost"
AF_INET6 ::1
_nss_myhostname_gethostbyname2_r("localhost", *) → status=NSS_STATUS_SUCCESS
errno=0/--- h_errno=0/Resolver Error 0 (no error)
"localhost"
AF_INET 127.0.0.1
_nss_myhostname_gethostbyname2_r("localhost", AF_UNIX) → status=NSS_STATUS_UNAVAIL
errno=97/EAFNOSUPPORT h_errno=4/No address associated with name
_nss_myhostname_gethostbyname_r("localhost") → status=NSS_STATUS_SUCCESS
errno=0/--- h_errno=0/Resolver Error 0 (no error)
"localhost"
AF_INET 127.0.0.1
_nss_myhostname_gethostbyaddr2_r("192.168.0.14") → status=NSS_STATUS_SUCCESS
errno=0/--- h_errno=0/Resolver Error 0 (no error) ttl=0
"laptop"
AF_INET 192.168.0.14
AF_INET 192.168.122.1
AF_INET 169.254.209.76
_nss_myhostname_gethostbyaddr_r("192.168.0.14") → status=NSS_STATUS_SUCCESS
errno=0/--- h_errno=0/Resolver Error 0 (no error)
"laptop"
AF_INET 192.168.0.14
AF_INET 192.168.122.1
AF_INET 169.254.209.76
-rw-r--r-- | src/test/test-nss.c | 190 |
1 files changed, 137 insertions, 53 deletions
diff --git a/src/test/test-nss.c b/src/test/test-nss.c index c43bda5917..4ccfe75147 100644 --- a/src/test/test-nss.c +++ b/src/test/test-nss.c @@ -77,7 +77,8 @@ static void* open_handle(const char* dir, const char* module, int flags) { path = strjoina("libnss_", module, ".so.2"); handle = dlopen(path, flags); - assert_se(handle); + if (!handle) + log_error("Failed to load module %s: %s", module, dlerror()); return handle; } @@ -379,75 +380,158 @@ static void test_byaddr(void *handle, puts(""); } +static int make_addresses(struct local_address **addresses) { + int n; + size_t n_alloc; + _cleanup_free_ struct local_address *addrs = NULL; + + n = local_addresses(NULL, 0, AF_UNSPEC, &addrs); + if (n < 0) + log_info_errno(n, "Failed to query local addresses: %m"); + + n_alloc = n; /* we _can_ do that */ + if (!GREEDY_REALLOC(addrs, n_alloc, n + 3)) + return log_oom(); + + addrs[n++] = (struct local_address) { .family = AF_INET, + .address.in = { htobe32(0x7F000001) } }; + addrs[n++] = (struct local_address) { .family = AF_INET, + .address.in = { htobe32(0x7F000002) } }; + addrs[n++] = (struct local_address) { .family = AF_INET6, + .address.in6 = in6addr_loopback }; + return 0; +} + +static int test_one_module(const char* dir, + const char *module, + char **names, + struct local_address *addresses, + int n_addresses) { + void *handle; + char **name; + int i; + + + log_info("======== %s ========", module); + + handle = open_handle(streq(module, "dns") ? NULL : dir, + module, + RTLD_LAZY|RTLD_NODELETE); + if (!handle) + return -EINVAL; + + STRV_FOREACH(name, names) + test_byname(handle, module, *name); + + for (i = 0; i < n_addresses; i++) + test_byaddr(handle, module, + &addresses[i].address, + FAMILY_ADDRESS_SIZE(addresses[i].family), + addresses[i].family); + + log_info(" "); + dlclose(handle); + return 0; +} + +static int parse_argv(int argc, char **argv, + char ***the_modules, + char ***the_names, + struct local_address **the_addresses, int *n_addresses) { + + int r, n = 0; + _cleanup_strv_free_ char **modules = NULL, **names = NULL; + _cleanup_free_ struct local_address *addrs = NULL; + size_t n_allocated = 0; + + if (argc > 1) + modules = strv_new(argv[1], NULL); + else + modules = strv_new( #ifdef HAVE_MYHOSTNAME -# define MODULE1 "myhostname\0" -#else -# define MODULE1 + "myhostname", #endif #ifdef HAVE_RESOLVED -# define MODULE2 "resolve\0" -#else -# define MODULE2 + "resolve", #endif #ifdef HAVE_MACHINED -# define MODULE3 "mymachines\0" -#else -# define MODULE3 + "mymachines", #endif -#define MODULE4 "dns\0" + "dns", + NULL); + if (!modules) + return -ENOMEM; + + if (argc > 2) { + char **name; + int family; + union in_addr_union address; + + STRV_FOREACH(name, argv + 2) { + r = in_addr_from_string_auto(*name, &family, &address); + if (r < 0) { + /* assume this is a name */ + r = strv_extend(&names, *name); + if (r < 0) + return r; + } else { + if (!GREEDY_REALLOC0(addrs, n_allocated, n + 1)) + return -ENOMEM; + + addrs[n++] = (struct local_address) { .family = family, + .address = address }; + } + } + } else { + _cleanup_free_ char *hostname; -int main(int argc, char **argv) { - _cleanup_free_ char *dir = NULL, *hostname = NULL; - const char *module; + hostname = gethostname_malloc(); + if (!hostname) + return -ENOMEM; - const uint32_t local_address_ipv4 = htobe32(0x7F000001); - const uint32_t local_address_ipv4_2 = htobe32(0x7F000002); + names = strv_new("localhost", "gateway", "foo_no_such_host", hostname, NULL); + if (!names) + return -ENOMEM; + + n = make_addresses(&addrs); + if (n < 0) + return n; + } + + *the_modules = modules; + *the_names = names; + modules = names = NULL; + *the_addresses = addrs; + *n_addresses = n; + addrs = NULL; + return 0; +} + +int main(int argc, char **argv) { + _cleanup_free_ char *dir = NULL; + _cleanup_strv_free_ char **modules = NULL, **names = NULL; _cleanup_free_ struct local_address *addresses = NULL; int n_addresses; + char **module; + int r; log_set_max_level(LOG_INFO); log_parse_environment(); - dir = dirname_malloc(argv[0]); - assert_se(dir); - - hostname = gethostname_malloc(); - assert_se(hostname); - - n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses); - if (n_addresses < 0) { - log_info_errno(n_addresses, "Failed to query local addresses: %m"); - n_addresses = 0; + r = parse_argv(argc, argv, &modules, &names, &addresses, &n_addresses); + if (r < 0) { + log_error_errno(r, "Failed to parse arguments: %m"); + return EXIT_FAILURE; } - NULSTR_FOREACH(module, MODULE1 MODULE2 MODULE3 MODULE4) { - void *handle; - const char *name; - int i; - - log_info("======== %s ========", module); - - handle = open_handle(streq(module, "dns") ? NULL : dir, - module, - RTLD_LAZY|RTLD_NODELETE); - NULSTR_FOREACH(name, "localhost\0" "gateway\0" "foo_no_such_host\0") - test_byname(handle, module, name); - - test_byname(handle, module, hostname); - - test_byaddr(handle, module, &local_address_ipv4, sizeof local_address_ipv4, AF_INET); - test_byaddr(handle, module, &local_address_ipv4_2, sizeof local_address_ipv4_2, AF_INET); - test_byaddr(handle, module, &in6addr_loopback, sizeof in6addr_loopback, AF_INET6); - - for (i = 0; i < n_addresses; i++) - test_byaddr(handle, module, - &addresses[i].address, - FAMILY_ADDRESS_SIZE(addresses[i].family), - addresses[i].family); - - dlclose(handle); + dir = dirname_malloc(argv[0]); + if (!dir) + return EXIT_FAILURE; - log_info(" "); + STRV_FOREACH(module, modules) { + r = test_one_module(dir, *module, names, addresses, n_addresses); + if (r < 0) + return EXIT_FAILURE; } return EXIT_SUCCESS; |