diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 716628368a..acaaaabf1c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1742,6 +1742,7 @@ virNetDevSetPromiscuous; virNetDevSetRcvAllMulti; virNetDevSetRcvMulti; virNetDevSetupControl; +virNetDevSysfsFile; virNetDevValidateConfig; diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 9a6d4e7bfb..6ee692d192 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -1614,9 +1614,9 @@ int virNetDevValidateConfig(const char *ifname ATTRIBUTE_UNUSED, #ifdef __linux__ # define NET_SYSFS "/sys/class/net/" -static int +int virNetDevSysfsFile(char **pf_sysfs_device_link, const char *ifname, - const char *file) + const char *file) { if (virAsprintf(pf_sysfs_device_link, NET_SYSFS "%s/%s", ifname, file) < 0) diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index fb0fd46fa0..3535319242 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -219,4 +219,9 @@ int virNetDevSetRcvAllMulti(const char *ifname, bool receive) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virNetDevGetRcvAllMulti(const char *ifname, bool *receive) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevSysfsFile(char **pf_sysfs_device_link, + const char *ifname, + const char *file) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; #endif /* __VIR_NETDEV_H__ */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 046cd085ce..9ebedc3620 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -176,6 +176,7 @@ test_programs = virshtest sockettest \ domainconftest \ virhostdevtest \ vircaps2xmltest \ + virnetdevtest \ $(NULL) if WITH_REMOTE @@ -402,6 +403,7 @@ test_libraries = libshunload.la \ virnetserverclientmock.la \ vircgroupmock.la \ virpcimock.la \ + virnetdevmock.la \ $(NULL) if WITH_QEMU test_libraries += libqemumonitortestutils.la \ @@ -1029,6 +1031,19 @@ virpcimock_la_LIBADD = $(GNULIB_LIBS) \ virpcimock_la_LDFLAGS = -module -avoid-version \ -rpath /evil/libtool/hack/to/force/shared/lib/creation +virnetdevtest_SOURCES = \ + virnetdevtest.c testutils.h testutils.c +virnetdevtest_CFLAGS = $(AM_CFLAGS) $(LIBNL_CFLAGS) +virnetdevtest_LDADD = $(LDADDS) + +virnetdevmock_la_SOURCES = \ + virnetdevmock.c +virnetdevmock_la_CFLAGS = $(AM_CFLAGS) $(LIBNL_CFLAGS) +virnetdevmock_la_LIBADD = $(GNULIB_LIBS) \ + ../src/libvirt.la +virnetdevmock_la_LDFLAGS = -module -avoid-version \ + -rpath /evil/libtool/hack/to/force/shared/lib/creation + if WITH_LINUX virusbtest_SOURCES = \ virusbtest.c testutils.h testutils.c diff --git a/tests/virnetdevmock.c b/tests/virnetdevmock.c new file mode 100644 index 0000000000..a9967b77c1 --- /dev/null +++ b/tests/virnetdevmock.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 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 + * . + * + * Author: Michal Privoznik + */ + +#include + +#ifdef __linux__ +# include "internal.h" +# include +# include +# include "virstring.h" +# include "virnetdev.h" + +# define NET_DEV_TEST_DATA_PREFIX abs_srcdir "/virnetdevtestdata/sys/class/net" + +int +virNetDevSysfsFile(char **pf_sysfs_device_link, + const char *ifname, + const char *file) +{ + + if (virAsprintfQuiet(pf_sysfs_device_link, "%s/%s/%s", + NET_DEV_TEST_DATA_PREFIX, ifname, file) < 0) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return 0; +} +#else +/* Nothing to override on non-__linux__ platforms */ +#endif diff --git a/tests/virnetdevtest.c b/tests/virnetdevtest.c new file mode 100644 index 0000000000..c31543e736 --- /dev/null +++ b/tests/virnetdevtest.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2015 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 + * . + * + * Author: Michal Privoznik + */ + +#include + +#include "testutils.h" + +#ifdef __linux__ + +# include "virnetdev.h" + +# define VIR_FROM_THIS VIR_FROM_NONE + +struct testVirNetDevGetLinkInfoData { + const char *ifname; /* ifname to get info on */ + virInterfaceState state; /* expected state */ + unsigned int speed; /* expected speed */ +}; + +static int +testVirNetDevGetLinkInfo(const void *opaque) +{ + int ret = -1; + const struct testVirNetDevGetLinkInfoData *data = opaque; + virInterfaceLink lnk; + + if (virNetDevGetLinkInfo(data->ifname, &lnk) < 0) + goto cleanup; + + if (lnk.state != data->state) { + fprintf(stderr, + "Fetched link state (%s) doesn't match the expected one (%s)", + virInterfaceStateTypeToString(lnk.state), + virInterfaceStateTypeToString(data->state)); + goto cleanup; + } + + if (lnk.speed != data->speed) { + fprintf(stderr, + "Fetched link speed (%u) doesn't match the expected one (%u)", + lnk.speed, data->speed); + goto cleanup; + } + + ret = 0; + cleanup: + return ret; +} + +static int +mymain(void) +{ + int ret = 0; + +# define DO_TEST_LINK(ifname, state, speed) \ + do { \ + struct testVirNetDevGetLinkInfoData data = {ifname, state, speed}; \ + if (virtTestRun("Link info: " # ifname, \ + testVirNetDevGetLinkInfo, &data) < 0) \ + ret = -1; \ + } while (0) + + DO_TEST_LINK("eth0", VIR_INTERFACE_STATE_UP, 1000); + DO_TEST_LINK("lo", VIR_INTERFACE_STATE_UNKNOWN, 0); + DO_TEST_LINK("eth0-broken", VIR_INTERFACE_STATE_DOWN, 0); + + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virnetdevmock.so") +#else +int +main(void) +{ + return EXIT_AM_SKIP; +} +#endif diff --git a/tests/virnetdevtestdata/sys/class/net/eth0-broken/operstate b/tests/virnetdevtestdata/sys/class/net/eth0-broken/operstate new file mode 100644 index 0000000000..eb0e90439e --- /dev/null +++ b/tests/virnetdevtestdata/sys/class/net/eth0-broken/operstate @@ -0,0 +1 @@ +down diff --git a/tests/virnetdevtestdata/sys/class/net/eth0-broken/speed b/tests/virnetdevtestdata/sys/class/net/eth0-broken/speed new file mode 100644 index 0000000000..4f6ff861c9 --- /dev/null +++ b/tests/virnetdevtestdata/sys/class/net/eth0-broken/speed @@ -0,0 +1 @@ +4294967295 diff --git a/tests/virnetdevtestdata/sys/class/net/eth0/operstate b/tests/virnetdevtestdata/sys/class/net/eth0/operstate new file mode 100644 index 0000000000..e31ee94e17 --- /dev/null +++ b/tests/virnetdevtestdata/sys/class/net/eth0/operstate @@ -0,0 +1 @@ +up diff --git a/tests/virnetdevtestdata/sys/class/net/eth0/speed b/tests/virnetdevtestdata/sys/class/net/eth0/speed new file mode 100644 index 0000000000..83b33d238d --- /dev/null +++ b/tests/virnetdevtestdata/sys/class/net/eth0/speed @@ -0,0 +1 @@ +1000 diff --git a/tests/virnetdevtestdata/sys/class/net/lo/operstate b/tests/virnetdevtestdata/sys/class/net/lo/operstate new file mode 100644 index 0000000000..3546645658 --- /dev/null +++ b/tests/virnetdevtestdata/sys/class/net/lo/operstate @@ -0,0 +1 @@ +unknown diff --git a/tests/virnetdevtestdata/sys/class/net/lo/speed b/tests/virnetdevtestdata/sys/class/net/lo/speed new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/tests/virnetdevtestdata/sys/class/net/lo/speed @@ -0,0 +1 @@ +0