From 9afa0060820fb6c682175165aa0f7be57034bea1 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Thu, 21 Oct 2010 19:11:50 +0100 Subject: [PATCH] Add test suite for virSocket APIs Add a test suite for check parsing, formatting, range calculation and netmask checking APIs in virSocketAddr. * tests/sockettest.c, tests/Makefile.am: Add new test case --- tests/Makefile.am | 8 +- tests/sockettest.c | 259 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 tests/sockettest.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 44fe5796e9..9720b6e2d1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -72,7 +72,7 @@ EXTRA_DIST = \ domainsnapshotxml2xmlin \ qemuhelpdata -check_PROGRAMS = virshtest conftest \ +check_PROGRAMS = virshtest conftest sockettest \ nodeinfotest statstest qparamtest virbuftest if WITH_XEN @@ -152,6 +152,7 @@ TESTS = virshtest \ statstest \ qparamtest \ virbuftest \ + sockettest \ $(test_scripts) if WITH_XEN @@ -214,6 +215,11 @@ TESTS_ENVIRONMENT = \ valgrind: $(MAKE) check VG="valgrind --quiet --leak-check=full --suppressions=$(srcdir)/.valgrind.supp" +sockettest_SOURCES = \ + sockettest.c \ + testutils.c testutils.h +sockettest_LDADD = ../src/libvirt_util.la $(LDADDS) + if WITH_XEN xml2sexprtest_SOURCES = \ xml2sexprtest.c testutilsxen.c testutilsxen.h \ diff --git a/tests/sockettest.c b/tests/sockettest.c new file mode 100644 index 0000000000..2c9ff03d92 --- /dev/null +++ b/tests/sockettest.c @@ -0,0 +1,259 @@ +/* + * sockettest.c: Testing for src/util/network.c APIs + * + * Copyright (C) 2010 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include + +#include +#include +#include + +#include "network.h" +#include "testutils.h" +#include "logging.h" +#include "memory.h" + +static void testQuietError(void *userData ATTRIBUTE_UNUSED, + virErrorPtr error ATTRIBUTE_UNUSED) +{ + /* nada */ +} + +static int testParse(virSocketAddr *addr, const char *addrstr, int family, bool pass) +{ + int rc; + + rc = virSocketParseAddr(addrstr, addr, family); + + if (rc < 0) + return pass ? -1 : 0; + else + return pass ? 0 : -1; +} + +static int testFormat(virSocketAddr *addr, const char *addrstr, bool pass) +{ + char *newaddrstr; + + newaddrstr = virSocketFormatAddr(addr); + if (!newaddrstr) + return pass ? -1 : 0; + + if (STRNEQ(newaddrstr, addrstr)) { + virtTestDifference(stderr, newaddrstr, addrstr); + VIR_FREE(newaddrstr); + return pass ? -1 : 0; + } else { + VIR_FREE(newaddrstr); + return pass ? 0 : -1; + } +} + +struct testParseData { + virSocketAddr *addr; + const char *addrstr; + int family; + bool pass; +}; +static int testParseHelper(const void *opaque) +{ + const struct testParseData *data = opaque; + return testParse(data->addr, data->addrstr, data->family, data->pass); +} + +struct testFormatData { + virSocketAddr *addr; + const char *addrstr; + bool pass; +}; +static int testFormatHelper(const void *opaque) +{ + const struct testFormatData *data = opaque; + return testFormat(data->addr, data->addrstr, data->pass); +} + + +static int testRange(const char *saddrstr, const char *eaddrstr, int size, bool pass) +{ + virSocketAddr saddr; + virSocketAddr eaddr; + + if (virSocketParseAddr(saddrstr, &saddr, AF_UNSPEC) < 0) + return -1; + if (virSocketParseAddr(eaddrstr, &eaddr, AF_UNSPEC) < 0) + return -1; + + int gotsize = virSocketGetRange(&saddr, &eaddr); + VIR_DEBUG("Size want %d vs got %d", size, gotsize); + if (gotsize < 0 || gotsize != size) { + return pass ? -1 : 0; + } else { + return pass ? 0 : -1; + } +} + +struct testRangeData { + const char *saddr; + const char *eaddr; + int size; + bool pass; +}; +static int testRangeHelper(const void *opaque) +{ + const struct testRangeData *data = opaque; + return testRange(data->saddr, data->eaddr, data->size, data->pass); +} + + +static int testNetmask(const char *addr1str, const char *addr2str, + const char *netmaskstr, bool pass) +{ + virSocketAddr addr1; + virSocketAddr addr2; + virSocketAddr netmask; + + if (virSocketParseAddr(addr1str, &addr1, AF_UNSPEC) < 0) + return -1; + if (virSocketParseAddr(addr2str, &addr2, AF_UNSPEC) < 0) + return -1; + if (virSocketParseAddr(netmaskstr, &netmask, AF_UNSPEC) < 0) + return -1; + + int ret = virSocketCheckNetmask(&addr1, &addr2, &netmask); + + if (ret <= 0) { + return pass ? -1 : 0; + } else { + return pass ? 0 : -1; + } +} + +struct testNetmaskData { + const char *addr1; + const char *addr2; + const char *netmask; + bool pass; +}; +static int testNetmaskHelper(const void *opaque) +{ + const struct testNetmaskData *data = opaque; + return testNetmask(data->addr1, data->addr2, data->netmask, data->pass); +} + + +static int +mymain(int argc ATTRIBUTE_UNUSED, + char **argv ATTRIBUTE_UNUSED) +{ + int ret = 0; + /* Some of our tests deliberately test failure cases, so + * register a handler to stop error messages cluttering + * up display + */ + if (!virTestGetDebug()) + virSetErrorFunc(NULL, testQuietError); + +#define DO_TEST_PARSE(addrstr, family, pass) \ + do { \ + virSocketAddr addr; \ + struct testParseData data = { &addr, addrstr, family, pass }; \ + memset(&addr, 0, sizeof(addr)); \ + if (virtTestRun("Test parse " addrstr, \ + 1, testParseHelper, &data) < 0) \ + ret = -1; \ + } while (0) + +#define DO_TEST_PARSE_AND_FORMAT(addrstr, family, pass) \ + do { \ + virSocketAddr addr; \ + struct testParseData data = { &addr, addrstr, family, pass }; \ + memset(&addr, 0, sizeof(addr)); \ + if (virtTestRun("Test parse " addrstr " family " #family, \ + 1, testParseHelper, &data) < 0) \ + ret = -1; \ + struct testFormatData data2 = { &addr, addrstr, pass }; \ + if (virtTestRun("Test format " addrstr " family " #family, \ + 1, testFormatHelper, &data2) < 0) \ + ret = -1; \ + } while (0) + +#define DO_TEST_RANGE(saddr, eaddr, size, pass) \ + do { \ + struct testRangeData data = { saddr, eaddr, size, pass }; \ + if (virtTestRun("Test range " saddr " -> " eaddr " size " #size, \ + 1, testRangeHelper, &data) < 0) \ + ret = -1; \ + } while (0) + +#define DO_TEST_NETMASK(addr1, addr2, netmask, pass) \ + do { \ + struct testNetmaskData data = { addr1, addr2, netmask, pass }; \ + if (virtTestRun("Test netmask " addr1 " + " addr2 " in " netmask, \ + 1, testNetmaskHelper, &data) < 0) \ + ret = -1; \ + } while (0) + + + DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNSPEC, true); + DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET, true); + DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET6, false); + DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNIX, false); + DO_TEST_PARSE_AND_FORMAT("127.0.0.256", AF_UNSPEC, false); + + DO_TEST_PARSE_AND_FORMAT("::1", AF_UNSPEC, true); + DO_TEST_PARSE_AND_FORMAT("::1", AF_INET, false); + DO_TEST_PARSE_AND_FORMAT("::1", AF_INET6, true); + DO_TEST_PARSE_AND_FORMAT("::1", AF_UNIX, false); + DO_TEST_PARSE_AND_FORMAT("::ffff", AF_UNSPEC, true); + + DO_TEST_RANGE("192.168.122.1", "192.168.122.1", 1, true); + DO_TEST_RANGE("192.168.122.1", "192.168.122.20", 20, true); + DO_TEST_RANGE("192.168.122.0", "192.168.122.255", 256, true); + DO_TEST_RANGE("192.168.122.20", "192.168.122.1", -1, false); + DO_TEST_RANGE("10.0.0.1", "192.168.122.20", -1, false); + DO_TEST_RANGE("192.168.122.20", "10.0.0.1", -1, false); + + DO_TEST_RANGE("2000::1", "2000::1", 1, true); + DO_TEST_RANGE("2000::1", "2000::2", 2, true); + DO_TEST_RANGE("2000::2", "2000::1", -1, false); + DO_TEST_RANGE("2000::1", "9001::1", -1, false); + + DO_TEST_NETMASK("192.168.122.1", "192.168.122.2", + "255.255.255.0", true); + DO_TEST_NETMASK("192.168.122.1", "192.168.122.4", + "255.255.255.248", true); + DO_TEST_NETMASK("192.168.122.1", "192.168.123.2", + "255.255.255.0", false); + DO_TEST_NETMASK("192.168.122.1", "192.168.123.2", + "255.255.0.0", true); + + DO_TEST_NETMASK("2000::1:1", "2000::1:1", + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", true); + DO_TEST_NETMASK("2000::1:1", "2000::2:1", + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", false); + DO_TEST_NETMASK("2000::1:1", "2000::2:1", + "ffff:ffff:ffff:ffff:ffff:ffff:fff8:0", true); + DO_TEST_NETMASK("2000::1:1", "9000::1:1", + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", false); + + return(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + +VIRT_TEST_MAIN(mymain)