backup: Wire up qemu full pull backup commands over QMP
[libvirt/ericb.git] / tests / viriscsitest.c
blobcc552a5cfe7460cd6224a86bac28ae843b2e6972
1 /*
2 * Copyright (C) 2014 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 WIN32
24 int
25 main(void)
27 return EXIT_AM_SKIP;
29 #else
30 # define LIBVIRT_VIRCOMMANDPRIV_H_ALLOW
31 # include "vircommandpriv.h"
32 # include "viriscsi.h"
34 # define VIR_FROM_THIS VIR_FROM_NONE
36 static const char *iscsiadmSessionOutput =
37 "tcp: [1] 10.20.30.40:3260,1 iqn.2004-06.example:example1:iscsi.test\n"
38 "tcp: [2] 10.20.30.41:3260,1 iqn.2005-05.example:example1:iscsi.hello\n"
39 "tcp: [3] 10.20.30.42:3260,1 iqn.2006-04.example:example1:iscsi.world\n"
40 "tcp: [5] 10.20.30.43:3260,1 iqn.2007-04.example:example1:iscsi.foo\n"
41 "tcp: [6] 10.20.30.44:3260,1 iqn.2008-04.example:example1:iscsi.bar\n"
42 "tcp: [7] 10.20.30.45:3260,1 iqn.2009-04.example:example1:iscsi.seven\n";
44 static const char *iscsiadmSessionOutputNonFlash =
45 "tcp: [1] 10.20.30.40:3260,1 iqn.2004-06.example:example1:iscsi.test (non-flash)\n"
46 "tcp: [2] 10.20.30.41:3260,1 iqn.2005-05.example:example1:iscsi.hello (non-flash)\n"
47 "tcp: [3] 10.20.30.42:3260,1 iqn.2006-04.example:example1:iscsi.world (non-flash)\n"
48 "tcp: [5] 10.20.30.43:3260,1 iqn.2007-04.example:example1:iscsi.foo (non-flash)\n"
49 "tcp: [6] 10.20.30.44:3260,1 iqn.2008-04.example:example1:iscsi.bar (non-flash)\n"
50 "tcp: [7] 10.20.30.45:3260,1 iqn.2009-04.example:example1:iscsi.seven (non-flash)\n";
52 const char *iscsiadmSendtargetsOutput =
53 "10.20.30.40:3260,1 iqn.2004-06.example:example1:iscsi.test\n"
54 "10.20.30.40:3260,1 iqn.2005-05.example:example1:iscsi.hello\n"
55 "10.20.30.40:3260,1 iqn.2006-04.example:example1:iscsi.world\n"
56 "10.20.30.40:3260,1 iqn.2007-04.example:example1:iscsi.foo\n"
57 "10.20.30.40:3260,1 iqn.2008-04.example:example1:iscsi.bar\n"
58 "10.20.30.40:3260,1 iqn.2009-04.example:example1:iscsi.seven\n";
60 const char *iscsiadmIfaceDefaultOutput =
61 "default tcp,<empty>,<empty>,<empty>,<empty>\n"
62 "iser iser,<empty>,<empty>,<empty>,<empty>\n";
64 const char *iscsiadmIfaceIfaceOutput =
65 "default tcp,<empty>,<empty>,<empty>,<empty>\n"
66 "iser iser,<empty>,<empty>,<empty>,<empty>\n"
67 "libvirt-iface-03020100 tcp,<empty>,<empty>,<empty>,iqn.2004-06.example:example1:initiator\n";
70 struct testIscsiadmCbData {
71 bool output_version;
72 bool iface_created;
75 static void testIscsiadmCb(const char *const*args,
76 const char *const*env ATTRIBUTE_UNUSED,
77 const char *input ATTRIBUTE_UNUSED,
78 char **output,
79 char **error ATTRIBUTE_UNUSED,
80 int *status,
81 void *opaque)
83 struct testIscsiadmCbData *data = opaque;
85 if (args[0] && STREQ(args[0], ISCSIADM) &&
86 args[1] && STREQ(args[1], "--mode") &&
87 args[2] && STREQ(args[2], "session") &&
88 args[3] == NULL) {
89 if (data->output_version)
90 ignore_value(VIR_STRDUP(*output, iscsiadmSessionOutputNonFlash));
91 else
92 ignore_value(VIR_STRDUP(*output, iscsiadmSessionOutput));
93 } else if (args[0] && STREQ(args[0], ISCSIADM) &&
94 args[1] && STREQ(args[1], "--mode") &&
95 args[2] && STREQ(args[2], "discovery") &&
96 args[3] && STREQ(args[3], "--type") &&
97 args[4] && STREQ(args[4], "sendtargets") &&
98 args[5] && STREQ(args[5], "--portal") &&
99 args[6] && STREQ(args[6], "10.20.30.40:3260,1") &&
100 args[7] && STREQ(args[7], "--op") &&
101 args[8] && STREQ(args[8], "nonpersistent") &&
102 args[9] == NULL) {
103 ignore_value(VIR_STRDUP(*output, iscsiadmSendtargetsOutput));
104 } else if (args[0] && STREQ(args[0], ISCSIADM) &&
105 args[1] && STREQ(args[1], "--mode") &&
106 args[2] && STREQ(args[2], "node") &&
107 args[3] && STREQ(args[3], "--portal") &&
108 args[4] && STREQ(args[4], "10.20.30.40:3260,1") &&
109 args[5] && STREQ(args[5], "--targetname") &&
110 args[6] && STREQ(args[6], "iqn.2004-06.example:example1:iscsi.test") &&
111 args[7] && STREQ(args[7], "--login") &&
112 args[8] == NULL) {
113 /* Mocking real environment output is not needed for now.
114 * Example output from real environment:
116 * Logging in to [iface: default, \
117 * target: iqn.2004-06.example:example1:iscsi.test, \
118 * portal: 10.20.30.40:3260,1] (multiple)
119 * Login to [iface: default, \
120 * target: iqn.2004-06.example:example1:iscsi.test, \
121 * portal: 10.20.30.40:3260,1] successful.
123 } else if (args[0] && STREQ(args[0], ISCSIADM) &&
124 args[1] && STREQ(args[1], "--mode") &&
125 args[2] && STREQ(args[2], "iface") &&
126 args[3] == NULL) {
127 if (data->iface_created)
128 ignore_value(VIR_STRDUP(*output, iscsiadmIfaceIfaceOutput));
129 else
130 ignore_value(VIR_STRDUP(*output, iscsiadmIfaceDefaultOutput));
131 } else if (args[0] && STREQ(args[0], ISCSIADM) &&
132 args[1] && STREQ(args[1], "--mode") &&
133 args[2] && STREQ(args[2], "iface") &&
134 args[3] && STREQ(args[3], "--interface") &&
135 args[4] && STREQ(args[4], "libvirt-iface-03020100") &&
136 args[5] && STREQ(args[5], "--op") &&
137 args[6] && STREQ(args[6], "new") &&
138 args[7] == NULL) {
139 /* Mocking real environment output is not needed for now.
140 * Example output from real environment:
142 * New interface libvirt-iface-03020100 added
144 data->iface_created = true;
145 } else if (args[0] && STREQ(args[0], ISCSIADM) &&
146 args[1] && STREQ(args[1], "--mode") &&
147 args[2] && STREQ(args[2], "iface") &&
148 args[3] && STREQ(args[3], "--interface") &&
149 args[4] && STREQ(args[4], "libvirt-iface-03020100") &&
150 args[5] && STREQ(args[5], "--op") &&
151 args[6] && STREQ(args[6], "update") &&
152 args[7] && STREQ(args[7], "--name") &&
153 args[8] && STREQ(args[8], "iface.initiatorname") &&
154 args[9] && STREQ(args[9], "--value") &&
155 args[10] && STREQ(args[10], "iqn.2004-06.example:example1:initiator") &&
156 args[11] == NULL &&
157 data->iface_created) {
158 /* Mocking real environment output is not needed for now.
159 * Example output from real environment:
161 * libvirt-iface-03020100 updated.
163 } else if (args[0] && STREQ(args[0], ISCSIADM) &&
164 args[1] && STREQ(args[1], "--mode") &&
165 args[2] && STREQ(args[2], "discovery") &&
166 args[3] && STREQ(args[3], "--type") &&
167 args[4] && STREQ(args[4], "sendtargets") &&
168 args[5] && STREQ(args[5], "--portal") &&
169 args[6] && STREQ(args[6], "10.20.30.40:3260,1") &&
170 args[7] && STREQ(args[7], "--interface") &&
171 args[8] && STREQ(args[8], "libvirt-iface-03020100") &&
172 args[9] == NULL &&
173 data->iface_created) {
174 ignore_value(VIR_STRDUP(*output, iscsiadmSendtargetsOutput));
175 } else if (args[0] && STREQ(args[0], ISCSIADM) &&
176 args[1] && STREQ(args[1], "--mode") &&
177 args[2] && STREQ(args[2], "node") &&
178 args[3] && STREQ(args[3], "--portal") &&
179 args[4] && STREQ(args[4], "10.20.30.40:3260,1") &&
180 args[5] && STREQ(args[5], "--targetname") &&
181 args[6] && STREQ(args[6], "iqn.2004-06.example:example1:iscsi.test") &&
182 args[7] && STREQ(args[7], "--login") &&
183 args[8] && STREQ(args[8], "--interface") &&
184 args[9] && STREQ(args[9], "libvirt-iface-03020100") &&
185 args[10] == NULL &&
186 data->iface_created) {
187 /* Mocking real environment output is not needed for now.
188 * Example output from real environment:
190 * Logging in to [iface: libvirt-iface-03020100, \
191 * target: iqn.2004-06.example:example1:iscsi.test, \
192 * portal: 10.20.30.40:3260,1] (multiple)
193 * Login to [iface: libvirt-iface-03020100, \
194 * target: iqn.2004-06.example:example1:iscsi.test, \
195 * portal: 10.20.30.40:3260,1] successful.
197 } else {
198 *status = -1;
202 struct testSessionInfo {
203 const char *device_path;
204 bool output_version;
205 const char *expected_session;
208 static int
209 testISCSIGetSession(const void *data)
211 const struct testSessionInfo *info = data;
212 struct testIscsiadmCbData cbData = { 0 };
213 char *actual_session = NULL;
214 int ret = -1;
216 cbData.output_version = info->output_version;
218 virCommandSetDryRun(NULL, testIscsiadmCb, &cbData);
220 actual_session = virISCSIGetSession(info->device_path, true);
222 if (STRNEQ_NULLABLE(actual_session, info->expected_session)) {
223 virReportError(VIR_ERR_INTERNAL_ERROR,
224 "Expected session: '%s' got: '%s'",
225 NULLSTR(info->expected_session),
226 NULLSTR(actual_session));
227 goto cleanup;
230 ret = 0;
232 cleanup:
233 virCommandSetDryRun(NULL, NULL, NULL);
234 VIR_FREE(actual_session);
235 return ret;
238 struct testScanTargetsInfo {
239 const char *fake_cmd_output;
240 const char *portal;
241 const char **expected_targets;
242 size_t nexpected;
245 static int
246 testISCSIScanTargets(const void *data)
248 const struct testScanTargetsInfo *info = data;
249 size_t ntargets = 0;
250 char **targets = NULL;
251 int ret = -1;
252 size_t i;
254 virCommandSetDryRun(NULL, testIscsiadmCb, NULL);
256 if (virISCSIScanTargets(info->portal, NULL,
257 false, &ntargets, &targets) < 0)
258 goto cleanup;
260 if (info->nexpected != ntargets) {
261 virReportError(VIR_ERR_INTERNAL_ERROR,
262 "Expected %zu targets, got %zu",
263 info->nexpected, ntargets);
264 goto cleanup;
267 for (i = 0; i < ntargets; i++) {
268 if (STRNEQ(info->expected_targets[i], targets[i])) {
269 virReportError(VIR_ERR_INTERNAL_ERROR,
270 "Expected target '%s', got '%s'",
271 info->expected_targets[i], targets[i]);
272 goto cleanup;
276 ret = 0;
278 cleanup:
279 virCommandSetDryRun(NULL, NULL, NULL);
280 for (i = 0; i < ntargets; i++)
281 VIR_FREE(targets[i]);
282 VIR_FREE(targets);
283 return ret;
287 struct testConnectionInfoLogin {
288 const char *portal;
289 const char *initiatoriqn;
290 const char *target;
294 static int
295 testISCSIConnectionLogin(const void *data)
297 const struct testConnectionInfoLogin *info = data;
298 struct testIscsiadmCbData cbData = { 0 };
299 int ret = -1;
301 virCommandSetDryRun(NULL, testIscsiadmCb, &cbData);
303 if (virISCSIConnectionLogin(info->portal, info->initiatoriqn, info->target) < 0)
304 goto cleanup;
306 ret = 0;
307 cleanup:
308 virCommandSetDryRun(NULL, NULL, NULL);
309 return ret;
313 static int
314 mymain(void)
316 int rv = 0;
318 # define DO_SESSION_TEST(name, session) \
319 do { \
320 struct testSessionInfo info = {name, false, session}; \
321 if (virTestRun("ISCSI get session test" name, \
322 testISCSIGetSession, &info) < 0) \
323 rv = -1; \
324 info.output_version = true; \
325 if (virTestRun("ISCSI get (non-flash) session test" name, \
326 testISCSIGetSession, &info) < 0) \
327 rv = -1; \
328 } while (0)
330 DO_SESSION_TEST("iqn.2004-06.example:example1:iscsi.test", "1");
331 DO_SESSION_TEST("iqn.2009-04.example:example1:iscsi.seven", "7");
332 DO_SESSION_TEST("iqn.2009-04.example:example1:iscsi.eight", NULL);
334 const char *targets[] = {
335 "iqn.2004-06.example:example1:iscsi.test",
336 "iqn.2005-05.example:example1:iscsi.hello",
337 "iqn.2006-04.example:example1:iscsi.world",
338 "iqn.2007-04.example:example1:iscsi.foo",
339 "iqn.2008-04.example:example1:iscsi.bar",
340 "iqn.2009-04.example:example1:iscsi.seven"
342 struct testScanTargetsInfo infoTargets = {
343 .fake_cmd_output = "iscsiadm_sendtargets",
344 .portal = "10.20.30.40:3260,1",
345 .expected_targets = targets,
346 .nexpected = ARRAY_CARDINALITY(targets),
348 if (virTestRun("ISCSI scan targets", testISCSIScanTargets, &infoTargets) < 0)
349 rv = -1;
351 # define DO_LOGIN_TEST(portal, iqn, target) \
352 do { \
353 struct testConnectionInfoLogin info = {portal, iqn, target }; \
354 if (virTestRun("ISCSI login " portal, \
355 testISCSIConnectionLogin, &info) < 0) \
356 rv = -1; \
357 } while (0)
359 DO_LOGIN_TEST("10.20.30.40:3260,1", NULL, "iqn.2004-06.example:example1:iscsi.test");
360 DO_LOGIN_TEST("10.20.30.40:3260,1", "iqn.2004-06.example:example1:initiator",
361 "iqn.2004-06.example:example1:iscsi.test");
363 if (rv < 0)
364 return EXIT_FAILURE;
365 return EXIT_SUCCESS;
368 VIR_TEST_MAIN_PRELOAD(mymain,
369 abs_builddir "/.libs/virrandommock.so")
370 #endif /* WIN32 */