mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-28 13:57:42 +03:00
Introduce virDBusCallMethod & virDBusMessageRead methods
Doing DBus method calls using libdbus.so is tedious in the extreme. systemd developers came up with a nice high level API for DBus method calls (sd_bus_call_method). While systemd doesn't use libdbus.so, their API design can easily be ported to libdbus.so. This patch thus introduces methods virDBusCallMethod & virDBusMessageRead, which are based on the code used for sd_bus_call_method and sd_bus_message_read. This code in systemd is under the LGPLv2+, so we're license compatible. This code is probably pretty unintelligible unless you are familiar with the DBus type system. So I added some API docs trying to explain how to use them, as well as test cases to validate that I didn't screw up the adaptation from the original systemd code. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
67dfc772d1
commit
834c9c9459
1
.gitignore
vendored
1
.gitignore
vendored
@ -191,6 +191,7 @@
|
||||
/tests/virbitmaptest
|
||||
/tests/virbuftest
|
||||
/tests/vircgrouptest
|
||||
/tests/virdbustest
|
||||
/tests/virdrivermoduletest
|
||||
/tests/virendiantest
|
||||
/tests/virhashtest
|
||||
|
@ -294,6 +294,7 @@ typedef enum {
|
||||
VIR_ERR_RESOURCE_BUSY = 87, /* resource is already in use */
|
||||
VIR_ERR_ACCESS_DENIED = 88, /* operation on the object/resource
|
||||
was denied */
|
||||
VIR_ERR_DBUS_SERVICE = 89, /* error from a dbus service */
|
||||
} virErrorNumber;
|
||||
|
||||
/**
|
||||
|
@ -1282,8 +1282,12 @@ virConfWriteMem;
|
||||
|
||||
|
||||
# util/virdbus.h
|
||||
virDBusCallMethod;
|
||||
virDBusGetSessionBus;
|
||||
virDBusGetSystemBus;
|
||||
virDBusMessageDecode;
|
||||
virDBusMessageEncode;
|
||||
virDBusMessageRead;
|
||||
|
||||
|
||||
# util/virdnsmasq.h
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,10 +27,21 @@
|
||||
# include <dbus/dbus.h>
|
||||
# else
|
||||
# define DBusConnection void
|
||||
# define DBusMessage void
|
||||
# endif
|
||||
# include "internal.h"
|
||||
|
||||
DBusConnection *virDBusGetSystemBus(void);
|
||||
DBusConnection *virDBusGetSessionBus(void);
|
||||
|
||||
int virDBusCallMethod(DBusConnection *conn,
|
||||
DBusMessage **reply,
|
||||
const char *destination,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *member,
|
||||
const char *types, ...);
|
||||
int virDBusMessageRead(DBusMessage *msg,
|
||||
const char *types, ...);
|
||||
|
||||
#endif /* __VIR_DBUS_H__ */
|
||||
|
45
src/util/virdbuspriv.h
Normal file
45
src/util/virdbuspriv.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* virdbuspriv.h: internal APIs for testing DBus code
|
||||
*
|
||||
* Copyright (C) 2012-2013 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __VIR_DBUS_PRIV_H__
|
||||
# define __VIR_DBUS_PRIV_H__
|
||||
|
||||
# include "virdbus.h"
|
||||
|
||||
# include <stdarg.h>
|
||||
|
||||
int virDBusMessageEncodeArgs(DBusMessage* msg,
|
||||
const char *types,
|
||||
va_list args);
|
||||
|
||||
int virDBusMessageDecodeArgs(DBusMessage* msg,
|
||||
const char *types,
|
||||
va_list args);
|
||||
|
||||
int virDBusMessageEncode(DBusMessage* msg,
|
||||
const char *types,
|
||||
...);
|
||||
|
||||
int virDBusMessageDecode(DBusMessage* msg,
|
||||
const char *types,
|
||||
...);
|
||||
|
||||
#endif /* __VIR_DBUS_PRIV_H__ */
|
@ -1243,6 +1243,12 @@ virErrorMsg(virErrorNumber error, const char *info)
|
||||
else
|
||||
errmsg = _("access denied: %s");
|
||||
break;
|
||||
case VIR_ERR_DBUS_SERVICE:
|
||||
if (info == NULL)
|
||||
errmsg = _("error from service");
|
||||
else
|
||||
errmsg = _("error from service: %s");
|
||||
break;
|
||||
}
|
||||
return errmsg;
|
||||
}
|
||||
|
@ -145,6 +145,17 @@ void virReportSystemErrorFull(int domcode,
|
||||
0, 0, \
|
||||
(fmt), __VA_ARGS__)
|
||||
|
||||
# define virReportDBusServiceError(message, name) \
|
||||
virRaiseErrorFull(__FILE__, __FUNCTION__, __LINE__, \
|
||||
VIR_FROM_THIS, \
|
||||
VIR_ERR_DBUS_SERVICE, \
|
||||
VIR_ERR_ERROR, \
|
||||
__FUNCTION__, \
|
||||
name, \
|
||||
NULL, \
|
||||
0, 0, \
|
||||
"%s", message);
|
||||
|
||||
void virReportOOMErrorFull(int domcode,
|
||||
const char *filename,
|
||||
const char *funcname,
|
||||
|
@ -128,6 +128,11 @@ test_programs = virshtest sockettest \
|
||||
fchosttest \
|
||||
$(NULL)
|
||||
|
||||
if WITH_DBUS
|
||||
test_programs += virdbustest
|
||||
endif
|
||||
|
||||
|
||||
if WITH_GNUTLS
|
||||
test_programs += virnettlscontexttest
|
||||
endif
|
||||
@ -640,6 +645,14 @@ vircgroupmock_la_CFLAGS = $(AM_CFLAGS)
|
||||
vircgroupmock_la_LDFLAGS = -module -avoid-version \
|
||||
-rpath /evil/libtool/hack/to/force/shared/lib/creation
|
||||
|
||||
if WITH_DBUS
|
||||
virdbustest_SOURCES = \
|
||||
virdbustest.c testutils.h testutils.c
|
||||
virdbustest_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
|
||||
virdbustest_LDADD = $(LDADDS)
|
||||
else
|
||||
EXTRA_DIST += virdbustest.c
|
||||
endif
|
||||
|
||||
viruritest_SOURCES = \
|
||||
viruritest.c testutils.h testutils.c
|
||||
|
393
tests/virdbustest.c
Normal file
393
tests/virdbustest.c
Normal file
@ -0,0 +1,393 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "virdbuspriv.h"
|
||||
#include "virlog.h"
|
||||
#include "testutils.h"
|
||||
|
||||
#define VERIFY(typname, valorig, valnew, fmt) \
|
||||
do { \
|
||||
VIR_DEBUG("Compare " typname " '" fmt "' to '" \
|
||||
fmt "'", valorig, valnew); \
|
||||
if (valorig != valnew) { \
|
||||
fprintf(stderr, "Failed to round-trip " typname " '" \
|
||||
fmt "' to '" fmt "'\n", valorig, valnew); \
|
||||
goto cleanup; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY_STR(typname, valorig, valnew, fmt) \
|
||||
do { \
|
||||
VIR_DEBUG("Compare " typname " '" fmt "' to '" \
|
||||
fmt "'", valorig, valnew); \
|
||||
if (STRNEQ(valorig, valnew)) { \
|
||||
fprintf(stderr, "Failed to round-trip " typname " '" \
|
||||
fmt "' to '" fmt "'\n", valorig, valnew); \
|
||||
goto cleanup; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int testMessageSimple(const void *args ATTRIBUTE_UNUSED)
|
||||
{
|
||||
DBusMessage *msg = NULL;
|
||||
int ret = -1;
|
||||
unsigned char in_byte = 200, out_byte = 0;
|
||||
int in_bool = true, out_bool = false;
|
||||
int in_int16 = 12000, out_int16 = 0;
|
||||
unsigned int in_uint16 = 32000, out_uint16 = 0;
|
||||
int in_int32 = 100000000, out_int32 = 0;
|
||||
unsigned int in_uint32 = 200000000, out_uint32 = 0;
|
||||
long long in_int64 = 1000000000000, out_int64 = 0;
|
||||
unsigned long long in_uint64 = 2000000000000, out_uint64 = 0;
|
||||
double in_double = 3.14159265359, out_double = 0;;
|
||||
const char *in_string = "Hello World";
|
||||
char *out_string = NULL;
|
||||
const char *in_objectpath = "/org/libvirt/test";
|
||||
char *out_objectpath = NULL;
|
||||
const char *in_signature = "ybnqiuxtdsog";
|
||||
char *out_signature = NULL;
|
||||
|
||||
if (!(msg = dbus_message_new_method_call("org.libvirt.test",
|
||||
"/org/libvirt/test",
|
||||
"org.libvirt.test.astrochicken",
|
||||
"cluck"))) {
|
||||
VIR_DEBUG("Failed to allocate method call");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDBusMessageEncode(msg,
|
||||
"ybnqiuxtdsog",
|
||||
in_byte, in_bool,
|
||||
in_int16, in_uint16,
|
||||
in_int32, in_uint32,
|
||||
in_int64, in_uint64,
|
||||
in_double, in_string,
|
||||
in_objectpath, in_signature) < 0) {
|
||||
VIR_DEBUG("Failed to encode arguments");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDBusMessageDecode(msg,
|
||||
"ybnqiuxtdsog",
|
||||
&out_byte, &out_bool,
|
||||
&out_int16, &out_uint16,
|
||||
&out_int32, &out_uint32,
|
||||
&out_int64, &out_uint64,
|
||||
&out_double, &out_string,
|
||||
&out_objectpath, &out_signature) < 0) {
|
||||
VIR_DEBUG("Failed to decode arguments");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
VERIFY("byte", in_byte, out_byte, "%d");
|
||||
VERIFY("bool", in_bool, out_bool, "%d");
|
||||
VERIFY("int16", in_int16, out_int16, "%d");
|
||||
VERIFY("uint16", in_int16, out_int16, "%d");
|
||||
VERIFY("int32", in_int32, out_int32, "%d");
|
||||
VERIFY("uint32", in_int32, out_int32, "%d");
|
||||
VERIFY("int64", in_int64, out_int64, "%lld");
|
||||
VERIFY("uint64", in_int64, out_int64, "%lld");
|
||||
VERIFY("double", in_double, out_double, "%lf");
|
||||
VERIFY_STR("string", in_string, out_string, "%s");
|
||||
VERIFY_STR("objectpath", in_objectpath, out_objectpath, "%s");
|
||||
VERIFY_STR("signature", in_signature, out_signature, "%s");
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(out_string);
|
||||
VIR_FREE(out_signature);
|
||||
VIR_FREE(out_objectpath);
|
||||
dbus_message_unref(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int testMessageVariant(const void *args ATTRIBUTE_UNUSED)
|
||||
{
|
||||
DBusMessage *msg = NULL;
|
||||
int ret = -1;
|
||||
const char *in_str1 = "Hello";
|
||||
int in_int32 = 100000000, out_int32 = 0;
|
||||
const char *in_str2 = "World";
|
||||
char *out_str1 = NULL, *out_str2 = NULL;
|
||||
|
||||
if (!(msg = dbus_message_new_method_call("org.libvirt.test",
|
||||
"/org/libvirt/test",
|
||||
"org.libvirt.test.astrochicken",
|
||||
"cluck"))) {
|
||||
VIR_DEBUG("Failed to allocate method call");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDBusMessageEncode(msg,
|
||||
"svs",
|
||||
in_str1,
|
||||
"i", in_int32,
|
||||
in_str2) < 0) {
|
||||
VIR_DEBUG("Failed to encode arguments");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDBusMessageDecode(msg,
|
||||
"svs",
|
||||
&out_str1,
|
||||
"i", &out_int32,
|
||||
&out_str2) < 0) {
|
||||
VIR_DEBUG("Failed to decode arguments");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
VERIFY_STR("str1", in_str1, out_str1, "%s");
|
||||
VERIFY("int32", in_int32, out_int32, "%d");
|
||||
VERIFY_STR("str2", in_str2, out_str2, "%s");
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(out_str1);
|
||||
VIR_FREE(out_str2);
|
||||
dbus_message_unref(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int testMessageArray(const void *args ATTRIBUTE_UNUSED)
|
||||
{
|
||||
DBusMessage *msg = NULL;
|
||||
int ret = -1;
|
||||
const char *in_str1 = "Hello";
|
||||
int in_int32a = 1000000000, out_int32a = 0;
|
||||
int in_int32b = 2000000000, out_int32b = 0;
|
||||
int in_int32c = 3000000000, out_int32c = 0;
|
||||
const char *in_str2 = "World";
|
||||
char *out_str1 = NULL, *out_str2 = NULL;
|
||||
|
||||
if (!(msg = dbus_message_new_method_call("org.libvirt.test",
|
||||
"/org/libvirt/test",
|
||||
"org.libvirt.test.astrochicken",
|
||||
"cluck"))) {
|
||||
VIR_DEBUG("Failed to allocate method call");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDBusMessageEncode(msg,
|
||||
"sais",
|
||||
in_str1,
|
||||
(long long)3, in_int32a, in_int32b, in_int32c,
|
||||
in_str2) < 0) {
|
||||
VIR_DEBUG("Failed to encode arguments");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDBusMessageDecode(msg,
|
||||
"sais",
|
||||
&out_str1,
|
||||
3, &out_int32a, &out_int32b, &out_int32c,
|
||||
&out_str2) < 0) {
|
||||
VIR_DEBUG("Failed to decode arguments");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
VERIFY_STR("str1", in_str1, out_str1, "%s");
|
||||
VERIFY("int32a", in_int32a, out_int32a, "%d");
|
||||
VERIFY("int32b", in_int32b, out_int32b, "%d");
|
||||
VERIFY("int32c", in_int32c, out_int32c, "%d");
|
||||
VERIFY_STR("str2", in_str2, out_str2, "%s");
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(out_str1);
|
||||
VIR_FREE(out_str2);
|
||||
dbus_message_unref(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int testMessageStruct(const void *args ATTRIBUTE_UNUSED)
|
||||
{
|
||||
DBusMessage *msg = NULL;
|
||||
int ret = -1;
|
||||
unsigned char in_byte = 200, out_byte = 0;
|
||||
int in_bool = true, out_bool = false;
|
||||
int in_int16 = 12000, out_int16 = 0;
|
||||
unsigned int in_uint16 = 32000, out_uint16 = 0;
|
||||
int in_int32 = 100000000, out_int32 = 0;
|
||||
unsigned int in_uint32 = 200000000, out_uint32 = 0;
|
||||
long long in_int64 = 1000000000000, out_int64 = 0;
|
||||
unsigned long long in_uint64 = 2000000000000, out_uint64 = 0;
|
||||
double in_double = 3.14159265359, out_double = 0;;
|
||||
const char *in_string = "Hello World";
|
||||
char *out_string = NULL;
|
||||
const char *in_objectpath = "/org/libvirt/test";
|
||||
char *out_objectpath = NULL;
|
||||
const char *in_signature = "ybnqiuxtdsog";
|
||||
char *out_signature = NULL;
|
||||
|
||||
if (!(msg = dbus_message_new_method_call("org.libvirt.test",
|
||||
"/org/libvirt/test",
|
||||
"org.libvirt.test.astrochicken",
|
||||
"cluck"))) {
|
||||
VIR_DEBUG("Failed to allocate method call");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDBusMessageEncode(msg,
|
||||
"ybn(qiuxtds)og",
|
||||
in_byte, in_bool,
|
||||
in_int16, in_uint16,
|
||||
in_int32, in_uint32,
|
||||
in_int64, in_uint64,
|
||||
in_double, in_string,
|
||||
in_objectpath, in_signature) < 0) {
|
||||
VIR_DEBUG("Failed to encode arguments");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDBusMessageDecode(msg,
|
||||
"ybn(qiuxtds)og",
|
||||
&out_byte, &out_bool,
|
||||
&out_int16, &out_uint16,
|
||||
&out_int32, &out_uint32,
|
||||
&out_int64, &out_uint64,
|
||||
&out_double, &out_string,
|
||||
&out_objectpath, &out_signature) < 0) {
|
||||
VIR_DEBUG("Failed to decode arguments");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
VERIFY("byte", in_byte, out_byte, "%d");
|
||||
VERIFY("bool", in_bool, out_bool, "%d");
|
||||
VERIFY("int16", in_int16, out_int16, "%d");
|
||||
VERIFY("uint16", in_int16, out_int16, "%d");
|
||||
VERIFY("int32", in_int32, out_int32, "%d");
|
||||
VERIFY("uint32", in_int32, out_int32, "%d");
|
||||
VERIFY("int64", in_int64, out_int64, "%lld");
|
||||
VERIFY("uint64", in_int64, out_int64, "%lld");
|
||||
VERIFY("double", in_double, out_double, "%lf");
|
||||
VERIFY_STR("string", in_string, out_string, "%s");
|
||||
VERIFY_STR("objectpath", in_objectpath, out_objectpath, "%s");
|
||||
VERIFY_STR("signature", in_signature, out_signature, "%s");
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(out_string);
|
||||
VIR_FREE(out_signature);
|
||||
VIR_FREE(out_objectpath);
|
||||
dbus_message_unref(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int testMessageDict(const void *args ATTRIBUTE_UNUSED)
|
||||
{
|
||||
DBusMessage *msg = NULL;
|
||||
int ret = -1;
|
||||
const char *in_str1 = "Hello";
|
||||
int in_int32a = 100000000, out_int32a = 0;
|
||||
const char *in_key1 = "turnover";
|
||||
int in_int32b = 200000000, out_int32b = 0;
|
||||
const char *in_key2 = "revenue";
|
||||
int in_int32c = 300000000, out_int32c = 0;
|
||||
const char *in_key3 = "debt";
|
||||
const char *in_str2 = "World";
|
||||
char *out_str1 = NULL, *out_str2 = NULL;
|
||||
char *out_key1 = NULL, *out_key2 = NULL, *out_key3 = NULL;
|
||||
|
||||
if (!(msg = dbus_message_new_method_call("org.libvirt.test",
|
||||
"/org/libvirt/test",
|
||||
"org.libvirt.test.astrochicken",
|
||||
"cluck"))) {
|
||||
VIR_DEBUG("Failed to allocate method call");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDBusMessageEncode(msg,
|
||||
"sa{si}s",
|
||||
in_str1,
|
||||
3,
|
||||
in_key1, in_int32a,
|
||||
in_key2, in_int32b,
|
||||
in_key3, in_int32c,
|
||||
in_str2) < 0) {
|
||||
VIR_DEBUG("Failed to encode arguments");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDBusMessageDecode(msg,
|
||||
"sa{si}s",
|
||||
&out_str1,
|
||||
3,
|
||||
&out_key1, &out_int32a,
|
||||
&out_key2, &out_int32b,
|
||||
&out_key3, &out_int32c,
|
||||
&out_str2) < 0) {
|
||||
VIR_DEBUG("Failed to decode arguments");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
VERIFY_STR("str1", in_str1, out_str1, "%s");
|
||||
VERIFY("int32a", in_int32a, out_int32a, "%d");
|
||||
VERIFY("int32b", in_int32b, out_int32b, "%d");
|
||||
VERIFY("int32c", in_int32c, out_int32c, "%d");
|
||||
VERIFY_STR("key1", in_key1, out_key1, "%s");
|
||||
VERIFY_STR("key1", in_key2, out_key2, "%s");
|
||||
VERIFY_STR("key1", in_key3, out_key3, "%s");
|
||||
VERIFY_STR("str2", in_str2, out_str2, "%s");
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(out_str1);
|
||||
VIR_FREE(out_str2);
|
||||
VIR_FREE(out_key1);
|
||||
VIR_FREE(out_key2);
|
||||
VIR_FREE(out_key3);
|
||||
dbus_message_unref(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mymain(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (virtTestRun("Test message simple ", 1, testMessageSimple, NULL) < 0)
|
||||
ret = -1;
|
||||
if (virtTestRun("Test message variant ", 1, testMessageVariant, NULL) < 0)
|
||||
ret = -1;
|
||||
if (virtTestRun("Test message array ", 1, testMessageArray, NULL) < 0)
|
||||
ret = -1;
|
||||
if (virtTestRun("Test message struct ", 1, testMessageStruct, NULL) < 0)
|
||||
ret = -1;
|
||||
if (virtTestRun("Test message dict ", 1, testMessageDict, NULL) < 0)
|
||||
ret = -1;
|
||||
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
VIRT_TEST_MAIN(mymain)
|
Loading…
x
Reference in New Issue
Block a user