backup: Wire up qemu full pull backup commands over QMP
[libvirt/ericb.git] / tests / virnetmessagetest.c
blob2d81441626613658880c44a2b1daaf004d0b84a5
1 /*
2 * Copyright (C) 2011, 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 <signal.h>
23 #include "testutils.h"
24 #include "virerror.h"
25 #include "viralloc.h"
26 #include "virlog.h"
27 #include "virstring.h"
28 #include "rpc/virnetmessage.h"
30 #define VIR_FROM_THIS VIR_FROM_RPC
32 VIR_LOG_INIT("tests.netmessagetest");
34 static int testMessageHeaderEncode(const void *args ATTRIBUTE_UNUSED)
36 virNetMessagePtr msg = virNetMessageNew(true);
37 static const char expect[] = {
38 0x00, 0x00, 0x00, 0x1c, /* Length */
39 0x11, 0x22, 0x33, 0x44, /* Program */
40 0x00, 0x00, 0x00, 0x01, /* Version */
41 0x00, 0x00, 0x06, 0x66, /* Procedure */
42 0x00, 0x00, 0x00, 0x00, /* Type */
43 0x00, 0x00, 0x00, 0x99, /* Serial */
44 0x00, 0x00, 0x00, 0x00, /* Status */
46 /* According to doc to virNetMessageEncodeHeader(&msg):
47 * msg->buffer will be this long */
48 unsigned long msg_buf_size = VIR_NET_MESSAGE_INITIAL + VIR_NET_MESSAGE_LEN_MAX;
49 int ret = -1;
51 if (!msg)
52 return -1;
54 msg->header.prog = 0x11223344;
55 msg->header.vers = 0x01;
56 msg->header.proc = 0x666;
57 msg->header.type = VIR_NET_CALL;
58 msg->header.serial = 0x99;
59 msg->header.status = VIR_NET_OK;
61 if (virNetMessageEncodeHeader(msg) < 0)
62 goto cleanup;
64 if (ARRAY_CARDINALITY(expect) != msg->bufferOffset) {
65 VIR_DEBUG("Expect message offset %zu got %zu",
66 sizeof(expect), msg->bufferOffset);
67 goto cleanup;
70 if (msg->bufferLength != msg_buf_size) {
71 VIR_DEBUG("Expect message offset %lu got %zu",
72 msg_buf_size, msg->bufferLength);
73 goto cleanup;
76 if (memcmp(expect, msg->buffer, sizeof(expect)) != 0) {
77 virTestDifferenceBin(stderr, expect, msg->buffer, sizeof(expect));
78 goto cleanup;
81 ret = 0;
82 cleanup:
83 virNetMessageFree(msg);
84 return ret;
87 static int testMessageHeaderDecode(const void *args ATTRIBUTE_UNUSED)
89 virNetMessagePtr msg = virNetMessageNew(true);
90 static char input_buf [] = {
91 0x00, 0x00, 0x00, 0x1c, /* Length */
92 0x11, 0x22, 0x33, 0x44, /* Program */
93 0x00, 0x00, 0x00, 0x01, /* Version */
94 0x00, 0x00, 0x06, 0x66, /* Procedure */
95 0x00, 0x00, 0x00, 0x01, /* Type */
96 0x00, 0x00, 0x00, 0x99, /* Serial */
97 0x00, 0x00, 0x00, 0x01, /* Status */
99 int ret = -1;
101 if (!msg)
102 return -1;
104 msg->bufferLength = 4;
105 if (VIR_ALLOC_N(msg->buffer, msg->bufferLength) < 0)
106 goto cleanup;
107 memcpy(msg->buffer, input_buf, msg->bufferLength);
109 msg->header.prog = 0x11223344;
110 msg->header.vers = 0x01;
111 msg->header.proc = 0x666;
112 msg->header.type = VIR_NET_CALL;
113 msg->header.serial = 0x99;
114 msg->header.status = VIR_NET_OK;
116 if (virNetMessageDecodeLength(msg) < 0) {
117 VIR_DEBUG("Failed to decode message header");
118 goto cleanup;
121 if (msg->bufferOffset != 0x4) {
122 VIR_DEBUG("Expecting offset %zu got %zu",
123 (size_t)4, msg->bufferOffset);
124 goto cleanup;
127 if (msg->bufferLength != 0x1c) {
128 VIR_DEBUG("Expecting length %zu got %zu",
129 (size_t)0x1c, msg->bufferLength);
130 goto cleanup;
133 memcpy(msg->buffer, input_buf, msg->bufferLength);
135 if (virNetMessageDecodeHeader(msg) < 0) {
136 VIR_DEBUG("Failed to decode message header");
137 goto cleanup;
140 if (msg->bufferOffset != msg->bufferLength) {
141 VIR_DEBUG("Expect message offset %zu got %zu",
142 msg->bufferOffset, msg->bufferLength);
143 goto cleanup;
146 if (msg->header.prog != 0x11223344) {
147 VIR_DEBUG("Expect prog %d got %d",
148 0x11223344, msg->header.prog);
149 goto cleanup;
151 if (msg->header.vers != 0x1) {
152 VIR_DEBUG("Expect vers %d got %d",
153 0x11223344, msg->header.vers);
154 goto cleanup;
156 if (msg->header.proc != 0x666) {
157 VIR_DEBUG("Expect proc %d got %d",
158 0x666, msg->header.proc);
159 goto cleanup;
161 if (msg->header.type != VIR_NET_REPLY) {
162 VIR_DEBUG("Expect type %d got %d",
163 VIR_NET_REPLY, msg->header.type);
164 goto cleanup;
166 if (msg->header.serial != 0x99) {
167 VIR_DEBUG("Expect serial %d got %d",
168 0x99, msg->header.serial);
169 goto cleanup;
171 if (msg->header.status != VIR_NET_ERROR) {
172 VIR_DEBUG("Expect status %d got %d",
173 VIR_NET_ERROR, msg->header.status);
174 goto cleanup;
177 ret = 0;
178 cleanup:
179 virNetMessageFree(msg);
180 return ret;
183 static int testMessagePayloadEncode(const void *args ATTRIBUTE_UNUSED)
185 virNetMessageError err;
186 virNetMessagePtr msg = virNetMessageNew(true);
187 int ret = -1;
188 static const char expect[] = {
189 0x00, 0x00, 0x00, 0x74, /* Length */
190 0x11, 0x22, 0x33, 0x44, /* Program */
191 0x00, 0x00, 0x00, 0x01, /* Version */
192 0x00, 0x00, 0x06, 0x66, /* Procedure */
193 0x00, 0x00, 0x00, 0x02, /* Type */
194 0x00, 0x00, 0x00, 0x99, /* Serial */
195 0x00, 0x00, 0x00, 0x01, /* Status */
197 0x00, 0x00, 0x00, 0x01, /* Error code */
198 0x00, 0x00, 0x00, 0x07, /* Error domain */
199 0x00, 0x00, 0x00, 0x01, /* Error message pointer */
200 0x00, 0x00, 0x00, 0x0b, /* Error message length */
201 'H', 'e', 'l', 'l', /* Error message string */
202 'o', ' ', 'W', 'o',
203 'r', 'l', 'd', '\0',
204 0x00, 0x00, 0x00, 0x02, /* Error level */
205 0x00, 0x00, 0x00, 0x00, /* Error domain pointer */
206 0x00, 0x00, 0x00, 0x01, /* Error str1 pointer */
207 0x00, 0x00, 0x00, 0x03, /* Error str1 length */
208 'O', 'n', 'e', '\0', /* Error str1 message */
209 0x00, 0x00, 0x00, 0x01, /* Error str2 pointer */
210 0x00, 0x00, 0x00, 0x03, /* Error str2 length */
211 'T', 'w', 'o', '\0', /* Error str2 message */
212 0x00, 0x00, 0x00, 0x01, /* Error str3 pointer */
213 0x00, 0x00, 0x00, 0x05, /* Error str3 length */
214 'T', 'h', 'r', 'e', /* Error str3 message */
215 'e', '\0', '\0', '\0',
216 0x00, 0x00, 0x00, 0x01, /* Error int1 */
217 0x00, 0x00, 0x00, 0x02, /* Error int2 */
218 0x00, 0x00, 0x00, 0x00, /* Error network pointer */
221 if (!msg)
222 return -1;
224 memset(&err, 0, sizeof(err));
226 err.code = VIR_ERR_INTERNAL_ERROR;
227 err.domain = VIR_FROM_RPC;
228 err.level = VIR_ERR_ERROR;
230 if (VIR_ALLOC(err.message) < 0 ||
231 VIR_STRDUP(*err.message, "Hello World") < 0 ||
232 VIR_ALLOC(err.str1) < 0 ||
233 VIR_STRDUP(*err.str1, "One") < 0 ||
234 VIR_ALLOC(err.str2) < 0 ||
235 VIR_STRDUP(*err.str2, "Two") < 0 ||
236 VIR_ALLOC(err.str3) < 0 ||
237 VIR_STRDUP(*err.str3, "Three") < 0)
238 goto cleanup;
240 err.int1 = 1;
241 err.int2 = 2;
243 msg->header.prog = 0x11223344;
244 msg->header.vers = 0x01;
245 msg->header.proc = 0x666;
246 msg->header.type = VIR_NET_MESSAGE;
247 msg->header.serial = 0x99;
248 msg->header.status = VIR_NET_ERROR;
250 if (virNetMessageEncodeHeader(msg) < 0)
251 goto cleanup;
253 if (virNetMessageEncodePayload(msg, (xdrproc_t)xdr_virNetMessageError, &err) < 0)
254 goto cleanup;
256 if (ARRAY_CARDINALITY(expect) != msg->bufferLength) {
257 VIR_DEBUG("Expect message length %zu got %zu",
258 sizeof(expect), msg->bufferLength);
259 goto cleanup;
262 if (msg->bufferOffset != 0) {
263 VIR_DEBUG("Expect message offset 0 got %zu",
264 msg->bufferOffset);
265 goto cleanup;
268 if (memcmp(expect, msg->buffer, sizeof(expect)) != 0) {
269 virTestDifferenceBin(stderr, expect, msg->buffer, sizeof(expect));
270 goto cleanup;
273 ret = 0;
274 cleanup:
275 if (err.message)
276 VIR_FREE(*err.message);
277 if (err.str1)
278 VIR_FREE(*err.str1);
279 if (err.str2)
280 VIR_FREE(*err.str2);
281 if (err.str3)
282 VIR_FREE(*err.str3);
283 VIR_FREE(err.message);
284 VIR_FREE(err.str1);
285 VIR_FREE(err.str2);
286 VIR_FREE(err.str3);
287 virNetMessageFree(msg);
288 return ret;
291 static int testMessagePayloadDecode(const void *args ATTRIBUTE_UNUSED)
293 virNetMessageError err;
294 virNetMessagePtr msg = virNetMessageNew(true);
295 static char input_buffer[] = {
296 0x00, 0x00, 0x00, 0x74, /* Length */
297 0x11, 0x22, 0x33, 0x44, /* Program */
298 0x00, 0x00, 0x00, 0x01, /* Version */
299 0x00, 0x00, 0x06, 0x66, /* Procedure */
300 0x00, 0x00, 0x00, 0x02, /* Type */
301 0x00, 0x00, 0x00, 0x99, /* Serial */
302 0x00, 0x00, 0x00, 0x01, /* Status */
304 0x00, 0x00, 0x00, 0x01, /* Error code */
305 0x00, 0x00, 0x00, 0x07, /* Error domain */
306 0x00, 0x00, 0x00, 0x01, /* Error message pointer */
307 0x00, 0x00, 0x00, 0x0b, /* Error message length */
308 'H', 'e', 'l', 'l', /* Error message string */
309 'o', ' ', 'W', 'o',
310 'r', 'l', 'd', '\0',
311 0x00, 0x00, 0x00, 0x02, /* Error level */
312 0x00, 0x00, 0x00, 0x00, /* Error domain pointer */
313 0x00, 0x00, 0x00, 0x01, /* Error str1 pointer */
314 0x00, 0x00, 0x00, 0x03, /* Error str1 length */
315 'O', 'n', 'e', '\0', /* Error str1 message */
316 0x00, 0x00, 0x00, 0x01, /* Error str2 pointer */
317 0x00, 0x00, 0x00, 0x03, /* Error str2 length */
318 'T', 'w', 'o', '\0', /* Error str2 message */
319 0x00, 0x00, 0x00, 0x01, /* Error str3 pointer */
320 0x00, 0x00, 0x00, 0x05, /* Error str3 length */
321 'T', 'h', 'r', 'e', /* Error str3 message */
322 'e', '\0', '\0', '\0',
323 0x00, 0x00, 0x00, 0x01, /* Error int1 */
324 0x00, 0x00, 0x00, 0x02, /* Error int2 */
325 0x00, 0x00, 0x00, 0x00, /* Error network pointer */
327 int ret = -1;
329 memset(&err, 0, sizeof(err));
331 if (!msg)
332 return -1;
334 msg->bufferLength = 4;
335 if (VIR_ALLOC_N(msg->buffer, msg->bufferLength) < 0)
336 goto cleanup;
337 memcpy(msg->buffer, input_buffer, msg->bufferLength);
339 if (virNetMessageDecodeLength(msg) < 0) {
340 VIR_DEBUG("Failed to decode message header");
341 goto cleanup;
344 if (msg->bufferOffset != 0x4) {
345 VIR_DEBUG("Expecting offset %zu got %zu",
346 (size_t)4, msg->bufferOffset);
347 goto cleanup;
350 if (msg->bufferLength != 0x74) {
351 VIR_DEBUG("Expecting length %zu got %zu",
352 (size_t)0x74, msg->bufferLength);
353 goto cleanup;
356 memcpy(msg->buffer, input_buffer, msg->bufferLength);
358 if (virNetMessageDecodeHeader(msg) < 0) {
359 VIR_DEBUG("Failed to decode message header");
360 goto cleanup;
363 if (msg->bufferOffset != 28) {
364 VIR_DEBUG("Expect message offset %zu got %zu",
365 msg->bufferOffset, (size_t)28);
366 goto cleanup;
369 if (msg->bufferLength != 0x74) {
370 VIR_DEBUG("Expecting length %zu got %zu",
371 (size_t)0x1c, msg->bufferLength);
372 goto cleanup;
375 if (virNetMessageDecodePayload(msg, (xdrproc_t)xdr_virNetMessageError, &err) < 0) {
376 VIR_DEBUG("Failed to decode message payload");
377 goto cleanup;
380 if (err.code != VIR_ERR_INTERNAL_ERROR) {
381 VIR_DEBUG("Expect code %d got %d",
382 VIR_ERR_INTERNAL_ERROR, err.code);
383 goto cleanup;
386 if (err.domain != VIR_FROM_RPC) {
387 VIR_DEBUG("Expect domain %d got %d",
388 VIR_ERR_RPC, err.domain);
389 goto cleanup;
392 if (err.message == NULL ||
393 STRNEQ(*err.message, "Hello World")) {
394 VIR_DEBUG("Expect str1 'Hello World' got %s",
395 err.message ? *err.message : "(null)");
396 goto cleanup;
399 if (err.dom != NULL) {
400 VIR_DEBUG("Expect NULL dom");
401 goto cleanup;
404 if (err.level != VIR_ERR_ERROR) {
405 VIR_DEBUG("Expect leve %d got %d",
406 VIR_ERR_ERROR, err.level);
407 goto cleanup;
410 if (err.str1 == NULL ||
411 STRNEQ(*err.str1, "One")) {
412 VIR_DEBUG("Expect str1 'One' got %s",
413 err.str1 ? *err.str1 : "(null)");
414 goto cleanup;
417 if (err.str2 == NULL ||
418 STRNEQ(*err.str2, "Two")) {
419 VIR_DEBUG("Expect str3 'Two' got %s",
420 err.str2 ? *err.str2 : "(null)");
421 goto cleanup;
424 if (err.str3 == NULL ||
425 STRNEQ(*err.str3, "Three")) {
426 VIR_DEBUG("Expect str3 'Three' got %s",
427 err.str3 ? *err.str3 : "(null)");
428 goto cleanup;
431 if (err.int1 != 1) {
432 VIR_DEBUG("Expect int1 1 got %d",
433 err.int1);
434 goto cleanup;
437 if (err.int2 != 2) {
438 VIR_DEBUG("Expect int2 2 got %d",
439 err.int2);
440 goto cleanup;
443 if (err.net != NULL) {
444 VIR_DEBUG("Expect NULL network");
445 goto cleanup;
448 ret = 0;
449 cleanup:
450 xdr_free((xdrproc_t)xdr_virNetMessageError, (void*)&err);
451 virNetMessageFree(msg);
452 return ret;
455 static int testMessagePayloadStreamEncode(const void *args ATTRIBUTE_UNUSED)
457 char stream[] = "The quick brown fox jumps over the lazy dog";
458 virNetMessagePtr msg = virNetMessageNew(true);
459 static const char expect[] = {
460 0x00, 0x00, 0x00, 0x47, /* Length */
461 0x11, 0x22, 0x33, 0x44, /* Program */
462 0x00, 0x00, 0x00, 0x01, /* Version */
463 0x00, 0x00, 0x06, 0x66, /* Procedure */
464 0x00, 0x00, 0x00, 0x03, /* Type */
465 0x00, 0x00, 0x00, 0x99, /* Serial */
466 0x00, 0x00, 0x00, 0x02, /* Status */
468 'T', 'h', 'e', ' ',
469 'q', 'u', 'i', 'c',
470 'k', ' ', 'b', 'r',
471 'o', 'w', 'n', ' ',
472 'f', 'o', 'x', ' ',
473 'j', 'u', 'm', 'p',
474 's', ' ', 'o', 'v',
475 'e', 'r', ' ', 't',
476 'h', 'e', ' ', 'l',
477 'a', 'z', 'y', ' ',
478 'd', 'o', 'g',
480 int ret = -1;
482 if (!msg)
483 return -1;
485 msg->header.prog = 0x11223344;
486 msg->header.vers = 0x01;
487 msg->header.proc = 0x666;
488 msg->header.type = VIR_NET_STREAM;
489 msg->header.serial = 0x99;
490 msg->header.status = VIR_NET_CONTINUE;
492 if (virNetMessageEncodeHeader(msg) < 0)
493 goto cleanup;
495 if (virNetMessageEncodePayloadRaw(msg, stream, strlen(stream)) < 0)
496 goto cleanup;
498 if (ARRAY_CARDINALITY(expect) != msg->bufferLength) {
499 VIR_DEBUG("Expect message length %zu got %zu",
500 sizeof(expect), msg->bufferLength);
501 goto cleanup;
504 if (msg->bufferOffset != 0) {
505 VIR_DEBUG("Expect message offset 0 got %zu",
506 msg->bufferOffset);
507 goto cleanup;
510 if (memcmp(expect, msg->buffer, sizeof(expect)) != 0) {
511 virTestDifferenceBin(stderr, expect, msg->buffer, sizeof(expect));
512 goto cleanup;
515 ret = 0;
516 cleanup:
517 virNetMessageFree(msg);
518 return ret;
522 static int
523 mymain(void)
525 int ret = 0;
527 signal(SIGPIPE, SIG_IGN);
529 if (virTestRun("Message Header Encode", testMessageHeaderEncode, NULL) < 0)
530 ret = -1;
532 if (virTestRun("Message Header Decode", testMessageHeaderDecode, NULL) < 0)
533 ret = -1;
535 if (virTestRun("Message Payload Encode", testMessagePayloadEncode, NULL) < 0)
536 ret = -1;
538 if (virTestRun("Message Payload Decode", testMessagePayloadDecode, NULL) < 0)
539 ret = -1;
541 if (virTestRun("Message Payload Stream Encode", testMessagePayloadStreamEncode, NULL) < 0)
542 ret = -1;
544 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
547 VIR_TEST_MAIN(mymain)