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/>.
23 #include "testutils.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
;
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)
64 if (ARRAY_CARDINALITY(expect
) != msg
->bufferOffset
) {
65 VIR_DEBUG("Expect message offset %zu got %zu",
66 sizeof(expect
), msg
->bufferOffset
);
70 if (msg
->bufferLength
!= msg_buf_size
) {
71 VIR_DEBUG("Expect message offset %lu got %zu",
72 msg_buf_size
, msg
->bufferLength
);
76 if (memcmp(expect
, msg
->buffer
, sizeof(expect
)) != 0) {
77 virTestDifferenceBin(stderr
, expect
, msg
->buffer
, sizeof(expect
));
83 virNetMessageFree(msg
);
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 */
104 msg
->bufferLength
= 4;
105 if (VIR_ALLOC_N(msg
->buffer
, msg
->bufferLength
) < 0)
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");
121 if (msg
->bufferOffset
!= 0x4) {
122 VIR_DEBUG("Expecting offset %zu got %zu",
123 (size_t)4, msg
->bufferOffset
);
127 if (msg
->bufferLength
!= 0x1c) {
128 VIR_DEBUG("Expecting length %zu got %zu",
129 (size_t)0x1c, msg
->bufferLength
);
133 memcpy(msg
->buffer
, input_buf
, msg
->bufferLength
);
135 if (virNetMessageDecodeHeader(msg
) < 0) {
136 VIR_DEBUG("Failed to decode message header");
140 if (msg
->bufferOffset
!= msg
->bufferLength
) {
141 VIR_DEBUG("Expect message offset %zu got %zu",
142 msg
->bufferOffset
, msg
->bufferLength
);
146 if (msg
->header
.prog
!= 0x11223344) {
147 VIR_DEBUG("Expect prog %d got %d",
148 0x11223344, msg
->header
.prog
);
151 if (msg
->header
.vers
!= 0x1) {
152 VIR_DEBUG("Expect vers %d got %d",
153 0x11223344, msg
->header
.vers
);
156 if (msg
->header
.proc
!= 0x666) {
157 VIR_DEBUG("Expect proc %d got %d",
158 0x666, msg
->header
.proc
);
161 if (msg
->header
.type
!= VIR_NET_REPLY
) {
162 VIR_DEBUG("Expect type %d got %d",
163 VIR_NET_REPLY
, msg
->header
.type
);
166 if (msg
->header
.serial
!= 0x99) {
167 VIR_DEBUG("Expect serial %d got %d",
168 0x99, msg
->header
.serial
);
171 if (msg
->header
.status
!= VIR_NET_ERROR
) {
172 VIR_DEBUG("Expect status %d got %d",
173 VIR_NET_ERROR
, msg
->header
.status
);
179 virNetMessageFree(msg
);
183 static int testMessagePayloadEncode(const void *args ATTRIBUTE_UNUSED
)
185 virNetMessageError err
;
186 virNetMessagePtr msg
= virNetMessageNew(true);
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 */
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 */
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)
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)
253 if (virNetMessageEncodePayload(msg
, (xdrproc_t
)xdr_virNetMessageError
, &err
) < 0)
256 if (ARRAY_CARDINALITY(expect
) != msg
->bufferLength
) {
257 VIR_DEBUG("Expect message length %zu got %zu",
258 sizeof(expect
), msg
->bufferLength
);
262 if (msg
->bufferOffset
!= 0) {
263 VIR_DEBUG("Expect message offset 0 got %zu",
268 if (memcmp(expect
, msg
->buffer
, sizeof(expect
)) != 0) {
269 virTestDifferenceBin(stderr
, expect
, msg
->buffer
, sizeof(expect
));
276 VIR_FREE(*err
.message
);
283 VIR_FREE(err
.message
);
287 virNetMessageFree(msg
);
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 */
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 */
329 memset(&err
, 0, sizeof(err
));
334 msg
->bufferLength
= 4;
335 if (VIR_ALLOC_N(msg
->buffer
, msg
->bufferLength
) < 0)
337 memcpy(msg
->buffer
, input_buffer
, msg
->bufferLength
);
339 if (virNetMessageDecodeLength(msg
) < 0) {
340 VIR_DEBUG("Failed to decode message header");
344 if (msg
->bufferOffset
!= 0x4) {
345 VIR_DEBUG("Expecting offset %zu got %zu",
346 (size_t)4, msg
->bufferOffset
);
350 if (msg
->bufferLength
!= 0x74) {
351 VIR_DEBUG("Expecting length %zu got %zu",
352 (size_t)0x74, msg
->bufferLength
);
356 memcpy(msg
->buffer
, input_buffer
, msg
->bufferLength
);
358 if (virNetMessageDecodeHeader(msg
) < 0) {
359 VIR_DEBUG("Failed to decode message header");
363 if (msg
->bufferOffset
!= 28) {
364 VIR_DEBUG("Expect message offset %zu got %zu",
365 msg
->bufferOffset
, (size_t)28);
369 if (msg
->bufferLength
!= 0x74) {
370 VIR_DEBUG("Expecting length %zu got %zu",
371 (size_t)0x1c, msg
->bufferLength
);
375 if (virNetMessageDecodePayload(msg
, (xdrproc_t
)xdr_virNetMessageError
, &err
) < 0) {
376 VIR_DEBUG("Failed to decode message payload");
380 if (err
.code
!= VIR_ERR_INTERNAL_ERROR
) {
381 VIR_DEBUG("Expect code %d got %d",
382 VIR_ERR_INTERNAL_ERROR
, err
.code
);
386 if (err
.domain
!= VIR_FROM_RPC
) {
387 VIR_DEBUG("Expect domain %d got %d",
388 VIR_ERR_RPC
, err
.domain
);
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)");
399 if (err
.dom
!= NULL
) {
400 VIR_DEBUG("Expect NULL dom");
404 if (err
.level
!= VIR_ERR_ERROR
) {
405 VIR_DEBUG("Expect leve %d got %d",
406 VIR_ERR_ERROR
, err
.level
);
410 if (err
.str1
== NULL
||
411 STRNEQ(*err
.str1
, "One")) {
412 VIR_DEBUG("Expect str1 'One' got %s",
413 err
.str1
? *err
.str1
: "(null)");
417 if (err
.str2
== NULL
||
418 STRNEQ(*err
.str2
, "Two")) {
419 VIR_DEBUG("Expect str3 'Two' got %s",
420 err
.str2
? *err
.str2
: "(null)");
424 if (err
.str3
== NULL
||
425 STRNEQ(*err
.str3
, "Three")) {
426 VIR_DEBUG("Expect str3 'Three' got %s",
427 err
.str3
? *err
.str3
: "(null)");
432 VIR_DEBUG("Expect int1 1 got %d",
438 VIR_DEBUG("Expect int2 2 got %d",
443 if (err
.net
!= NULL
) {
444 VIR_DEBUG("Expect NULL network");
450 xdr_free((xdrproc_t
)xdr_virNetMessageError
, (void*)&err
);
451 virNetMessageFree(msg
);
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 */
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)
495 if (virNetMessageEncodePayloadRaw(msg
, stream
, strlen(stream
)) < 0)
498 if (ARRAY_CARDINALITY(expect
) != msg
->bufferLength
) {
499 VIR_DEBUG("Expect message length %zu got %zu",
500 sizeof(expect
), msg
->bufferLength
);
504 if (msg
->bufferOffset
!= 0) {
505 VIR_DEBUG("Expect message offset 0 got %zu",
510 if (memcmp(expect
, msg
->buffer
, sizeof(expect
)) != 0) {
511 virTestDifferenceBin(stderr
, expect
, msg
->buffer
, sizeof(expect
));
517 virNetMessageFree(msg
);
527 signal(SIGPIPE
, SIG_IGN
);
529 if (virTestRun("Message Header Encode", testMessageHeaderEncode
, NULL
) < 0)
532 if (virTestRun("Message Header Decode", testMessageHeaderDecode
, NULL
) < 0)
535 if (virTestRun("Message Payload Encode", testMessagePayloadEncode
, NULL
) < 0)
538 if (virTestRun("Message Payload Decode", testMessagePayloadDecode
, NULL
) < 0)
541 if (virTestRun("Message Payload Stream Encode", testMessagePayloadStreamEncode
, NULL
) < 0)
544 return ret
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;
547 VIR_TEST_MAIN(mymain
)