backup: Wire up qemu full pull backup commands over QMP
[libvirt/ericb.git] / tests / nsstest.c
blob4118c31cefab0b492287535ad1d7cafd4675cc23
1 /*
2 * Copyright (C) 2016 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
19 #include <config.h>
21 #include "testutils.h"
23 #ifdef NSS
25 # include <arpa/inet.h>
26 # include "libvirt_nss.h"
27 # include "virsocketaddr.h"
29 # define VIR_FROM_THIS VIR_FROM_NONE
31 # define BUF_SIZE 1024
33 struct testNSSData {
34 const char *hostname;
35 const char *const *ipAddr;
36 int af;
39 static int
40 testGetHostByName(const void *opaque)
42 const struct testNSSData *data = opaque;
43 const bool existent = data->hostname && data->ipAddr && data->ipAddr[0];
44 int ret = -1;
45 struct hostent resolved;
46 char buf[BUF_SIZE] = { 0 };
47 char **addrList;
48 int rv, tmp_errno = 0, tmp_herrno = 0;
49 size_t i = 0;
51 memset(&resolved, 0, sizeof(resolved));
53 rv = NSS_NAME(gethostbyname2)(data->hostname,
54 data->af,
55 &resolved,
56 buf, sizeof(buf),
57 &tmp_errno,
58 &tmp_herrno);
60 if (rv == NSS_STATUS_TRYAGAIN ||
61 rv == NSS_STATUS_UNAVAIL ||
62 rv == NSS_STATUS_RETURN) {
63 /* Resolving failed in unexpected fashion. */
64 virReportError(VIR_ERR_INTERNAL_ERROR,
65 "Resolving of %s failed due to internal error",
66 data->hostname);
67 goto cleanup;
68 } else if (rv == NSS_STATUS_NOTFOUND) {
69 /* Resolving failed. Should it? */
70 if (!existent)
71 ret = 0;
72 else
73 virReportError(VIR_ERR_INTERNAL_ERROR,
74 "Resolving of %s failed",
75 data->hostname);
76 goto cleanup;
79 /* Resolving succeeded. Should it? */
80 if (!existent) {
81 virReportError(VIR_ERR_INTERNAL_ERROR,
82 "Resolving of %s succeeded but was expected to fail",
83 data->hostname);
84 goto cleanup;
87 /* Now lets see if resolved address match our expectations. */
89 if (!resolved.h_name) {
90 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
91 "resolved.h_name empty");
92 goto cleanup;
95 if (data->af != AF_UNSPEC &&
96 resolved.h_addrtype != data->af) {
97 virReportError(VIR_ERR_INTERNAL_ERROR,
98 "Expected AF_INET (%d) got %d",
99 data->af, resolved.h_addrtype);
100 goto cleanup;
103 if ((resolved.h_addrtype == AF_INET && resolved.h_length != 4) ||
104 (resolved.h_addrtype == AF_INET6 && resolved.h_length != 16)) {
105 /* IPv4 addresses are encoded into 4 bytes */
106 virReportError(VIR_ERR_INTERNAL_ERROR,
107 "Expected %d bytes long address, got %d",
108 resolved.h_addrtype == AF_INET ? 4 : 16,
109 resolved.h_length);
110 goto cleanup;
113 if (!resolved.h_addr_list) {
114 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
115 "resolved.h_addr_list empty");
116 goto cleanup;
119 addrList = resolved.h_addr_list;
120 i = 0;
121 while (*addrList) {
122 virSocketAddr sa;
123 char *ipAddr;
124 void *address = *addrList;
126 memset(&sa, 0, sizeof(sa));
128 if (resolved.h_addrtype == AF_INET) {
129 virSocketAddrSetIPv4AddrNetOrder(&sa, *((uint32_t *) address));
130 } else {
131 virSocketAddrSetIPv6AddrNetOrder(&sa, address);
134 if (!(ipAddr = virSocketAddrFormat(&sa))) {
135 /* error reported by helper */
136 goto cleanup;
139 if (STRNEQ_NULLABLE(data->ipAddr[i], ipAddr)) {
140 virReportError(VIR_ERR_INTERNAL_ERROR,
141 "Unexpected address %s, expecting %s",
142 ipAddr, NULLSTR(data->ipAddr[i]));
143 VIR_FREE(ipAddr);
144 goto cleanup;
146 VIR_FREE(ipAddr);
148 addrList++;
149 i++;
152 if (data->ipAddr[i]) {
153 virReportError(VIR_ERR_INTERNAL_ERROR,
154 "Expected %s address, got NULL",
155 data->ipAddr[i]);
156 goto cleanup;
159 ret = 0;
160 cleanup:
161 return ret;
164 static int
165 mymain(void)
167 int ret = 0;
169 # define DO_TEST(name, family, ...) \
170 do { \
171 const char *addr[] = { __VA_ARGS__, NULL}; \
172 struct testNSSData data = { \
173 .hostname = name, .ipAddr = addr, .af = family, \
174 }; \
175 if (virTestRun(name, testGetHostByName, &data) < 0) \
176 ret = -1; \
177 } while (0)
179 # if !defined(LIBVIRT_NSS_GUEST)
180 DO_TEST("fedora", AF_INET, "192.168.122.197", "192.168.122.198", "192.168.122.199");
181 DO_TEST("gentoo", AF_INET, "192.168.122.254");
182 DO_TEST("gentoo", AF_INET6, "2001:1234:dead:beef::2");
183 DO_TEST("gentoo", AF_UNSPEC, "192.168.122.254");
184 DO_TEST("non-existent", AF_UNSPEC, NULL);
185 # else /* defined(LIBVIRT_NSS_GUEST) */
186 DO_TEST("debian", AF_INET, "192.168.122.2");
187 DO_TEST("suse", AF_INET, "192.168.122.3");
188 # endif /* defined(LIBVIRT_NSS_GUEST) */
190 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
193 VIR_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/nssmock.so")
194 #else
196 main(void)
198 return EXIT_AM_SKIP;
200 #endif