Index: head/etc/mtree/BSD.tests.dist =================================================================== --- head/etc/mtree/BSD.tests.dist (revision 292322) +++ head/etc/mtree/BSD.tests.dist (revision 292323) @@ -1,622 +1,624 @@ # $FreeBSD$ # # Please see the file src/etc/mtree/README before making changes to this file. # /set type=dir uname=root gname=wheel mode=0755 . bin cat .. chown .. date .. dd .. expr .. ls .. mv .. pax .. pkill .. sh builtins .. errors .. execution .. expansion .. parameters .. parser .. set-e .. .. sleep .. test .. .. cddl lib .. sbin .. usr.bin .. usr.sbin dtrace common aggs .. arithmetic .. arrays .. assocs .. begin .. bitfields .. buffering .. builtinvar .. cg .. clauses .. cpc .. decls .. drops .. dtraceUtil .. end .. enum .. error .. exit .. fbtprovider .. funcs .. grammar .. include .. inline .. io .. ip .. java_api .. json .. lexer .. llquantize .. mdb .. mib .. misc .. multiaggs .. offsetof .. operators .. pid .. plockstat .. pointers .. pragma .. predicates .. preprocessor .. print .. printa .. printf .. privs .. probes .. proc .. profile-n .. providers .. raise .. rates .. safety .. scalars .. sched .. scripting .. sdt .. sizeof .. speculation .. stability .. stack .. stackdepth .. stop .. strlen .. strtoll .. struct .. syscall .. sysevent .. tick-n .. trace .. tracemem .. translators .. typedef .. types .. uctf .. union .. usdt .. ustack .. vars .. version .. .. .. .. .. etc rc.d .. .. games .. gnu lib .. usr.bin diff .. .. .. lib atf libatf-c detail .. .. libatf-c++ detail .. .. test-programs .. .. libarchive .. libc c063 .. db .. gen execve .. posix_spawn .. .. hash data .. .. inet .. locale .. net getaddrinfo data .. .. .. + nss + .. regex data .. .. resolv .. rpc .. ssp .. stdio .. stdlib .. string .. sys .. time .. tls dso .. .. termios .. ttyio .. .. libcrypt .. libmp .. libnv .. libpam .. libproc .. librt .. libthr dlopen .. .. libutil .. libxo .. msun .. .. libexec atf atf-check .. atf-sh .. .. rtld-elf .. .. sbin dhclient .. devd .. growfs .. ifconfig .. mdconfig .. .. secure lib .. libexec .. usr.bin .. usr.sbin .. .. share examples tests atf .. plain .. .. .. .. sys acl .. aio .. fifo .. file .. kern acct .. execve .. pipe .. .. kqueue .. mqueue .. netinet .. opencrypto .. pjdfstest chflags .. chmod .. chown .. ftruncate .. granular .. link .. mkdir .. mkfifo .. mknod .. open .. rename .. rmdir .. symlink .. truncate .. unlink .. .. posixshm .. vfs .. vm .. .. usr.bin apply .. basename .. bmake archives fmt_44bsd .. fmt_44bsd_mod .. fmt_oldbsd .. .. basic t0 .. t1 .. t2 .. t3 .. .. execution ellipsis .. empty .. joberr .. plus .. .. shell builtin .. meta .. path .. path_select .. replace .. select .. .. suffixes basic .. src_wild1 .. src_wild2 .. .. syntax directive-t0 .. enl .. funny-targets .. semi .. .. sysmk t0 2 1 .. .. mk .. .. t1 2 1 .. .. mk .. .. t2 2 1 .. .. mk .. .. .. variables modifier_M .. modifier_t .. opt_V .. t0 .. .. .. calendar .. cmp .. cpio .. col .. comm .. cut .. dirname .. file2c .. grep .. gzip .. ident .. join .. jot .. lastcomm .. limits .. m4 .. mkimg .. ncal .. opensm .. printf .. sed regress.multitest.out .. .. soelim .. tar .. timeout .. tr .. truncate .. units .. uudecode .. uuencode .. xargs .. xo .. yacc yacc .. .. .. usr.sbin etcupdate .. fstyp .. makefs .. newsyslog .. nmtree .. pw .. sa .. .. .. # vim: set expandtab ts=4 sw=4: Index: head/lib/libc/tests/nss/Makefile =================================================================== --- head/lib/libc/tests/nss/Makefile (nonexistent) +++ head/lib/libc/tests/nss/Makefile (revision 292323) @@ -0,0 +1,22 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/lib/libc/nss +BINDIR= ${TESTSDIR} + +.PATH: ${.CURDIR:H}/resolv + +FILES+= mach + +CFLAGS+= -I${SRCTOP}/tests + +ATF_TESTS_C+= getaddrinfo_test +ATF_TESTS_C+= getgr_test +ATF_TESTS_C+= gethostby_test +TEST_METADATA.gethostby_test= timeout="1200" +ATF_TESTS_C+= getpw_test +ATF_TESTS_C+= getproto_test +ATF_TESTS_C+= getrpc_test +ATF_TESTS_C+= getserv_test +ATF_TESTS_C+= getusershell_test + +.include Property changes on: head/lib/libc/tests/nss/Makefile ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libc/tests/nss/getaddrinfo_test.c =================================================================== --- head/lib/libc/tests/nss/getaddrinfo_test.c (nonexistent) +++ head/lib/libc/tests/nss/getaddrinfo_test.c (revision 292323) @@ -0,0 +1,556 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "freebsd_test_suite/macros.h" +#include "testutil.h" + +enum test_methods { + TEST_GETADDRINFO, + TEST_BUILD_SNAPSHOT +}; + +static struct addrinfo hints; +static enum test_methods method = TEST_GETADDRINFO; + +DECLARE_TEST_DATA(addrinfo) +DECLARE_TEST_FILE_SNAPSHOT(addrinfo) +DECLARE_2PASS_TEST(addrinfo) + +static void clone_addrinfo(struct addrinfo *, struct addrinfo const *); +static int compare_addrinfo(struct addrinfo *, struct addrinfo *, void *); +static void dump_addrinfo(struct addrinfo *); + +static void sdump_addrinfo(struct addrinfo *, char *, size_t); + +IMPLEMENT_TEST_DATA(addrinfo) +IMPLEMENT_TEST_FILE_SNAPSHOT(addrinfo) +IMPLEMENT_2PASS_TEST(addrinfo) + +static void +clone_addrinfo(struct addrinfo *dest, struct addrinfo const *src) +{ + + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + memcpy(dest, src, sizeof(struct addrinfo)); + if (src->ai_canonname != NULL) + dest->ai_canonname = strdup(src->ai_canonname); + + if (src->ai_addr != NULL) { + dest->ai_addr = malloc(src->ai_addrlen); + ATF_REQUIRE(dest->ai_addr != NULL); + memcpy(dest->ai_addr, src->ai_addr, src->ai_addrlen); + } + + if (src->ai_next != NULL) { + dest->ai_next = malloc(sizeof(struct addrinfo)); + ATF_REQUIRE(dest->ai_next != NULL); + clone_addrinfo(dest->ai_next, src->ai_next); + } +} + +static int +compare_addrinfo_(struct addrinfo *ai1, struct addrinfo *ai2) +{ + + if ((ai1 == NULL) || (ai2 == NULL)) + return (-1); + + if (ai1->ai_flags != ai2->ai_flags || + ai1->ai_family != ai2->ai_family || + ai1->ai_socktype != ai2->ai_socktype || + ai1->ai_protocol != ai2->ai_protocol || + ai1->ai_addrlen != ai2->ai_addrlen || + ((ai1->ai_addr == NULL || ai2->ai_addr == NULL) && + ai1->ai_addr != ai2->ai_addr) || + ((ai1->ai_canonname == NULL || ai2->ai_canonname == NULL) && + ai1->ai_canonname != ai2->ai_canonname)) + return (-1); + + if (ai1->ai_canonname != NULL && + strcmp(ai1->ai_canonname, ai2->ai_canonname) != 0) + return (-1); + + if (ai1->ai_addr != NULL && + memcmp(ai1->ai_addr, ai2->ai_addr, ai1->ai_addrlen) != 0) + return (-1); + + if (ai1->ai_next == NULL && ai2->ai_next == NULL) + return (0); + else + return (compare_addrinfo_(ai1->ai_next, ai2->ai_next)); +} + +static int +compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2, void *mdata) +{ + int rv; + + printf("testing equality of 2 addrinfo structures\n"); + + rv = compare_addrinfo_(ai1, ai2); + + if (rv == 0) + printf("equal\n"); + else { + dump_addrinfo(ai1); + dump_addrinfo(ai2); + printf("not equal\n"); + } + + return (rv); +} + +void +free_addrinfo(struct addrinfo *ai) +{ + if (ai == NULL) + return; + + free(ai->ai_addr); + free(ai->ai_canonname); + free_addrinfo(ai->ai_next); +} + +void +sdump_addrinfo(struct addrinfo *ai, char *buffer, size_t buflen) +{ + int written, i; + + written = snprintf(buffer, buflen, "%d %d %d %d %d ", + ai->ai_flags, ai->ai_family, ai->ai_socktype, ai->ai_protocol, + ai->ai_addrlen); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + written = snprintf(buffer, buflen, "%s ", + ai->ai_canonname == NULL ? "(null)" : ai->ai_canonname); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (ai->ai_addr == NULL) { + written = snprintf(buffer, buflen, "(null)"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } else { + for (i = 0; i < ai->ai_addrlen; i++) { + written = snprintf(buffer, buflen, + i + 1 != ai->ai_addrlen ? "%d." : "%d", + ((unsigned char *)ai->ai_addr)[i]); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } + + if (ai->ai_next != NULL) { + written = snprintf(buffer, buflen, ":"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + sdump_addrinfo(ai->ai_next, buffer, buflen); + } +} + +void +dump_addrinfo(struct addrinfo *result) +{ + if (result != NULL) { + char buffer[2048]; + sdump_addrinfo(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +addrinfo_read_snapshot_addr(char *addr, unsigned char *result, size_t len) +{ + char *s, *ps, *ts; + + ps = addr; + while ((s = strsep(&ps, ".")) != NULL) { + if (len == 0) + return (-1); + + *result = (unsigned char)strtol(s, &ts, 10); + ++result; + if (*ts != '\0') + return (-1); + + --len; + } + if (len != 0) + return (-1); + else + return (0); +} + +static int +addrinfo_read_snapshot_ai(struct addrinfo *ai, char *line) +{ + char *s, *ps, *ts; + int i, rv, *pi; + + rv = 0; + i = 0; + ps = line; + memset(ai, 0, sizeof(struct addrinfo)); + while ((s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + case 1: + case 2: + case 3: + pi = &ai->ai_flags + i; + *pi = (int)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 4: + ai->ai_addrlen = (socklen_t)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 5: + if (strcmp(s, "(null)") != 0) { + ai->ai_canonname = strdup(s); + ATF_REQUIRE(ai->ai_canonname != NULL); + } + break; + case 6: + if (strcmp(s, "(null)") != 0) { + ai->ai_addr = calloc(1, ai->ai_addrlen); + ATF_REQUIRE(ai->ai_addr != NULL); + rv = addrinfo_read_snapshot_addr(s, + (unsigned char *)ai->ai_addr, + ai->ai_addrlen); + + if (rv != 0) + goto fin; + } + break; + default: + /* NOTE: should not be reachable */ + rv = -1; + goto fin; + } + + ++i; + } + +fin: + if (i != 7 || rv != 0) { + free_addrinfo(ai); + ai = NULL; + return (-1); + } + + return (0); +} + +static int +addrinfo_read_snapshot_func(struct addrinfo *ai, char *line) +{ + struct addrinfo *ai2; + char *s, *ps; + int i, rv; + + printf("1 line read from snapshot:\n%s\n", line); + + rv = 0; + i = 0; + ps = line; + + s = strsep(&ps, ":"); + if (s == NULL) + return (-1); + + rv = addrinfo_read_snapshot_ai(ai, s); + if (rv != 0) + return (-1); + + ai2 = ai; + while ((s = strsep(&ps, ":")) != NULL) { + ai2->ai_next = calloc(1, sizeof(struct addrinfo)); + ATF_REQUIRE(ai2->ai_next != NULL); + + rv = addrinfo_read_snapshot_ai(ai2->ai_next, s); + if (rv != 0) { + free_addrinfo(ai); + ai = NULL; + return (-1); + } + + ai2 = ai2->ai_next; + } + + return (0); +} + +static int +addrinfo_test_correctness(struct addrinfo *ai, void *mdata) +{ + + printf("testing correctness with the following data:\n"); + dump_addrinfo(ai); + + if (ai == NULL) + goto errfin; + + if (!(ai->ai_family >= 0 && ai->ai_family < AF_MAX)) + goto errfin; + + if (ai->ai_socktype != 0 && ai->ai_socktype != SOCK_STREAM && + ai->ai_socktype != SOCK_DGRAM && ai->ai_socktype != SOCK_RAW) + goto errfin; + + if (ai->ai_protocol != 0 && ai->ai_protocol != IPPROTO_UDP && + ai->ai_protocol != IPPROTO_TCP) + goto errfin; + + if ((ai->ai_flags & ~(AI_CANONNAME | AI_NUMERICHOST | AI_PASSIVE)) != 0) + goto errfin; + + if (ai->ai_addrlen != ai->ai_addr->sa_len || + ai->ai_family != ai->ai_addr->sa_family) + goto errfin; + + printf("correct\n"); + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +static int +addrinfo_read_hostlist_func(struct addrinfo *ai, char *line) +{ + struct addrinfo *result; + int rv; + + printf("resolving %s: ", line); + rv = getaddrinfo(line, NULL, &hints, &result); + if (rv == 0) { + printf("found\n"); + + rv = addrinfo_test_correctness(result, NULL); + if (rv != 0) { + freeaddrinfo(result); + result = NULL; + return (rv); + } + + clone_addrinfo(ai, result); + freeaddrinfo(result); + result = NULL; + } else { + printf("not found\n"); + + memset(ai, 0, sizeof(struct addrinfo)); + } + return (0); +} + +void +run_tests(char *hostlist_file, char *snapshot_file, int ai_family) +{ + struct addrinfo_test_data td, td_snap; + int rv; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = ai_family; + hints.ai_flags = AI_CANONNAME; + + if (snapshot_file != NULL) + method = TEST_BUILD_SNAPSHOT; + + TEST_DATA_INIT(addrinfo, &td, clone_addrinfo, free_addrinfo); + TEST_DATA_INIT(addrinfo, &td_snap, clone_addrinfo, free_addrinfo); + + ATF_REQUIRE_MSG(access(hostlist_file, R_OK) == 0, + "can't access the hostlist file %s\n", hostlist_file); + + printf("building host lists from %s\n", hostlist_file); + + rv = TEST_SNAPSHOT_FILE_READ(addrinfo, hostlist_file, &td, + addrinfo_read_hostlist_func); + if (rv != 0) + goto fin; + + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the snapshot " + "file %s\n", snapshot_file); + + rv = -1; + goto fin; + } + } else { + rv = TEST_SNAPSHOT_FILE_READ(addrinfo, snapshot_file, + &td_snap, addrinfo_read_snapshot_func); + if (rv != 0) { + printf("error reading snapshot file: %s\n", + strerror(errno)); + goto fin; + } + } + } + + switch (method) { + case TEST_GETADDRINFO: + if (snapshot_file != NULL) + ATF_CHECK(DO_2PASS_TEST(addrinfo, &td, &td_snap, + compare_addrinfo, NULL) == 0); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) { + ATF_CHECK(TEST_SNAPSHOT_FILE_WRITE(addrinfo, + snapshot_file, &td, sdump_addrinfo) == 0); + } + break; + default: + break; + } + +fin: + TEST_DATA_DESTROY(addrinfo, &td_snap); + TEST_DATA_DESTROY(addrinfo, &td); + + free(hostlist_file); + free(snapshot_file); +} + +#define HOSTLIST_FILE "mach" +#define RUN_TESTS(tc, snapshot_file, ai_family) do { \ + char *_hostlist_file; \ + char *_snapshot_file; \ + ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \ + atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \ + if (snapshot_file == NULL) \ + _snapshot_file = NULL; \ + else { \ + _snapshot_file = strdup(snapshot_file); \ + ATF_REQUIRE(_snapshot_file != NULL); \ + } \ + run_tests(_hostlist_file, _snapshot_file, ai_family); \ +} while(0) + +ATF_TC_WITHOUT_HEAD(pf_unspec); +ATF_TC_BODY(pf_unspec, tc) +{ + + RUN_TESTS(tc, NULL, AF_UNSPEC); +} + +ATF_TC_WITHOUT_HEAD(pf_unspec_with_snapshot); +ATF_TC_BODY(pf_unspec_with_snapshot, tc) +{ + + RUN_TESTS(tc, "snapshot_ai", AF_UNSPEC); +} + +ATF_TC_WITHOUT_HEAD(pf_inet); +ATF_TC_BODY(pf_inet, tc) +{ + + ATF_REQUIRE_FEATURE("inet"); + RUN_TESTS(tc, NULL, AF_INET); +} + +ATF_TC_WITHOUT_HEAD(pf_inet_with_snapshot); +ATF_TC_BODY(pf_inet_with_snapshot, tc) +{ + + ATF_REQUIRE_FEATURE("inet"); + RUN_TESTS(tc, "snapshot_ai4", AF_INET); +} + +ATF_TC_WITHOUT_HEAD(pf_inet6); +ATF_TC_BODY(pf_inet6, tc) +{ + + ATF_REQUIRE_FEATURE("inet6"); + RUN_TESTS(tc, NULL, AF_INET6); +} + +ATF_TC_WITHOUT_HEAD(pf_inet6_with_snapshot); +ATF_TC_BODY(pf_inet6_with_snapshot, tc) +{ + + ATF_REQUIRE_FEATURE("inet6"); + RUN_TESTS(tc, "snapshot_ai6", AF_INET6); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pf_unspec); + ATF_TP_ADD_TC(tp, pf_unspec_with_snapshot); + ATF_TP_ADD_TC(tp, pf_inet); + ATF_TP_ADD_TC(tp, pf_inet_with_snapshot); + ATF_TP_ADD_TC(tp, pf_inet6); + ATF_TP_ADD_TC(tp, pf_inet6_with_snapshot); + + return (atf_no_error()); +} Property changes on: head/lib/libc/tests/nss/getaddrinfo_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libc/tests/nss/getgr_test.c =================================================================== --- head/lib/libc/tests/nss/getgr_test.c (nonexistent) +++ head/lib/libc/tests/nss/getgr_test.c (revision 292323) @@ -0,0 +1,541 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETGRENT = 1, + TEST_GETGRNAM = 2, + TEST_GETGRGID = 4, + TEST_GETGRENT_2PASS = 8, + TEST_BUILD_SNAPSHOT = 16, +}; + +static enum test_methods method = TEST_BUILD_SNAPSHOT; + +DECLARE_TEST_DATA(group) +DECLARE_TEST_FILE_SNAPSHOT(group) +DECLARE_1PASS_TEST(group) +DECLARE_2PASS_TEST(group) + +static void clone_group(struct group *, struct group const *); +static int compare_group(struct group *, struct group *, void *); +static void dump_group(struct group *); +static void free_group(struct group *); + +static void sdump_group(struct group *, char *, size_t); +static int group_read_snapshot_func(struct group *, char *); + +static int group_check_ambiguity(struct group_test_data *, + struct group *); +static int group_fill_test_data(struct group_test_data *); +static int group_test_correctness(struct group *, void *); +static int group_test_getgrnam(struct group *, void *); +static int group_test_getgrgid(struct group *, void *); +static int group_test_getgrent(struct group *, void *); + +IMPLEMENT_TEST_DATA(group) +IMPLEMENT_TEST_FILE_SNAPSHOT(group) +IMPLEMENT_1PASS_TEST(group) +IMPLEMENT_2PASS_TEST(group) + +static void +clone_group(struct group *dest, struct group const *src) +{ + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + char **cp; + int members_num; + + memset(dest, 0, sizeof(struct group)); + + if (src->gr_name != NULL) { + dest->gr_name = strdup(src->gr_name); + ATF_REQUIRE(dest->gr_name != NULL); + } + + if (src->gr_passwd != NULL) { + dest->gr_passwd = strdup(src->gr_passwd); + ATF_REQUIRE(dest->gr_passwd != NULL); + } + dest->gr_gid = src->gr_gid; + + if (src->gr_mem != NULL) { + members_num = 0; + for (cp = src->gr_mem; *cp; ++cp) + ++members_num; + + dest->gr_mem = calloc(1, (members_num + 1) * sizeof(char *)); + ATF_REQUIRE(dest->gr_mem != NULL); + + for (cp = src->gr_mem; *cp; ++cp) { + dest->gr_mem[cp - src->gr_mem] = strdup(*cp); + ATF_REQUIRE(dest->gr_mem[cp - src->gr_mem] != NULL); + } + } +} + +static void +free_group(struct group *grp) +{ + char **cp; + + ATF_REQUIRE(grp != NULL); + + free(grp->gr_name); + free(grp->gr_passwd); + + for (cp = grp->gr_mem; *cp; ++cp) + free(*cp); + free(grp->gr_mem); +} + +static int +compare_group(struct group *grp1, struct group *grp2, void *mdata) +{ + char **c1, **c2; + + if (grp1 == grp2) + return (0); + + if (grp1 == NULL || grp2 == NULL) + goto errfin; + + if (strcmp(grp1->gr_name, grp2->gr_name) != 0 || + strcmp(grp1->gr_passwd, grp2->gr_passwd) != 0 || + grp1->gr_gid != grp2->gr_gid) + goto errfin; + + c1 = grp1->gr_mem; + c2 = grp2->gr_mem; + + if (grp1->gr_mem == NULL || grp2->gr_mem == NULL) + goto errfin; + + for (; *c1 && *c2; ++c1, ++c2) + if (strcmp(*c1, *c2) != 0) + goto errfin; + + if (*c1 != '\0' || *c2 != '\0') + goto errfin; + + return 0; + +errfin: + if (mdata == NULL) { + printf("following structures are not equal:\n"); + dump_group(grp1); + dump_group(grp2); + } + + return (-1); +} + +static void +sdump_group(struct group *grp, char *buffer, size_t buflen) +{ + char **cp; + int written; + + written = snprintf(buffer, buflen, "%s %s %d", + grp->gr_name, grp->gr_passwd, grp->gr_gid); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (grp->gr_mem != NULL) { + if (*(grp->gr_mem) != '\0') { + for (cp = grp->gr_mem; *cp; ++cp) { + written = snprintf(buffer, buflen, " %s",*cp); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } else + snprintf(buffer, buflen, " nomem"); + } else + snprintf(buffer, buflen, " (null)"); +} + +static int +group_read_snapshot_func(struct group *grp, char *line) +{ + StringList *sl; + char *s, *ps, *ts; + int i; + + printf("1 line read from snapshot:\n%s\n", line); + + i = 0; + sl = NULL; + ps = line; + memset(grp, 0, sizeof(struct group)); + while ((s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + grp->gr_name = strdup(s); + ATF_REQUIRE(grp->gr_name != NULL); + break; + + case 1: + grp->gr_passwd = strdup(s); + ATF_REQUIRE(grp->gr_passwd != NULL); + break; + + case 2: + grp->gr_gid = (gid_t)strtol(s, &ts, 10); + if (*ts != '\0') { + free(grp->gr_name); + free(grp->gr_passwd); + grp->gr_name = NULL; + grp->gr_passwd = NULL; + return (-1); + } + break; + + default: + if (sl == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl = sl_init(); + ATF_REQUIRE(sl != NULL); + + if (strcmp(s, "nomem") != 0) { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + } else { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + break; + } + ++i; + } + + if (i < 3) { + free(grp->gr_name); + free(grp->gr_passwd); + memset(grp, 0, sizeof(struct group)); + return (-1); + } + + sl_add(sl, NULL); + grp->gr_mem = sl->sl_str; + + /* NOTE: is it a dirty hack or not? */ + free(sl); + return (0); +} + +static void +dump_group(struct group *result) +{ + if (result != NULL) { + char buffer[1024]; + sdump_group(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +group_fill_test_data(struct group_test_data *td) +{ + struct group *grp; + + setgroupent(1); + while ((grp = getgrent()) != NULL) { + if (group_test_correctness(grp, NULL) == 0) + TEST_DATA_APPEND(group, td, grp); + else + return (-1); + } + endgrent(); + + return (0); +} + +static int +group_test_correctness(struct group *grp, void *mdata) +{ + printf("testing correctness with the following data:\n"); + dump_group(grp); + + if (grp == NULL) + goto errfin; + + if (grp->gr_name == NULL) + goto errfin; + + if (grp->gr_passwd == NULL) + goto errfin; + + if (grp->gr_mem == NULL) + goto errfin; + + printf("correct\n"); + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +/* group_check_ambiguity() is needed here because when doing the getgrent() + * calls sequence, records from different nsswitch sources can be different, + * though having the same pw_name/pw_uid */ +static int +group_check_ambiguity(struct group_test_data *td, struct group *pwd) +{ + + return (TEST_DATA_FIND(group, td, pwd, compare_group, + NULL) != NULL ? 0 : -1); +} + +static int +group_test_getgrnam(struct group *grp_model, void *mdata) +{ + struct group *grp; + + printf("testing getgrnam() with the following data:\n"); + dump_group(grp_model); + + grp = getgrnam(grp_model->gr_name); + if (group_test_correctness(grp, NULL) != 0) + goto errfin; + + if (compare_group(grp, grp_model, NULL) != 0 && + group_check_ambiguity((struct group_test_data *)mdata, grp) != 0) + goto errfin; + + return (0); + +errfin: + return (-1); +} + +static int +group_test_getgrgid(struct group *grp_model, void *mdata) +{ + struct group *grp; + + printf("testing getgrgid() with the following data...\n"); + dump_group(grp_model); + + grp = getgrgid(grp_model->gr_gid); + if (group_test_correctness(grp, NULL) != 0 || + (compare_group(grp, grp_model, NULL) != 0 && + group_check_ambiguity((struct group_test_data *)mdata, grp) != 0)) { + return (-1); + } else { + return (0); + } +} + +static int +group_test_getgrent(struct group *grp, void *mdata) +{ + /* Only correctness can be checked when doing 1-pass test for + * getgrent(). */ + return (group_test_correctness(grp, NULL)); +} + +static int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct group_test_data td, td_snap, td_2pass; + int rv; + + TEST_DATA_INIT(group, &td, clone_group, free_group); + TEST_DATA_INIT(group, &td_snap, clone_group, free_group); + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the file %s\n", + snapshot_file); + + rv = -1; + goto fin; + } + } else { + if (method == TEST_BUILD_SNAPSHOT) { + rv = 0; + goto fin; + } + + TEST_SNAPSHOT_FILE_READ(group, snapshot_file, + &td_snap, group_read_snapshot_func); + } + } + + rv = group_fill_test_data(&td); + if (rv == -1) + return (-1); + switch (method) { + case TEST_GETGRNAM: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(group, &td, + group_test_getgrnam, (void *)&td); + else + rv = DO_1PASS_TEST(group, &td_snap, + group_test_getgrnam, (void *)&td_snap); + break; + case TEST_GETGRGID: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(group, &td, + group_test_getgrgid, (void *)&td); + else + rv = DO_1PASS_TEST(group, &td_snap, + group_test_getgrgid, (void *)&td_snap); + break; + case TEST_GETGRENT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(group, &td, group_test_getgrent, + (void *)&td); + else + rv = DO_2PASS_TEST(group, &td, &td_snap, + compare_group, NULL); + break; + case TEST_GETGRENT_2PASS: + TEST_DATA_INIT(group, &td_2pass, clone_group, free_group); + rv = group_fill_test_data(&td_2pass); + if (rv != -1) + rv = DO_2PASS_TEST(group, &td, &td_2pass, + compare_group, NULL); + TEST_DATA_DESTROY(group, &td_2pass); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) + rv = TEST_SNAPSHOT_FILE_WRITE(group, snapshot_file, &td, + sdump_group); + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(group, &td_snap); + TEST_DATA_DESTROY(group, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_grp" + +ATF_TC_BODY(getgrent, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrent_with_snapshot); +ATF_TC_BODY(getgrent_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrent_with_two_pass); +ATF_TC_BODY(getgrent_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRENT_2PASS) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrgid); +ATF_TC_BODY(getgrgid, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRGID) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrgid_with_snapshot); +ATF_TC_BODY(getgrgid_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRGID) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrnam); +ATF_TC_BODY(getgrnam, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRNAM) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrnam_with_snapshot); +ATF_TC_BODY(getgrnam_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRNAM) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrent); +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getgrent); + ATF_TP_ADD_TC(tp, getgrent_with_snapshot); + ATF_TP_ADD_TC(tp, getgrent_with_two_pass); + ATF_TP_ADD_TC(tp, getgrgid); + ATF_TP_ADD_TC(tp, getgrgid_with_snapshot); + ATF_TP_ADD_TC(tp, getgrnam); + ATF_TP_ADD_TC(tp, getgrnam_with_snapshot); + + return (atf_no_error()); +} Property changes on: head/lib/libc/tests/nss/getgr_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libc/tests/nss/gethostby_test.c =================================================================== --- head/lib/libc/tests/nss/gethostby_test.c (nonexistent) +++ head/lib/libc/tests/nss/gethostby_test.c (revision 292323) @@ -0,0 +1,1506 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "freebsd_test_suite/macros.h" +#include "testutil.h" + +enum test_methods { + TEST_GETHOSTBYNAME2, + TEST_GETHOSTBYADDR, + TEST_GETHOSTBYNAME2_GETADDRINFO, + TEST_GETHOSTBYADDR_GETNAMEINFO, + TEST_BUILD_SNAPSHOT, + TEST_BUILD_ADDR_SNAPSHOT +}; + +static int ipnode_flags = 0; +static int af_type = AF_INET; +static bool use_ipnode_functions; + +DECLARE_TEST_DATA(hostent) +DECLARE_TEST_FILE_SNAPSHOT(hostent) +DECLARE_1PASS_TEST(hostent) +DECLARE_2PASS_TEST(hostent) + +/* These stubs will use gethostby***() or getipnodeby***() functions, + * depending on the use_ipnode_functions global variable value */ +static struct hostent *__gethostbyname2(const char *, int); +static struct hostent *__gethostbyaddr(const void *, socklen_t, int); +static void __freehostent(struct hostent *); + +static void clone_hostent(struct hostent *, struct hostent const *); +static int compare_hostent(struct hostent *, struct hostent *, void *); +static void dump_hostent(struct hostent *); +static void free_hostent(struct hostent *); + +static int is_hostent_equal(struct hostent *, struct addrinfo *); + +static void sdump_hostent(struct hostent *, char *, size_t); +static int hostent_read_hostlist_func(struct hostent *, char *); +static int hostent_read_snapshot_addr(char *, unsigned char *, size_t); +static int hostent_read_snapshot_func(struct hostent *, char *); + +static int hostent_test_correctness(struct hostent *, void *); +static int hostent_test_gethostbyaddr(struct hostent *, void *); +static int hostent_test_getaddrinfo_eq(struct hostent *, void *); +static int hostent_test_getnameinfo_eq(struct hostent *, void *); + +static void usage(void) __attribute__((__noreturn__)); + +IMPLEMENT_TEST_DATA(hostent) +IMPLEMENT_TEST_FILE_SNAPSHOT(hostent) +IMPLEMENT_1PASS_TEST(hostent) +IMPLEMENT_2PASS_TEST(hostent) + +static struct hostent * +__gethostbyname2(const char *name, int af) +{ + struct hostent *he; + int error; + + if (use_ipnode_functions) { + error = 0; + he = getipnodebyname(name, af, ipnode_flags, &error); + if (he == NULL) + errno = error; + } else + he = gethostbyname2(name, af); + + return (he); +} + +static struct hostent * +__gethostbyaddr(const void *addr, socklen_t len, int af) +{ + struct hostent *he; + int error; + + if (use_ipnode_functions) { + error = 0; + he = getipnodebyaddr(addr, len, af, &error); + if (he == NULL) + errno = error; + } else + he = gethostbyaddr(addr, len, af); + + return (he); +} + +static void +__freehostent(struct hostent *he) +{ + + /* NOTE: checking for he != NULL - just in case */ + if (use_ipnode_functions && he != NULL) + freehostent(he); +} + +static void +clone_hostent(struct hostent *dest, struct hostent const *src) +{ + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + char **cp; + int aliases_num; + int addrs_num; + size_t offset; + + memset(dest, 0, sizeof(struct hostent)); + + if (src->h_name != NULL) { + dest->h_name = strdup(src->h_name); + ATF_REQUIRE(dest->h_name != NULL); + } + + dest->h_addrtype = src->h_addrtype; + dest->h_length = src->h_length; + + if (src->h_aliases != NULL) { + aliases_num = 0; + for (cp = src->h_aliases; *cp; ++cp) + ++aliases_num; + + dest->h_aliases = calloc(1, (aliases_num + 1) * + sizeof(char *)); + ATF_REQUIRE(dest->h_aliases != NULL); + + for (cp = src->h_aliases; *cp; ++cp) { + dest->h_aliases[cp - src->h_aliases] = strdup(*cp); + ATF_REQUIRE(dest->h_aliases[cp - src->h_aliases] != NULL); + } + } + + if (src->h_addr_list != NULL) { + addrs_num = 0; + for (cp = src->h_addr_list; *cp; ++cp) + ++addrs_num; + + dest->h_addr_list = calloc(1, (addrs_num + 1) * sizeof(char *)); + ATF_REQUIRE(dest->h_addr_list != NULL); + + for (cp = src->h_addr_list; *cp; ++cp) { + offset = cp - src->h_addr_list; + dest->h_addr_list[offset] = malloc(src->h_length); + ATF_REQUIRE(dest->h_addr_list[offset] != NULL); + memcpy(dest->h_addr_list[offset], + src->h_addr_list[offset], src->h_length); + } + } +} + +static void +free_hostent(struct hostent *ht) +{ + char **cp; + + ATF_REQUIRE(ht != NULL); + + free(ht->h_name); + + if (ht->h_aliases != NULL) { + for (cp = ht->h_aliases; *cp; ++cp) + free(*cp); + free(ht->h_aliases); + } + + if (ht->h_addr_list != NULL) { + for (cp = ht->h_addr_list; *cp; ++cp) + free(*cp); + free(ht->h_addr_list); + } +} + +static int +compare_hostent(struct hostent *ht1, struct hostent *ht2, void *mdata) +{ + char **c1, **c2, **ct, **cb; + int b; + + if (ht1 == ht2) + return 0; + + if (ht1 == NULL || ht2 == NULL) + goto errfin; + + if (ht1->h_name == NULL || ht2->h_name == NULL) + goto errfin; + + if (ht1->h_addrtype != ht2->h_addrtype || + ht1->h_length != ht2->h_length || + strcmp(ht1->h_name, ht2->h_name) != 0) + goto errfin; + + c1 = ht1->h_aliases; + c2 = ht2->h_aliases; + + if ((ht1->h_aliases == NULL || ht2->h_aliases == NULL) && + ht1->h_aliases != ht2->h_aliases) + goto errfin; + + if (c1 != NULL && c2 != NULL) { + cb = c1; + for (;*c1; ++c1) { + b = 0; + for (ct = c2; *ct; ++ct) { + if (strcmp(*c1, *ct) == 0) { + b = 1; + break; + } + } + if (b == 0) { + printf("h1 aliases item can't be found in h2 " + "aliases\n"); + goto errfin; + } + } + + c1 = cb; + for (;*c2; ++c2) { + b = 0; + for (ct = c1; *ct; ++ct) { + if (strcmp(*c2, *ct) == 0) { + b = 1; + break; + } + } + if (b == 0) { + printf("h2 aliases item can't be found in h1 " + "aliases\n"); + goto errfin; + } + } + } + + c1 = ht1->h_addr_list; + c2 = ht2->h_addr_list; + + if ((ht1->h_addr_list == NULL || ht2->h_addr_list== NULL) && + ht1->h_addr_list != ht2->h_addr_list) + goto errfin; + + if (c1 != NULL && c2 != NULL) { + cb = c1; + for (; *c1; ++c1) { + b = 0; + for (ct = c2; *ct; ++ct) { + if (memcmp(*c1, *ct, ht1->h_length) == 0) { + b = 1; + break; + } + } + if (b == 0) { + printf("h1 addresses item can't be found in " + "h2 addresses\n"); + goto errfin; + } + } + + c1 = cb; + for (; *c2; ++c2) { + b = 0; + for (ct = c1; *ct; ++ct) { + if (memcmp(*c2, *ct, ht1->h_length) == 0) { + b = 1; + break; + } + } + if (b == 0) { + printf("h2 addresses item can't be found in " + "h1 addresses\n"); + goto errfin; + } + } + } + + return 0; + +errfin: + if (mdata == NULL) { + printf("following structures are not equal:\n"); + dump_hostent(ht1); + dump_hostent(ht2); + } + + return (-1); +} + +static int +check_addrinfo_for_name(struct addrinfo *ai, char const *name) +{ + struct addrinfo *ai2; + + for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) { + if (strcmp(ai2->ai_canonname, name) == 0) + return (0); + } + + return (-1); +} + +static int +check_addrinfo_for_addr(struct addrinfo *ai, char const *addr, + socklen_t addrlen, int af) +{ + struct addrinfo *ai2; + + for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) { + if (af != ai2->ai_family) + continue; + + switch (af) { + case AF_INET: + if (memcmp(addr, + (void *)&((struct sockaddr_in *)ai2->ai_addr)->sin_addr, + MIN(addrlen, ai2->ai_addrlen)) == 0) + return (0); + break; + case AF_INET6: + if (memcmp(addr, + (void *)&((struct sockaddr_in6 *)ai2->ai_addr)->sin6_addr, + MIN(addrlen, ai2->ai_addrlen)) == 0) + return (0); + break; + default: + break; + } + } + + return (-1); +} + +static int +is_hostent_equal(struct hostent *he, struct addrinfo *ai) +{ + char **cp; + int rv; + +#ifdef DEBUG + printf("checking equality of he and ai\n"); +#endif + + rv = check_addrinfo_for_name(ai, he->h_name); + if (rv != 0) { + printf("not equal - he->h_name couldn't be found\n"); + return (rv); + } + + for (cp = he->h_addr_list; *cp; ++cp) { + rv = check_addrinfo_for_addr(ai, *cp, he->h_length, + he->h_addrtype); + if (rv != 0) { + printf("not equal - one of he->h_addr_list couldn't be found\n"); + return (rv); + } + } + +#ifdef DEBUG + printf("equal\n"); +#endif + + return (0); +} + +static void +sdump_hostent(struct hostent *ht, char *buffer, size_t buflen) +{ + char **cp; + size_t i; + int written; + + written = snprintf(buffer, buflen, "%s %d %d", + ht->h_name, ht->h_addrtype, ht->h_length); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (ht->h_aliases != NULL) { + if (*(ht->h_aliases) != NULL) { + for (cp = ht->h_aliases; *cp; ++cp) { + written = snprintf(buffer, buflen, " %s",*cp); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } else { + written = snprintf(buffer, buflen, " noaliases"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } + } else { + written = snprintf(buffer, buflen, " (null)"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } + + written = snprintf(buffer, buflen, " : "); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (ht->h_addr_list != NULL) { + if (*(ht->h_addr_list) != NULL) { + for (cp = ht->h_addr_list; *cp; ++cp) { + for (i = 0; i < ht->h_length; ++i ) { + written = snprintf(buffer, buflen, + i + 1 != ht->h_length ? "%d." : "%d", + (unsigned char)(*cp)[i]); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + + if (*(cp + 1) ) { + written = snprintf(buffer, buflen, " "); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } + } + } else { + written = snprintf(buffer, buflen, " noaddrs"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } + } else { + written = snprintf(buffer, buflen, " (null)"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } +} + +static int +hostent_read_hostlist_func(struct hostent *he, char *line) +{ + struct hostent *result; + int rv; + +#ifdef DEBUG + printf("resolving %s: ", line); +#endif + result = __gethostbyname2(line, af_type); + if (result != NULL) { +#ifdef DEBUG + printf("found\n"); +#endif + + rv = hostent_test_correctness(result, NULL); + if (rv != 0) { + __freehostent(result); + return (rv); + } + + clone_hostent(he, result); + __freehostent(result); + } else { +#ifdef DEBUG + printf("not found\n"); +#endif + memset(he, 0, sizeof(struct hostent)); + he->h_name = strdup(line); + ATF_REQUIRE(he->h_name != NULL); + } + return (0); +} + +static int +hostent_read_snapshot_addr(char *addr, unsigned char *result, size_t len) +{ + char *s, *ps, *ts; + + ps = addr; + while ( (s = strsep(&ps, ".")) != NULL) { + if (len == 0) + return (-1); + + *result = (unsigned char)strtol(s, &ts, 10); + ++result; + if (*ts != '\0') + return (-1); + + --len; + } + if (len != 0) + return (-1); + else + return (0); +} + +static int +hostent_read_snapshot_func(struct hostent *ht, char *line) +{ + StringList *sl1, *sl2; + char *s, *ps, *ts; + int i, rv; + +#ifdef DEBUG + printf("1 line read from snapshot:\n%s\n", line); +#endif + + rv = 0; + i = 0; + sl1 = sl2 = NULL; + ps = line; + memset(ht, 0, sizeof(struct hostent)); + while ((s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + ht->h_name = strdup(s); + ATF_REQUIRE(ht->h_name != NULL); + break; + + case 1: + ht->h_addrtype = (int)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + + case 2: + ht->h_length = (int)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + + case 3: + if (sl1 == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl1 = sl_init(); + ATF_REQUIRE(sl1 != NULL); + + if (strcmp(s, "noaliases") != 0) { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl1, ts); + } + } else { + if (strcmp(s, ":") == 0) + ++i; + else { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl1, ts); + } + } + break; + + case 4: + if (sl2 == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl2 = sl_init(); + ATF_REQUIRE(sl2 != NULL); + + if (strcmp(s, "noaddrs") != 0) { + ts = calloc(1, ht->h_length); + ATF_REQUIRE(ts != NULL); + rv = hostent_read_snapshot_addr(s, + (unsigned char *)ts, + ht->h_length); + sl_add(sl2, ts); + if (rv != 0) + goto fin; + } + } else { + ts = calloc(1, ht->h_length); + ATF_REQUIRE(ts != NULL); + rv = hostent_read_snapshot_addr(s, + (unsigned char *)ts, ht->h_length); + sl_add(sl2, ts); + if (rv != 0) + goto fin; + } + break; + default: + break; + } + + if (i != 3 && i != 4) + ++i; + } + +fin: + if (sl1 != NULL) { + sl_add(sl1, NULL); + ht->h_aliases = sl1->sl_str; + } + if (sl2 != NULL) { + sl_add(sl2, NULL); + ht->h_addr_list = sl2->sl_str; + } + + if ((i != 4) || (rv != 0)) { + free_hostent(ht); + memset(ht, 0, sizeof(struct hostent)); + return (-1); + } + + /* NOTE: is it a dirty hack or not? */ + free(sl1); + free(sl2); + return (0); +} + +static void +dump_hostent(struct hostent *result) +{ + if (result != NULL) { + char buffer[1024]; + sdump_hostent(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +hostent_test_correctness(struct hostent *ht, void *mdata) +{ + +#ifdef DEBUG + printf("testing correctness with the following data:\n"); + dump_hostent(ht); +#endif + + if (ht == NULL) + goto errfin; + + if (ht->h_name == NULL) + goto errfin; + + if (!((ht->h_addrtype >= 0) && (ht->h_addrtype < AF_MAX))) + goto errfin; + + if ((ht->h_length != sizeof(struct in_addr)) && + (ht->h_length != sizeof(struct in6_addr))) + goto errfin; + + if (ht->h_aliases == NULL) + goto errfin; + + if (ht->h_addr_list == NULL) + goto errfin; + +#ifdef DEBUG + printf("correct\n"); +#endif + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +static int +hostent_test_gethostbyaddr(struct hostent *he, void *mdata) +{ + struct hostent *result; + struct hostent_test_data *addr_test_data; + int rv; + + addr_test_data = (struct hostent_test_data *)mdata; + + /* We should omit unresolved hostents */ + if (he->h_addr_list != NULL) { + char **cp; + for (cp = he->h_addr_list; *cp; ++cp) { +#ifdef DEBUG + printf("doing reverse lookup for %s\n", he->h_name); +#endif + + result = __gethostbyaddr(*cp, he->h_length, + he->h_addrtype); + if (result == NULL) { +#ifdef DEBUG + printf("%s: warning: reverse lookup failed " + "for %s: %s\n", __func__, he->h_name, + strerror(errno)); +#endif + continue; + } + rv = hostent_test_correctness(result, NULL); + if (rv != 0) { + __freehostent(result); + return (rv); + } + + if (addr_test_data != NULL) + TEST_DATA_APPEND(hostent, addr_test_data, + result); + + __freehostent(result); + } + } + + return (0); +} + +static int +hostent_test_getaddrinfo_eq(struct hostent *he, void *mdata) +{ + struct addrinfo *ai, hints; + int rv; + + ai = NULL; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = af_type; + hints.ai_flags = AI_CANONNAME; + + printf("using getaddrinfo() to resolve %s\n", he->h_name); + + /* struct hostent *he was not resolved */ + if (he->h_addr_list == NULL) { + /* We can be sure that he->h_name is not NULL */ + rv = getaddrinfo(he->h_name, NULL, &hints, &ai); + if (rv == 0) { + printf("not ok - shouldn't have been resolved\n"); + return (-1); + } + } else { + rv = getaddrinfo(he->h_name, NULL, &hints, &ai); + if (rv != 0) { + printf("not ok - should have been resolved\n"); + return (-1); + } + + rv = is_hostent_equal(he, ai); + if (rv != 0) { + printf("not ok - addrinfo and hostent are not equal\n"); + return (-1); + } + + } + + return (0); +} + +static int +hostent_test_getnameinfo_eq(struct hostent *he, void *mdata) +{ + char **cp; + char buffer[NI_MAXHOST]; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + struct sockaddr *saddr; + struct hostent *result; + int i, rv; + + if (he->h_addr_list == NULL) + return (0); + + for (cp = he->h_addr_list; *cp; ++cp) { +#ifdef DEBUG + printf("doing reverse lookup for %s\n", he->h_name); +#endif + result = __gethostbyaddr(*cp, he->h_length, + he->h_addrtype); + if (result != NULL) { + rv = hostent_test_correctness(result, NULL); + if (rv != 0) { + __freehostent(result); + return (rv); + } + } else + printf("%s: warning: reverse lookup failed " + "for %s: %s\n", __func__, he->h_name, + strerror(errno)); + + switch (he->h_addrtype) { + case AF_INET: + memset(&sin, 0, sizeof(struct sockaddr_in)); + sin.sin_len = sizeof(struct sockaddr_in); + sin.sin_family = AF_INET; + memcpy(&sin.sin_addr, *cp, he->h_length); + + saddr = (struct sockaddr *)&sin; + break; + case AF_INET6: + memset(&sin6, 0, sizeof(struct sockaddr_in6)); + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_family = AF_INET6; + memcpy(&sin6.sin6_addr, *cp, he->h_length); + + saddr = (struct sockaddr *)&sin6; + break; + default: + printf("warning: %d family is unsupported\n", + he->h_addrtype); + continue; + } + + ATF_REQUIRE(saddr != NULL); + rv = getnameinfo(saddr, saddr->sa_len, buffer, + sizeof(buffer), NULL, 0, NI_NAMEREQD); + + if (rv != 0 && result != NULL) { + printf("getnameinfo() didn't make the reverse " + "lookup, when it should have (%s)\n", + gai_strerror(rv)); + return (rv); + } + + if (rv == 0 && result == NULL) { + printf("getnameinfo() made the " + "reverse lookup, when it shouldn't have\n"); + return (rv); + } + + if (rv != 0 && result == NULL) { +#ifdef DEBUG + printf("both getnameinfo() and ***byaddr() failed as " + "expected\n"); +#endif + continue; + } + +#ifdef DEBUG + printf("comparing %s with %s\n", result->h_name, + buffer); +#endif + + /* + * An address might reverse resolve to hostname alias or the + * official hostname, e.g. moon.vub.ac.be. + */ + bool found_a_match; + + if (strcmp(result->h_name, buffer) == 0) { + found_a_match = true; +#ifdef DEBUG + printf("matched official hostname\n"); +#endif + } else { + for (i = 0; i < nitems(result->h_aliases); i++) { + printf("[%d] resolved: %s\n", i, + result->h_aliases[i]); + if (strcmp(result->h_aliases[i], + buffer) == 0) { + printf("matched hostname alias\n"); + found_a_match = true; + break; + } + } + } + __freehostent(result); + + if (found_a_match) { +#ifdef DEBUG + printf("getnameinfo() and ***byaddr() results are " + "equal\n"); +#endif + } else { + printf("getnameinfo() and ***byaddr() results are not " + "equal for %s\n", he->h_name); + return (-1); + } + } + + return (0); +} + +int +run_tests(const char *hostlist_file, const char *snapshot_file, int af_type, + enum test_methods method, bool use_ipv6_mapping) +{ + struct hostent_test_data td, td_addr, td_snap; + res_state statp; + int rv = -2; + + switch (af_type) { + case AF_INET: + ATF_REQUIRE_FEATURE("inet"); + ATF_REQUIRE(!use_ipv6_mapping); + break; + case AF_INET6: + ATF_REQUIRE_FEATURE("inet6"); + break; + default: + atf_tc_fail("unhandled address family: %d", af_type); + break; + } + + if (!use_ipnode_functions) { + statp = __res_state(); + if (statp == NULL || ((statp->options & RES_INIT) == 0 && + res_ninit(statp) == -1)) { + printf("error: can't init res_state\n"); + + return (-1); + } + + if (use_ipv6_mapping) + statp->options |= RES_USE_INET6; + else + statp->options &= ~RES_USE_INET6; + } + + TEST_DATA_INIT(hostent, &td, clone_hostent, free_hostent); + TEST_DATA_INIT(hostent, &td_addr, clone_hostent, free_hostent); + TEST_DATA_INIT(hostent, &td_snap, clone_hostent, free_hostent); + + if (access(hostlist_file, R_OK) != 0) { + printf("can't access the hostlist file %s\n", hostlist_file); + rv = -1; + goto fin; + } + +#ifdef DEBUG + printf("building host lists from %s\n", hostlist_file); +#endif + + rv = TEST_SNAPSHOT_FILE_READ(hostent, hostlist_file, &td, + hostent_read_hostlist_func); + if (rv != 0) { + printf("failed to read the host list file: %s\n", + hostlist_file); + goto fin; + } + + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) { + if (method != TEST_GETHOSTBYADDR) + method = TEST_BUILD_SNAPSHOT; + else + method = TEST_BUILD_ADDR_SNAPSHOT; + } else { + printf("can't access the snapshot file %s\n", + snapshot_file); + rv = -1; + goto fin; + } + } else { + rv = TEST_SNAPSHOT_FILE_READ(hostent, snapshot_file, + &td_snap, hostent_read_snapshot_func); + if (rv != 0) { + printf("error reading snapshot file\n"); + goto fin; + } + } + } + + switch (method) { + case TEST_GETHOSTBYNAME2: + if (snapshot_file != NULL) + rv = DO_2PASS_TEST(hostent, &td, &td_snap, + compare_hostent, NULL); + break; + case TEST_GETHOSTBYADDR: + rv = DO_1PASS_TEST(hostent, &td, + hostent_test_gethostbyaddr, (void *)&td_addr); + if (rv != 0) + goto fin; + + if (snapshot_file != NULL) + rv = DO_2PASS_TEST(hostent, &td_addr, &td_snap, + compare_hostent, NULL); + break; + case TEST_GETHOSTBYNAME2_GETADDRINFO: + rv = DO_1PASS_TEST(hostent, &td, + hostent_test_getaddrinfo_eq, NULL); + break; + case TEST_GETHOSTBYADDR_GETNAMEINFO: + rv = DO_1PASS_TEST(hostent, &td, + hostent_test_getnameinfo_eq, NULL); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) { + rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file, + &td, sdump_hostent); + } + break; + case TEST_BUILD_ADDR_SNAPSHOT: + if (snapshot_file != NULL) { + rv = DO_1PASS_TEST(hostent, &td, + hostent_test_gethostbyaddr, (void *)&td_addr); + if (rv != 0) + goto fin; + rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file, + &td_addr, sdump_hostent); + } + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(hostent, &td_snap); + TEST_DATA_DESTROY(hostent, &td_addr); + TEST_DATA_DESTROY(hostent, &td); + + return (rv); +} + +#define HOSTLIST_FILE "mach" + +#define _RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \ +do { \ + char *_hostlist_file; \ + char *_snapshot_file; \ + ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \ + atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \ + if (snapshot_file == NULL) \ + _snapshot_file = NULL; \ + else { \ + _snapshot_file = strdup(snapshot_file); \ + ATF_REQUIRE(_snapshot_file != NULL); \ + } \ + ATF_REQUIRE(run_tests(_hostlist_file, _snapshot_file, af_type, \ + method, use_ipv6_mapping) == 0); \ +} while(0) + +#define RUN_HOST_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \ +do { \ + use_ipnode_functions = false; \ + _RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \ +} while(0) + +#define RUN_IPNODE_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \ +do { \ + use_ipnode_functions = true; \ + _RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \ +} while(0) + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4); +ATF_TC_BODY(gethostbyaddr_ipv4, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4_with_snapshot); +ATF_TC_BODY(gethostbyaddr_ipv4_with_snapshot, tc) +{ + + RUN_HOST_TESTS(tc, "snapshot_htaddr4", AF_INET, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6); +ATF_TC_BODY(gethostbyaddr_ipv6, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_AI_V4MAPPED); +ATF_TC_BODY(gethostbyaddr_ipv6_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot); +ATF_TC_BODY(gethostbyaddr_ipv6_with_snapshot, tc) +{ + + RUN_HOST_TESTS(tc, "snapshot_htaddr6", AF_INET6, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED); +ATF_TC_BODY(gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_HOST_TESTS(tc, "snapshot_htaddr6map", AF_INET6, TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv4); +ATF_TC_BODY(gethostbyname2_getaddrinfo_ipv4, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv6); +ATF_TC_BODY(gethostbyname2_getaddrinfo_ipv6, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv4); +ATF_TC_BODY(gethostbyaddr_getnameinfo_ipv4, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv6); +ATF_TC_BODY(gethostbyaddr_getnameinfo_ipv6, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4); +ATF_TC_BODY(gethostbyname2_ipv4, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4_with_snapshot); +ATF_TC_BODY(gethostbyname2_ipv4_with_snapshot, tc) +{ + + RUN_HOST_TESTS(tc, "snapshot_htname4", AF_INET, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6); +ATF_TC_BODY(gethostbyname2_ipv6, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_AI_V4MAPPED); +ATF_TC_BODY(gethostbyname2_ipv6_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot); +ATF_TC_BODY(gethostbyname2_ipv6_with_snapshot, tc) +{ + + RUN_HOST_TESTS(tc, "snapshot_htname6", AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED); +ATF_TC_BODY(gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_HOST_TESTS(tc, "snapshot_htname6map", AF_INET6, TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4); +ATF_TC_BODY(getipnodebyaddr_ipv4, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4_with_snapshot); +ATF_TC_BODY(getipnodebyaddr_ipv4_with_snapshot, tc) +{ + + RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr4", AF_INET, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv4); +ATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv4, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6); +ATF_TC_BODY(getipnodebyaddr_ipv6, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED); +ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG); +ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL); +ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ALL; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot); +ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot, tc) +{ + + RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr6", AF_INET6, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED); +ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodeaddr6_AI_V4MAPPED", AF_INET6, + TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG); +ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodeaddr6_AI_V4MAPPED_CFG", AF_INET6, + TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL); +ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ALL; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodeaddr6_AI_V4MAPPED_CFG_AI_ALL", AF_INET6, + TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv6); +ATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv6, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4); +ATF_TC_BODY(getipnodebyname_ipv4, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot); +ATF_TC_BODY(getipnodebyname_ipv4_with_snapshot, tc) +{ + + RUN_IPNODE_TESTS(tc, "snapshot_ipnodename4", AF_INET, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv4_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, "snapshot_ipnodename4_AI_ADDRCONFIG", AF_INET, + TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv4); +ATF_TC_BODY(getipnodebyname_getaddrinfo_ipv4, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6); +ATF_TC_BODY(getipnodebyname_ipv6, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot, tc) +{ + + RUN_IPNODE_TESTS(tc, "snapshot_ipnodename6", AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv6_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED); +ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG); +ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL); +ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ALL; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodename6_AI_V4MAPPED", AF_INET6, + TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodename6_AI_V4MAPPED_CFG", AF_INET6, + TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ADDRCONFIG", AF_INET6, + TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ALL; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ALL", AF_INET6, + TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, "snapshot_ipnodename6_AI_ADDRCONFIG", AF_INET6, + TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv6); +ATF_TC_BODY(getipnodebyname_getaddrinfo_ipv6, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* gethostbyaddr */ + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv4); + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv4_with_snapshot); + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6); + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_AI_V4MAPPED); /* XXX */ + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_with_snapshot); + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, gethostbyaddr_getnameinfo_ipv4); + ATF_TP_ADD_TC(tp, gethostbyaddr_getnameinfo_ipv6); + + /* gethostbyname2 */ + ATF_TP_ADD_TC(tp, gethostbyname2_getaddrinfo_ipv4); + ATF_TP_ADD_TC(tp, gethostbyname2_getaddrinfo_ipv6); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv4); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv4_with_snapshot); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv6); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_with_snapshot); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED); + + /* getipnodebyaddr */ + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv4); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv4_with_snapshot); + ATF_TP_ADD_TC(tp, getipnodebyaddr_getnameinfo_ipv4); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED_CFG); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL); + ATF_TP_ADD_TC(tp, getipnodebyaddr_getnameinfo_ipv6); + + /* getipnodebyname */ + ATF_TP_ADD_TC(tp, getipnodebyname_ipv4); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_with_snapshot); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_getaddrinfo_ipv4); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_getaddrinfo_ipv6); + + return (atf_no_error()); +} Property changes on: head/lib/libc/tests/nss/gethostby_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libc/tests/nss/getproto_test.c =================================================================== --- head/lib/libc/tests/nss/getproto_test.c (nonexistent) +++ head/lib/libc/tests/nss/getproto_test.c (revision 292323) @@ -0,0 +1,556 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETPROTOENT, + TEST_GETPROTOBYNAME, + TEST_GETPROTOBYNUMBER, + TEST_GETPROTOENT_2PASS, + TEST_BUILD_SNAPSHOT +}; + +DECLARE_TEST_DATA(protoent) +DECLARE_TEST_FILE_SNAPSHOT(protoent) +DECLARE_1PASS_TEST(protoent) +DECLARE_2PASS_TEST(protoent) + +static void clone_protoent(struct protoent *, struct protoent const *); +static int compare_protoent(struct protoent *, struct protoent *, void *); +static void dump_protoent(struct protoent *); +static void free_protoent(struct protoent *); + +static void sdump_protoent(struct protoent *, char *, size_t); +static int protoent_read_snapshot_func(struct protoent *, char *); + +static int protoent_check_ambiguity(struct protoent_test_data *, + struct protoent *); +static int protoent_fill_test_data(struct protoent_test_data *); +static int protoent_test_correctness(struct protoent *, void *); +static int protoent_test_getprotobyname(struct protoent *, void *); +static int protoent_test_getprotobynumber(struct protoent *, void *); +static int protoent_test_getprotoent(struct protoent *, void *); + +IMPLEMENT_TEST_DATA(protoent) +IMPLEMENT_TEST_FILE_SNAPSHOT(protoent) +IMPLEMENT_1PASS_TEST(protoent) +IMPLEMENT_2PASS_TEST(protoent) + +static void +clone_protoent(struct protoent *dest, struct protoent const *src) +{ + assert(dest != NULL); + assert(src != NULL); + + char **cp; + int aliases_num; + + memset(dest, 0, sizeof(struct protoent)); + + if (src->p_name != NULL) { + dest->p_name = strdup(src->p_name); + assert(dest->p_name != NULL); + } + + dest->p_proto = src->p_proto; + + if (src->p_aliases != NULL) { + aliases_num = 0; + for (cp = src->p_aliases; *cp; ++cp) + ++aliases_num; + + dest->p_aliases = calloc(1, (aliases_num+1) * sizeof(char *)); + assert(dest->p_aliases != NULL); + + for (cp = src->p_aliases; *cp; ++cp) { + dest->p_aliases[cp - src->p_aliases] = strdup(*cp); + assert(dest->p_aliases[cp - src->p_aliases] != NULL); + } + } +} + +static void +free_protoent(struct protoent *pe) +{ + char **cp; + + assert(pe != NULL); + + free(pe->p_name); + + for (cp = pe->p_aliases; *cp; ++cp) + free(*cp); + free(pe->p_aliases); +} + +static int +compare_protoent(struct protoent *pe1, struct protoent *pe2, void *mdata) +{ + char **c1, **c2; + + if (pe1 == pe2) + return 0; + + if ((pe1 == NULL) || (pe2 == NULL)) + goto errfin; + + if ((strcmp(pe1->p_name, pe2->p_name) != 0) || + (pe1->p_proto != pe2->p_proto)) + goto errfin; + + c1 = pe1->p_aliases; + c2 = pe2->p_aliases; + + if ((pe1->p_aliases == NULL) || (pe2->p_aliases == NULL)) + goto errfin; + + for (;*c1 && *c2; ++c1, ++c2) + if (strcmp(*c1, *c2) != 0) + goto errfin; + + if ((*c1 != '\0') || (*c2 != '\0')) + goto errfin; + + return 0; + +errfin: + if (mdata == NULL) { + printf("following structures are not equal:\n"); + dump_protoent(pe1); + dump_protoent(pe2); + } + + return (-1); +} + +static void +sdump_protoent(struct protoent *pe, char *buffer, size_t buflen) +{ + char **cp; + int written; + + written = snprintf(buffer, buflen, "%s %d", + pe->p_name, pe->p_proto); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (pe->p_aliases != NULL) { + if (*(pe->p_aliases) != '\0') { + for (cp = pe->p_aliases; *cp; ++cp) { + written = snprintf(buffer, buflen, " %s",*cp); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } else + snprintf(buffer, buflen, " noaliases"); + } else + snprintf(buffer, buflen, " (null)"); +} + +static int +protoent_read_snapshot_func(struct protoent *pe, char *line) +{ + StringList *sl; + char *s, *ps, *ts; + int i; + + printf("1 line read from snapshot:\n%s\n", line); + + i = 0; + sl = NULL; + ps = line; + memset(pe, 0, sizeof(struct protoent)); + while ( (s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + pe->p_name = strdup(s); + assert(pe->p_name != NULL); + break; + + case 1: + pe->p_proto = (int)strtol(s, &ts, 10); + if (*ts != '\0') { + free(pe->p_name); + return (-1); + } + break; + + default: + if (sl == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl = sl_init(); + assert(sl != NULL); + + if (strcmp(s, "noaliases") != 0) { + ts = strdup(s); + assert(ts != NULL); + sl_add(sl, ts); + } + } else { + ts = strdup(s); + assert(ts != NULL); + sl_add(sl, ts); + } + break; + } + ++i; + } + + if (i < 3) { + free(pe->p_name); + memset(pe, 0, sizeof(struct protoent)); + return (-1); + } + + sl_add(sl, NULL); + pe->p_aliases = sl->sl_str; + + /* NOTE: is it a dirty hack or not? */ + free(sl); + return (0); +} + +static void +dump_protoent(struct protoent *result) +{ + if (result != NULL) { + char buffer[1024]; + sdump_protoent(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +protoent_fill_test_data(struct protoent_test_data *td) +{ + struct protoent *pe; + + setprotoent(1); + while ((pe = getprotoent()) != NULL) { + if (protoent_test_correctness(pe, NULL) == 0) + TEST_DATA_APPEND(protoent, td, pe); + else + return (-1); + } + endprotoent(); + + return (0); +} + +static int +protoent_test_correctness(struct protoent *pe, void *mdata) +{ + printf("testing correctness with the following data:\n"); + dump_protoent(pe); + + if (pe == NULL) + goto errfin; + + if (pe->p_name == NULL) + goto errfin; + + if (pe->p_proto < 0) + goto errfin; + + if (pe->p_aliases == NULL) + goto errfin; + + printf("correct\n"); + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +/* protoent_check_ambiguity() is needed when one port+proto is associated with + * more than one peice (these cases are usually marked as PROBLEM in + * /etc/peices. This functions is needed also when one peice+proto is + * associated with several ports. We have to check all the protoent structures + * to make sure that pe really exists and correct */ +static int +protoent_check_ambiguity(struct protoent_test_data *td, struct protoent *pe) +{ + + return (TEST_DATA_FIND(protoent, td, pe, compare_protoent, + NULL) != NULL ? 0 : -1); +} + +static int +protoent_test_getprotobyname(struct protoent *pe_model, void *mdata) +{ + char **alias; + struct protoent *pe; + + printf("testing getprotobyname() with the following data:\n"); + dump_protoent(pe_model); + + pe = getprotobyname(pe_model->p_name); + if (protoent_test_correctness(pe, NULL) != 0) + goto errfin; + + if ((compare_protoent(pe, pe_model, NULL) != 0) && + (protoent_check_ambiguity((struct protoent_test_data *)mdata, pe) + !=0)) + goto errfin; + + for (alias = pe_model->p_aliases; *alias; ++alias) { + pe = getprotobyname(*alias); + + if (protoent_test_correctness(pe, NULL) != 0) + goto errfin; + + if ((compare_protoent(pe, pe_model, NULL) != 0) && + (protoent_check_ambiguity( + (struct protoent_test_data *)mdata, pe) != 0)) + goto errfin; + } + + printf("ok\n"); + return (0); + +errfin: + printf("not ok\n"); + + return (-1); +} + +static int +protoent_test_getprotobynumber(struct protoent *pe_model, void *mdata) +{ + struct protoent *pe; + + printf("testing getprotobyport() with the following data...\n"); + dump_protoent(pe_model); + + pe = getprotobynumber(pe_model->p_proto); + if ((protoent_test_correctness(pe, NULL) != 0) || + ((compare_protoent(pe, pe_model, NULL) != 0) && + (protoent_check_ambiguity((struct protoent_test_data *)mdata, pe) + != 0))) { + printf("not ok\n"); + return (-1); + } else { + printf("ok\n"); + return (0); + } +} + +static int +protoent_test_getprotoent(struct protoent *pe, void *mdata) +{ + /* Only correctness can be checked when doing 1-pass test for + * getprotoent(). */ + return (protoent_test_correctness(pe, NULL)); +} + +int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct protoent_test_data td, td_snap, td_2pass; + int rv; + + TEST_DATA_INIT(protoent, &td, clone_protoent, free_protoent); + TEST_DATA_INIT(protoent, &td_snap, clone_protoent, free_protoent); + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the file %s\n", + snapshot_file); + + rv = -1; + goto fin; + } + } else { + if (method == TEST_BUILD_SNAPSHOT) { + rv = 0; + goto fin; + } + + TEST_SNAPSHOT_FILE_READ(protoent, snapshot_file, + &td_snap, protoent_read_snapshot_func); + } + } + + rv = protoent_fill_test_data(&td); + if (rv == -1) + return (-1); + switch (method) { + case TEST_GETPROTOBYNAME: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(protoent, &td, + protoent_test_getprotobyname, (void *)&td); + else + rv = DO_1PASS_TEST(protoent, &td_snap, + protoent_test_getprotobyname, (void *)&td_snap); + break; + case TEST_GETPROTOBYNUMBER: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(protoent, &td, + protoent_test_getprotobynumber, (void *)&td); + else + rv = DO_1PASS_TEST(protoent, &td_snap, + protoent_test_getprotobynumber, (void *)&td_snap); + break; + case TEST_GETPROTOENT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(protoent, &td, + protoent_test_getprotoent, (void *)&td); + else + rv = DO_2PASS_TEST(protoent, &td, &td_snap, + compare_protoent, NULL); + break; + case TEST_GETPROTOENT_2PASS: + TEST_DATA_INIT(protoent, &td_2pass, clone_protoent, + free_protoent); + rv = protoent_fill_test_data(&td_2pass); + if (rv != -1) + rv = DO_2PASS_TEST(protoent, &td, &td_2pass, + compare_protoent, NULL); + TEST_DATA_DESTROY(protoent, &td_2pass); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) + rv = TEST_SNAPSHOT_FILE_WRITE(protoent, snapshot_file, + &td, sdump_protoent); + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(protoent, &td_snap); + TEST_DATA_DESTROY(protoent, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_proto" + +ATF_TC_WITHOUT_HEAD(build_snapshot); +ATF_TC_BODY(build_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotoent); +ATF_TC_BODY(getprotoent, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotoent_with_snapshot); +ATF_TC_BODY(getprotoent_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPROTOENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotoent_with_two_pass); +ATF_TC_BODY(getprotoent_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOENT_2PASS) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotobyname); +ATF_TC_BODY(getprotobyname, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotobyname_with_snapshot); +ATF_TC_BODY(getprotobyname_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPROTOBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotobynumber); +ATF_TC_BODY(getprotobynumber, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOBYNUMBER) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotobynumber_with_snapshot); +ATF_TC_BODY(getprotobynumber_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPROTOBYNUMBER) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, build_snapshot); + ATF_TP_ADD_TC(tp, getprotoent); + ATF_TP_ADD_TC(tp, getprotoent_with_snapshot); + ATF_TP_ADD_TC(tp, getprotoent_with_two_pass); + ATF_TP_ADD_TC(tp, getprotobyname); + ATF_TP_ADD_TC(tp, getprotobyname_with_snapshot); + ATF_TP_ADD_TC(tp, getprotobynumber); + ATF_TP_ADD_TC(tp, getprotobynumber_with_snapshot); + + return (atf_no_error()); +} Property changes on: head/lib/libc/tests/nss/getproto_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libc/tests/nss/getpw_test.c =================================================================== --- head/lib/libc/tests/nss/getpw_test.c (nonexistent) +++ head/lib/libc/tests/nss/getpw_test.c (revision 292323) @@ -0,0 +1,530 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETPWENT, + TEST_GETPWNAM, + TEST_GETPWUID, + TEST_GETPWENT_2PASS, + TEST_BUILD_SNAPSHOT +}; + +static enum test_methods method = TEST_BUILD_SNAPSHOT; + +DECLARE_TEST_DATA(passwd) +DECLARE_TEST_FILE_SNAPSHOT(passwd) +DECLARE_1PASS_TEST(passwd) +DECLARE_2PASS_TEST(passwd) + +static void clone_passwd(struct passwd *, struct passwd const *); +static int compare_passwd(struct passwd *, struct passwd *, void *); +static void free_passwd(struct passwd *); + +static void sdump_passwd(struct passwd *, char *, size_t); +static void dump_passwd(struct passwd *); + +static int passwd_read_snapshot_func(struct passwd *, char *); + +static int passwd_check_ambiguity(struct passwd_test_data *, struct passwd *); +static int passwd_fill_test_data(struct passwd_test_data *); +static int passwd_test_correctness(struct passwd *, void *); +static int passwd_test_getpwnam(struct passwd *, void *); +static int passwd_test_getpwuid(struct passwd *, void *); +static int passwd_test_getpwent(struct passwd *, void *); + +IMPLEMENT_TEST_DATA(passwd) +IMPLEMENT_TEST_FILE_SNAPSHOT(passwd) +IMPLEMENT_1PASS_TEST(passwd) +IMPLEMENT_2PASS_TEST(passwd) + +static void +clone_passwd(struct passwd *dest, struct passwd const *src) +{ + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + memcpy(dest, src, sizeof(struct passwd)); + if (src->pw_name != NULL) + dest->pw_name = strdup(src->pw_name); + if (src->pw_passwd != NULL) + dest->pw_passwd = strdup(src->pw_passwd); + if (src->pw_class != NULL) + dest->pw_class = strdup(src->pw_class); + if (src->pw_gecos != NULL) + dest->pw_gecos = strdup(src->pw_gecos); + if (src->pw_dir != NULL) + dest->pw_dir = strdup(src->pw_dir); + if (src->pw_shell != NULL) + dest->pw_shell = strdup(dest->pw_shell); +} + +static int +compare_passwd(struct passwd *pwd1, struct passwd *pwd2, void *mdata) +{ + ATF_REQUIRE(pwd1 != NULL); + ATF_REQUIRE(pwd2 != NULL); + + if (pwd1 == pwd2) + return (0); + + if (pwd1->pw_uid != pwd2->pw_uid || + pwd1->pw_gid != pwd2->pw_gid || + pwd1->pw_change != pwd2->pw_change || + pwd1->pw_expire != pwd2->pw_expire || + pwd1->pw_fields != pwd2->pw_fields || + strcmp(pwd1->pw_name, pwd2->pw_name) != 0 || + strcmp(pwd1->pw_passwd, pwd2->pw_passwd) != 0 || + strcmp(pwd1->pw_class, pwd2->pw_class) != 0 || + strcmp(pwd1->pw_gecos, pwd2->pw_gecos) != 0 || + strcmp(pwd1->pw_dir, pwd2->pw_dir) != 0 || + strcmp(pwd1->pw_shell, pwd2->pw_shell) != 0) + return (-1); + else + return (0); +} + +static void +free_passwd(struct passwd *pwd) +{ + free(pwd->pw_name); + free(pwd->pw_passwd); + free(pwd->pw_class); + free(pwd->pw_gecos); + free(pwd->pw_dir); + free(pwd->pw_shell); +} + +static void +sdump_passwd(struct passwd *pwd, char *buffer, size_t buflen) +{ + snprintf(buffer, buflen, "%s:%s:%d:%d:%jd:%s:%s:%s:%s:%jd:%d", + pwd->pw_name, pwd->pw_passwd, pwd->pw_uid, pwd->pw_gid, + (uintmax_t)pwd->pw_change, pwd->pw_class, pwd->pw_gecos, + pwd->pw_dir, pwd->pw_shell, (uintmax_t)pwd->pw_expire, + pwd->pw_fields); +} + +static void +dump_passwd(struct passwd *pwd) +{ + if (pwd != NULL) { + char buffer[2048]; + sdump_passwd(pwd, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +passwd_read_snapshot_func(struct passwd *pwd, char *line) +{ + char *s, *ps, *ts; + int i; + +#ifdef DEBUG + printf("1 line read from snapshot:\n%s\n", line); +#endif + + i = 0; + ps = line; + memset(pwd, 0, sizeof(struct passwd)); + while ((s = strsep(&ps, ":")) != NULL) { + switch (i) { + case 0: + pwd->pw_name = strdup(s); + ATF_REQUIRE(pwd->pw_name != NULL); + break; + case 1: + pwd->pw_passwd = strdup(s); + ATF_REQUIRE(pwd->pw_passwd != NULL); + break; + case 2: + pwd->pw_uid = (uid_t)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 3: + pwd->pw_gid = (gid_t)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 4: + pwd->pw_change = (time_t)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 5: + pwd->pw_class = strdup(s); + ATF_REQUIRE(pwd->pw_class != NULL); + break; + case 6: + pwd->pw_gecos = strdup(s); + ATF_REQUIRE(pwd->pw_gecos != NULL); + break; + case 7: + pwd->pw_dir = strdup(s); + ATF_REQUIRE(pwd->pw_dir != NULL); + break; + case 8: + pwd->pw_shell = strdup(s); + ATF_REQUIRE(pwd->pw_shell != NULL); + break; + case 9: + pwd->pw_expire = (time_t)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 10: + pwd->pw_fields = (int)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + default: + break; + } + ++i; + } + +fin: + if (i != 11) { + free_passwd(pwd); + memset(pwd, 0, sizeof(struct passwd)); + return (-1); + } + + return (0); +} + +static int +passwd_fill_test_data(struct passwd_test_data *td) +{ + struct passwd *pwd; + + setpassent(1); + while ((pwd = getpwent()) != NULL) { + if (passwd_test_correctness(pwd, NULL) == 0) + TEST_DATA_APPEND(passwd, td, pwd); + else + return (-1); + } + endpwent(); + + return (0); +} + +static int +passwd_test_correctness(struct passwd *pwd, void *mdata) +{ + +#ifdef DEBUG + printf("testing correctness with the following data:\n"); + dump_passwd(pwd); +#endif + + if (pwd == NULL) + return (-1); + + if (pwd->pw_name == NULL) + goto errfin; + + if (pwd->pw_passwd == NULL) + goto errfin; + + if (pwd->pw_class == NULL) + goto errfin; + + if (pwd->pw_gecos == NULL) + goto errfin; + + if (pwd->pw_dir == NULL) + goto errfin; + + if (pwd->pw_shell == NULL) + goto errfin; + +#ifdef DEBUG + printf("correct\n"); +#endif + + return (0); +errfin: +#ifdef DEBUG + printf("incorrect\n"); +#endif + + return (-1); +} + +/* passwd_check_ambiguity() is needed here because when doing the getpwent() + * calls sequence, records from different nsswitch sources can be different, + * though having the same pw_name/pw_uid */ +static int +passwd_check_ambiguity(struct passwd_test_data *td, struct passwd *pwd) +{ + + return (TEST_DATA_FIND(passwd, td, pwd, compare_passwd, + NULL) != NULL ? 0 : -1); +} + +static int +passwd_test_getpwnam(struct passwd *pwd_model, void *mdata) +{ + struct passwd *pwd; + +#ifdef DEBUG + printf("testing getpwnam() with the following data:\n"); + dump_passwd(pwd_model); +#endif + + pwd = getpwnam(pwd_model->pw_name); + if (passwd_test_correctness(pwd, NULL) != 0) + goto errfin; + + if ((compare_passwd(pwd, pwd_model, NULL) != 0) && + (passwd_check_ambiguity((struct passwd_test_data *)mdata, pwd) + !=0)) + goto errfin; + +#ifdef DEBUG + printf("ok\n"); +#endif + return (0); + +errfin: +#ifdef DEBUG + printf("not ok\n"); +#endif + return (-1); +} + +static int +passwd_test_getpwuid(struct passwd *pwd_model, void *mdata) +{ + struct passwd *pwd; + +#ifdef DEBUG + printf("testing getpwuid() with the following data...\n"); + dump_passwd(pwd_model); +#endif + + pwd = getpwuid(pwd_model->pw_uid); + if ((passwd_test_correctness(pwd, NULL) != 0) || + ((compare_passwd(pwd, pwd_model, NULL) != 0) && + (passwd_check_ambiguity((struct passwd_test_data *)mdata, pwd) + != 0))) { +#ifdef DEBUG + printf("not ok\n"); +#endif + return (-1); + } else { +#ifdef DEBUG + printf("ok\n"); +#endif + return (0); + } +} + +static int +passwd_test_getpwent(struct passwd *pwd, void *mdata) +{ + /* Only correctness can be checked when doing 1-pass test for + * getpwent(). */ + return (passwd_test_correctness(pwd, NULL)); +} + +static int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct passwd_test_data td, td_snap, td_2pass; + int rv; + + TEST_DATA_INIT(passwd, &td, clone_passwd, free_passwd); + TEST_DATA_INIT(passwd, &td_snap, clone_passwd, free_passwd); + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the file %s\n", + snapshot_file); + rv = -1; + goto fin; + } + } else { + if (method == TEST_BUILD_SNAPSHOT) { + rv = 0; + goto fin; + } + + TEST_SNAPSHOT_FILE_READ(passwd, snapshot_file, + &td_snap, passwd_read_snapshot_func); + } + } + + rv = passwd_fill_test_data(&td); + if (rv == -1) + return (-1); + + switch (method) { + case TEST_GETPWNAM: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(passwd, &td, + passwd_test_getpwnam, (void *)&td); + else + rv = DO_1PASS_TEST(passwd, &td_snap, + passwd_test_getpwnam, (void *)&td_snap); + break; + case TEST_GETPWUID: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(passwd, &td, + passwd_test_getpwuid, (void *)&td); + else + rv = DO_1PASS_TEST(passwd, &td_snap, + passwd_test_getpwuid, (void *)&td_snap); + break; + case TEST_GETPWENT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(passwd, &td, passwd_test_getpwent, + (void *)&td); + else + rv = DO_2PASS_TEST(passwd, &td, &td_snap, + compare_passwd, NULL); + break; + case TEST_GETPWENT_2PASS: + TEST_DATA_INIT(passwd, &td_2pass, clone_passwd, free_passwd); + rv = passwd_fill_test_data(&td_2pass); + if (rv != -1) + rv = DO_2PASS_TEST(passwd, &td, &td_2pass, + compare_passwd, NULL); + TEST_DATA_DESTROY(passwd, &td_2pass); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) + rv = TEST_SNAPSHOT_FILE_WRITE(passwd, snapshot_file, + &td, sdump_passwd); + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(passwd, &td_snap); + TEST_DATA_DESTROY(passwd, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_pwd" + +ATF_TC_WITHOUT_HEAD(build_snapshot); +ATF_TC_BODY(build_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwent); +ATF_TC_BODY(getpwent, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwent_with_snapshot); +ATF_TC_BODY(getpwent_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwent_with_two_pass); +ATF_TC_BODY(getpwent_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWENT_2PASS) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwnam); +ATF_TC_BODY(getpwnam, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWNAM) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwnam_with_snapshot); +ATF_TC_BODY(getpwnam_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWNAM) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwuid); +ATF_TC_BODY(getpwuid, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWUID) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwuid_with_snapshot); +ATF_TC_BODY(getpwuid_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWUID) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, build_snapshot); + ATF_TP_ADD_TC(tp, getpwent); + ATF_TP_ADD_TC(tp, getpwent_with_snapshot); + ATF_TP_ADD_TC(tp, getpwent_with_two_pass); + ATF_TP_ADD_TC(tp, getpwnam); + ATF_TP_ADD_TC(tp, getpwnam_with_snapshot); + ATF_TP_ADD_TC(tp, getpwuid); + ATF_TP_ADD_TC(tp, getpwuid_with_snapshot); + + return (atf_no_error()); +} Property changes on: head/lib/libc/tests/nss/getpw_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libc/tests/nss/getrpc_test.c =================================================================== --- head/lib/libc/tests/nss/getrpc_test.c (nonexistent) +++ head/lib/libc/tests/nss/getrpc_test.c (revision 292323) @@ -0,0 +1,560 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETRPCENT, + TEST_GETRPCBYNAME, + TEST_GETRPCBYNUMBER, + TEST_GETRPCENT_2PASS, + TEST_BUILD_SNAPSHOT +}; + +DECLARE_TEST_DATA(rpcent) +DECLARE_TEST_FILE_SNAPSHOT(rpcent) +DECLARE_1PASS_TEST(rpcent) +DECLARE_2PASS_TEST(rpcent) + +static void clone_rpcent(struct rpcent *, struct rpcent const *); +static int compare_rpcent(struct rpcent *, struct rpcent *, void *); +static void dump_rpcent(struct rpcent *); +static void free_rpcent(struct rpcent *); + +static void sdump_rpcent(struct rpcent *, char *, size_t); +static int rpcent_read_snapshot_func(struct rpcent *, char *); + +static int rpcent_check_ambiguity(struct rpcent_test_data *, + struct rpcent *); +static int rpcent_fill_test_data(struct rpcent_test_data *); +static int rpcent_test_correctness(struct rpcent *, void *); +static int rpcent_test_getrpcbyname(struct rpcent *, void *); +static int rpcent_test_getrpcbynumber(struct rpcent *, void *); +static int rpcent_test_getrpcent(struct rpcent *, void *); + +static void usage(void) __attribute__((__noreturn__)); + +IMPLEMENT_TEST_DATA(rpcent) +IMPLEMENT_TEST_FILE_SNAPSHOT(rpcent) +IMPLEMENT_1PASS_TEST(rpcent) +IMPLEMENT_2PASS_TEST(rpcent) + +static void +clone_rpcent(struct rpcent *dest, struct rpcent const *src) +{ + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + char **cp; + int aliases_num; + + memset(dest, 0, sizeof(struct rpcent)); + + if (src->r_name != NULL) { + dest->r_name = strdup(src->r_name); + ATF_REQUIRE(dest->r_name != NULL); + } + + dest->r_number = src->r_number; + + if (src->r_aliases != NULL) { + aliases_num = 0; + for (cp = src->r_aliases; *cp; ++cp) + ++aliases_num; + + dest->r_aliases = calloc(1, (aliases_num + 1) * sizeof(char *)); + ATF_REQUIRE(dest->r_aliases != NULL); + + for (cp = src->r_aliases; *cp; ++cp) { + dest->r_aliases[cp - src->r_aliases] = strdup(*cp); + ATF_REQUIRE(dest->r_aliases[cp - src->r_aliases] != NULL); + } + } +} + +static void +free_rpcent(struct rpcent *rpc) +{ + char **cp; + + ATF_REQUIRE(rpc != NULL); + + free(rpc->r_name); + + for (cp = rpc->r_aliases; *cp; ++cp) + free(*cp); + free(rpc->r_aliases); +} + +static int +compare_rpcent(struct rpcent *rpc1, struct rpcent *rpc2, void *mdata) +{ + char **c1, **c2; + + if (rpc1 == rpc2) + return 0; + + if ((rpc1 == NULL) || (rpc2 == NULL)) + goto errfin; + + if ((strcmp(rpc1->r_name, rpc2->r_name) != 0) || + (rpc1->r_number != rpc2->r_number)) + goto errfin; + + c1 = rpc1->r_aliases; + c2 = rpc2->r_aliases; + + if ((rpc1->r_aliases == NULL) || (rpc2->r_aliases == NULL)) + goto errfin; + + for (;*c1 && *c2; ++c1, ++c2) + if (strcmp(*c1, *c2) != 0) + goto errfin; + + if ((*c1 != '\0') || (*c2 != '\0')) + goto errfin; + + return 0; + +errfin: + if (mdata == NULL) { + printf("following structures are not equal:\n"); + dump_rpcent(rpc1); + dump_rpcent(rpc2); + } + + return (-1); +} + +static void +sdump_rpcent(struct rpcent *rpc, char *buffer, size_t buflen) +{ + char **cp; + int written; + + written = snprintf(buffer, buflen, "%s %d", + rpc->r_name, rpc->r_number); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (rpc->r_aliases != NULL) { + if (*(rpc->r_aliases) != '\0') { + for (cp = rpc->r_aliases; *cp; ++cp) { + written = snprintf(buffer, buflen, " %s",*cp); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } else + snprintf(buffer, buflen, " noaliases"); + } else + snprintf(buffer, buflen, " (null)"); +} + +static int +rpcent_read_snapshot_func(struct rpcent *rpc, char *line) +{ + StringList *sl; + char *s, *ps, *ts; + int i; + + printf("1 line read from snapshot:\n%s\n", line); + + i = 0; + sl = NULL; + ps = line; + memset(rpc, 0, sizeof(struct rpcent)); + while ((s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + rpc->r_name = strdup(s); + ATF_REQUIRE(rpc->r_name != NULL); + break; + + case 1: + rpc->r_number = (int)strtol(s, &ts, 10); + if (*ts != '\0') { + free(rpc->r_name); + return (-1); + } + break; + + default: + if (sl == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl = sl_init(); + ATF_REQUIRE(sl != NULL); + + if (strcmp(s, "noaliases") != 0) { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + } else { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + break; + } + i++; + } + + if (i < 3) { + free(rpc->r_name); + memset(rpc, 0, sizeof(struct rpcent)); + return (-1); + } + + sl_add(sl, NULL); + rpc->r_aliases = sl->sl_str; + + /* NOTE: is it a dirty hack or not? */ + free(sl); + return (0); +} + +static void +dump_rpcent(struct rpcent *result) +{ + if (result != NULL) { + char buffer[1024]; + sdump_rpcent(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +rpcent_fill_test_data(struct rpcent_test_data *td) +{ + struct rpcent *rpc; + + setrpcent(1); + while ((rpc = getrpcent()) != NULL) { + if (rpcent_test_correctness(rpc, NULL) == 0) + TEST_DATA_APPEND(rpcent, td, rpc); + else + return (-1); + } + endrpcent(); + + return (0); +} + +static int +rpcent_test_correctness(struct rpcent *rpc, void *mdata) +{ + + printf("testing correctness with the following data:\n"); + dump_rpcent(rpc); + + if (rpc == NULL) + goto errfin; + + if (rpc->r_name == NULL) + goto errfin; + + if (rpc->r_number < 0) + goto errfin; + + if (rpc->r_aliases == NULL) + goto errfin; + + printf("correct\n"); + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +/* rpcent_check_ambiguity() is needed when one port+rpc is associated with + * more than one peice (these cases are usually marked as PROBLEM in + * /etc/peices. This functions is needed also when one peice+rpc is + * associated with several ports. We have to check all the rpcent structures + * to make sure that rpc really exists and correct */ +static int +rpcent_check_ambiguity(struct rpcent_test_data *td, struct rpcent *rpc) +{ + + return (TEST_DATA_FIND(rpcent, td, rpc, compare_rpcent, + NULL) != NULL ? 0 : -1); +} + +static int +rpcent_test_getrpcbyname(struct rpcent *rpc_model, void *mdata) +{ + char **alias; + struct rpcent *rpc; + + printf("testing getrpcbyname() with the following data:\n"); + dump_rpcent(rpc_model); + + rpc = getrpcbyname(rpc_model->r_name); + if (rpcent_test_correctness(rpc, NULL) != 0) + goto errfin; + + if ((compare_rpcent(rpc, rpc_model, NULL) != 0) && + (rpcent_check_ambiguity((struct rpcent_test_data *)mdata, rpc) + !=0)) + goto errfin; + + for (alias = rpc_model->r_aliases; *alias; ++alias) { + rpc = getrpcbyname(*alias); + + if (rpcent_test_correctness(rpc, NULL) != 0) + goto errfin; + + if ((compare_rpcent(rpc, rpc_model, NULL) != 0) && + (rpcent_check_ambiguity( + (struct rpcent_test_data *)mdata, rpc) != 0)) + goto errfin; + } + + printf("ok\n"); + return (0); + +errfin: + printf("not ok\n"); + + return (-1); +} + +static int +rpcent_test_getrpcbynumber(struct rpcent *rpc_model, void *mdata) +{ + struct rpcent *rpc; + + printf("testing getrpcbyport() with the following data...\n"); + dump_rpcent(rpc_model); + + rpc = getrpcbynumber(rpc_model->r_number); + if (rpcent_test_correctness(rpc, NULL) != 0 || + (compare_rpcent(rpc, rpc_model, NULL) != 0 && + rpcent_check_ambiguity((struct rpcent_test_data *)mdata, rpc) + != 0)) { + printf("not ok\n"); + return (-1); + } else { + printf("ok\n"); + return (0); + } +} + +static int +rpcent_test_getrpcent(struct rpcent *rpc, void *mdata) +{ + + /* + * Only correctness can be checked when doing 1-pass test for + * getrpcent(). + */ + return (rpcent_test_correctness(rpc, NULL)); +} + +int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct rpcent_test_data td, td_snap, td_2pass; + int rv; + + TEST_DATA_INIT(rpcent, &td, clone_rpcent, free_rpcent); + TEST_DATA_INIT(rpcent, &td_snap, clone_rpcent, free_rpcent); + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the file %s\n", + snapshot_file); + + rv = -1; + goto fin; + } + } else { + if (method == TEST_BUILD_SNAPSHOT) { + rv = 0; + goto fin; + } + + TEST_SNAPSHOT_FILE_READ(rpcent, snapshot_file, + &td_snap, rpcent_read_snapshot_func); + } + } + + rv = rpcent_fill_test_data(&td); + if (rv == -1) + return (-1); + switch (method) { + case TEST_GETRPCBYNAME: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(rpcent, &td, + rpcent_test_getrpcbyname, (void *)&td); + else + rv = DO_1PASS_TEST(rpcent, &td_snap, + rpcent_test_getrpcbyname, (void *)&td_snap); + break; + case TEST_GETRPCBYNUMBER: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(rpcent, &td, + rpcent_test_getrpcbynumber, (void *)&td); + else + rv = DO_1PASS_TEST(rpcent, &td_snap, + rpcent_test_getrpcbynumber, (void *)&td_snap); + break; + case TEST_GETRPCENT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(rpcent, &td, rpcent_test_getrpcent, + (void *)&td); + else + rv = DO_2PASS_TEST(rpcent, &td, &td_snap, + compare_rpcent, NULL); + break; + case TEST_GETRPCENT_2PASS: + TEST_DATA_INIT(rpcent, &td_2pass, clone_rpcent, free_rpcent); + rv = rpcent_fill_test_data(&td_2pass); + if (rv != -1) + rv = DO_2PASS_TEST(rpcent, &td, &td_2pass, + compare_rpcent, NULL); + TEST_DATA_DESTROY(rpcent, &td_2pass); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) + rv = TEST_SNAPSHOT_FILE_WRITE(rpcent, snapshot_file, &td, + sdump_rpcent); + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(rpcent, &td_snap); + TEST_DATA_DESTROY(rpcent, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_rpc" + +ATF_TC_WITHOUT_HEAD(build_snapshot); +ATF_TC_BODY(build_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbyname); +ATF_TC_BODY(getrpcbyname, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETRPCBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbyname_with_snapshot); +ATF_TC_BODY(getrpcbyname_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETRPCBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbynumber); +ATF_TC_BODY(getrpcbynumber, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETRPCBYNUMBER) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbynumber_with_snapshot); +ATF_TC_BODY(getrpcbynumber_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETRPCBYNUMBER) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbyent); +ATF_TC_BODY(getrpcbyent, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETRPCENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbyent_with_snapshot); +ATF_TC_BODY(getrpcbyent_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETRPCENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbyent_with_two_pass); +ATF_TC_BODY(getrpcbyent_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETRPCENT_2PASS) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, build_snapshot); + ATF_TP_ADD_TC(tp, getrpcbyname); + ATF_TP_ADD_TC(tp, getrpcbyname_with_snapshot); + ATF_TP_ADD_TC(tp, getrpcbynumber); + ATF_TP_ADD_TC(tp, getrpcbynumber_with_snapshot); + ATF_TP_ADD_TC(tp, getrpcbyent); + ATF_TP_ADD_TC(tp, getrpcbyent_with_snapshot); + ATF_TP_ADD_TC(tp, getrpcbyent_with_two_pass); + + return (atf_no_error()); +} Property changes on: head/lib/libc/tests/nss/getrpc_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libc/tests/nss/getserv_test.c =================================================================== --- head/lib/libc/tests/nss/getserv_test.c (nonexistent) +++ head/lib/libc/tests/nss/getserv_test.c (revision 292323) @@ -0,0 +1,570 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETSERVENT, + TEST_GETSERVBYNAME, + TEST_GETSERVBYPORT, + TEST_GETSERVENT_2PASS, + TEST_BUILD_SNAPSHOT +}; + +DECLARE_TEST_DATA(servent) +DECLARE_TEST_FILE_SNAPSHOT(servent) +DECLARE_1PASS_TEST(servent) +DECLARE_2PASS_TEST(servent) + +static void clone_servent(struct servent *, struct servent const *); +static int compare_servent(struct servent *, struct servent *, void *); +static void dump_servent(struct servent *); +static void free_servent(struct servent *); + +static void sdump_servent(struct servent *, char *, size_t); +static int servent_read_snapshot_func(struct servent *, char *); + +static int servent_check_ambiguity(struct servent_test_data *, + struct servent *); +static int servent_fill_test_data(struct servent_test_data *); +static int servent_test_correctness(struct servent *, void *); +static int servent_test_getservbyname(struct servent *, void *); +static int servent_test_getservbyport(struct servent *, void *); +static int servent_test_getservent(struct servent *, void *); + +IMPLEMENT_TEST_DATA(servent) +IMPLEMENT_TEST_FILE_SNAPSHOT(servent) +IMPLEMENT_1PASS_TEST(servent) +IMPLEMENT_2PASS_TEST(servent) + +static void +clone_servent(struct servent *dest, struct servent const *src) +{ + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + char **cp; + int aliases_num; + + memset(dest, 0, sizeof(struct servent)); + + if (src->s_name != NULL) { + dest->s_name = strdup(src->s_name); + ATF_REQUIRE(dest->s_name != NULL); + } + + if (src->s_proto != NULL) { + dest->s_proto = strdup(src->s_proto); + ATF_REQUIRE(dest->s_proto != NULL); + } + dest->s_port = src->s_port; + + if (src->s_aliases != NULL) { + aliases_num = 0; + for (cp = src->s_aliases; *cp; ++cp) + ++aliases_num; + + dest->s_aliases = calloc(1, (aliases_num + 1) * sizeof(char *)); + ATF_REQUIRE(dest->s_aliases != NULL); + + for (cp = src->s_aliases; *cp; ++cp) { + dest->s_aliases[cp - src->s_aliases] = strdup(*cp); + ATF_REQUIRE(dest->s_aliases[cp - src->s_aliases] != NULL); + } + } +} + +static void +free_servent(struct servent *serv) +{ + char **cp; + + ATF_REQUIRE(serv != NULL); + + free(serv->s_name); + free(serv->s_proto); + + for (cp = serv->s_aliases; *cp; ++cp) + free(*cp); + free(serv->s_aliases); +} + +static int +compare_servent(struct servent *serv1, struct servent *serv2, void *mdata) +{ + char **c1, **c2; + + if (serv1 == serv2) + return 0; + + if ((serv1 == NULL) || (serv2 == NULL)) + goto errfin; + + if ((strcmp(serv1->s_name, serv2->s_name) != 0) || + (strcmp(serv1->s_proto, serv2->s_proto) != 0) || + (serv1->s_port != serv2->s_port)) + goto errfin; + + c1 = serv1->s_aliases; + c2 = serv2->s_aliases; + + if ((serv1->s_aliases == NULL) || (serv2->s_aliases == NULL)) + goto errfin; + + for (;*c1 && *c2; ++c1, ++c2) + if (strcmp(*c1, *c2) != 0) + goto errfin; + + if ((*c1 != '\0') || (*c2 != '\0')) + goto errfin; + + return 0; + +errfin: + if (mdata == NULL) { + printf("following structures are not equal:\n"); + dump_servent(serv1); + dump_servent(serv2); + } + + return (-1); +} + +static void +sdump_servent(struct servent *serv, char *buffer, size_t buflen) +{ + char **cp; + int written; + + written = snprintf(buffer, buflen, "%s %d %s", + serv->s_name, ntohs(serv->s_port), serv->s_proto); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (serv->s_aliases != NULL) { + if (*(serv->s_aliases) != '\0') { + for (cp = serv->s_aliases; *cp; ++cp) { + written = snprintf(buffer, buflen, " %s",*cp); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } else + snprintf(buffer, buflen, " noaliases"); + } else + snprintf(buffer, buflen, " (null)"); +} + +static int +servent_read_snapshot_func(struct servent *serv, char *line) +{ + StringList *sl; + char *s, *ps, *ts; + int i; + + printf("1 line read from snapshot:\n%s\n", line); + + i = 0; + sl = NULL; + ps = line; + memset(serv, 0, sizeof(struct servent)); + while ( (s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + serv->s_name = strdup(s); + ATF_REQUIRE(serv->s_name != NULL); + break; + + case 1: + serv->s_port = htons( + (int)strtol(s, &ts, 10)); + if (*ts != '\0') { + free(serv->s_name); + return (-1); + } + break; + + case 2: + serv->s_proto = strdup(s); + ATF_REQUIRE(serv->s_proto != NULL); + break; + + default: + if (sl == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl = sl_init(); + ATF_REQUIRE(sl != NULL); + + if (strcmp(s, "noaliases") != 0) { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + } else { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + break; + } + ++i; + } + + if (i < 3) { + free(serv->s_name); + free(serv->s_proto); + memset(serv, 0, sizeof(struct servent)); + return (-1); + } + + sl_add(sl, NULL); + serv->s_aliases = sl->sl_str; + + /* NOTE: is it a dirty hack or not? */ + free(sl); + return (0); +} + +static void +dump_servent(struct servent *result) +{ + if (result != NULL) { + char buffer[1024]; + sdump_servent(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +servent_fill_test_data(struct servent_test_data *td) +{ + struct servent *serv; + + setservent(1); + while ((serv = getservent()) != NULL) { + if (servent_test_correctness(serv, NULL) == 0) + TEST_DATA_APPEND(servent, td, serv); + else + return (-1); + } + endservent(); + + return (0); +} + +static int +servent_test_correctness(struct servent *serv, void *mdata) +{ + printf("testing correctness with the following data:\n"); + dump_servent(serv); + + if (serv == NULL) + goto errfin; + + if (serv->s_name == NULL) + goto errfin; + + if (serv->s_proto == NULL) + goto errfin; + + if (ntohs(serv->s_port < 0)) + goto errfin; + + if (serv->s_aliases == NULL) + goto errfin; + + printf("correct\n"); + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +/* servent_check_ambiguity() is needed when one port+proto is associated with + * more than one service (these cases are usually marked as PROBLEM in + * /etc/services. This functions is needed also when one service+proto is + * associated with several ports. We have to check all the servent structures + * to make sure that serv really exists and correct */ +static int +servent_check_ambiguity(struct servent_test_data *td, struct servent *serv) +{ + + return (TEST_DATA_FIND(servent, td, serv, compare_servent, + NULL) != NULL ? 0 : -1); +} + +static int +servent_test_getservbyname(struct servent *serv_model, void *mdata) +{ + char **alias; + struct servent *serv; + + printf("testing getservbyname() with the following data:\n"); + dump_servent(serv_model); + + serv = getservbyname(serv_model->s_name, serv_model->s_proto); + if (servent_test_correctness(serv, NULL) != 0) + goto errfin; + + if ((compare_servent(serv, serv_model, NULL) != 0) && + (servent_check_ambiguity((struct servent_test_data *)mdata, serv) + !=0)) + goto errfin; + + for (alias = serv_model->s_aliases; *alias; ++alias) { + serv = getservbyname(*alias, serv_model->s_proto); + + if (servent_test_correctness(serv, NULL) != 0) + goto errfin; + + if ((compare_servent(serv, serv_model, NULL) != 0) && + (servent_check_ambiguity( + (struct servent_test_data *)mdata, serv) != 0)) + goto errfin; + } + + printf("ok\n"); + return (0); + +errfin: + printf("not ok\n"); + + return (-1); +} + +static int +servent_test_getservbyport(struct servent *serv_model, void *mdata) +{ + struct servent *serv; + + printf("testing getservbyport() with the following data...\n"); + dump_servent(serv_model); + + serv = getservbyport(serv_model->s_port, serv_model->s_proto); + if ((servent_test_correctness(serv, NULL) != 0) || + ((compare_servent(serv, serv_model, NULL) != 0) && + (servent_check_ambiguity((struct servent_test_data *)mdata, serv) + != 0))) { + printf("not ok\n"); + return (-1); + } else { + printf("ok\n"); + return (0); + } +} + +static int +servent_test_getservent(struct servent *serv, void *mdata) +{ + /* Only correctness can be checked when doing 1-pass test for + * getservent(). */ + return (servent_test_correctness(serv, NULL)); +} + +int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct servent_test_data td, td_snap, td_2pass; + int rv; + + TEST_DATA_INIT(servent, &td, clone_servent, free_servent); + TEST_DATA_INIT(servent, &td_snap, clone_servent, free_servent); + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the file %s\n", + snapshot_file); + + rv = -1; + goto fin; + } + } else { + if (method == TEST_BUILD_SNAPSHOT) { + rv = 0; + goto fin; + } + + TEST_SNAPSHOT_FILE_READ(servent, snapshot_file, + &td_snap, servent_read_snapshot_func); + } + } + + rv = servent_fill_test_data(&td); + if (rv == -1) + return (-1); + switch (method) { + case TEST_GETSERVBYNAME: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(servent, &td, + servent_test_getservbyname, (void *)&td); + else + rv = DO_1PASS_TEST(servent, &td_snap, + servent_test_getservbyname, (void *)&td_snap); + break; + case TEST_GETSERVBYPORT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(servent, &td, + servent_test_getservbyport, (void *)&td); + else + rv = DO_1PASS_TEST(servent, &td_snap, + servent_test_getservbyport, (void *)&td_snap); + break; + case TEST_GETSERVENT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(servent, &td, servent_test_getservent, + (void *)&td); + else + rv = DO_2PASS_TEST(servent, &td, &td_snap, + compare_servent, NULL); + break; + case TEST_GETSERVENT_2PASS: + TEST_DATA_INIT(servent, &td_2pass, clone_servent, free_servent); + rv = servent_fill_test_data(&td_2pass); + if (rv != -1) + rv = DO_2PASS_TEST(servent, &td, &td_2pass, + compare_servent, NULL); + TEST_DATA_DESTROY(servent, &td_2pass); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) + rv = TEST_SNAPSHOT_FILE_WRITE(servent, snapshot_file, &td, + sdump_servent); + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(servent, &td_snap); + TEST_DATA_DESTROY(servent, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_serv" + +ATF_TC_WITHOUT_HEAD(build_snapshot); +ATF_TC_BODY(build_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyname); +ATF_TC_BODY(getservbyname, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETSERVBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyname_with_snapshot); +ATF_TC_BODY(getservbyname_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyport); +ATF_TC_BODY(getservbyport, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETSERVBYPORT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyport_with_snapshot); +ATF_TC_BODY(getservbyport_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVBYPORT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyent); +ATF_TC_BODY(getservbyent, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETSERVENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyent_with_snapshot); +ATF_TC_BODY(getservbyent_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyent_with_two_pass); +ATF_TC_BODY(getservbyent_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETSERVENT_2PASS) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, build_snapshot); + ATF_TP_ADD_TC(tp, getservbyent); + ATF_TP_ADD_TC(tp, getservbyent_with_snapshot); + ATF_TP_ADD_TC(tp, getservbyent_with_two_pass); + ATF_TP_ADD_TC(tp, getservbyname); + ATF_TP_ADD_TC(tp, getservbyname_with_snapshot); + ATF_TP_ADD_TC(tp, getservbyport); + ATF_TP_ADD_TC(tp, getservbyport_with_snapshot); + + return (atf_no_error()); +} Property changes on: head/lib/libc/tests/nss/getserv_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libc/tests/nss/getusershell_test.c =================================================================== --- head/lib/libc/tests/nss/getusershell_test.c (nonexistent) +++ head/lib/libc/tests/nss/getusershell_test.c (revision 292323) @@ -0,0 +1,225 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETUSERSHELL, + TEST_BUILD_SNAPSHOT +}; + +struct usershell { + char *path; +}; + +static enum test_methods method = TEST_GETUSERSHELL; + +DECLARE_TEST_DATA(usershell) +DECLARE_TEST_FILE_SNAPSHOT(usershell) +DECLARE_2PASS_TEST(usershell) + +static void clone_usershell(struct usershell *, struct usershell const *); +static int compare_usershell(struct usershell *, struct usershell *, void *); +static void free_usershell(struct usershell *); + +static void sdump_usershell(struct usershell *, char *, size_t); +static void dump_usershell(struct usershell *); + +IMPLEMENT_TEST_DATA(usershell) +IMPLEMENT_TEST_FILE_SNAPSHOT(usershell) +IMPLEMENT_2PASS_TEST(usershell) + +static void +clone_usershell(struct usershell *dest, struct usershell const *src) +{ + assert(dest != NULL); + assert(src != NULL); + + if (src->path != NULL) { + dest->path = strdup(src->path); + assert(dest->path != NULL); + } +} + +static int +compare_usershell(struct usershell *us1, struct usershell *us2, void *mdata) +{ + int rv; + + assert(us1 != NULL); + assert(us2 != NULL); + + dump_usershell(us1); + dump_usershell(us2); + + if (us1 == us2) + return (0); + + rv = strcmp(us1->path, us2->path); + if (rv != 0) { + printf("following structures are not equal:\n"); + dump_usershell(us1); + dump_usershell(us2); + } + + return (rv); +} + +static void +free_usershell(struct usershell *us) +{ + free(us->path); +} + +static void +sdump_usershell(struct usershell *us, char *buffer, size_t buflen) +{ + snprintf(buffer, buflen, "%s", us->path); +} + +static void +dump_usershell(struct usershell *us) +{ + if (us != NULL) { + char buffer[2048]; + sdump_usershell(us, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +usershell_read_snapshot_func(struct usershell *us, char *line) +{ + + us->path = strdup(line); + ATF_REQUIRE(us->path != NULL); + + return (0); +} + +int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct usershell_test_data td, td_snap; + struct usershell ushell; + int rv; + + rv = 0; + + TEST_DATA_INIT(usershell, &td, clone_usershell, free_usershell); + TEST_DATA_INIT(usershell, &td_snap, clone_usershell, free_usershell); + + setusershell(); + while ((ushell.path = getusershell()) != NULL) { + printf("usershell found:\n"); + dump_usershell(&ushell); + TEST_DATA_APPEND(usershell, &td, &ushell); + } + endusershell(); + + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the snapshot file %s\n", + snapshot_file); + + rv = -1; + goto fin; + } + } else { + rv = TEST_SNAPSHOT_FILE_READ(usershell, snapshot_file, + &td_snap, usershell_read_snapshot_func); + if (rv != 0) { + printf("error reading snapshot file\n"); + goto fin; + } + } + } + + switch (method) { + case TEST_GETUSERSHELL: + rv = DO_2PASS_TEST(usershell, &td, &td_snap, + compare_usershell, NULL); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) { + rv = TEST_SNAPSHOT_FILE_WRITE(usershell, snapshot_file, + &td, sdump_usershell); + } + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(usershell, &td_snap); + TEST_DATA_DESTROY(usershell, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_usershell" + +ATF_TC_WITHOUT_HEAD(getusershell_with_snapshot); +ATF_TC_BODY(getusershell_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getusershell_with_two_pass); +ATF_TC_BODY(getusershell_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETUSERSHELL) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getusershell_with_snapshot); + ATF_TP_ADD_TC(tp, getusershell_with_two_pass); + + return (atf_no_error()); +} Property changes on: head/lib/libc/tests/nss/getusershell_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libc/tests/nss/testutil.h =================================================================== --- head/lib/libc/tests/nss/testutil.h (nonexistent) +++ head/lib/libc/tests/nss/testutil.h (revision 292323) @@ -0,0 +1,333 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include + +#define DECLARE_TEST_DATA(ent) \ +struct ent##_entry { \ + struct ent data; \ + STAILQ_ENTRY(ent##_entry) entries; \ +}; \ + \ +struct ent##_test_data { \ + void (*clone_func)(struct ent *, struct ent const *); \ + void (*free_func)(struct ent *); \ + \ + STAILQ_HEAD(ent_head, ent##_entry) snapshot_data; \ +}; \ + \ +void __##ent##_test_data_init(struct ent##_test_data *, \ + void (*)(struct ent *, struct ent const *), \ + void (*freef)(struct ent *)); \ +void __##ent##_test_data_destroy(struct ent##_test_data *); \ + \ +void __##ent##_test_data_append(struct ent##_test_data *, struct ent *data);\ +int __##ent##_test_data_foreach(struct ent##_test_data *, \ + int (*)(struct ent *, void *), void *); \ +int __##ent##_test_data_compare(struct ent##_test_data *, \ + struct ent##_test_data *, int (*)(struct ent *, struct ent *, \ + void *), void *); \ +struct ent *__##ent##_test_data_find(struct ent##_test_data *, struct ent *,\ + int (*)(struct ent *, struct ent *, void *), void *); \ +void __##ent##_test_data_clear(struct ent##_test_data *); + +#define TEST_DATA_INIT(ent, td, clonef, freef)\ + __##ent##_test_data_init(td, clonef, freef) +#define TEST_DATA_DESTROY(ent, td) __##ent##_test_data_destroy(td) +#define TEST_DATA_APPEND(ent, td, d) __##ent##_test_data_append(td, d) +#define TEST_DATA_FOREACH(ent, td, f, mdata)\ + __##ent##_test_data_foreach(td, f, mdata) +#define TEST_DATA_COMPARE(ent, td1, td2, fcmp, mdata)\ + __##ent##_test_data_compare(td1, td2, fcmp, mdata); +#define TEST_DATA_FIND(ent, td, d, fcmp, mdata)\ + __##ent##_test_data_find(td, d, fcmp, mdata) +#define TEST_DATA_CLEAR(ent, td) __##ent##_test_data_clear(td) + +#define IMPLEMENT_TEST_DATA(ent) \ +void \ +__##ent##_test_data_init(struct ent##_test_data *td, \ + void (*clonef)(struct ent *, struct ent const *), \ + void (*freef)(struct ent *)) \ +{ \ + ATF_REQUIRE(td != NULL); \ + ATF_REQUIRE(clonef != NULL); \ + ATF_REQUIRE(freef != NULL); \ + \ + memset(td, 0, sizeof(*td)); \ + td->clone_func = clonef; \ + td->free_func = freef; \ + STAILQ_INIT(&td->snapshot_data); \ +} \ + \ +void \ +__##ent##_test_data_destroy(struct ent##_test_data *td) \ +{ \ + __##ent##_test_data_clear(td); \ +} \ + \ +void \ +__##ent##_test_data_append(struct ent##_test_data *td, struct ent *app_data)\ +{ \ + struct ent##_entry *e; \ + \ + ATF_REQUIRE(td != NULL); \ + ATF_REQUIRE(app_data != NULL); \ + \ + e = (struct ent##_entry *)malloc(sizeof(struct ent##_entry)); \ + ATF_REQUIRE(e != NULL); \ + memset(e, 0, sizeof(struct ent##_entry)); \ + \ + td->clone_func(&e->data, app_data); \ + STAILQ_INSERT_TAIL(&td->snapshot_data, e, entries); \ +} \ + \ +int \ +__##ent##_test_data_foreach(struct ent##_test_data *td, \ + int (*forf)(struct ent *, void *), void *mdata) \ +{ \ + struct ent##_entry *e; \ + int rv; \ + \ + ATF_REQUIRE(td != NULL); \ + ATF_REQUIRE(forf != NULL); \ + \ + rv = 0; \ + STAILQ_FOREACH(e, &td->snapshot_data, entries) { \ + rv = forf(&e->data, mdata); \ + if (rv != 0) \ + break; \ + } \ + \ + return (rv); \ +} \ + \ +int \ +__##ent##_test_data_compare(struct ent##_test_data *td1, struct ent##_test_data *td2,\ + int (*cmp_func)(struct ent *, struct ent *, void *), void *mdata)\ +{ \ + struct ent##_entry *e1, *e2; \ + int rv; \ + \ + ATF_REQUIRE(td1 != NULL); \ + ATF_REQUIRE(td2 != NULL); \ + ATF_REQUIRE(cmp_func != NULL); \ + \ + e1 = STAILQ_FIRST(&td1->snapshot_data); \ + e2 = STAILQ_FIRST(&td2->snapshot_data); \ + \ + rv = 0; \ + do { \ + if ((e1 == NULL) || (e2 == NULL)) { \ + if (e1 == e2) \ + return (0); \ + else \ + return (-1); \ + } \ + \ + rv = cmp_func(&e1->data, &e2->data, mdata); \ + e1 = STAILQ_NEXT(e1, entries); \ + e2 = STAILQ_NEXT(e2, entries); \ + } while (rv == 0); \ + \ + return (rv); \ +} \ + \ +struct ent * \ +__##ent##_test_data_find(struct ent##_test_data *td, struct ent *data, \ + int (*cmp)(struct ent *, struct ent *, void *), void *mdata) \ +{ \ + struct ent##_entry *e; \ + struct ent *result; \ + \ + ATF_REQUIRE(td != NULL); \ + ATF_REQUIRE(cmp != NULL); \ + \ + result = NULL; \ + STAILQ_FOREACH(e, &td->snapshot_data, entries) { \ + if (cmp(&e->data, data, mdata) == 0) { \ + result = &e->data; \ + break; \ + } \ + } \ + \ + return (result); \ +} \ + \ + \ +void \ +__##ent##_test_data_clear(struct ent##_test_data *td) \ +{ \ + struct ent##_entry *e; \ + ATF_REQUIRE(td != NULL); \ + \ + while (!STAILQ_EMPTY(&td->snapshot_data)) { \ + e = STAILQ_FIRST(&td->snapshot_data); \ + STAILQ_REMOVE_HEAD(&td->snapshot_data, entries); \ + \ + td->free_func(&e->data); \ + free(e); \ + e = NULL; \ + } \ +} + +#define DECLARE_TEST_FILE_SNAPSHOT(ent) \ +struct ent##_snp_param { \ + FILE *fp; \ + void (*sdump_func)(struct ent *, char *, size_t); \ +}; \ + \ +int __##ent##_snapshot_write_func(struct ent *, void *); \ +int __##ent##_snapshot_write(char const *, struct ent##_test_data *, \ + void (*)(struct ent *, char *, size_t)); \ +int __##ent##_snapshot_read(char const *, struct ent##_test_data *, \ + int (*)(struct ent *, char *)); + +#define TEST_SNAPSHOT_FILE_WRITE(ent, fname, td, f) \ + __##ent##_snapshot_write(fname, td, f) +#define TEST_SNAPSHOT_FILE_READ(ent, fname, td, f) \ + __##ent##_snapshot_read(fname, td, f) + +#define IMPLEMENT_TEST_FILE_SNAPSHOT(ent) \ +int \ +__##ent##_snapshot_write_func(struct ent *data, void *mdata) \ +{ \ + char buffer[1024]; \ + struct ent##_snp_param *param; \ + \ + ATF_REQUIRE(data != NULL); \ + \ + param = (struct ent##_snp_param *)mdata; \ + param->sdump_func(data, buffer, sizeof(buffer)); \ + fputs(buffer, param->fp); \ + fputc('\n', param->fp); \ + \ + return (0); \ +} \ + \ +int \ +__##ent##_snapshot_write(char const *fname, struct ent##_test_data *td, \ + void (*sdump_func)(struct ent *, char *, size_t)) \ +{ \ + struct ent##_snp_param param; \ + \ + ATF_REQUIRE(fname != NULL); \ + ATF_REQUIRE(td != NULL); \ + \ + param.fp = fopen(fname, "w"); \ + if (param.fp == NULL) \ + return (-1); \ + \ + param.sdump_func = sdump_func; \ + __##ent##_test_data_foreach(td, __##ent##_snapshot_write_func, ¶m);\ + fclose(param.fp); \ + \ + return (0); \ +} \ + \ +int \ +__##ent##_snapshot_read(char const *fname, struct ent##_test_data *td, \ + int (*read_func)(struct ent *, char *)) \ +{ \ + char buffer[1024]; \ + struct ent data; \ + char *s; \ + FILE *fi; \ + size_t len; \ + int rv; \ + \ + ATF_REQUIRE(fname != NULL); \ + ATF_REQUIRE(td != NULL); \ + \ + fi = fopen(fname, "r"); \ + if (fi == NULL) \ + return (-1); \ + \ + rv = 0; \ + memset(buffer, 0, sizeof(buffer)); \ + while (!feof(fi)) { \ + s = fgets(buffer, sizeof(buffer), fi); \ + if (s != NULL && s[0] != '#') { \ + len = strlen(s); \ + if (len == 0) \ + continue; \ + if (buffer[len - 1] == '\n') \ + buffer[len -1] = '\0'; \ + \ + rv = read_func(&data, s); \ + if (rv == 0) { \ + __##ent##_test_data_append(td, &data); \ + td->free_func(&data); \ + } else \ + goto fin; \ + } \ + } \ + \ +fin: \ + fclose(fi); \ + return (rv); \ +} + +#define DECLARE_1PASS_TEST(ent) \ +int __##ent##_1pass_test(struct ent##_test_data *, \ + int (*)(struct ent *, void *), \ + void *); + +#define DO_1PASS_TEST(ent, td, f, mdata) \ + __##ent##_1pass_test(td, f, mdata) + +#define IMPLEMENT_1PASS_TEST(ent) \ +int \ +__##ent##_1pass_test(struct ent##_test_data *td, \ + int (*tf)(struct ent *, void *), \ + void *mdata) \ +{ \ + int rv; \ + rv = __##ent##_test_data_foreach(td, tf, mdata); \ + \ + return (rv); \ +} + +#define DECLARE_2PASS_TEST(ent) \ +int __##ent##_2pass_test(struct ent##_test_data *, \ + struct ent##_test_data *, \ + int (*)(struct ent *, struct ent *, void *), void *); + +#define DO_2PASS_TEST(ent, td1, td2, f, mdata) \ + __##ent##_2pass_test(td1, td2, f, mdata) + +#define IMPLEMENT_2PASS_TEST(ent) \ +int \ +__##ent##_2pass_test(struct ent##_test_data *td1, \ + struct ent##_test_data *td2, \ + int (*cmp_func)(struct ent *, struct ent *, void *), \ + void *cmp_mdata) \ +{ \ + int rv; \ + \ + rv = __##ent##_test_data_compare(td1, td2, cmp_func, cmp_mdata); \ + return (rv); \ +} Property changes on: head/lib/libc/tests/nss/testutil.h ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getaddr.t =================================================================== --- head/tools/regression/lib/libc/nss/test-getaddr.t (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getaddr.t (nonexistent) @@ -1,33 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -do_test() { - number=$1 - comment=$2 - opt=$3 - if ./$executable $opt; then - echo "ok $number - $comment" - else - echo "not ok $number - $comment" - fi -} - -cd `dirname $0` - -executable=`basename $0 .t` - -make $executable 2>&1 > /dev/null - -echo 1..6 -#Tests with hints.ai_family is set to PF_UNSPEC -do_test 1 'getaddrinfo() (PF_UNSPEC)' '-f mach' -do_test 2 'getaddrinfo() snapshot (PF_UNSPEC)' '-f mach -s snapshot_ai' - -#Tests with hints.ai_family is set to PF_INET -do_test 3 'getaddrinfo() (PF_INET)' '-f mach' -do_test 4 'getaddrinfo() snapshot (PF_INET)' '-4 -f mach -s snapshot_ai4' - -#Tests with hints.ai_family is set to PF_INET6 -do_test 5 'getaddrinfo() (PF_INET6)' '-f mach' -do_test 6 'getaddrinfo() snapshot (PF_INET6)' '-6 -f mach -s snapshot_ai6' - Property changes on: head/tools/regression/lib/libc/nss/test-getaddr.t ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getrpc.t =================================================================== --- head/tools/regression/lib/libc/nss/test-getrpc.t (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getrpc.t (nonexistent) @@ -1,29 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -do_test() { - number=$1 - comment=$2 - opt=$3 - if ./$executable $opt; then - echo "ok $number - $comment" - else - echo "not ok $number - $comment" - fi -} - -cd `dirname $0` - -executable=`basename $0 .t` - -make $executable 2>&1 > /dev/null - -echo 1..8 -do_test 1 'getrpcbyname()' '-n' -do_test 2 'getrpcbynumber()' '-v' -do_test 3 'getrpcent()' '-e' -do_test 4 'getrpcent() 2-pass' '-2' -do_test 5 'building snapshot, if needed' '-s snapshot_rpc' -do_test 6 'getrpcbyname() snapshot' '-n -s snapshot_rpc' -do_test 7 'getrpcbynumber() snapshot' '-v -s snapshot_rpc' -do_test 8 'getrpcent() snapshot' '-e -s snapshot_rpc' Property changes on: head/tools/regression/lib/libc/nss/test-getrpc.t ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/README =================================================================== --- head/tools/regression/lib/libc/nss/README (revision 292322) +++ head/tools/regression/lib/libc/nss/README (nonexistent) @@ -1,203 +0,0 @@ -$FreeBSD$ - -A brief how-to --------------- - -Each nsswitch regression test does 2 kinds of actions: -1. It runs a series of queries and tests the correctness of results. - There are 2 basic criteria which are used for that: - - numbers must be in the correct range - - certain pointers should not be NULL - -2. It makes a snapshot of the results of all queries that were made. - The idea of snapshots is to test that nsswitch-related function - calls behave equally (i.e. return same results for the same queries) - between system upgrades. When the test is executed and the snapshot is - already created, the test will compare the result of each query with - the appropriate result from the snapshot and will signal if they - differ. - -In order for nsswitch tests to be as useful as possible you should use -them in the following way: - -Step 1 (before upgrading your system). -Build the tests with "make" command and execute them with "prove -v" -command. If there are errors during the execution, then appropriate -nsswitch functions should be checked. Note, that errors on this state -can happen only if the particular function return incorrect data. - -After the stage 1 a number of "snapshot_[test name]" files will appear -in your test folder. - -Step 2 (after upgrading you system). -Rebuild the tests with "make clean; make" command and execute them -again with "prove -v" (check that "snapshot_[test name]" files -are in the same folder with tests). On this stage regression tests -will catch not only the correctness errors, but will also determine -the changes in nsswitch functions behaviour. - -In case of the test failure you will get the following message: - -To get more details about the error you should do the following: -Step 1. Run the test alone with debug output enabled. -Step 2. Mail the snapshot file and the debug test output to the -freebsd-current@ mailing list. - -Example testing session for getpwXXX() family of functions ----------------------------------------------------------- -1. make - -2. prove -v ./test-getpw.t - - test-getpw....1..8 - ok 1 - getpwnam() - ok 2 - getpwuid() - ok 3 - getpwent() - ok 4 - getpwent() 2-pass - ok 5 - building snapshot, if needed - ok 6 - getpwnam() snapshot - ok 7 - getpwuid() snapshot - ok 8 - getpwent() snapshot - ok - All tests successful. - Files=1, Tests=8, 1 wallclock secs ( 0.00 cusr + 0.20 csys = 0.20 CPU) - - -3. Upgrading the system. - -4. make clean; make - -5. prove -v ./test-getpw.t (suppose that something has gone wrong) - - test-getpw....1..8 - ok 1 - getpwnam() - ok 2 - getpwuid() - ok 3 - getpwent() - ok 4 - getpwent() 2-pass - ok 5 - building snapshot, if needed - not ok 6 - getpwnam() snapshot - ok 7 - getpwuid() snapshot - not ok 8 - getpwent() snapshot - FAILED tests 6, 8 - Failed 2/8 tests, 75.00% okay - Failed 1/1 test scripts, 0.00% okay. 2/8 subtests failed, 75.00% okay. - -6. We see that test number 6 failed. According to get-getpw.t, this test - is executed like this: - do_test 6 'getpwnam() snapshot' '-n -s snapshot_pwd' - - To determine why the test has failed, we need to run it in debug mode - - it means adding "-d" to the options list. - -7. ./test-getpw -dn -s snapshot_pwd - ... - testing getpwnam() with the following data: - toor:*:0:0:0::ne-again Superuser:/root::0:4831 - testing correctness with the following data: - toor:*:0:0:0::Bourne-again Superuser:/root::0:4831 - correct - not ok - -8. Here we can see that the data from snapshot (first "toor" line) and - the data received from the getpwnam() call (second "toor" line) are - different. It is the reason why the test has failed. If you can't - (or don't want) to investigate the problem by yourself, mail - the test debug output and the snapshot file to the developers list. - -Notes on using standalone nsswitch tests ----------------------------------------- - -All nsswitch tests have [-d] optional command line argument which enables -debug output. The debug output can be extremely helpful to determine the -cause of test failure. - -In all nsswitch tests -s command line argument specifies the -snapshot file. If this file doesn't exist, it would be built during -test execution. If it already exists then it will be used to check -the results of particular function calls. This argument is mostly -optional, but some tests (test-getaddr and test-getusershell) force -it to be specified. - -test-gethostby and test-getaddr require the list of hostnames, that should -be queried during the test. This list must be specified via -f -command line argument. Each hostname should occupy exactly one line -in the file. - -Detailed tests description --------------------------- - -./test-getaddr - tests the getaddrinfo() function. - Usage: test-getaddr [-d] [-46] [-s ] -f - -d - enable debug output - -4 - force IPv4 usage - -6 - force IPv6 usage - -s - build/use specified snapshot file - -f - use specified hostnames list for testing - -./test-getgr - Usage: test-getgr -nge2 [-d] [-s ] - -d - enable debug output - -n - test getgrnam(3) - -g - test getgrgid(3) - -e - test getgrent(3) - -2 - test getgrent(3) in 2-pass mode - -s - build/use specified snapshot file - -./test-gethostby - Usage: test-gethostby -na2i [-o] [-d] [-m46] [-s ] -f - -n - test gethostbyname2(3) - -a - test gethostbyaddr(3) - -2 - test gethostbyname2(3) results to be equal with getaddrinfo(3) - results for the similar query - -i - test gethostbyaddr(3) results to be equal with getnameinfo(3) - results for the similar query - -o - use getipnodebyname(3)/getipnodebyaddr(3) for testing instead of - gethostbyname2(3)/gethostbyaddr(3) - -d - enable debug output - -m - force IPv4-to-IPv6 mapping - -4 - force IPv4 usage - -6 - force IPv6 usage - -s - build/use specified snapshot file - -f - use specified hostnames list for testing - -./test-getproto - Usage: test-getproto -nve2 [-d] [-s ] - -d - enable debug output - -n - test getprotobyname(3) - -v - test getprotobynumber(3) - -e - test getprotoent(3) - -2 - test getprotoent(3) in 2-pass mode - -s - build/use specified snapshot file - -./test-getpw - Usage: test-getpw -nue2 [-d] [-s ] - -d - enable debug output - -n - test getpwnam(3) - -u - test getpwuid(3) - -e - test getpwent(3) - -2 - test getpwent(3) in 2-pass mode - -s - build/use snapshot file - -./test-getrpc - Usage: test-getrpc -nve2 [-d] [-s ] - -d - enable debug output - -n - test getrpcbyname(3) - -v - test getrpcbynumber(3) - -e - test getrpcent(3) - -2 - test getrpcent(3) in 2-pass mode - -s - build/use specified snapshot file - -./test-getserv - Usage: test-getserv -npe2 [-d] [-s ] - -d - enable debug output - -n - test getservbyname(3) - -p - test getservbyport(3) - -e - test getservent(3) - -2 - test getservent(3) in 2-pass mode - -s - build/use specified snapshot file - -./test-getusershell - Usage: test-getusershell [-d] -s - -d - enable debug output - -s - build/use specified snapshot file - Property changes on: head/tools/regression/lib/libc/nss/README ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getproto.t =================================================================== --- head/tools/regression/lib/libc/nss/test-getproto.t (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getproto.t (nonexistent) @@ -1,29 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -do_test() { - number=$1 - comment=$2 - opt=$3 - if ./$executable $opt; then - echo "ok $number - $comment" - else - echo "not ok $number - $comment" - fi -} - -cd `dirname $0` - -executable=`basename $0 .t` - -make $executable 2>&1 > /dev/null - -echo 1..8 -do_test 1 'getprotobyname()' '-n' -do_test 2 'getprotobynumber()' '-v' -do_test 3 'getprotoent()' '-e' -do_test 4 'getprotoent() 2-pass' '-2' -do_test 5 'building snapshot, if needed' '-s snapshot_proto' -do_test 6 'getprotobyname() snapshot' '-n -s snapshot_proto' -do_test 7 'getprotobynumber() snapshot' '-v -s snapshot_proto' -do_test 8 'getprotoent() snapshot' '-e -s snapshot_proto' Property changes on: head/tools/regression/lib/libc/nss/test-getproto.t ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getusershell.t =================================================================== --- head/tools/regression/lib/libc/nss/test-getusershell.t (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getusershell.t (nonexistent) @@ -1,22 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -do_test() { - number=$1 - comment=$2 - opt=$3 - if ./$executable $opt; then - echo "ok $number - $comment" - else - echo "not ok $number - $comment" - fi -} - -cd `dirname $0` - -executable=`basename $0 .t` - -make $executable 2>&1 > /dev/null - -echo 1..1 -do_test 1 'getusershell() snapshot' '-s snapshot_usershell' Property changes on: head/tools/regression/lib/libc/nss/test-getusershell.t ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-gethostby.c =================================================================== --- head/tools/regression/lib/libc/nss/test-gethostby.c (revision 292322) +++ head/tools/regression/lib/libc/nss/test-gethostby.c (nonexistent) @@ -1,1105 +0,0 @@ -/*- - * Copyright (c) 2006 Michael Bushkov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "testutil.h" - -#ifndef min -#define min(a,b) (((a)<(b))?(a):(b)) -#endif - -enum test_methods { - TEST_GETHOSTBYNAME2, - TEST_GETHOSTBYADDR, - TEST_GETHOSTBYNAME2_GETADDRINFO, - TEST_GETHOSTBYADDR_GETNAMEINFO, - TEST_BUILD_SNAPSHOT, - TEST_BUILD_ADDR_SNAPSHOT -}; - -static int use_ipnode_functions = 0; -static int use_ipv6_mapping = 0; -static int ipnode_flags = 0; -static int debug = 0; -static int af_type = AF_INET; -static enum test_methods method = TEST_BUILD_SNAPSHOT; - -DECLARE_TEST_DATA(hostent) -DECLARE_TEST_FILE_SNAPSHOT(hostent) -DECLARE_1PASS_TEST(hostent) -DECLARE_2PASS_TEST(hostent) - -/* These stubs will use gethostby***() or getipnodeby***() functions, - * depending on the use_ipnode_functions global variable value */ -static struct hostent *__gethostbyname2(const char *, int); -static struct hostent *__gethostbyaddr(const void *, socklen_t, int); -static void __freehostent(struct hostent *); - -static void clone_hostent(struct hostent *, struct hostent const *); -static int compare_hostent(struct hostent *, struct hostent *, void *); -static void dump_hostent(struct hostent *); -static void free_hostent(struct hostent *); - -static int is_hostent_equal(struct hostent *, struct addrinfo *); - -static void sdump_hostent(struct hostent *, char *, size_t); -static int hostent_read_hostlist_func(struct hostent *, char *); -static int hostent_read_snapshot_addr(char *, unsigned char *, size_t); -static int hostent_read_snapshot_func(struct hostent *, char *); - -static int hostent_test_correctness(struct hostent *, void *); -static int hostent_test_gethostbyaddr(struct hostent *, void *); -static int hostent_test_getaddrinfo_eq(struct hostent *, void *); -static int hostent_test_getnameinfo_eq(struct hostent *, void *); - -static void usage(void) __attribute__((__noreturn__)); - -IMPLEMENT_TEST_DATA(hostent) -IMPLEMENT_TEST_FILE_SNAPSHOT(hostent) -IMPLEMENT_1PASS_TEST(hostent) -IMPLEMENT_2PASS_TEST(hostent) - -static struct hostent * -__gethostbyname2(const char *name, int af) -{ - struct hostent *he; - int error; - - if (use_ipnode_functions == 0) - he = gethostbyname2(name, af); - else { - error = 0; - he = getipnodebyname(name, af, ipnode_flags, &error); - if (he == NULL) - errno = error; - } - - return (he); -} - -static struct hostent * -__gethostbyaddr(const void *addr, socklen_t len, int af) -{ - struct hostent *he; - int error; - - if (use_ipnode_functions == 0) - he = gethostbyaddr(addr, len, af); - else { - error = 0; - he = getipnodebyaddr(addr, len, af, &error); - if (he == NULL) - errno = error; - } - - return (he); -} - -static void -__freehostent(struct hostent *he) -{ - /* NOTE: checking for he != NULL - just in case */ - if ((use_ipnode_functions != 0) && (he != NULL)) - freehostent(he); -} - -static void -clone_hostent(struct hostent *dest, struct hostent const *src) -{ - assert(dest != NULL); - assert(src != NULL); - - char **cp; - int aliases_num; - int addrs_num; - size_t offset; - - memset(dest, 0, sizeof(struct hostent)); - - if (src->h_name != NULL) { - dest->h_name = strdup(src->h_name); - assert(dest->h_name != NULL); - } - - dest->h_addrtype = src->h_addrtype; - dest->h_length = src->h_length; - - if (src->h_aliases != NULL) { - aliases_num = 0; - for (cp = src->h_aliases; *cp; ++cp) - ++aliases_num; - - dest->h_aliases = (char **)malloc((aliases_num + 1) * - (sizeof(char *))); - assert(dest->h_aliases != NULL); - memset(dest->h_aliases, 0, (aliases_num + 1) * - (sizeof(char *))); - - for (cp = src->h_aliases; *cp; ++cp) { - dest->h_aliases[cp - src->h_aliases] = strdup(*cp); - assert(dest->h_aliases[cp - src->h_aliases] != NULL); - } - } - - if (src->h_addr_list != NULL) { - addrs_num = 0; - for (cp = src->h_addr_list; *cp; ++cp) - ++addrs_num; - - dest->h_addr_list = (char **)malloc((addrs_num + 1) * - (sizeof(char *))); - assert(dest->h_addr_list != NULL); - memset(dest->h_addr_list, 0, (addrs_num + 1) * - (sizeof(char *))); - - for (cp = src->h_addr_list; *cp; ++cp) { - offset = cp - src->h_addr_list; - dest->h_addr_list[offset] = - (char *)malloc(src->h_length); - assert(dest->h_addr_list[offset] != NULL); - memcpy(dest->h_addr_list[offset], - src->h_addr_list[offset], src->h_length); - } - } -} - -static void -free_hostent(struct hostent *ht) -{ - char **cp; - - assert(ht != NULL); - - free(ht->h_name); - - if (ht->h_aliases != NULL) { - for (cp = ht->h_aliases; *cp; ++cp) - free(*cp); - free(ht->h_aliases); - } - - if (ht->h_addr_list != NULL) { - for (cp = ht->h_addr_list; *cp; ++cp) - free(*cp); - free(ht->h_addr_list); - } -} - -static int -compare_hostent(struct hostent *ht1, struct hostent *ht2, void *mdata) -{ - char **c1, **c2, **ct, **cb; - int b; - - if (ht1 == ht2) - return 0; - - if ((ht1 == NULL) || (ht2 == NULL)) - goto errfin; - - if ((ht1->h_name == NULL) || (ht2->h_name == NULL)) - goto errfin; - - if ((ht1->h_addrtype != ht2->h_addrtype) || - (ht1->h_length != ht2->h_length) || - (strcmp(ht1->h_name, ht2->h_name) != 0)) - goto errfin; - - c1 = ht1->h_aliases; - c2 = ht2->h_aliases; - - if (((ht1->h_aliases == NULL) || (ht2->h_aliases == NULL)) && - (ht1->h_aliases != ht2->h_aliases)) - goto errfin; - - if ((c1 != NULL) && (c2 != NULL)) { - cb = c1; - for (;*c1; ++c1) { - b = 0; - for (ct = c2; *ct; ++ct) { - if (strcmp(*c1, *ct) == 0) { - b = 1; - break; - } - } - if (b == 0) { - if (debug) - printf("h1 aliases item can't be "\ - "found in h2 aliases\n"); - goto errfin; - } - } - - c1 = cb; - for (;*c2; ++c2) { - b = 0; - for (ct = c1; *ct; ++ct) { - if (strcmp(*c2, *ct) == 0) { - b = 1; - break; - } - } - if (b == 0) { - if (debug) - printf("h2 aliases item can't be "\ - " found in h1 aliases\n"); - goto errfin; - } - } - } - - c1 = ht1->h_addr_list; - c2 = ht2->h_addr_list; - - if (((ht1->h_addr_list == NULL) || (ht2->h_addr_list== NULL)) && - (ht1->h_addr_list != ht2->h_addr_list)) - goto errfin; - - if ((c1 != NULL) && (c2 != NULL)) { - cb = c1; - for (;*c1; ++c1) { - b = 0; - for (ct = c2; *ct; ++ct) { - if (memcmp(*c1, *ct, ht1->h_length) == 0) { - b = 1; - break; - } - } - if (b == 0) { - if (debug) - printf("h1 addresses item can't be "\ - "found in h2 addresses\n"); - goto errfin; - } - } - - c1 = cb; - for (;*c2; ++c2) { - b = 0; - for (ct = c1; *ct; ++ct) { - if (memcmp(*c2, *ct, ht1->h_length) == 0) { - b = 1; - break; - } - } - if (b == 0) { - if (debug) - printf("h2 addresses item can't be "\ - "found in h1 addresses\n"); - goto errfin; - } - } - } - - return 0; - -errfin: - if ((debug) && (mdata == NULL)) { - printf("following structures are not equal:\n"); - dump_hostent(ht1); - dump_hostent(ht2); - } - - return (-1); -} - -static int -check_addrinfo_for_name(struct addrinfo *ai, char const *name) -{ - struct addrinfo *ai2; - - for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) { - if (strcmp(ai2->ai_canonname, name) == 0) - return (0); - } - - return (-1); -} - -static int -check_addrinfo_for_addr(struct addrinfo *ai, char const *addr, - socklen_t addrlen, int af) -{ - struct addrinfo *ai2; - - for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) { - if (af != ai2->ai_family) - continue; - - switch (af) { - case AF_INET: - if (memcmp(addr, - (void *)&((struct sockaddr_in *)ai2->ai_addr)->sin_addr, - min(addrlen, ai2->ai_addrlen)) == 0) - return (0); - break; - case AF_INET6: - if (memcmp(addr, - (void *)&((struct sockaddr_in6 *)ai2->ai_addr)->sin6_addr, - min(addrlen, ai2->ai_addrlen)) == 0) - return (0); - break; - default: - break; - } - } - - return (-1); -} - -static int -is_hostent_equal(struct hostent *he, struct addrinfo *ai) -{ - char **cp; - int rv; - - if (debug) - printf("checking equality of he and ai\n"); - - rv = check_addrinfo_for_name(ai, he->h_name); - if (rv != 0) { - if (debug) - printf("not equal - he->h_name couldn't be found\n"); - - return (rv); - } - - for (cp = he->h_addr_list; *cp; ++cp) { - rv = check_addrinfo_for_addr(ai, *cp, he->h_length, - he->h_addrtype); - if (rv != 0) { - if (debug) - printf("not equal - one of he->h_addr_list couldn't be found\n"); - - return (rv); - } - } - - if (debug) - printf("equal\n"); - - return (0); -} - -static void -sdump_hostent(struct hostent *ht, char *buffer, size_t buflen) -{ - char **cp; - size_t i; - int written; - - written = snprintf(buffer, buflen, "%s %d %d", - ht->h_name, ht->h_addrtype, ht->h_length); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (ht->h_aliases != NULL) { - if (*(ht->h_aliases) != NULL) { - for (cp = ht->h_aliases; *cp; ++cp) { - written = snprintf(buffer, buflen, " %s",*cp); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (buflen == 0) - return; - } - } else { - written = snprintf(buffer, buflen, " noaliases"); - buffer += written; - if (written > buflen) - return; - buflen -= written; - } - } else { - written = snprintf(buffer, buflen, " (null)"); - buffer += written; - if (written > buflen) - return; - buflen -= written; - } - - written = snprintf(buffer, buflen, " : "); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (ht->h_addr_list != NULL) { - if (*(ht->h_addr_list) != NULL) { - for (cp = ht->h_addr_list; *cp; ++cp) { - for (i = 0; i < ht->h_length; ++i ) { - written = snprintf(buffer, buflen, - i + 1 != ht->h_length ? "%d." : "%d", - (unsigned char)(*cp)[i]); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (buflen == 0) - return; - } - - if (*(cp + 1) ) { - written = snprintf(buffer, buflen, " "); - buffer += written; - if (written > buflen) - return; - buflen -= written; - } - } - } else { - written = snprintf(buffer, buflen, " noaddrs"); - buffer += written; - if (written > buflen) - return; - buflen -= written; - } - } else { - written = snprintf(buffer, buflen, " (null)"); - buffer += written; - if (written > buflen) - return; - buflen -= written; - } -} - -static int -hostent_read_hostlist_func(struct hostent *he, char *line) -{ - struct hostent *result; - int rv; - - if (debug) - printf("resolving %s: ", line); - result = __gethostbyname2(line, af_type); - if (result != NULL) { - if (debug) - printf("found\n"); - - rv = hostent_test_correctness(result, NULL); - if (rv != 0) { - __freehostent(result); - return (rv); - } - - clone_hostent(he, result); - __freehostent(result); - } else { - if (debug) - printf("not found\n"); - - memset(he, 0, sizeof(struct hostent)); - he->h_name = strdup(line); - assert(he->h_name != NULL); - } - return (0); -} - -static int -hostent_read_snapshot_addr(char *addr, unsigned char *result, size_t len) -{ - char *s, *ps, *ts; - - ps = addr; - while ( (s = strsep(&ps, ".")) != NULL) { - if (len == 0) - return (-1); - - *result = (unsigned char)strtol(s, &ts, 10); - ++result; - if (*ts != '\0') - return (-1); - - --len; - } - if (len != 0) - return (-1); - else - return (0); -} - -static int -hostent_read_snapshot_func(struct hostent *ht, char *line) -{ - StringList *sl1, *sl2; - char *s, *ps, *ts; - int i, rv; - - if (debug) - printf("1 line read from snapshot:\n%s\n", line); - - rv = 0; - i = 0; - sl1 = sl2 = NULL; - ps = line; - memset(ht, 0, sizeof(struct hostent)); - while ( (s = strsep(&ps, " ")) != NULL) { - switch (i) { - case 0: - ht->h_name = strdup(s); - assert(ht->h_name != NULL); - break; - - case 1: - ht->h_addrtype = (int)strtol(s, &ts, 10); - if (*ts != '\0') - goto fin; - break; - - case 2: - ht->h_length = (int)strtol(s, &ts, 10); - if (*ts != '\0') - goto fin; - break; - - case 3: - if (sl1 == NULL) { - if (strcmp(s, "(null)") == 0) - return (0); - - sl1 = sl_init(); - assert(sl1 != NULL); - - if (strcmp(s, "noaliases") != 0) { - ts = strdup(s); - assert(ts != NULL); - sl_add(sl1, ts); - } - } else { - if (strcmp(s, ":") == 0) - ++i; - else { - ts = strdup(s); - assert(ts != NULL); - sl_add(sl1, ts); - } - } - break; - - case 4: - if (sl2 == NULL) { - if (strcmp(s, "(null)") == 0) - return (0); - - sl2 = sl_init(); - assert(sl2 != NULL); - - if (strcmp(s, "noaddrs") != 0) { - ts = (char *)malloc(ht->h_length); - assert(ts != NULL); - memset(ts, 0, ht->h_length); - rv = hostent_read_snapshot_addr(s,\ - (unsigned char *)ts, ht->h_length); - sl_add(sl2, ts); - if (rv != 0) - goto fin; - } - } else { - ts = (char *)malloc(ht->h_length); - assert(ts != NULL); - memset(ts, 0, ht->h_length); - rv = hostent_read_snapshot_addr(s,\ - (unsigned char *)ts, ht->h_length); - sl_add(sl2, ts); - if (rv != 0) - goto fin; - } - break; - default: - break; - }; - - if ((i != 3) && (i != 4)) - ++i; - } - -fin: - if (sl1 != NULL) { - sl_add(sl1, NULL); - ht->h_aliases = sl1->sl_str; - } - if (sl2 != NULL) { - sl_add(sl2, NULL); - ht->h_addr_list = sl2->sl_str; - } - - if ((i != 4) || (rv != 0)) { - free_hostent(ht); - memset(ht, 0, sizeof(struct hostent)); - return (-1); - } - - /* NOTE: is it a dirty hack or not? */ - free(sl1); - free(sl2); - return (0); -} - -static void -dump_hostent(struct hostent *result) -{ - if (result != NULL) { - char buffer[1024]; - sdump_hostent(result, buffer, sizeof(buffer)); - printf("%s\n", buffer); - } else - printf("(null)\n"); -} - -static int -hostent_test_correctness(struct hostent *ht, void *mdata) -{ - if (debug) { - printf("testing correctness with the following data:\n"); - dump_hostent(ht); - } - - if (ht == NULL) - goto errfin; - - if (ht->h_name == NULL) - goto errfin; - - if (!((ht->h_addrtype >= 0) && (ht->h_addrtype < AF_MAX))) - goto errfin; - - if ((ht->h_length != sizeof(struct in_addr)) && - (ht->h_length != sizeof(struct in6_addr))) - goto errfin; - - if (ht->h_aliases == NULL) - goto errfin; - - if (ht->h_addr_list == NULL) - goto errfin; - - if (debug) - printf("correct\n"); - - return (0); -errfin: - if (debug) - printf("incorrect\n"); - - return (-1); -} - -static int -hostent_test_gethostbyaddr(struct hostent *he, void *mdata) -{ - struct hostent *result; - struct hostent_test_data *addr_test_data; - int rv; - - addr_test_data = (struct hostent_test_data *)mdata; - - /* We should omit unresolved hostents */ - if (he->h_addr_list != NULL) { - char **cp; - for (cp = he->h_addr_list; *cp; ++cp) { - if (debug) - printf("doing reverse lookup for %s\n", he->h_name); - - result = __gethostbyaddr(*cp, he->h_length, - he->h_addrtype); - if (result == NULL) { - if (debug) - printf("warning: reverse lookup failed\n"); - - continue; - } - rv = hostent_test_correctness(result, NULL); - if (rv != 0) { - __freehostent(result); - return (rv); - } - - if (addr_test_data != NULL) - TEST_DATA_APPEND(hostent, addr_test_data, result); - - __freehostent(result); - } - } - - return (0); -} - -static int -hostent_test_getaddrinfo_eq(struct hostent *he, void *mdata) -{ - struct addrinfo *ai, hints; - int rv; - - ai = NULL; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = af_type; - hints.ai_flags = AI_CANONNAME; - - if (debug) - printf("using getaddrinfo() to resolve %s\n", he->h_name); - - /* struct hostent *he was not resolved */ - if (he->h_addr_list == NULL) { - /* We can be sure that he->h_name is not NULL */ - rv = getaddrinfo(he->h_name, NULL, &hints, &ai); - if (rv == 0) { - if (debug) - printf("not ok - shouldn't have been resolved\n"); - return (-1); - } - } else { - rv = getaddrinfo(he->h_name, NULL, &hints, &ai); - if (rv != 0) { - if (debug) - printf("not ok - should have beed resolved\n"); - return (-1); - } - - rv = is_hostent_equal(he, ai); - if (rv != 0) { - if (debug) - printf("not ok - addrinfo and hostent are not equal\n"); - return (-1); - } - - } - - return (0); -} - -static int -hostent_test_getnameinfo_eq(struct hostent *he, void *mdata) -{ - char buffer[NI_MAXHOST]; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - struct sockaddr *saddr; - struct hostent *result; - int rv; - - if (he->h_addr_list != NULL) { - char **cp; - for (cp = he->h_addr_list; *cp; ++cp) { - if (debug) - printf("doing reverse lookup for %s\n", he->h_name); - - result = __gethostbyaddr(*cp, he->h_length, - he->h_addrtype); - if (result != NULL) { - rv = hostent_test_correctness(result, NULL); - if (rv != 0) { - __freehostent(result); - return (rv); - } - } else { - if (debug) - printf("reverse lookup failed\n"); - } - - switch (he->h_addrtype) { - case AF_INET: - memset(&sin, 0, sizeof(struct sockaddr_in)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_family = AF_INET; - memcpy(&sin.sin_addr, *cp, he->h_length); - - saddr = (struct sockaddr *)&sin; - break; - case AF_INET6: - memset(&sin6, 0, sizeof(struct sockaddr_in6)); - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_family = AF_INET6; - memcpy(&sin6.sin6_addr, *cp, he->h_length); - - saddr = (struct sockaddr *)&sin6; - break; - default: - if (debug) - printf("warning: %d family is unsupported\n", - he->h_addrtype); - continue; - } - - assert(saddr != NULL); - rv = getnameinfo(saddr, saddr->sa_len, buffer, - sizeof(buffer), NULL, 0, NI_NAMEREQD); - - if ((rv != 0) && (result != NULL)) { - if (debug) - printf("not ok - getnameinfo() didn't make the reverse lookup, when it should have (%s)\n", - gai_strerror(rv)); - return (rv); - } - - if ((rv == 0) && (result == NULL)) { - if (debug) - printf("not ok - getnameinfo() made the reverse lookup, when it shouldn't have\n"); - return (rv); - } - - if ((rv != 0) && (result == NULL)) { - if (debug) - printf("ok - both getnameinfo() and ***byaddr() failed\n"); - - continue; - } - - if (debug) - printf("comparing %s with %s\n", result->h_name, - buffer); - - rv = strcmp(result->h_name, buffer); - __freehostent(result); - - if (rv != 0) { - if (debug) - printf("not ok - getnameinfo() and ***byaddr() results are not equal\n"); - return (rv); - } else { - if (debug) - printf("ok - getnameinfo() and ***byaddr() results are equal\n"); - } - } - } - - return (0); -} - -static void -usage(void) -{ - (void)fprintf(stderr, - "Usage: %s -na2i [-o] [-d] [-46] [-mAcM] [-C] [-s ] -f \n", - getprogname()); - exit(1); -} - -int -main(int argc, char **argv) -{ - struct hostent_test_data td, td_addr, td_snap; - char *snapshot_file, *hostlist_file; - res_state statp; - int rv; - int c; - - if (argc < 2) - usage(); - - snapshot_file = NULL; - hostlist_file = NULL; - while ((c = getopt(argc, argv, "nad2iod46mAcMs:f:")) != -1) - switch (c) { - case '4': - af_type = AF_INET; - break; - case '6': - af_type = AF_INET6; - break; - case 'M': - af_type = AF_INET6; - use_ipv6_mapping = 1; - ipnode_flags |= AI_V4MAPPED_CFG; - break; - case 'm': - af_type = AF_INET6; - use_ipv6_mapping = 1; - ipnode_flags |= AI_V4MAPPED; - break; - case 'c': - ipnode_flags |= AI_ADDRCONFIG; - break; - case 'A': - ipnode_flags |= AI_ALL; - break; - case 'o': - use_ipnode_functions = 1; - break; - case 'd': - debug = 1; - break; - case 'n': - method = TEST_GETHOSTBYNAME2; - break; - case 'a': - method = TEST_GETHOSTBYADDR; - break; - case '2': - method = TEST_GETHOSTBYNAME2_GETADDRINFO; - break; - case 'i': - method = TEST_GETHOSTBYADDR_GETNAMEINFO; - break; - case 's': - snapshot_file = strdup(optarg); - break; - case 'f': - hostlist_file = strdup(optarg); - break; - default: - usage(); - } - - if (use_ipnode_functions == 0) { - statp = __res_state(); - if ((statp == NULL) || ((statp->options & RES_INIT) == 0 && - res_ninit(statp) == -1)) { - if (debug) - printf("error: can't init res_state\n"); - - free(snapshot_file); - free(hostlist_file); - return (-1); - } - - if (use_ipv6_mapping == 0) - statp->options &= ~RES_USE_INET6; - else - statp->options |= RES_USE_INET6; - } - - TEST_DATA_INIT(hostent, &td, clone_hostent, free_hostent); - TEST_DATA_INIT(hostent, &td_addr, clone_hostent, free_hostent); - TEST_DATA_INIT(hostent, &td_snap, clone_hostent, free_hostent); - - if (hostlist_file == NULL) - usage(); - - if (access(hostlist_file, R_OK) != 0) { - if (debug) - printf("can't access the hostlist file %s\n", - hostlist_file); - - usage(); - } - - if (debug) - printf("building host lists from %s\n", hostlist_file); - - rv = TEST_SNAPSHOT_FILE_READ(hostent, hostlist_file, &td, - hostent_read_hostlist_func); - if (rv != 0) - goto fin; - - if (snapshot_file != NULL) { - if (access(snapshot_file, W_OK | R_OK) != 0) { - if (errno == ENOENT) { - if (method != TEST_GETHOSTBYADDR) - method = TEST_BUILD_SNAPSHOT; - else - method = TEST_BUILD_ADDR_SNAPSHOT; - } else { - if (debug) - printf("can't access the snapshot file %s\n", - snapshot_file); - - rv = -1; - goto fin; - } - } else { - rv = TEST_SNAPSHOT_FILE_READ(hostent, snapshot_file, - &td_snap, hostent_read_snapshot_func); - if (rv != 0) { - if (debug) - printf("error reading snapshot file\n"); - goto fin; - } - } - } - - switch (method) { - case TEST_GETHOSTBYNAME2: - if (snapshot_file != NULL) - rv = DO_2PASS_TEST(hostent, &td, &td_snap, - compare_hostent, NULL); - break; - case TEST_GETHOSTBYADDR: - rv = DO_1PASS_TEST(hostent, &td, - hostent_test_gethostbyaddr, (void *)&td_addr); - - if (snapshot_file != NULL) - rv = DO_2PASS_TEST(hostent, &td_addr, &td_snap, - compare_hostent, NULL); - break; - case TEST_GETHOSTBYNAME2_GETADDRINFO: - rv = DO_1PASS_TEST(hostent, &td, - hostent_test_getaddrinfo_eq, NULL); - break; - case TEST_GETHOSTBYADDR_GETNAMEINFO: - rv = DO_1PASS_TEST(hostent, &td, - hostent_test_getnameinfo_eq, NULL); - break; - case TEST_BUILD_SNAPSHOT: - if (snapshot_file != NULL) { - rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file, &td, - sdump_hostent); - } - break; - case TEST_BUILD_ADDR_SNAPSHOT: - if (snapshot_file != NULL) { - rv = DO_1PASS_TEST(hostent, &td, - hostent_test_gethostbyaddr, (void *)&td_addr); - - rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file, - &td_addr, sdump_hostent); - } - break; - default: - rv = 0; - break; - }; - -fin: - TEST_DATA_DESTROY(hostent, &td_snap); - TEST_DATA_DESTROY(hostent, &td_addr); - TEST_DATA_DESTROY(hostent, &td); - free(hostlist_file); - free(snapshot_file); - - return (rv); -} - Property changes on: head/tools/regression/lib/libc/nss/test-gethostby.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-gethostby.t =================================================================== --- head/tools/regression/lib/libc/nss/test-gethostby.t (revision 292322) +++ head/tools/regression/lib/libc/nss/test-gethostby.t (nonexistent) @@ -1,113 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -do_test() { - number=$1 - comment=$2 - opt=$3 - if ./$executable $opt; then - echo "ok $number - $comment" - else - echo "not ok $number - $comment" - fi -} - -cd `dirname $0` - -executable=`basename $0 .t` - -make $executable 2>&1 > /dev/null - -echo 1..46 -#Tests for gethostby***() functions -#IPv4-driven testing -do_test 1 'gethostbyname2() (IPv4)' '-4 -n -f mach' -do_test 2 'gethostbyaddr() (IPv4)' '-4 -a -f mach' -do_test 3 'gethostbyname2()-getaddrinfo() (IPv4)' '-4 -2 -f mach' -do_test 4 'gethostbyaddr()-getnameinfo() (IPv4)' '-4 -i -f mach' -do_test 5 'gethostbyname2() snapshot (IPv4)'\ - '-4 -n -s snapshot_htname4 -f mach' -do_test 6 'gethostbyaddr() snapshot (IPv4)'\ - '-4 -a -s snapshot_htaddr4 -f mach' - -#IPv6-driven testing -do_test 7 'gethostbyname2() (IPv6)' '-6 -n -f mach' -do_test 8 'gethostbyaddr() (IPv6)' '-6 -a -f mach' -do_test 9 'gethostbyname2()-getaddrinfo() (IPv6)' '-6 -2 -f mach' -do_test 10 'gethostbyaddr()-getnameinfo() (IPv6)' '-6 -i -f mach' -do_test 11 'gethostbyname2() snapshot (IPv6)'\ - '-6 -n -s snapshot_htname6 -f mach' -do_test 12 'gethostbyaddr() snapshot (IPv6)'\ - '-6 -a -s snapshot_htaddr6 -f mach' - -#Mapped IPv6-driven testing (getaddrinfo() equality test is useless here) -do_test 13 'gethostbyname2() (IPv6 mapped)' '-m -n -f mach' -do_test 14 'gethostbyaddr() (IPv6 mapped)' '-m -a -f mach' -do_test 15 'gethostbyname2() snapshot (IPv6 mapped)'\ - '-m -n -s snapshot_htname6map -f mach' -do_test 16 'gethostbyaddr() snapshot (IPv6 mapped)'\ - '-m -a -s snapshot_htaddr6map -f mach' - -#Tests for getipnodeby***() functions -#IPv4-driven testing, flags are 0 -do_test 17 'getipnodebyname() (IPv4)' '-o -4 -n -f mach' -do_test 18 'getipnodebyaddr() (IPv4)' '-o -4 -a -f mach' -do_test 19 'getipnodebyname()-getaddrinfo() (IPv4)' '-o -4 -2 -f mach' -do_test 20 'getipnodebyaddr()-getnameinfo() (IPv4)' '-o -4 -i -f mach' -do_test 21 'getipnodebyname() snapshot (IPv4)'\ - '-o -4 -n -s snapshot_ipnodename4 -f mach' -do_test 22 'getipnodebyname() snapshot (IPv4)'\ - '-o -4 -a -s snapshot_ipnodeaddr4 -f mach' - -#IPv6-driven testing, flags are 0 -do_test 23 'getipnodebyname() (IPv6)' '-o -6 -n -f mach' -do_test 24 'getipnodebyaddr() (IPv6)' '-o -6 -a -f mach' -do_test 25 'getipnodebyname()-getaddrinfo() (IPv6)' '-o -6 -2 -f mach' -do_test 26 'getipnodebyaddr()-getnameinfo() (IPv6)' '-o -6 -i -f mach' -do_test 27 'getipnodebyname() snapshot (IPv6)'\ - '-o -6 -n -s snapshot_ipnodename6 -f mach' -do_test 28 'getipnodebyaddr() snapshot (IPv6)'\ - '-o -6 -a -s snapshot_ipnodeaddr6 -f mach' - -#Mapped IPv6-driven testing, flags are AI_V4MAPPED -do_test 29 'getipnodebyname() (IPv6, AI_V4MAPPED)' '-o -m -n -f mach' -do_test 30 'getipnodebyaddr() (IPv6, AI_V4MAPPED)' '-o -m -a -f mach' -do_test 31 'getipnodebyname() snapshot (IPv6, AI_V4MAPPED)'\ - '-o -m -n -s snapshot_ipnodename6_AI_V4MAPPED -f mach' -do_test 32 'getipnodebyaddr() snapshot (IPv6, AI_V4MAPPED)'\ - '-o -m -a -s snapshot_ipnodeaddr6_AI_V4MAPPED -f mach' - -#Mapped IPv6-driven testing, flags are AI_V4MAPPED_CFG -do_test 33 'getipnodebyname() (IPv6, AI_V4MAPPED_CFG)' '-o -M -n -f mach' -do_test 34 'getipnodebyaddr() (IPv6, AI_V4MAPPED_CFG)' '-o -M -a -f mach' -do_test 35 'getipnodebyname() snapshot (IPv6, AI_V4MAPPED_CFG)'\ - '-o -M -n -s snapshot_ipnodename6_AI_V4MAPPED_CFG -f mach' -do_test 36 'getipnodebyaddr() snapshot (IPv6, AI_V4MAPPED_CFG)'\ - '-o -M -a -s snapshot_ipnodeaddr6_AI_V4MAPPED_CFG -f mach' - -#Mapped IPv6-driven testing, flags are AI_V4MAPPED_CFG | AI_ALL -do_test 37 'getipnodebyname() (IPv6, AI_V4MAPPED_CFG | AI_ALL)'\ - '-o -MA -n -f mach' -do_test 38 'getipnodebyaddr() (IPv6, AI_V4MAPPED_CFG | AI_ALL)'\ - '-o -MA -a -f mach' -do_test 39 'getipnodebyname() snapshot (IPv6, AI_V4MAPPED_CFG | AI_ALL)'\ - '-o -MA -n -s snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ALL -f mach' -do_test 40 'getipnodebyaddr() snapshot (IPv6, AI_V4MAPPED_CFG | AI_ALL)'\ - '-o -MA -a -s snapshot_ipnodeaddr6_AI_V4MAPPED_CFG_AI_ALL -f mach' - -#Mapped IPv6-driven testing, flags are AI_V4MAPPED_CFG | AI_ADDRCONFIG -do_test 41 'getipnodebyname() (IPv6, AI_V4MAPPED_CFG | AI_ADDRCONFIG)'\ - '-o -Mc -n -f mach' -do_test 42 'getipnodebyname() snapshot (IPv6, AI_V4MAPPED_CFG | AI_ADDRCONFIG)'\ - '-o -Mc -n -s snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ADDRCONFIG -f mach' - -#IPv4-driven testing, flags are AI_ADDRCONFIG -do_test 43 'getipnodebyname() (IPv4, AI_ADDRCONFIG)' '-o -4c -n -f mach' -do_test 44 'getipnodebyname() snapshot (IPv4, AI_ADDRCONFIG)'\ - '-o -4c -n -s snapshot_ipnodename4_AI_ADDRCONFIG -f mach' - -#IPv6-driven testing, flags are AI_ADDRCONFIG -do_test 45 'getipnodebyname() (IPv6, AI_ADDRCONFIG)' '-o -6c -n -f mach' -do_test 46 'getipnodebyname() snapshot (IPv6, AI_ADDRCONFIG)'\ - '-o -6c -n -s snapshot_ipnodename6_AI_ADDRCONFIG -f mach' - Property changes on: head/tools/regression/lib/libc/nss/test-gethostby.t ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getserv.c =================================================================== --- head/tools/regression/lib/libc/nss/test-getserv.c (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getserv.c (nonexistent) @@ -1,551 +0,0 @@ -/*- - * Copyright (c) 2006 Michael Bushkov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "testutil.h" - -enum test_methods { - TEST_GETSERVENT, - TEST_GETSERVBYNAME, - TEST_GETSERVBYPORT, - TEST_GETSERVENT_2PASS, - TEST_BUILD_SNAPSHOT -}; - -static int debug = 0; -static enum test_methods method = TEST_BUILD_SNAPSHOT; - -DECLARE_TEST_DATA(servent) -DECLARE_TEST_FILE_SNAPSHOT(servent) -DECLARE_1PASS_TEST(servent) -DECLARE_2PASS_TEST(servent) - -static void clone_servent(struct servent *, struct servent const *); -static int compare_servent(struct servent *, struct servent *, void *); -static void dump_servent(struct servent *); -static void free_servent(struct servent *); - -static void sdump_servent(struct servent *, char *, size_t); -static int servent_read_snapshot_func(struct servent *, char *); - -static int servent_check_ambiguity(struct servent_test_data *, - struct servent *); -static int servent_fill_test_data(struct servent_test_data *); -static int servent_test_correctness(struct servent *, void *); -static int servent_test_getservbyname(struct servent *, void *); -static int servent_test_getservbyport(struct servent *, void *); -static int servent_test_getservent(struct servent *, void *); - -static void usage(void) __attribute__((__noreturn__)); - -IMPLEMENT_TEST_DATA(servent) -IMPLEMENT_TEST_FILE_SNAPSHOT(servent) -IMPLEMENT_1PASS_TEST(servent) -IMPLEMENT_2PASS_TEST(servent) - -static void -clone_servent(struct servent *dest, struct servent const *src) -{ - assert(dest != NULL); - assert(src != NULL); - - char **cp; - int aliases_num; - - memset(dest, 0, sizeof(struct servent)); - - if (src->s_name != NULL) { - dest->s_name = strdup(src->s_name); - assert(dest->s_name != NULL); - } - - if (src->s_proto != NULL) { - dest->s_proto = strdup(src->s_proto); - assert(dest->s_proto != NULL); - } - dest->s_port = src->s_port; - - if (src->s_aliases != NULL) { - aliases_num = 0; - for (cp = src->s_aliases; *cp; ++cp) - ++aliases_num; - - dest->s_aliases = (char **)malloc((aliases_num+1) * (sizeof(char *))); - assert(dest->s_aliases != NULL); - memset(dest->s_aliases, 0, (aliases_num+1) * (sizeof(char *))); - - for (cp = src->s_aliases; *cp; ++cp) { - dest->s_aliases[cp - src->s_aliases] = strdup(*cp); - assert(dest->s_aliases[cp - src->s_aliases] != NULL); - } - } -} - -static void -free_servent(struct servent *serv) -{ - char **cp; - - assert(serv != NULL); - - free(serv->s_name); - free(serv->s_proto); - - for (cp = serv->s_aliases; *cp; ++cp) - free(*cp); - free(serv->s_aliases); -} - -static int -compare_servent(struct servent *serv1, struct servent *serv2, void *mdata) -{ - char **c1, **c2; - - if (serv1 == serv2) - return 0; - - if ((serv1 == NULL) || (serv2 == NULL)) - goto errfin; - - if ((strcmp(serv1->s_name, serv2->s_name) != 0) || - (strcmp(serv1->s_proto, serv2->s_proto) != 0) || - (serv1->s_port != serv2->s_port)) - goto errfin; - - c1 = serv1->s_aliases; - c2 = serv2->s_aliases; - - if ((serv1->s_aliases == NULL) || (serv2->s_aliases == NULL)) - goto errfin; - - for (;*c1 && *c2; ++c1, ++c2) - if (strcmp(*c1, *c2) != 0) - goto errfin; - - if ((*c1 != '\0') || (*c2 != '\0')) - goto errfin; - - return 0; - -errfin: - if ((debug) && (mdata == NULL)) { - printf("following structures are not equal:\n"); - dump_servent(serv1); - dump_servent(serv2); - } - - return (-1); -} - -static void -sdump_servent(struct servent *serv, char *buffer, size_t buflen) -{ - char **cp; - int written; - - written = snprintf(buffer, buflen, "%s %d %s", - serv->s_name, ntohs(serv->s_port), serv->s_proto); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (serv->s_aliases != NULL) { - if (*(serv->s_aliases) != '\0') { - for (cp = serv->s_aliases; *cp; ++cp) { - written = snprintf(buffer, buflen, " %s",*cp); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (buflen == 0) - return; - } - } else - snprintf(buffer, buflen, " noaliases"); - } else - snprintf(buffer, buflen, " (null)"); -} - -static int -servent_read_snapshot_func(struct servent *serv, char *line) -{ - StringList *sl; - char *s, *ps, *ts; - int i; - - if (debug) - printf("1 line read from snapshot:\n%s\n", line); - - i = 0; - sl = NULL; - ps = line; - memset(serv, 0, sizeof(struct servent)); - while ( (s = strsep(&ps, " ")) != NULL) { - switch (i) { - case 0: - serv->s_name = strdup(s); - assert(serv->s_name != NULL); - break; - - case 1: - serv->s_port = htons( - (int)strtol(s, &ts, 10)); - if (*ts != '\0') { - free(serv->s_name); - return (-1); - } - break; - - case 2: - serv->s_proto = strdup(s); - assert(serv->s_proto != NULL); - break; - - default: - if (sl == NULL) { - if (strcmp(s, "(null)") == 0) - return (0); - - sl = sl_init(); - assert(sl != NULL); - - if (strcmp(s, "noaliases") != 0) { - ts = strdup(s); - assert(ts != NULL); - sl_add(sl, ts); - } - } else { - ts = strdup(s); - assert(ts != NULL); - sl_add(sl, ts); - } - break; - }; - ++i; - } - - if (i < 3) { - free(serv->s_name); - free(serv->s_proto); - memset(serv, 0, sizeof(struct servent)); - return (-1); - } - - sl_add(sl, NULL); - serv->s_aliases = sl->sl_str; - - /* NOTE: is it a dirty hack or not? */ - free(sl); - return (0); -} - -static void -dump_servent(struct servent *result) -{ - if (result != NULL) { - char buffer[1024]; - sdump_servent(result, buffer, sizeof(buffer)); - printf("%s\n", buffer); - } else - printf("(null)\n"); -} - -static int -servent_fill_test_data(struct servent_test_data *td) -{ - struct servent *serv; - - setservent(1); - while ((serv = getservent()) != NULL) { - if (servent_test_correctness(serv, NULL) == 0) - TEST_DATA_APPEND(servent, td, serv); - else - return (-1); - } - endservent(); - - return (0); -} - -static int -servent_test_correctness(struct servent *serv, void *mdata) -{ - if (debug) { - printf("testing correctness with the following data:\n"); - dump_servent(serv); - } - - if (serv == NULL) - goto errfin; - - if (serv->s_name == NULL) - goto errfin; - - if (serv->s_proto == NULL) - goto errfin; - - if (ntohs(serv->s_port < 0)) - goto errfin; - - if (serv->s_aliases == NULL) - goto errfin; - - if (debug) - printf("correct\n"); - - return (0); -errfin: - if (debug) - printf("incorrect\n"); - - return (-1); -} - -/* servent_check_ambiguity() is needed when one port+proto is associated with - * more than one service (these cases are usually marked as PROBLEM in - * /etc/services. This functions is needed also when one service+proto is - * associated with several ports. We have to check all the servent structures - * to make sure that serv really exists and correct */ -static int -servent_check_ambiguity(struct servent_test_data *td, struct servent *serv) -{ - - return (TEST_DATA_FIND(servent, td, serv, compare_servent, - NULL) != NULL ? 0 : -1); -} - -static int -servent_test_getservbyname(struct servent *serv_model, void *mdata) -{ - char **alias; - struct servent *serv; - - if (debug) { - printf("testing getservbyname() with the following data:\n"); - dump_servent(serv_model); - } - - serv = getservbyname(serv_model->s_name, serv_model->s_proto); - if (servent_test_correctness(serv, NULL) != 0) - goto errfin; - - if ((compare_servent(serv, serv_model, NULL) != 0) && - (servent_check_ambiguity((struct servent_test_data *)mdata, serv) - !=0)) - goto errfin; - - for (alias = serv_model->s_aliases; *alias; ++alias) { - serv = getservbyname(*alias, serv_model->s_proto); - - if (servent_test_correctness(serv, NULL) != 0) - goto errfin; - - if ((compare_servent(serv, serv_model, NULL) != 0) && - (servent_check_ambiguity( - (struct servent_test_data *)mdata, serv) != 0)) - goto errfin; - } - - if (debug) - printf("ok\n"); - return (0); - -errfin: - if (debug) - printf("not ok\n"); - - return (-1); -} - -static int -servent_test_getservbyport(struct servent *serv_model, void *mdata) -{ - struct servent *serv; - - if (debug) { - printf("testing getservbyport() with the following data...\n"); - dump_servent(serv_model); - } - - serv = getservbyport(serv_model->s_port, serv_model->s_proto); - if ((servent_test_correctness(serv, NULL) != 0) || - ((compare_servent(serv, serv_model, NULL) != 0) && - (servent_check_ambiguity((struct servent_test_data *)mdata, serv) - != 0))) { - if (debug) - printf("not ok\n"); - return (-1); - } else { - if (debug) - printf("ok\n"); - return (0); - } -} - -static int -servent_test_getservent(struct servent *serv, void *mdata) -{ - /* Only correctness can be checked when doing 1-pass test for - * getservent(). */ - return (servent_test_correctness(serv, NULL)); -} - -static void -usage(void) -{ - (void)fprintf(stderr, - "Usage: %s -npe2 [-d] [-s ]\n", - getprogname()); - exit(1); -} - -int -main(int argc, char **argv) -{ - struct servent_test_data td, td_snap, td_2pass; - char *snapshot_file; - int rv; - int c; - - if (argc < 2) - usage(); - - snapshot_file = NULL; - while ((c = getopt(argc, argv, "npe2ds:")) != -1) - switch (c) { - case 'd': - debug++; - break; - case 'n': - method = TEST_GETSERVBYNAME; - break; - case 'p': - method = TEST_GETSERVBYPORT; - break; - case 'e': - method = TEST_GETSERVENT; - break; - case '2': - method = TEST_GETSERVENT_2PASS; - break; - case 's': - snapshot_file = strdup(optarg); - break; - default: - usage(); - } - - TEST_DATA_INIT(servent, &td, clone_servent, free_servent); - TEST_DATA_INIT(servent, &td_snap, clone_servent, free_servent); - if (snapshot_file != NULL) { - if (access(snapshot_file, W_OK | R_OK) != 0) { - if (errno == ENOENT) - method = TEST_BUILD_SNAPSHOT; - else { - if (debug) - printf("can't access the file %s\n", - snapshot_file); - - rv = -1; - goto fin; - } - } else { - if (method == TEST_BUILD_SNAPSHOT) { - rv = 0; - goto fin; - } - - TEST_SNAPSHOT_FILE_READ(servent, snapshot_file, - &td_snap, servent_read_snapshot_func); - } - } - - rv = servent_fill_test_data(&td); - if (rv == -1) - return (-1); - switch (method) { - case TEST_GETSERVBYNAME: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(servent, &td, - servent_test_getservbyname, (void *)&td); - else - rv = DO_1PASS_TEST(servent, &td_snap, - servent_test_getservbyname, (void *)&td_snap); - break; - case TEST_GETSERVBYPORT: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(servent, &td, - servent_test_getservbyport, (void *)&td); - else - rv = DO_1PASS_TEST(servent, &td_snap, - servent_test_getservbyport, (void *)&td_snap); - break; - case TEST_GETSERVENT: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(servent, &td, servent_test_getservent, - (void *)&td); - else - rv = DO_2PASS_TEST(servent, &td, &td_snap, - compare_servent, NULL); - break; - case TEST_GETSERVENT_2PASS: - TEST_DATA_INIT(servent, &td_2pass, clone_servent, free_servent); - rv = servent_fill_test_data(&td_2pass); - if (rv != -1) - rv = DO_2PASS_TEST(servent, &td, &td_2pass, - compare_servent, NULL); - TEST_DATA_DESTROY(servent, &td_2pass); - break; - case TEST_BUILD_SNAPSHOT: - if (snapshot_file != NULL) - rv = TEST_SNAPSHOT_FILE_WRITE(servent, snapshot_file, &td, - sdump_servent); - break; - default: - rv = 0; - break; - }; - -fin: - TEST_DATA_DESTROY(servent, &td_snap); - TEST_DATA_DESTROY(servent, &td); - free(snapshot_file); - return (rv); -} Property changes on: head/tools/regression/lib/libc/nss/test-getserv.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getgr.c =================================================================== --- head/tools/regression/lib/libc/nss/test-getgr.c (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getgr.c (nonexistent) @@ -1,534 +0,0 @@ -/*- - * Copyright (c) 2006 Michael Bushkov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "testutil.h" - -enum test_methods { - TEST_GETGRENT, - TEST_GETGRNAM, - TEST_GETGRGID, - TEST_GETGRENT_2PASS, - TEST_BUILD_SNAPSHOT -}; - -static int debug = 0; -static enum test_methods method = TEST_BUILD_SNAPSHOT; - -DECLARE_TEST_DATA(group) -DECLARE_TEST_FILE_SNAPSHOT(group) -DECLARE_1PASS_TEST(group) -DECLARE_2PASS_TEST(group) - -static void clone_group(struct group *, struct group const *); -static int compare_group(struct group *, struct group *, void *); -static void dump_group(struct group *); -static void free_group(struct group *); - -static void sdump_group(struct group *, char *, size_t); -static int group_read_snapshot_func(struct group *, char *); - -static int group_check_ambiguity(struct group_test_data *, - struct group *); -static int group_fill_test_data(struct group_test_data *); -static int group_test_correctness(struct group *, void *); -static int group_test_getgrnam(struct group *, void *); -static int group_test_getgrgid(struct group *, void *); -static int group_test_getgrent(struct group *, void *); - -static void usage(void) __attribute__((__noreturn__)); - -IMPLEMENT_TEST_DATA(group) -IMPLEMENT_TEST_FILE_SNAPSHOT(group) -IMPLEMENT_1PASS_TEST(group) -IMPLEMENT_2PASS_TEST(group) - -static void -clone_group(struct group *dest, struct group const *src) -{ - assert(dest != NULL); - assert(src != NULL); - - char **cp; - int members_num; - - memset(dest, 0, sizeof(struct group)); - - if (src->gr_name != NULL) { - dest->gr_name = strdup(src->gr_name); - assert(dest->gr_name != NULL); - } - - if (src->gr_passwd != NULL) { - dest->gr_passwd = strdup(src->gr_passwd); - assert(dest->gr_passwd != NULL); - } - dest->gr_gid = src->gr_gid; - - if (src->gr_mem != NULL) { - members_num = 0; - for (cp = src->gr_mem; *cp; ++cp) - ++members_num; - - dest->gr_mem = (char **)malloc( - (members_num + 1) * (sizeof(char *))); - assert(dest->gr_mem != NULL); - memset(dest->gr_mem, 0, (members_num+1) * (sizeof(char *))); - - for (cp = src->gr_mem; *cp; ++cp) { - dest->gr_mem[cp - src->gr_mem] = strdup(*cp); - assert(dest->gr_mem[cp - src->gr_mem] != NULL); - } - } -} - -static void -free_group(struct group *grp) -{ - char **cp; - - assert(grp != NULL); - - free(grp->gr_name); - free(grp->gr_passwd); - - for (cp = grp->gr_mem; *cp; ++cp) - free(*cp); - free(grp->gr_mem); -} - -static int -compare_group(struct group *grp1, struct group *grp2, void *mdata) -{ - char **c1, **c2; - - if (grp1 == grp2) - return (0); - - if ((grp1 == NULL) || (grp2 == NULL)) - goto errfin; - - if ((strcmp(grp1->gr_name, grp2->gr_name) != 0) || - (strcmp(grp1->gr_passwd, grp2->gr_passwd) != 0) || - (grp1->gr_gid != grp2->gr_gid)) - goto errfin; - - c1 = grp1->gr_mem; - c2 = grp2->gr_mem; - - if ((grp1->gr_mem == NULL) || (grp2->gr_mem == NULL)) - goto errfin; - - for (;*c1 && *c2; ++c1, ++c2) - if (strcmp(*c1, *c2) != 0) - goto errfin; - - if ((*c1 != '\0') || (*c2 != '\0')) - goto errfin; - - return 0; - -errfin: - if ((debug) && (mdata == NULL)) { - printf("following structures are not equal:\n"); - dump_group(grp1); - dump_group(grp2); - } - - return (-1); -} - -static void -sdump_group(struct group *grp, char *buffer, size_t buflen) -{ - char **cp; - int written; - - written = snprintf(buffer, buflen, "%s %s %d", - grp->gr_name, grp->gr_passwd, grp->gr_gid); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (grp->gr_mem != NULL) { - if (*(grp->gr_mem) != '\0') { - for (cp = grp->gr_mem; *cp; ++cp) { - written = snprintf(buffer, buflen, " %s",*cp); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (buflen == 0) - return; - } - } else - snprintf(buffer, buflen, " nomem"); - } else - snprintf(buffer, buflen, " (null)"); -} - -static int -group_read_snapshot_func(struct group *grp, char *line) -{ - StringList *sl; - char *s, *ps, *ts; - int i; - - if (debug) - printf("1 line read from snapshot:\n%s\n", line); - - i = 0; - sl = NULL; - ps = line; - memset(grp, 0, sizeof(struct group)); - while ( (s = strsep(&ps, " ")) != NULL) { - switch (i) { - case 0: - grp->gr_name = strdup(s); - assert(grp->gr_name != NULL); - break; - - case 1: - grp->gr_passwd = strdup(s); - assert(grp->gr_passwd != NULL); - break; - - case 2: - grp->gr_gid = (gid_t)strtol(s, &ts, 10); - if (*ts != '\0') { - free(grp->gr_name); - free(grp->gr_passwd); - return (-1); - } - break; - - default: - if (sl == NULL) { - if (strcmp(s, "(null)") == 0) - return (0); - - sl = sl_init(); - assert(sl != NULL); - - if (strcmp(s, "nomem") != 0) { - ts = strdup(s); - assert(ts != NULL); - sl_add(sl, ts); - } - } else { - ts = strdup(s); - assert(ts != NULL); - sl_add(sl, ts); - } - break; - }; - ++i; - } - - if (i < 3) { - free(grp->gr_name); - free(grp->gr_passwd); - memset(grp, 0, sizeof(struct group)); - return (-1); - } - - sl_add(sl, NULL); - grp->gr_mem = sl->sl_str; - - /* NOTE: is it a dirty hack or not? */ - free(sl); - return (0); -} - -static void -dump_group(struct group *result) -{ - if (result != NULL) { - char buffer[1024]; - sdump_group(result, buffer, sizeof(buffer)); - printf("%s\n", buffer); - } else - printf("(null)\n"); -} - -static int -group_fill_test_data(struct group_test_data *td) -{ - struct group *grp; - - setgroupent(1); - while ((grp = getgrent()) != NULL) { - if (group_test_correctness(grp, NULL) == 0) - TEST_DATA_APPEND(group, td, grp); - else - return (-1); - } - endgrent(); - - return (0); -} - -static int -group_test_correctness(struct group *grp, void *mdata) -{ - if (debug) { - printf("testing correctness with the following data:\n"); - dump_group(grp); - } - - if (grp == NULL) - goto errfin; - - if (grp->gr_name == NULL) - goto errfin; - - if (grp->gr_passwd == NULL) - goto errfin; - - if (grp->gr_mem == NULL) - goto errfin; - - if (debug) - printf("correct\n"); - - return (0); -errfin: - if (debug) - printf("incorrect\n"); - - return (-1); -} - -/* group_check_ambiguity() is needed here because when doing the getgrent() - * calls sequence, records from different nsswitch sources can be different, - * though having the same pw_name/pw_uid */ -static int -group_check_ambiguity(struct group_test_data *td, struct group *pwd) -{ - - return (TEST_DATA_FIND(group, td, pwd, compare_group, - NULL) != NULL ? 0 : -1); -} - -static int -group_test_getgrnam(struct group *grp_model, void *mdata) -{ - struct group *grp; - - if (debug) { - printf("testing getgrnam() with the following data:\n"); - dump_group(grp_model); - } - - grp = getgrnam(grp_model->gr_name); - if (group_test_correctness(grp, NULL) != 0) - goto errfin; - - if ((compare_group(grp, grp_model, NULL) != 0) && - (group_check_ambiguity((struct group_test_data *)mdata, grp) - !=0)) - goto errfin; - - if (debug) - printf("ok\n"); - return (0); - -errfin: - if (debug) - printf("not ok\n"); - - return (-1); -} - -static int -group_test_getgrgid(struct group *grp_model, void *mdata) -{ - struct group *grp; - - if (debug) { - printf("testing getgrgid() with the following data...\n"); - dump_group(grp_model); - } - - grp = getgrgid(grp_model->gr_gid); - if ((group_test_correctness(grp, NULL) != 0) || - ((compare_group(grp, grp_model, NULL) != 0) && - (group_check_ambiguity((struct group_test_data *)mdata, grp) - != 0))) { - if (debug) - printf("not ok\n"); - return (-1); - } else { - if (debug) - printf("ok\n"); - return (0); - } -} - -static int -group_test_getgrent(struct group *grp, void *mdata) -{ - /* Only correctness can be checked when doing 1-pass test for - * getgrent(). */ - return (group_test_correctness(grp, NULL)); -} - -static void -usage(void) -{ - (void)fprintf(stderr, - "Usage: %s -nge2 [-d] [-s ]\n", - getprogname()); - exit(1); -} - -int -main(int argc, char **argv) -{ - struct group_test_data td, td_snap, td_2pass; - char *snapshot_file; - int rv; - int c; - - if (argc < 2) - usage(); - - snapshot_file = NULL; - while ((c = getopt(argc, argv, "nge2ds:")) != -1) - switch (c) { - case 'd': - debug++; - break; - case 'n': - method = TEST_GETGRNAM; - break; - case 'g': - method = TEST_GETGRGID; - break; - case 'e': - method = TEST_GETGRENT; - break; - case '2': - method = TEST_GETGRENT_2PASS; - break; - case 's': - snapshot_file = strdup(optarg); - break; - default: - usage(); - } - - TEST_DATA_INIT(group, &td, clone_group, free_group); - TEST_DATA_INIT(group, &td_snap, clone_group, free_group); - if (snapshot_file != NULL) { - if (access(snapshot_file, W_OK | R_OK) != 0) { - if (errno == ENOENT) - method = TEST_BUILD_SNAPSHOT; - else { - if (debug) - printf("can't access the file %s\n", - snapshot_file); - - rv = -1; - goto fin; - } - } else { - if (method == TEST_BUILD_SNAPSHOT) { - rv = 0; - goto fin; - } - - TEST_SNAPSHOT_FILE_READ(group, snapshot_file, - &td_snap, group_read_snapshot_func); - } - } - - rv = group_fill_test_data(&td); - if (rv == -1) - return (-1); - switch (method) { - case TEST_GETGRNAM: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(group, &td, - group_test_getgrnam, (void *)&td); - else - rv = DO_1PASS_TEST(group, &td_snap, - group_test_getgrnam, (void *)&td_snap); - break; - case TEST_GETGRGID: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(group, &td, - group_test_getgrgid, (void *)&td); - else - rv = DO_1PASS_TEST(group, &td_snap, - group_test_getgrgid, (void *)&td_snap); - break; - case TEST_GETGRENT: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(group, &td, group_test_getgrent, - (void *)&td); - else - rv = DO_2PASS_TEST(group, &td, &td_snap, - compare_group, NULL); - break; - case TEST_GETGRENT_2PASS: - TEST_DATA_INIT(group, &td_2pass, clone_group, free_group); - rv = group_fill_test_data(&td_2pass); - if (rv != -1) - rv = DO_2PASS_TEST(group, &td, &td_2pass, - compare_group, NULL); - TEST_DATA_DESTROY(group, &td_2pass); - break; - case TEST_BUILD_SNAPSHOT: - if (snapshot_file != NULL) - rv = TEST_SNAPSHOT_FILE_WRITE(group, snapshot_file, &td, - sdump_group); - break; - default: - rv = 0; - break; - }; - -fin: - TEST_DATA_DESTROY(group, &td_snap); - TEST_DATA_DESTROY(group, &td); - free(snapshot_file); - return (rv); -} Property changes on: head/tools/regression/lib/libc/nss/test-getgr.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getgr.t =================================================================== --- head/tools/regression/lib/libc/nss/test-getgr.t (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getgr.t (nonexistent) @@ -1,29 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -do_test() { - number=$1 - comment=$2 - opt=$3 - if ./$executable $opt; then - echo "ok $number - $comment" - else - echo "not ok $number - $comment" - fi -} - -cd `dirname $0` - -executable=`basename $0 .t` - -make $executable 2>&1 > /dev/null - -echo 1..8 -do_test 1 'getgrnam()' '-n' -do_test 2 'getgrgid()' '-g' -do_test 3 'getgrent()' '-e' -do_test 4 'getgrent() 2-pass' '-2' -do_test 5 'building snapshot, if needed' '-s snapshot_grp' -do_test 6 'getgrnam() snapshot' '-n -s snapshot_grp' -do_test 7 'getgrgid() snapshot' '-g -s snapshot_grp' -do_test 8 'getgrent() snapshot' '-e -s snapshot_grp' Property changes on: head/tools/regression/lib/libc/nss/test-getgr.t ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/testutil.h =================================================================== --- head/tools/regression/lib/libc/nss/testutil.h (revision 292322) +++ head/tools/regression/lib/libc/nss/testutil.h (nonexistent) @@ -1,332 +0,0 @@ -/*- - * Copyright (c) 2006 Michael Bushkov - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include - -#define DECLARE_TEST_DATA(ent) \ -struct ent##_entry { \ - struct ent data; \ - STAILQ_ENTRY(ent##_entry) entries; \ -}; \ - \ -struct ent##_test_data { \ - void (*clone_func)(struct ent *, struct ent const *); \ - void (*free_func)(struct ent *); \ - \ - STAILQ_HEAD(ent_head, ent##_entry) snapshot_data; \ -}; \ - \ -void __##ent##_test_data_init(struct ent##_test_data *, \ - void (*)(struct ent *, struct ent const *), \ - void (*freef)(struct ent *)); \ -void __##ent##_test_data_destroy(struct ent##_test_data *); \ - \ -void __##ent##_test_data_append(struct ent##_test_data *, struct ent *data);\ -int __##ent##_test_data_foreach(struct ent##_test_data *, \ - int (*)(struct ent *, void *), void *); \ -int __##ent##_test_data_compare(struct ent##_test_data *, \ - struct ent##_test_data *, int (*)(struct ent *, struct ent *, \ - void *), void *); \ -struct ent *__##ent##_test_data_find(struct ent##_test_data *, struct ent *,\ - int (*)(struct ent *, struct ent *, void *), void *); \ -void __##ent##_test_data_clear(struct ent##_test_data *); - -#define TEST_DATA_INIT(ent, td, clonef, freef)\ - __##ent##_test_data_init(td, clonef, freef) -#define TEST_DATA_DESTROY(ent, td) __##ent##_test_data_destroy(td) -#define TEST_DATA_APPEND(ent, td, d) __##ent##_test_data_append(td, d) -#define TEST_DATA_FOREACH(ent, td, f, mdata)\ - __##ent##_test_data_foreach(td, f, mdata) -#define TEST_DATA_COMPARE(ent, td1, td2, fcmp, mdata)\ - __##ent##_test_data_compare(td1, td2, fcmp, mdata); -#define TEST_DATA_FIND(ent, td, d, fcmp, mdata)\ - __##ent##_test_data_find(td, d, fcmp, mdata) -#define TEST_DATA_CLEAR(ent, td) __##ent##_test_data_clear(td) - -#define IMPLEMENT_TEST_DATA(ent) \ -void \ -__##ent##_test_data_init(struct ent##_test_data *td, \ - void (*clonef)(struct ent *, struct ent const *), \ - void (*freef)(struct ent *)) \ -{ \ - assert(td != NULL); \ - assert(clonef != NULL); \ - assert(freef != NULL); \ - \ - memset(td, 0, sizeof(*td)); \ - td->clone_func = clonef; \ - td->free_func = freef; \ - STAILQ_INIT(&td->snapshot_data); \ -} \ - \ -void \ -__##ent##_test_data_destroy(struct ent##_test_data *td) \ -{ \ - __##ent##_test_data_clear(td); \ -} \ - \ -void \ -__##ent##_test_data_append(struct ent##_test_data *td, struct ent *app_data)\ -{ \ - struct ent##_entry *e; \ - \ - assert(td != NULL); \ - assert(app_data != NULL); \ - \ - e = (struct ent##_entry *)malloc(sizeof(struct ent##_entry)); \ - assert(e != NULL); \ - memset(e, 0, sizeof(struct ent##_entry)); \ - \ - td->clone_func(&e->data, app_data); \ - STAILQ_INSERT_TAIL(&td->snapshot_data, e, entries); \ -} \ - \ -int \ -__##ent##_test_data_foreach(struct ent##_test_data *td, \ - int (*forf)(struct ent *, void *), void *mdata) \ -{ \ - struct ent##_entry *e; \ - int rv; \ - \ - assert(td != NULL); \ - assert(forf != NULL); \ - \ - rv = 0; \ - STAILQ_FOREACH(e, &td->snapshot_data, entries) { \ - rv = forf(&e->data, mdata); \ - if (rv != 0) \ - break; \ - } \ - \ - return (rv); \ -} \ - \ -int \ -__##ent##_test_data_compare(struct ent##_test_data *td1, struct ent##_test_data *td2,\ - int (*cmp_func)(struct ent *, struct ent *, void *), void *mdata)\ -{ \ - struct ent##_entry *e1, *e2; \ - int rv; \ - \ - assert(td1 != NULL); \ - assert(td2 != NULL); \ - assert(cmp_func != NULL); \ - \ - e1 = STAILQ_FIRST(&td1->snapshot_data); \ - e2 = STAILQ_FIRST(&td2->snapshot_data); \ - \ - rv = 0; \ - do { \ - if ((e1 == NULL) || (e2 == NULL)) { \ - if (e1 == e2) \ - return (0); \ - else \ - return (-1); \ - } \ - \ - rv = cmp_func(&e1->data, &e2->data, mdata); \ - e1 = STAILQ_NEXT(e1, entries); \ - e2 = STAILQ_NEXT(e2, entries); \ - } while (rv == 0); \ - \ - return (rv); \ -} \ - \ -struct ent * \ -__##ent##_test_data_find(struct ent##_test_data *td, struct ent *data, \ - int (*cmp)(struct ent *, struct ent *, void *), void *mdata) \ -{ \ - struct ent##_entry *e; \ - struct ent *result; \ - \ - assert(td != NULL); \ - assert(cmp != NULL); \ - \ - result = NULL; \ - STAILQ_FOREACH(e, &td->snapshot_data, entries) { \ - if (cmp(&e->data, data, mdata) == 0) { \ - result = &e->data; \ - break; \ - } \ - } \ - \ - return (result); \ -} \ - \ - \ -void \ -__##ent##_test_data_clear(struct ent##_test_data *td) \ -{ \ - struct ent##_entry *e; \ - assert(td != NULL); \ - \ - while (!STAILQ_EMPTY(&td->snapshot_data)) { \ - e = STAILQ_FIRST(&td->snapshot_data); \ - STAILQ_REMOVE_HEAD(&td->snapshot_data, entries); \ - \ - td->free_func(&e->data); \ - free(e); \ - } \ -} - -#define DECLARE_TEST_FILE_SNAPSHOT(ent) \ -struct ent##_snp_param { \ - FILE *fp; \ - void (*sdump_func)(struct ent *, char *, size_t); \ -}; \ - \ -int __##ent##_snapshot_write_func(struct ent *, void *); \ -int __##ent##_snapshot_write(char const *, struct ent##_test_data *, \ - void (*)(struct ent *, char *, size_t)); \ -int __##ent##_snapshot_read(char const *, struct ent##_test_data *, \ - int (*)(struct ent *, char *)); - -#define TEST_SNAPSHOT_FILE_WRITE(ent, fname, td, f) \ - __##ent##_snapshot_write(fname, td, f) -#define TEST_SNAPSHOT_FILE_READ(ent, fname, td, f) \ - __##ent##_snapshot_read(fname, td, f) - -#define IMPLEMENT_TEST_FILE_SNAPSHOT(ent) \ -int \ -__##ent##_snapshot_write_func(struct ent *data, void *mdata) \ -{ \ - char buffer[1024]; \ - struct ent##_snp_param *param; \ - \ - assert(data != NULL); \ - \ - param = (struct ent##_snp_param *)mdata; \ - param->sdump_func(data, buffer, sizeof(buffer)); \ - fputs(buffer, param->fp); \ - fputc('\n', param->fp); \ - \ - return (0); \ -} \ - \ -int \ -__##ent##_snapshot_write(char const *fname, struct ent##_test_data *td, \ - void (*sdump_func)(struct ent *, char *, size_t)) \ -{ \ - struct ent##_snp_param param; \ - \ - assert(fname != NULL); \ - assert(td != NULL); \ - \ - param.fp = fopen(fname, "w"); \ - if (param.fp == NULL) \ - return (-1); \ - \ - param.sdump_func = sdump_func; \ - __##ent##_test_data_foreach(td, __##ent##_snapshot_write_func, ¶m);\ - fclose(param.fp); \ - \ - return (0); \ -} \ - \ -int \ -__##ent##_snapshot_read(char const *fname, struct ent##_test_data *td, \ - int (*read_func)(struct ent *, char *)) \ -{ \ - char buffer[1024]; \ - struct ent data; \ - char *s; \ - FILE *fi; \ - size_t len; \ - int rv; \ - \ - assert(fname != NULL); \ - assert(td != NULL); \ - \ - fi = fopen(fname, "r"); \ - if (fi == NULL) \ - return (-1); \ - \ - rv = 0; \ - memset(buffer, 0, sizeof(buffer)); \ - while (!feof(fi)) { \ - s = fgets(buffer, sizeof(buffer), fi); \ - if (s != NULL && s[0] != '#') { \ - len = strlen(s); \ - if (len == 0) \ - continue; \ - if (buffer[len - 1] == '\n') \ - buffer[len -1] = '\0'; \ - \ - rv = read_func(&data, s); \ - if (rv == 0) { \ - __##ent##_test_data_append(td, &data); \ - td->free_func(&data); \ - } else \ - goto fin; \ - } \ - } \ - \ -fin: \ - fclose(fi); \ - return (rv); \ -} - -#define DECLARE_1PASS_TEST(ent) \ -int __##ent##_1pass_test(struct ent##_test_data *, \ - int (*)(struct ent *, void *), \ - void *); - -#define DO_1PASS_TEST(ent, td, f, mdata) \ - __##ent##_1pass_test(td, f, mdata) - -#define IMPLEMENT_1PASS_TEST(ent) \ -int \ -__##ent##_1pass_test(struct ent##_test_data *td, \ - int (*tf)(struct ent *, void *), \ - void *mdata) \ -{ \ - int rv; \ - rv = __##ent##_test_data_foreach(td, tf, mdata); \ - \ - return (rv); \ -} - -#define DECLARE_2PASS_TEST(ent) \ -int __##ent##_2pass_test(struct ent##_test_data *, \ - struct ent##_test_data *, \ - int (*)(struct ent *, struct ent *, void *), void *); - -#define DO_2PASS_TEST(ent, td1, td2, f, mdata) \ - __##ent##_2pass_test(td1, td2, f, mdata) - -#define IMPLEMENT_2PASS_TEST(ent) \ -int \ -__##ent##_2pass_test(struct ent##_test_data *td1, \ - struct ent##_test_data *td2, \ - int (*cmp_func)(struct ent *, struct ent *, void *), \ - void *cmp_mdata) \ -{ \ - int rv; \ - \ - rv = __##ent##_test_data_compare(td1, td2, cmp_func, cmp_mdata); \ - return (rv); \ -} Property changes on: head/tools/regression/lib/libc/nss/testutil.h ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getaddr.c =================================================================== --- head/tools/regression/lib/libc/nss/test-getaddr.c (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getaddr.c (nonexistent) @@ -1,539 +0,0 @@ -/*- - * Copyright (c) 2006 Michael Bushkov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "testutil.h" - -enum test_methods { - TEST_GETADDRINFO, - TEST_BUILD_SNAPSHOT -}; - -static int debug = 0; -static struct addrinfo hints; -static enum test_methods method = TEST_GETADDRINFO; - -DECLARE_TEST_DATA(addrinfo) -DECLARE_TEST_FILE_SNAPSHOT(addrinfo) -DECLARE_2PASS_TEST(addrinfo) - -static void clone_addrinfo(struct addrinfo *, struct addrinfo const *); -static int compare_addrinfo(struct addrinfo *, struct addrinfo *, void *); -static void dump_addrinfo(struct addrinfo *); -static void free_addrinfo(struct addrinfo *); - -static void sdump_addrinfo(struct addrinfo *, char *, size_t); - -IMPLEMENT_TEST_DATA(addrinfo) -IMPLEMENT_TEST_FILE_SNAPSHOT(addrinfo) -IMPLEMENT_2PASS_TEST(addrinfo) - -static void -clone_addrinfo(struct addrinfo *dest, struct addrinfo const *src) -{ - assert(dest != NULL); - assert(src != NULL); - - memcpy(dest, src, sizeof(struct addrinfo)); - if (src->ai_canonname != NULL) - dest->ai_canonname = strdup(src->ai_canonname); - - if (src->ai_addr != NULL) { - dest->ai_addr = (struct sockaddr *)malloc(src->ai_addrlen); - assert(dest->ai_addr != NULL); - memcpy(dest->ai_addr, src->ai_addr, src->ai_addrlen); - } - - if (src->ai_next != NULL) { - dest->ai_next = (struct addrinfo *)malloc( - sizeof(struct addrinfo)); - assert(dest->ai_next != NULL); - clone_addrinfo(dest->ai_next, src->ai_next); - } -} - -static int -compare_addrinfo_(struct addrinfo *ai1, struct addrinfo *ai2) -{ - if ((ai1 == NULL) || (ai2 == NULL)) - return (-1); - - if ((ai1->ai_flags != ai2->ai_flags) || - (ai1->ai_family != ai2->ai_family) || - (ai1->ai_socktype != ai2->ai_socktype) || - (ai1->ai_protocol != ai2->ai_protocol) || - (ai1->ai_addrlen != ai2->ai_addrlen) || - (((ai1->ai_addr == NULL) || (ai2->ai_addr == NULL)) && - (ai1->ai_addr != ai2->ai_addr)) || - (((ai1->ai_canonname == NULL) || (ai2->ai_canonname == NULL)) && - (ai1->ai_canonname != ai2->ai_canonname))) - return (-1); - - if ((ai1->ai_canonname != NULL) && - (strcmp(ai1->ai_canonname, ai2->ai_canonname) != 0)) - return (-1); - - if ((ai1->ai_addr != NULL) && - (memcmp(ai1->ai_addr, ai2->ai_addr, ai1->ai_addrlen) != 0)) - return (-1); - - if ((ai1->ai_next == NULL) && (ai2->ai_next == NULL)) - return (0); - else - return (compare_addrinfo_(ai1->ai_next, ai2->ai_next)); -} - -static int -compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2, void *mdata) -{ - int rv; - - if (debug) { - printf("testing equality of 2 addrinfo structures\n"); - } - - rv = compare_addrinfo_(ai1, ai2); - - if (debug) { - if (rv == 0) - printf("equal\n"); - else { - dump_addrinfo(ai1); - dump_addrinfo(ai2); - printf("not equal\n"); - } - } - - return (rv); -} - -void -free_addrinfo(struct addrinfo *ai) -{ - if (ai == NULL) - return; - - free(ai->ai_addr); - free(ai->ai_canonname); - free_addrinfo(ai->ai_next); -} - -void -sdump_addrinfo(struct addrinfo *ai, char *buffer, size_t buflen) -{ - int written, i; - - written = snprintf(buffer, buflen, "%d %d %d %d %d ", - ai->ai_flags, ai->ai_family, ai->ai_socktype, ai->ai_protocol, - ai->ai_addrlen); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - written = snprintf(buffer, buflen, "%s ", - ai->ai_canonname == NULL ? "(null)" : ai->ai_canonname); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (ai->ai_addr == NULL) { - written = snprintf(buffer, buflen, "(null)"); - buffer += written; - if (written > buflen) - return; - buflen -= written; - } else { - for (i = 0; i < ai->ai_addrlen; ++i ) { - written = snprintf(buffer, buflen, - i + 1 != ai->ai_addrlen ? "%d." : "%d", - ((unsigned char *)ai->ai_addr)[i]); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (buflen == 0) - return; - } - } - - if (ai->ai_next != NULL) { - written = snprintf(buffer, buflen, ":"); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - sdump_addrinfo(ai->ai_next, buffer, buflen); - } -} - -void -dump_addrinfo(struct addrinfo *result) -{ - if (result != NULL) { - char buffer[2048]; - sdump_addrinfo(result, buffer, sizeof(buffer)); - printf("%s\n", buffer); - } else - printf("(null)\n"); -} - -static int -addrinfo_read_snapshot_addr(char *addr, unsigned char *result, size_t len) -{ - char *s, *ps, *ts; - - ps = addr; - while ( (s = strsep(&ps, ".")) != NULL) { - if (len == 0) - return (-1); - - *result = (unsigned char)strtol(s, &ts, 10); - ++result; - if (*ts != '\0') - return (-1); - - --len; - } - if (len != 0) - return (-1); - else - return (0); -} - -static int -addrinfo_read_snapshot_ai(struct addrinfo *ai, char *line) -{ - char *s, *ps, *ts; - int i, rv, *pi; - - rv = 0; - i = 0; - ps = line; - memset(ai, 0, sizeof(struct addrinfo)); - while ( (s = strsep(&ps, " ")) != NULL) { - switch (i) { - case 0: - case 1: - case 2: - case 3: - pi = &ai->ai_flags + i; - *pi = (int)strtol(s, &ts, 10); - if (*ts != '\0') - goto fin; - break; - case 4: - ai->ai_addrlen = (socklen_t)strtol(s, &ts, 10); - if (*ts != '\0') - goto fin; - break; - case 5: - if (strcmp(s, "(null)") != 0) { - ai->ai_canonname = strdup(s); - assert(ai->ai_canonname != NULL); - } - break; - case 6: - if (strcmp(s, "(null)") != 0) { - ai->ai_addr = (struct sockaddr *)malloc( - ai->ai_addrlen); - assert(ai->ai_addr != NULL); - memset(ai->ai_addr, 0, ai->ai_addrlen); - rv = addrinfo_read_snapshot_addr(s, - (unsigned char *)ai->ai_addr, - ai->ai_addrlen); - - if (rv != 0) - goto fin; - } - break; - default: - /* NOTE: should not be reachable */ - rv = -1; - goto fin; - }; - - ++i; - } - -fin: - if ((i != 7) || (rv != 0)) { - free_addrinfo(ai); - memset(ai, 0, sizeof(struct addrinfo)); - return (-1); - } - - return (0); -} - -static int -addrinfo_read_snapshot_func(struct addrinfo *ai, char *line) -{ - struct addrinfo *ai2; - char *s, *ps; - int i, rv; - - if (debug) - printf("1 line read from snapshot:\n%s\n", line); - - rv = 0; - i = 0; - ps = line; - - s = strsep(&ps, ":"); - if (s == NULL) - return (-1); - - rv = addrinfo_read_snapshot_ai(ai, s); - if (rv != 0) - return (-1); - - ai2 = ai; - while ( (s = strsep(&ps, ":")) != NULL) { - ai2->ai_next = (struct addrinfo *)malloc( - sizeof(struct addrinfo)); - assert(ai2->ai_next != NULL); - memset(ai2->ai_next, 0, sizeof(struct addrinfo)); - - rv = addrinfo_read_snapshot_ai(ai2->ai_next, s); - if (rv != 0) { - free_addrinfo(ai); - return (-1); - } - - ai2 = ai2->ai_next; - } - - return (0); -} - -static int -addrinfo_test_correctness(struct addrinfo *ai, void *mdata) -{ - if (debug) { - printf("testing correctness with the following data:\n"); - dump_addrinfo(ai); - } - - if (ai == NULL) - goto errfin; - - if (!((ai->ai_family >= 0) && (ai->ai_family < AF_MAX))) - goto errfin; - - if ((ai->ai_socktype != 0) && (ai->ai_socktype != SOCK_STREAM) && - (ai->ai_socktype != SOCK_DGRAM) && (ai->ai_socktype != SOCK_RAW)) - goto errfin; - - if ((ai->ai_protocol != 0) && (ai->ai_protocol != IPPROTO_UDP) && - (ai->ai_protocol != IPPROTO_TCP)) - goto errfin; - - if ((ai->ai_flags & ~(AI_CANONNAME | AI_NUMERICHOST | AI_PASSIVE)) != 0) - goto errfin; - - if ((ai->ai_addrlen != ai->ai_addr->sa_len) || - (ai->ai_family != ai->ai_addr->sa_family)) - goto errfin; - - if (debug) - printf("correct\n"); - - return (0); -errfin: - if (debug) - printf("incorrect\n"); - - return (-1); -} - -static int -addrinfo_read_hostlist_func(struct addrinfo *ai, char *line) -{ - struct addrinfo *result; - int rv; - - if (debug) - printf("resolving %s: ", line); - rv = getaddrinfo(line, NULL, &hints, &result); - if (rv == 0) { - if (debug) - printf("found\n"); - - rv = addrinfo_test_correctness(result, NULL); - if (rv != 0) { - freeaddrinfo(result); - return (rv); - } - - clone_addrinfo(ai, result); - freeaddrinfo(result); - } else { - if (debug) - printf("not found\n"); - - memset(ai, 0, sizeof(struct addrinfo)); - } - return (0); -} - -static void -usage(void) -{ - (void)fprintf(stderr, - "Usage: %s [-d] [-46] [-s -f \n", - getprogname()); - exit(1); -} - -int -main(int argc, char **argv) -{ - struct addrinfo_test_data td, td_snap; - char *snapshot_file, *hostlist_file; - int rv; - int c; - - if (argc < 2) - usage(); - - snapshot_file = NULL; - hostlist_file = NULL; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = PF_UNSPEC; - hints.ai_flags = AI_CANONNAME; - while ((c = getopt(argc, argv, "46dns:f:")) != -1) - switch (c) { - case '4': - hints.ai_family = PF_INET; - break; - case '6': - hints.ai_family = PF_INET6; - break; - case 'd': - debug = 1; - break; - case 's': - snapshot_file = strdup(optarg); - method = TEST_BUILD_SNAPSHOT; - break; - case 'f': - hostlist_file = strdup(optarg); - break; - default: - usage(); - } - - TEST_DATA_INIT(addrinfo, &td, clone_addrinfo, free_addrinfo); - TEST_DATA_INIT(addrinfo, &td_snap, clone_addrinfo, free_addrinfo); - - if (hostlist_file == NULL) - usage(); - - if (access(hostlist_file, R_OK) != 0) { - if (debug) - printf("can't access the hostlist file %s\n", - hostlist_file); - - usage(); - } - - if (debug) - printf("building host lists from %s\n", hostlist_file); - - rv = TEST_SNAPSHOT_FILE_READ(addrinfo, hostlist_file, &td, - addrinfo_read_hostlist_func); - if (rv != 0) - goto fin; - - if (snapshot_file != NULL) { - if (access(snapshot_file, W_OK | R_OK) != 0) { - if (errno == ENOENT) - method = TEST_BUILD_SNAPSHOT; - else { - if (debug) - printf("can't access the snapshot file %s\n", - snapshot_file); - - rv = -1; - goto fin; - } - } else { - rv = TEST_SNAPSHOT_FILE_READ(addrinfo, snapshot_file, - &td_snap, addrinfo_read_snapshot_func); - if (rv != 0) { - if (debug) - printf("error reading snapshot file\n"); - goto fin; - } - } - } - - switch (method) { - case TEST_GETADDRINFO: - if (snapshot_file != NULL) - rv = DO_2PASS_TEST(addrinfo, &td, &td_snap, - compare_addrinfo, NULL); - break; - case TEST_BUILD_SNAPSHOT: - if (snapshot_file != NULL) { - rv = TEST_SNAPSHOT_FILE_WRITE(addrinfo, snapshot_file, &td, - sdump_addrinfo); - } - break; - default: - rv = 0; - break; - }; - -fin: - TEST_DATA_DESTROY(addrinfo, &td_snap); - TEST_DATA_DESTROY(addrinfo, &td); - free(hostlist_file); - free(snapshot_file); - return (rv); - -} - Property changes on: head/tools/regression/lib/libc/nss/test-getaddr.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getrpc.c =================================================================== --- head/tools/regression/lib/libc/nss/test-getrpc.c (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getrpc.c (nonexistent) @@ -1,535 +0,0 @@ -/*- - * Copyright (c) 2006 Michael Bushkov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "testutil.h" - -enum test_methods { - TEST_GETRPCENT, - TEST_GETRPCBYNAME, - TEST_GETRPCBYNUMBER, - TEST_GETRPCENT_2PASS, - TEST_BUILD_SNAPSHOT -}; - -static int debug = 0; -static enum test_methods method = TEST_BUILD_SNAPSHOT; - -DECLARE_TEST_DATA(rpcent) -DECLARE_TEST_FILE_SNAPSHOT(rpcent) -DECLARE_1PASS_TEST(rpcent) -DECLARE_2PASS_TEST(rpcent) - -static void clone_rpcent(struct rpcent *, struct rpcent const *); -static int compare_rpcent(struct rpcent *, struct rpcent *, void *); -static void dump_rpcent(struct rpcent *); -static void free_rpcent(struct rpcent *); - -static void sdump_rpcent(struct rpcent *, char *, size_t); -static int rpcent_read_snapshot_func(struct rpcent *, char *); - -static int rpcent_check_ambiguity(struct rpcent_test_data *, - struct rpcent *); -static int rpcent_fill_test_data(struct rpcent_test_data *); -static int rpcent_test_correctness(struct rpcent *, void *); -static int rpcent_test_getrpcbyname(struct rpcent *, void *); -static int rpcent_test_getrpcbynumber(struct rpcent *, void *); -static int rpcent_test_getrpcent(struct rpcent *, void *); - -static void usage(void) __attribute__((__noreturn__)); - -IMPLEMENT_TEST_DATA(rpcent) -IMPLEMENT_TEST_FILE_SNAPSHOT(rpcent) -IMPLEMENT_1PASS_TEST(rpcent) -IMPLEMENT_2PASS_TEST(rpcent) - -static void -clone_rpcent(struct rpcent *dest, struct rpcent const *src) -{ - assert(dest != NULL); - assert(src != NULL); - - char **cp; - int aliases_num; - - memset(dest, 0, sizeof(struct rpcent)); - - if (src->r_name != NULL) { - dest->r_name = strdup(src->r_name); - assert(dest->r_name != NULL); - } - - dest->r_number = src->r_number; - - if (src->r_aliases != NULL) { - aliases_num = 0; - for (cp = src->r_aliases; *cp; ++cp) - ++aliases_num; - - dest->r_aliases = (char **)malloc((aliases_num+1) * (sizeof(char *))); - assert(dest->r_aliases != NULL); - memset(dest->r_aliases, 0, (aliases_num+1) * (sizeof(char *))); - - for (cp = src->r_aliases; *cp; ++cp) { - dest->r_aliases[cp - src->r_aliases] = strdup(*cp); - assert(dest->r_aliases[cp - src->r_aliases] != NULL); - } - } -} - -static void -free_rpcent(struct rpcent *rpc) -{ - char **cp; - - assert(rpc != NULL); - - free(rpc->r_name); - - for (cp = rpc->r_aliases; *cp; ++cp) - free(*cp); - free(rpc->r_aliases); -} - -static int -compare_rpcent(struct rpcent *rpc1, struct rpcent *rpc2, void *mdata) -{ - char **c1, **c2; - - if (rpc1 == rpc2) - return 0; - - if ((rpc1 == NULL) || (rpc2 == NULL)) - goto errfin; - - if ((strcmp(rpc1->r_name, rpc2->r_name) != 0) || - (rpc1->r_number != rpc2->r_number)) - goto errfin; - - c1 = rpc1->r_aliases; - c2 = rpc2->r_aliases; - - if ((rpc1->r_aliases == NULL) || (rpc2->r_aliases == NULL)) - goto errfin; - - for (;*c1 && *c2; ++c1, ++c2) - if (strcmp(*c1, *c2) != 0) - goto errfin; - - if ((*c1 != '\0') || (*c2 != '\0')) - goto errfin; - - return 0; - -errfin: - if ((debug) && (mdata == NULL)) { - printf("following structures are not equal:\n"); - dump_rpcent(rpc1); - dump_rpcent(rpc2); - } - - return (-1); -} - -static void -sdump_rpcent(struct rpcent *rpc, char *buffer, size_t buflen) -{ - char **cp; - int written; - - written = snprintf(buffer, buflen, "%s %d", - rpc->r_name, rpc->r_number); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (rpc->r_aliases != NULL) { - if (*(rpc->r_aliases) != '\0') { - for (cp = rpc->r_aliases; *cp; ++cp) { - written = snprintf(buffer, buflen, " %s",*cp); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (buflen == 0) - return; - } - } else - snprintf(buffer, buflen, " noaliases"); - } else - snprintf(buffer, buflen, " (null)"); -} - -static int -rpcent_read_snapshot_func(struct rpcent *rpc, char *line) -{ - StringList *sl; - char *s, *ps, *ts; - int i; - - if (debug) - printf("1 line read from snapshot:\n%s\n", line); - - i = 0; - sl = NULL; - ps = line; - memset(rpc, 0, sizeof(struct rpcent)); - while ( (s = strsep(&ps, " ")) != NULL) { - switch (i) { - case 0: - rpc->r_name = strdup(s); - assert(rpc->r_name != NULL); - break; - - case 1: - rpc->r_number = (int)strtol(s, &ts, 10); - if (*ts != '\0') { - free(rpc->r_name); - return (-1); - } - break; - - default: - if (sl == NULL) { - if (strcmp(s, "(null)") == 0) - return (0); - - sl = sl_init(); - assert(sl != NULL); - - if (strcmp(s, "noaliases") != 0) { - ts = strdup(s); - assert(ts != NULL); - sl_add(sl, ts); - } - } else { - ts = strdup(s); - assert(ts != NULL); - sl_add(sl, ts); - } - break; - }; - ++i; - } - - if (i < 3) { - free(rpc->r_name); - memset(rpc, 0, sizeof(struct rpcent)); - return (-1); - } - - sl_add(sl, NULL); - rpc->r_aliases = sl->sl_str; - - /* NOTE: is it a dirty hack or not? */ - free(sl); - return (0); -} - -static void -dump_rpcent(struct rpcent *result) -{ - if (result != NULL) { - char buffer[1024]; - sdump_rpcent(result, buffer, sizeof(buffer)); - printf("%s\n", buffer); - } else - printf("(null)\n"); -} - -static int -rpcent_fill_test_data(struct rpcent_test_data *td) -{ - struct rpcent *rpc; - - setrpcent(1); - while ((rpc = getrpcent()) != NULL) { - if (rpcent_test_correctness(rpc, NULL) == 0) - TEST_DATA_APPEND(rpcent, td, rpc); - else - return (-1); - } - endrpcent(); - - return (0); -} - -static int -rpcent_test_correctness(struct rpcent *rpc, void *mdata) -{ - if (debug) { - printf("testing correctness with the following data:\n"); - dump_rpcent(rpc); - } - - if (rpc == NULL) - goto errfin; - - if (rpc->r_name == NULL) - goto errfin; - - if (rpc->r_number < 0) - goto errfin; - - if (rpc->r_aliases == NULL) - goto errfin; - - if (debug) - printf("correct\n"); - - return (0); -errfin: - if (debug) - printf("incorrect\n"); - - return (-1); -} - -/* rpcent_check_ambiguity() is needed when one port+rpc is associated with - * more than one peice (these cases are usually marked as PROBLEM in - * /etc/peices. This functions is needed also when one peice+rpc is - * associated with several ports. We have to check all the rpcent structures - * to make sure that rpc really exists and correct */ -static int -rpcent_check_ambiguity(struct rpcent_test_data *td, struct rpcent *rpc) -{ - - return (TEST_DATA_FIND(rpcent, td, rpc, compare_rpcent, - NULL) != NULL ? 0 : -1); -} - -static int -rpcent_test_getrpcbyname(struct rpcent *rpc_model, void *mdata) -{ - char **alias; - struct rpcent *rpc; - - if (debug) { - printf("testing getrpcbyname() with the following data:\n"); - dump_rpcent(rpc_model); - } - - rpc = getrpcbyname(rpc_model->r_name); - if (rpcent_test_correctness(rpc, NULL) != 0) - goto errfin; - - if ((compare_rpcent(rpc, rpc_model, NULL) != 0) && - (rpcent_check_ambiguity((struct rpcent_test_data *)mdata, rpc) - !=0)) - goto errfin; - - for (alias = rpc_model->r_aliases; *alias; ++alias) { - rpc = getrpcbyname(*alias); - - if (rpcent_test_correctness(rpc, NULL) != 0) - goto errfin; - - if ((compare_rpcent(rpc, rpc_model, NULL) != 0) && - (rpcent_check_ambiguity( - (struct rpcent_test_data *)mdata, rpc) != 0)) - goto errfin; - } - - if (debug) - printf("ok\n"); - return (0); - -errfin: - if (debug) - printf("not ok\n"); - - return (-1); -} - -static int -rpcent_test_getrpcbynumber(struct rpcent *rpc_model, void *mdata) -{ - struct rpcent *rpc; - - if (debug) { - printf("testing getrpcbyport() with the following data...\n"); - dump_rpcent(rpc_model); - } - - rpc = getrpcbynumber(rpc_model->r_number); - if ((rpcent_test_correctness(rpc, NULL) != 0) || - ((compare_rpcent(rpc, rpc_model, NULL) != 0) && - (rpcent_check_ambiguity((struct rpcent_test_data *)mdata, rpc) - != 0))) { - if (debug) - printf("not ok\n"); - return (-1); - } else { - if (debug) - printf("ok\n"); - return (0); - } -} - -static int -rpcent_test_getrpcent(struct rpcent *rpc, void *mdata) -{ - /* Only correctness can be checked when doing 1-pass test for - * getrpcent(). */ - return (rpcent_test_correctness(rpc, NULL)); -} - -static void -usage(void) -{ - (void)fprintf(stderr, - "Usage: %s -nve2 [-d] [-s ]\n", - getprogname()); - exit(1); -} - -int -main(int argc, char **argv) -{ - struct rpcent_test_data td, td_snap, td_2pass; - char *snapshot_file; - int rv; - int c; - - if (argc < 2) - usage(); - - snapshot_file = NULL; - while ((c = getopt(argc, argv, "nve2ds:")) != -1) - switch (c) { - case 'd': - debug++; - break; - case 'n': - method = TEST_GETRPCBYNAME; - break; - case 'v': - method = TEST_GETRPCBYNUMBER; - break; - case 'e': - method = TEST_GETRPCENT; - break; - case '2': - method = TEST_GETRPCENT_2PASS; - break; - case 's': - snapshot_file = strdup(optarg); - break; - default: - usage(); - } - - TEST_DATA_INIT(rpcent, &td, clone_rpcent, free_rpcent); - TEST_DATA_INIT(rpcent, &td_snap, clone_rpcent, free_rpcent); - if (snapshot_file != NULL) { - if (access(snapshot_file, W_OK | R_OK) != 0) { - if (errno == ENOENT) - method = TEST_BUILD_SNAPSHOT; - else { - if (debug) - printf("can't access the file %s\n", - snapshot_file); - - rv = -1; - goto fin; - } - } else { - if (method == TEST_BUILD_SNAPSHOT) { - rv = 0; - goto fin; - } - - TEST_SNAPSHOT_FILE_READ(rpcent, snapshot_file, - &td_snap, rpcent_read_snapshot_func); - } - } - - rv = rpcent_fill_test_data(&td); - if (rv == -1) - return (-1); - switch (method) { - case TEST_GETRPCBYNAME: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(rpcent, &td, - rpcent_test_getrpcbyname, (void *)&td); - else - rv = DO_1PASS_TEST(rpcent, &td_snap, - rpcent_test_getrpcbyname, (void *)&td_snap); - break; - case TEST_GETRPCBYNUMBER: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(rpcent, &td, - rpcent_test_getrpcbynumber, (void *)&td); - else - rv = DO_1PASS_TEST(rpcent, &td_snap, - rpcent_test_getrpcbynumber, (void *)&td_snap); - break; - case TEST_GETRPCENT: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(rpcent, &td, rpcent_test_getrpcent, - (void *)&td); - else - rv = DO_2PASS_TEST(rpcent, &td, &td_snap, - compare_rpcent, NULL); - break; - case TEST_GETRPCENT_2PASS: - TEST_DATA_INIT(rpcent, &td_2pass, clone_rpcent, free_rpcent); - rv = rpcent_fill_test_data(&td_2pass); - if (rv != -1) - rv = DO_2PASS_TEST(rpcent, &td, &td_2pass, - compare_rpcent, NULL); - TEST_DATA_DESTROY(rpcent, &td_2pass); - break; - case TEST_BUILD_SNAPSHOT: - if (snapshot_file != NULL) - rv = TEST_SNAPSHOT_FILE_WRITE(rpcent, snapshot_file, &td, - sdump_rpcent); - break; - default: - rv = 0; - break; - }; - -fin: - TEST_DATA_DESTROY(rpcent, &td_snap); - TEST_DATA_DESTROY(rpcent, &td); - free(snapshot_file); - return (rv); -} Property changes on: head/tools/regression/lib/libc/nss/test-getrpc.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getproto.c =================================================================== --- head/tools/regression/lib/libc/nss/test-getproto.c (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getproto.c (nonexistent) @@ -1,536 +0,0 @@ -/*- - * Copyright (c) 2006 Michael Bushkov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "testutil.h" - -enum test_methods { - TEST_GETPROTOENT, - TEST_GETPROTOBYNAME, - TEST_GETPROTOBYNUMBER, - TEST_GETPROTOENT_2PASS, - TEST_BUILD_SNAPSHOT -}; - -static int debug = 0; -static enum test_methods method = TEST_BUILD_SNAPSHOT; - -DECLARE_TEST_DATA(protoent) -DECLARE_TEST_FILE_SNAPSHOT(protoent) -DECLARE_1PASS_TEST(protoent) -DECLARE_2PASS_TEST(protoent) - -static void clone_protoent(struct protoent *, struct protoent const *); -static int compare_protoent(struct protoent *, struct protoent *, void *); -static void dump_protoent(struct protoent *); -static void free_protoent(struct protoent *); - -static void sdump_protoent(struct protoent *, char *, size_t); -static int protoent_read_snapshot_func(struct protoent *, char *); - -static int protoent_check_ambiguity(struct protoent_test_data *, - struct protoent *); -static int protoent_fill_test_data(struct protoent_test_data *); -static int protoent_test_correctness(struct protoent *, void *); -static int protoent_test_getprotobyname(struct protoent *, void *); -static int protoent_test_getprotobynumber(struct protoent *, void *); -static int protoent_test_getprotoent(struct protoent *, void *); - -static void usage(void) __attribute__((__noreturn__)); - -IMPLEMENT_TEST_DATA(protoent) -IMPLEMENT_TEST_FILE_SNAPSHOT(protoent) -IMPLEMENT_1PASS_TEST(protoent) -IMPLEMENT_2PASS_TEST(protoent) - -static void -clone_protoent(struct protoent *dest, struct protoent const *src) -{ - assert(dest != NULL); - assert(src != NULL); - - char **cp; - int aliases_num; - - memset(dest, 0, sizeof(struct protoent)); - - if (src->p_name != NULL) { - dest->p_name = strdup(src->p_name); - assert(dest->p_name != NULL); - } - - dest->p_proto = src->p_proto; - - if (src->p_aliases != NULL) { - aliases_num = 0; - for (cp = src->p_aliases; *cp; ++cp) - ++aliases_num; - - dest->p_aliases = (char **)malloc((aliases_num+1) * (sizeof(char *))); - assert(dest->p_aliases != NULL); - memset(dest->p_aliases, 0, (aliases_num+1) * (sizeof(char *))); - - for (cp = src->p_aliases; *cp; ++cp) { - dest->p_aliases[cp - src->p_aliases] = strdup(*cp); - assert(dest->p_aliases[cp - src->p_aliases] != NULL); - } - } -} - -static void -free_protoent(struct protoent *pe) -{ - char **cp; - - assert(pe != NULL); - - free(pe->p_name); - - for (cp = pe->p_aliases; *cp; ++cp) - free(*cp); - free(pe->p_aliases); -} - -static int -compare_protoent(struct protoent *pe1, struct protoent *pe2, void *mdata) -{ - char **c1, **c2; - - if (pe1 == pe2) - return 0; - - if ((pe1 == NULL) || (pe2 == NULL)) - goto errfin; - - if ((strcmp(pe1->p_name, pe2->p_name) != 0) || - (pe1->p_proto != pe2->p_proto)) - goto errfin; - - c1 = pe1->p_aliases; - c2 = pe2->p_aliases; - - if ((pe1->p_aliases == NULL) || (pe2->p_aliases == NULL)) - goto errfin; - - for (;*c1 && *c2; ++c1, ++c2) - if (strcmp(*c1, *c2) != 0) - goto errfin; - - if ((*c1 != '\0') || (*c2 != '\0')) - goto errfin; - - return 0; - -errfin: - if ((debug) && (mdata == NULL)) { - printf("following structures are not equal:\n"); - dump_protoent(pe1); - dump_protoent(pe2); - } - - return (-1); -} - -static void -sdump_protoent(struct protoent *pe, char *buffer, size_t buflen) -{ - char **cp; - int written; - - written = snprintf(buffer, buflen, "%s %d", - pe->p_name, pe->p_proto); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (pe->p_aliases != NULL) { - if (*(pe->p_aliases) != '\0') { - for (cp = pe->p_aliases; *cp; ++cp) { - written = snprintf(buffer, buflen, " %s",*cp); - buffer += written; - if (written > buflen) - return; - buflen -= written; - - if (buflen == 0) - return; - } - } else - snprintf(buffer, buflen, " noaliases"); - } else - snprintf(buffer, buflen, " (null)"); -} - -static int -protoent_read_snapshot_func(struct protoent *pe, char *line) -{ - StringList *sl; - char *s, *ps, *ts; - int i; - - if (debug) - printf("1 line read from snapshot:\n%s\n", line); - - i = 0; - sl = NULL; - ps = line; - memset(pe, 0, sizeof(struct protoent)); - while ( (s = strsep(&ps, " ")) != NULL) { - switch (i) { - case 0: - pe->p_name = strdup(s); - assert(pe->p_name != NULL); - break; - - case 1: - pe->p_proto = (int)strtol(s, &ts, 10); - if (*ts != '\0') { - free(pe->p_name); - return (-1); - } - break; - - default: - if (sl == NULL) { - if (strcmp(s, "(null)") == 0) - return (0); - - sl = sl_init(); - assert(sl != NULL); - - if (strcmp(s, "noaliases") != 0) { - ts = strdup(s); - assert(ts != NULL); - sl_add(sl, ts); - } - } else { - ts = strdup(s); - assert(ts != NULL); - sl_add(sl, ts); - } - break; - }; - ++i; - } - - if (i < 3) { - free(pe->p_name); - memset(pe, 0, sizeof(struct protoent)); - return (-1); - } - - sl_add(sl, NULL); - pe->p_aliases = sl->sl_str; - - /* NOTE: is it a dirty hack or not? */ - free(sl); - return (0); -} - -static void -dump_protoent(struct protoent *result) -{ - if (result != NULL) { - char buffer[1024]; - sdump_protoent(result, buffer, sizeof(buffer)); - printf("%s\n", buffer); - } else - printf("(null)\n"); -} - -static int -protoent_fill_test_data(struct protoent_test_data *td) -{ - struct protoent *pe; - - setprotoent(1); - while ((pe = getprotoent()) != NULL) { - if (protoent_test_correctness(pe, NULL) == 0) - TEST_DATA_APPEND(protoent, td, pe); - else - return (-1); - } - endprotoent(); - - return (0); -} - -static int -protoent_test_correctness(struct protoent *pe, void *mdata) -{ - if (debug) { - printf("testing correctness with the following data:\n"); - dump_protoent(pe); - } - - if (pe == NULL) - goto errfin; - - if (pe->p_name == NULL) - goto errfin; - - if (pe->p_proto < 0) - goto errfin; - - if (pe->p_aliases == NULL) - goto errfin; - - if (debug) - printf("correct\n"); - - return (0); -errfin: - if (debug) - printf("incorrect\n"); - - return (-1); -} - -/* protoent_check_ambiguity() is needed when one port+proto is associated with - * more than one peice (these cases are usually marked as PROBLEM in - * /etc/peices. This functions is needed also when one peice+proto is - * associated with several ports. We have to check all the protoent structures - * to make sure that pe really exists and correct */ -static int -protoent_check_ambiguity(struct protoent_test_data *td, struct protoent *pe) -{ - - return (TEST_DATA_FIND(protoent, td, pe, compare_protoent, - NULL) != NULL ? 0 : -1); -} - -static int -protoent_test_getprotobyname(struct protoent *pe_model, void *mdata) -{ - char **alias; - struct protoent *pe; - - if (debug) { - printf("testing getprotobyname() with the following data:\n"); - dump_protoent(pe_model); - } - - pe = getprotobyname(pe_model->p_name); - if (protoent_test_correctness(pe, NULL) != 0) - goto errfin; - - if ((compare_protoent(pe, pe_model, NULL) != 0) && - (protoent_check_ambiguity((struct protoent_test_data *)mdata, pe) - !=0)) - goto errfin; - - for (alias = pe_model->p_aliases; *alias; ++alias) { - pe = getprotobyname(*alias); - - if (protoent_test_correctness(pe, NULL) != 0) - goto errfin; - - if ((compare_protoent(pe, pe_model, NULL) != 0) && - (protoent_check_ambiguity( - (struct protoent_test_data *)mdata, pe) != 0)) - goto errfin; - } - - if (debug) - printf("ok\n"); - return (0); - -errfin: - if (debug) - printf("not ok\n"); - - return (-1); -} - -static int -protoent_test_getprotobynumber(struct protoent *pe_model, void *mdata) -{ - struct protoent *pe; - - if (debug) { - printf("testing getprotobyport() with the following data...\n"); - dump_protoent(pe_model); - } - - pe = getprotobynumber(pe_model->p_proto); - if ((protoent_test_correctness(pe, NULL) != 0) || - ((compare_protoent(pe, pe_model, NULL) != 0) && - (protoent_check_ambiguity((struct protoent_test_data *)mdata, pe) - != 0))) { - if (debug) - printf("not ok\n"); - return (-1); - } else { - if (debug) - printf("ok\n"); - return (0); - } -} - -static int -protoent_test_getprotoent(struct protoent *pe, void *mdata) -{ - /* Only correctness can be checked when doing 1-pass test for - * getprotoent(). */ - return (protoent_test_correctness(pe, NULL)); -} - -static void -usage(void) -{ - (void)fprintf(stderr, - "Usage: %s -nve2 [-d] [-s ]\n", - getprogname()); - exit(1); -} - -int -main(int argc, char **argv) -{ - struct protoent_test_data td, td_snap, td_2pass; - char *snapshot_file; - int rv; - int c; - - if (argc < 2) - usage(); - - snapshot_file = NULL; - while ((c = getopt(argc, argv, "nve2ds:")) != -1) - switch (c) { - case 'd': - debug++; - break; - case 'n': - method = TEST_GETPROTOBYNAME; - break; - case 'v': - method = TEST_GETPROTOBYNUMBER; - break; - case 'e': - method = TEST_GETPROTOENT; - break; - case '2': - method = TEST_GETPROTOENT_2PASS; - break; - case 's': - snapshot_file = strdup(optarg); - break; - default: - usage(); - } - - TEST_DATA_INIT(protoent, &td, clone_protoent, free_protoent); - TEST_DATA_INIT(protoent, &td_snap, clone_protoent, free_protoent); - if (snapshot_file != NULL) { - if (access(snapshot_file, W_OK | R_OK) != 0) { - if (errno == ENOENT) - method = TEST_BUILD_SNAPSHOT; - else { - if (debug) - printf("can't access the file %s\n", - snapshot_file); - - rv = -1; - goto fin; - } - } else { - if (method == TEST_BUILD_SNAPSHOT) { - rv = 0; - goto fin; - } - - TEST_SNAPSHOT_FILE_READ(protoent, snapshot_file, - &td_snap, protoent_read_snapshot_func); - } - } - - rv = protoent_fill_test_data(&td); - if (rv == -1) - return (-1); - switch (method) { - case TEST_GETPROTOBYNAME: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(protoent, &td, - protoent_test_getprotobyname, (void *)&td); - else - rv = DO_1PASS_TEST(protoent, &td_snap, - protoent_test_getprotobyname, (void *)&td_snap); - break; - case TEST_GETPROTOBYNUMBER: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(protoent, &td, - protoent_test_getprotobynumber, (void *)&td); - else - rv = DO_1PASS_TEST(protoent, &td_snap, - protoent_test_getprotobynumber, (void *)&td_snap); - break; - case TEST_GETPROTOENT: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(protoent, &td, - protoent_test_getprotoent, (void *)&td); - else - rv = DO_2PASS_TEST(protoent, &td, &td_snap, - compare_protoent, NULL); - break; - case TEST_GETPROTOENT_2PASS: - TEST_DATA_INIT(protoent, &td_2pass, clone_protoent, - free_protoent); - rv = protoent_fill_test_data(&td_2pass); - if (rv != -1) - rv = DO_2PASS_TEST(protoent, &td, &td_2pass, - compare_protoent, NULL); - TEST_DATA_DESTROY(protoent, &td_2pass); - break; - case TEST_BUILD_SNAPSHOT: - if (snapshot_file != NULL) - rv = TEST_SNAPSHOT_FILE_WRITE(protoent, snapshot_file, &td, - sdump_protoent); - break; - default: - rv = 0; - break; - }; - -fin: - TEST_DATA_DESTROY(protoent, &td_snap); - TEST_DATA_DESTROY(protoent, &td); - free(snapshot_file); - return (rv); -} Property changes on: head/tools/regression/lib/libc/nss/test-getproto.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getpw.c =================================================================== --- head/tools/regression/lib/libc/nss/test-getpw.c (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getpw.c (nonexistent) @@ -1,489 +0,0 @@ -/*- - * Copyright (c) 2006 Michael Bushkov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include "testutil.h" - -enum test_methods { - TEST_GETPWENT, - TEST_GETPWNAM, - TEST_GETPWUID, - TEST_GETPWENT_2PASS, - TEST_BUILD_SNAPSHOT -}; - -static int debug = 0; -static enum test_methods method = TEST_BUILD_SNAPSHOT; - -DECLARE_TEST_DATA(passwd) -DECLARE_TEST_FILE_SNAPSHOT(passwd) -DECLARE_1PASS_TEST(passwd) -DECLARE_2PASS_TEST(passwd) - -static void clone_passwd(struct passwd *, struct passwd const *); -static int compare_passwd(struct passwd *, struct passwd *, void *); -static void free_passwd(struct passwd *); - -static void sdump_passwd(struct passwd *, char *, size_t); -static void dump_passwd(struct passwd *); - -static int passwd_read_snapshot_func(struct passwd *, char *); - -static int passwd_check_ambiguity(struct passwd_test_data *, struct passwd *); -static int passwd_fill_test_data(struct passwd_test_data *); -static int passwd_test_correctness(struct passwd *, void *); -static int passwd_test_getpwnam(struct passwd *, void *); -static int passwd_test_getpwuid(struct passwd *, void *); -static int passwd_test_getpwent(struct passwd *, void *); - -static void usage(void) __attribute__((__noreturn__)); - -IMPLEMENT_TEST_DATA(passwd) -IMPLEMENT_TEST_FILE_SNAPSHOT(passwd) -IMPLEMENT_1PASS_TEST(passwd) -IMPLEMENT_2PASS_TEST(passwd) - -static void -clone_passwd(struct passwd *dest, struct passwd const *src) -{ - assert(dest != NULL); - assert(src != NULL); - - memcpy(dest, src, sizeof(struct passwd)); - if (src->pw_name != NULL) - dest->pw_name = strdup(src->pw_name); - if (src->pw_passwd != NULL) - dest->pw_passwd = strdup(src->pw_passwd); - if (src->pw_class != NULL) - dest->pw_class = strdup(src->pw_class); - if (src->pw_gecos != NULL) - dest->pw_gecos = strdup(src->pw_gecos); - if (src->pw_dir != NULL) - dest->pw_dir = strdup(src->pw_dir); - if (src->pw_shell != NULL) - dest->pw_shell = strdup(dest->pw_shell); -} - -static int -compare_passwd(struct passwd *pwd1, struct passwd *pwd2, void *mdata) -{ - assert(pwd1 != NULL); - assert(pwd2 != NULL); - - if (pwd1 == pwd2) - return (0); - - if ((pwd1->pw_uid != pwd2->pw_uid) || - (pwd1->pw_gid != pwd2->pw_gid) || - (pwd1->pw_change != pwd2->pw_change) || - (pwd1->pw_expire != pwd2->pw_expire) || - (pwd1->pw_fields != pwd2->pw_fields) || - (strcmp(pwd1->pw_name, pwd2->pw_name) != 0) || - (strcmp(pwd1->pw_passwd, pwd2->pw_passwd) != 0) || - (strcmp(pwd1->pw_class, pwd2->pw_class) != 0) || - (strcmp(pwd1->pw_gecos, pwd2->pw_gecos) != 0) || - (strcmp(pwd1->pw_dir, pwd2->pw_dir) != 0) || - (strcmp(pwd1->pw_shell, pwd2->pw_shell) != 0) - ) - return (-1); - else - return (0); -} - -static void -free_passwd(struct passwd *pwd) -{ - free(pwd->pw_name); - free(pwd->pw_passwd); - free(pwd->pw_class); - free(pwd->pw_gecos); - free(pwd->pw_dir); - free(pwd->pw_shell); -} - -static void -sdump_passwd(struct passwd *pwd, char *buffer, size_t buflen) -{ - snprintf(buffer, buflen, "%s:%s:%d:%d:%d:%s:%s:%s:%s:%d:%d", - pwd->pw_name, pwd->pw_passwd, pwd->pw_uid, pwd->pw_gid, - pwd->pw_change, pwd->pw_class, pwd->pw_gecos, pwd->pw_dir, - pwd->pw_shell, pwd->pw_expire, pwd->pw_fields); -} - -static void -dump_passwd(struct passwd *pwd) -{ - if (pwd != NULL) { - char buffer[2048]; - sdump_passwd(pwd, buffer, sizeof(buffer)); - printf("%s\n", buffer); - } else - printf("(null)\n"); -} - -static int -passwd_read_snapshot_func(struct passwd *pwd, char *line) -{ - char *s, *ps, *ts; - int i; - - if (debug) - printf("1 line read from snapshot:\n%s\n", line); - - i = 0; - ps = line; - memset(pwd, 0, sizeof(struct passwd)); - while ( (s = strsep(&ps, ":")) != NULL) { - switch (i) { - case 0: - pwd->pw_name = strdup(s); - assert(pwd->pw_name != NULL); - break; - case 1: - pwd->pw_passwd = strdup(s); - assert(pwd->pw_passwd != NULL); - break; - case 2: - pwd->pw_uid = (uid_t)strtol(s, &ts, 10); - if (*ts != '\0') - goto fin; - break; - case 3: - pwd->pw_gid = (gid_t)strtol(s, &ts, 10); - if (*ts != '\0') - goto fin; - break; - case 4: - pwd->pw_change = (time_t)strtol(s, &ts, 10); - if (*ts != '\0') - goto fin; - break; - case 5: - pwd->pw_class = strdup(s); - assert(pwd->pw_class != NULL); - break; - case 6: - pwd->pw_gecos = strdup(s); - assert(pwd->pw_gecos != NULL); - break; - case 7: - pwd->pw_dir = strdup(s); - assert(pwd->pw_dir != NULL); - break; - case 8: - pwd->pw_shell = strdup(s); - assert(pwd->pw_shell != NULL); - break; - case 9: - pwd->pw_expire = (time_t)strtol(s, &ts, 10); - if (*ts != '\0') - goto fin; - break; - case 10: - pwd->pw_fields = (int)strtol(s, &ts, 10); - if (*ts != '\0') - goto fin; - break; - default: - break; - }; - ++i; - } - -fin: - if (i != 11) { - free_passwd(pwd); - memset(pwd, 0, sizeof(struct passwd)); - return (-1); - } - - return (0); -} - -static int -passwd_fill_test_data(struct passwd_test_data *td) -{ - struct passwd *pwd; - - setpassent(1); - while ((pwd = getpwent()) != NULL) { - if (passwd_test_correctness(pwd, NULL) == 0) - TEST_DATA_APPEND(passwd, td, pwd); - else - return (-1); - } - endpwent(); - - return (0); -} - -static int -passwd_test_correctness(struct passwd *pwd, void *mdata) -{ - if (debug) { - printf("testing correctness with the following data:\n"); - dump_passwd(pwd); - } - - if (pwd == NULL) - return (-1); - - if (pwd->pw_name == NULL) - goto errfin; - - if (pwd->pw_passwd == NULL) - goto errfin; - - if (pwd->pw_class == NULL) - goto errfin; - - if (pwd->pw_gecos == NULL) - goto errfin; - - if (pwd->pw_dir == NULL) - goto errfin; - - if (pwd->pw_shell == NULL) - goto errfin; - - if (debug) - printf("correct\n"); - - return (0); -errfin: - if (debug) - printf("incorrect\n"); - - return (-1); -} - -/* passwd_check_ambiguity() is needed here because when doing the getpwent() - * calls sequence, records from different nsswitch sources can be different, - * though having the same pw_name/pw_uid */ -static int -passwd_check_ambiguity(struct passwd_test_data *td, struct passwd *pwd) -{ - - return (TEST_DATA_FIND(passwd, td, pwd, compare_passwd, - NULL) != NULL ? 0 : -1); -} - -static int -passwd_test_getpwnam(struct passwd *pwd_model, void *mdata) -{ - struct passwd *pwd; - - if (debug) { - printf("testing getpwnam() with the following data:\n"); - dump_passwd(pwd_model); - } - - pwd = getpwnam(pwd_model->pw_name); - if (passwd_test_correctness(pwd, NULL) != 0) - goto errfin; - - if ((compare_passwd(pwd, pwd_model, NULL) != 0) && - (passwd_check_ambiguity((struct passwd_test_data *)mdata, pwd) - !=0)) - goto errfin; - - if (debug) - printf("ok\n"); - return (0); - -errfin: - if (debug) - printf("not ok\n"); - - return (-1); -} - -static int -passwd_test_getpwuid(struct passwd *pwd_model, void *mdata) -{ - struct passwd *pwd; - - if (debug) { - printf("testing getpwuid() with the following data...\n"); - dump_passwd(pwd_model); - } - - pwd = getpwuid(pwd_model->pw_uid); - if ((passwd_test_correctness(pwd, NULL) != 0) || - ((compare_passwd(pwd, pwd_model, NULL) != 0) && - (passwd_check_ambiguity((struct passwd_test_data *)mdata, pwd) - != 0))) { - if (debug) - printf("not ok\n"); - return (-1); - } else { - if (debug) - printf("ok\n"); - return (0); - } -} - -static int -passwd_test_getpwent(struct passwd *pwd, void *mdata) -{ - /* Only correctness can be checked when doing 1-pass test for - * getpwent(). */ - return (passwd_test_correctness(pwd, NULL)); -} - -static void -usage(void) -{ - (void)fprintf(stderr, - "Usage: %s -nue2 [-d] [-s ]\n", - getprogname()); - exit(1); -} - -int -main(int argc, char **argv) -{ - struct passwd_test_data td, td_snap, td_2pass; - char *snapshot_file; - int rv; - int c; - - if (argc < 2) - usage(); - - snapshot_file = NULL; - while ((c = getopt(argc, argv, "nue2ds:")) != -1) - switch (c) { - case 'd': - debug++; - break; - case 'n': - method = TEST_GETPWNAM; - break; - case 'u': - method = TEST_GETPWUID; - break; - case 'e': - method = TEST_GETPWENT; - break; - case '2': - method = TEST_GETPWENT_2PASS; - break; - case 's': - snapshot_file = strdup(optarg); - break; - default: - usage(); - } - - TEST_DATA_INIT(passwd, &td, clone_passwd, free_passwd); - TEST_DATA_INIT(passwd, &td_snap, clone_passwd, free_passwd); - if (snapshot_file != NULL) { - if (access(snapshot_file, W_OK | R_OK) != 0) { - if (errno == ENOENT) - method = TEST_BUILD_SNAPSHOT; - else { - if (debug) - printf("can't access the file %s\n", - snapshot_file); - - rv = -1; - goto fin; - } - } else { - if (method == TEST_BUILD_SNAPSHOT) { - rv = 0; - goto fin; - } - - TEST_SNAPSHOT_FILE_READ(passwd, snapshot_file, - &td_snap, passwd_read_snapshot_func); - } - } - - rv = passwd_fill_test_data(&td); - if (rv == -1) - return (-1); - - switch (method) { - case TEST_GETPWNAM: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(passwd, &td, - passwd_test_getpwnam, (void *)&td); - else - rv = DO_1PASS_TEST(passwd, &td_snap, - passwd_test_getpwnam, (void *)&td_snap); - break; - case TEST_GETPWUID: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(passwd, &td, - passwd_test_getpwuid, (void *)&td); - else - rv = DO_1PASS_TEST(passwd, &td_snap, - passwd_test_getpwuid, (void *)&td_snap); - break; - case TEST_GETPWENT: - if (snapshot_file == NULL) - rv = DO_1PASS_TEST(passwd, &td, passwd_test_getpwent, - (void *)&td); - else - rv = DO_2PASS_TEST(passwd, &td, &td_snap, - compare_passwd, NULL); - break; - case TEST_GETPWENT_2PASS: - TEST_DATA_INIT(passwd, &td_2pass, clone_passwd, free_passwd); - rv = passwd_fill_test_data(&td_2pass); - if (rv != -1) - rv = DO_2PASS_TEST(passwd, &td, &td_2pass, - compare_passwd, NULL); - TEST_DATA_DESTROY(passwd, &td_2pass); - break; - case TEST_BUILD_SNAPSHOT: - if (snapshot_file != NULL) - rv = TEST_SNAPSHOT_FILE_WRITE(passwd, snapshot_file, &td, - sdump_passwd); - break; - default: - rv = 0; - break; - }; - -fin: - TEST_DATA_DESTROY(passwd, &td_snap); - TEST_DATA_DESTROY(passwd, &td); - free(snapshot_file); - return (rv); -} Property changes on: head/tools/regression/lib/libc/nss/test-getpw.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getpw.t =================================================================== --- head/tools/regression/lib/libc/nss/test-getpw.t (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getpw.t (nonexistent) @@ -1,29 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -do_test() { - number=$1 - comment=$2 - opt=$3 - if ./$executable $opt; then - echo "ok $number - $comment" - else - echo "not ok $number - $comment" - fi -} - -cd `dirname $0` - -executable=`basename $0 .t` - -make $executable 2>&1 > /dev/null - -echo 1..8 -do_test 1 'getpwnam()' '-n' -do_test 2 'getpwuid()' '-u' -do_test 3 'getpwent()' '-e' -do_test 4 'getpwent() 2-pass' '-2' -do_test 5 'building snapshot, if needed' '-s snapshot_pwd' -do_test 6 'getpwnam() snapshot' '-n -s snapshot_pwd' -do_test 7 'getpwuid() snapshot' '-u -s snapshot_pwd' -do_test 8 'getpwent() snapshot' '-e -s snapshot_pwd' Property changes on: head/tools/regression/lib/libc/nss/test-getpw.t ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getusershell.c =================================================================== --- head/tools/regression/lib/libc/nss/test-getusershell.c (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getusershell.c (nonexistent) @@ -1,235 +0,0 @@ -/*- - * Copyright (c) 2006 Michael Bushkov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include "testutil.h" - -enum test_methods { - TEST_GETUSERSHELL, - TEST_BUILD_SNAPSHOT -}; - -struct usershell { - char *path; -}; - -static int debug = 0; -static enum test_methods method = TEST_GETUSERSHELL; - -DECLARE_TEST_DATA(usershell) -DECLARE_TEST_FILE_SNAPSHOT(usershell) -DECLARE_2PASS_TEST(usershell) - -static void clone_usershell(struct usershell *, struct usershell const *); -static int compare_usershell(struct usershell *, struct usershell *, void *); -static void free_usershell(struct usershell *); - -static void sdump_usershell(struct usershell *, char *, size_t); -static void dump_usershell(struct usershell *); - -static int usershell_read_snapshot_func(struct usershell *, char *); - -static void usage(void) __attribute__((__noreturn__)); - -IMPLEMENT_TEST_DATA(usershell) -IMPLEMENT_TEST_FILE_SNAPSHOT(usershell) -IMPLEMENT_2PASS_TEST(usershell) - -static void -clone_usershell(struct usershell *dest, struct usershell const *src) -{ - assert(dest != NULL); - assert(src != NULL); - - if (src->path != NULL) { - dest->path = strdup(src->path); - assert(dest->path != NULL); - } -} - -static int -compare_usershell(struct usershell *us1, struct usershell *us2, void *mdata) -{ - int rv; - - assert(us1 != NULL); - assert(us2 != NULL); - - dump_usershell(us1); - dump_usershell(us2); - - if (us1 == us2) - return (0); - - rv = strcmp(us1->path, us2->path); - if (rv != 0) { - printf("following structures are not equal:\n"); - dump_usershell(us1); - dump_usershell(us2); - } - - return (rv); -} - -static void -free_usershell(struct usershell *us) -{ - free(us->path); -} - -static void -sdump_usershell(struct usershell *us, char *buffer, size_t buflen) -{ - snprintf(buffer, buflen, "%s", us->path); -} - -static void -dump_usershell(struct usershell *us) -{ - if (us != NULL) { - char buffer[2048]; - sdump_usershell(us, buffer, sizeof(buffer)); - printf("%s\n", buffer); - } else - printf("(null)\n"); -} - -static int -usershell_read_snapshot_func(struct usershell *us, char *line) -{ - us->path = strdup(line); - assert(us->path != NULL); - - return (0); -} - -static void -usage(void) -{ - (void)fprintf(stderr, - "Usage: %s [-d] -s \n", - getprogname()); - exit(1); -} - -int -main(int argc, char **argv) -{ - struct usershell_test_data td, td_snap; - struct usershell ushell; - char *snapshot_file; - int rv; - int c; - - if (argc < 2) - usage(); - - rv = 0; - snapshot_file = NULL; - while ((c = getopt(argc, argv, "ds:")) != -1) { - switch (c) { - case 'd': - debug = 1; - break; - case 's': - snapshot_file = strdup(optarg); - break; - default: - usage(); - } - } - - TEST_DATA_INIT(usershell, &td, clone_usershell, free_usershell); - TEST_DATA_INIT(usershell, &td_snap, clone_usershell, free_usershell); - - setusershell(); - while ((ushell.path = getusershell()) != NULL) { - if (debug) { - printf("usershell found:\n"); - dump_usershell(&ushell); - } - TEST_DATA_APPEND(usershell, &td, &ushell); - } - endusershell(); - - - if (snapshot_file != NULL) { - if (access(snapshot_file, W_OK | R_OK) != 0) { - if (errno == ENOENT) - method = TEST_BUILD_SNAPSHOT; - else { - if (debug) - printf("can't access the snapshot file %s\n", - snapshot_file); - - rv = -1; - goto fin; - } - } else { - rv = TEST_SNAPSHOT_FILE_READ(usershell, snapshot_file, - &td_snap, usershell_read_snapshot_func); - if (rv != 0) { - if (debug) - printf("error reading snapshot file\n"); - goto fin; - } - } - } - - switch (method) { - case TEST_GETUSERSHELL: - if (snapshot_file != NULL) { - rv = DO_2PASS_TEST(usershell, &td, &td_snap, - compare_usershell, NULL); - } - break; - case TEST_BUILD_SNAPSHOT: - if (snapshot_file != NULL) { - rv = TEST_SNAPSHOT_FILE_WRITE(usershell, snapshot_file, &td, - sdump_usershell); - } - break; - default: - rv = 0; - break; - }; - -fin: - TEST_DATA_DESTROY(usershell, &td_snap); - TEST_DATA_DESTROY(usershell, &td); - free(snapshot_file); - return (rv); - -} Property changes on: head/tools/regression/lib/libc/nss/test-getusershell.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/test-getserv.t =================================================================== --- head/tools/regression/lib/libc/nss/test-getserv.t (revision 292322) +++ head/tools/regression/lib/libc/nss/test-getserv.t (nonexistent) @@ -1,29 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -do_test() { - number=$1 - comment=$2 - opt=$3 - if ./$executable $opt; then - echo "ok $number - $comment" - else - echo "not ok $number - $comment" - fi -} - -cd `dirname $0` - -executable=`basename $0 .t` - -make $executable 2>&1 > /dev/null - -echo 1..8 -do_test 1 'getservbyname()' '-n' -do_test 2 'getservbyport()' '-p' -do_test 3 'getservent()' '-e' -do_test 4 'getservent() 2-pass' '-2' -do_test 5 'building snapshot, if needed' '-s snapshot_serv' -do_test 6 'getservbyname() snapshot' '-n -s snapshot_serv' -do_test 7 'getservbyport() snapshot' '-p -s snapshot_serv' -do_test 8 'getservent() snapshot' '-e -s snapshot_serv' Property changes on: head/tools/regression/lib/libc/nss/test-getserv.t ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/mach =================================================================== --- head/tools/regression/lib/libc/nss/mach (revision 292322) +++ head/tools/regression/lib/libc/nss/mach (nonexistent) @@ -1,46 +0,0 @@ -# $FreeBSD$ -localhost -anoncvs.cirr.com -anoncvs.netbsd.se -antioche.antioche.eu.org -centaurus.4web.cz -chur.math.ntnu.no -console.netbsd.org -cvs.netbsd.org -cvsup.netbsd.se -ftp.chg.ru -ftp.estpak.ee -ftp.fsn.hu -ftp.funet.fi -ftp.netbsd.org -ftp.nluug.nl -ftp.plig.org -ftp.uni-erlangen.de -ftp.xgate.co.kr -gd.tuwien.ac.at -gort.ludd.luth.se -irc.warped.net -knug.youn.co.kr -mail.jp.netbsd.org -mail.netbsd.org -melanoma.cs.rmit.edu.au -mirror.aarnet.edu.au -moon.vub.ac.be -net.bsd.cz -netbsd.3miasto.net -netbsd.4ka.mipt.ru -netbsd.csie.nctu.edu.tw -netbsd.enderunix.org -netbsd.ftp.fu-berlin.de -netbsd.pair.com -netbsdiso.interoute.net.uk -netbsdwww.cs.rmit.edu.au -netbsdwww.interoute.net.uk -ns.netbsd.org -skeleton.phys.spbu.ru -www.en.netbsd.de -www.netbsd.cl -www.netbsd.nl -www.netbsd.org -www.netbsd.ro -zeppo.rediris.es Property changes on: head/tools/regression/lib/libc/nss/mach ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/tools/regression/lib/libc/nss/Makefile =================================================================== --- head/tools/regression/lib/libc/nss/Makefile (revision 292322) +++ head/tools/regression/lib/libc/nss/Makefile (nonexistent) @@ -1,12 +0,0 @@ -# $FreeBSD$ - -TESTS= test-getaddr test-getgr test-gethostby test-getpw test-getproto\ - test-getrpc test-getserv test-getusershell -CFLAGS+= -g -Wall - -.PHONY: tests -tests: ${TESTS} - -.PHONY: clean -clean: - -rm -f ${TESTS} Property changes on: head/tools/regression/lib/libc/nss/Makefile ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property