diff --git a/po/POTFILES.in b/po/POTFILES.in index bdff67906a..b0a1ed401b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -213,6 +213,7 @@ src/util/virkeyfile.c src/util/virlease.c src/util/virlockspace.c src/util/virlog.c +src/util/virmacmap.c src/util/virnetdev.c src/util/virnetdevbandwidth.c src/util/virnetdevbridge.c diff --git a/src/Makefile.am b/src/Makefile.am index d440548bef..a9106fa978 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -137,6 +137,7 @@ UTIL_SOURCES = \ util/virlockspace.c util/virlockspace.h \ util/virlog.c util/virlog.h \ util/virmacaddr.h util/virmacaddr.c \ + util/virmacmap.h util/virmacmap.c \ util/virnetdev.h util/virnetdev.c \ util/virnetdevbandwidth.h util/virnetdevbandwidth.c \ util/virnetdevbridge.h util/virnetdevbridge.c \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 9189f56fe4..6303dec8b3 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1927,6 +1927,15 @@ virMacAddrSet; virMacAddrSetRaw; +# util/virmacmap.h +virMacMapAdd; +virMacMapDumpStr; +virMacMapLookup; +virMacMapNew; +virMacMapRemove; +virMacMapWriteFile; + + # util/virnetdev.h virNetDevAddMulti; virNetDevDelMulti; diff --git a/src/util/virmacmap.c b/src/util/virmacmap.c new file mode 100644 index 0000000000..36c364e100 --- /dev/null +++ b/src/util/virmacmap.c @@ -0,0 +1,388 @@ +/* + * virmacmap.c: MAC address <-> Domain name mapping + * + * Copyright (C) 2016 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 + * . + * + * Authors: + * Michal Privoznik + */ + +#include + +#include "virmacmap.h" +#include "virobject.h" +#include "virlog.h" +#include "virjson.h" +#include "virfile.h" +#include "virhash.h" +#include "virstring.h" +#include "viralloc.h" + +#define VIR_FROM_THIS VIR_FROM_NETWORK + +VIR_LOG_INIT("util.virmacmap"); + +/** + * VIR_MAC_MAP_FILE_SIZE_MAX: + * + * Macro providing the upper limit on the size of mac maps file + */ +#define VIR_MAC_MAP_FILE_SIZE_MAX (32 * 1024 * 1024) + +struct virMacMap { + virObjectLockable parent; + + virHashTablePtr macs; +}; + + +static virClassPtr virMacMapClass; + + +static void +virMacMapDispose(void *obj) +{ + virMacMapPtr mgr = obj; + virHashFree(mgr->macs); +} + + +static void +virMacMapHashFree(void *payload, const void *name ATTRIBUTE_UNUSED) +{ + virStringListFree(payload); +} + + +static int virMacMapOnceInit(void) +{ + if (!(virMacMapClass = virClassNew(virClassForObjectLockable(), + "virMacMapClass", + sizeof(virMacMap), + virMacMapDispose))) + return -1; + + return 0; +} + +VIR_ONCE_GLOBAL_INIT(virMacMap); + + +static int +virMacMapAddLocked(virMacMapPtr mgr, + const char *domain, + const char *mac) +{ + int ret = -1; + const char **macsList = NULL; + char **newMacsList = NULL; + + if ((macsList = virHashLookup(mgr->macs, domain)) && + virStringListHasString(macsList, mac)) { + ret = 0; + goto cleanup; + } + + if (!(newMacsList = virStringListAdd(macsList, mac)) || + virHashUpdateEntry(mgr->macs, domain, newMacsList) < 0) + goto cleanup; + newMacsList = NULL; + + ret = 0; + cleanup: + virStringListFree(newMacsList); + return ret; +} + + +static int +virMacMapRemoveLocked(virMacMapPtr mgr, + const char *domain, + const char *mac) +{ + char **macsList = NULL; + char **newMacsList = NULL; + + if (!(macsList = virHashLookup(mgr->macs, domain))) + return 0; + + newMacsList = macsList; + virStringListRemove(&macsList, mac); + if (!macsList) { + virHashSteal(mgr->macs, domain); + } else { + if (macsList != newMacsList && + virHashUpdateEntry(mgr->macs, domain, newMacsList) < 0) + return -1; + } + + return 0; +} + + +static int +virMacMapLoadFile(virMacMapPtr mgr, + const char *file) +{ + char *map_str = NULL; + virJSONValuePtr map = NULL; + int map_str_len = 0; + size_t i; + int ret = -1; + + if (virFileExists(file) && + (map_str_len = virFileReadAll(file, + VIR_MAC_MAP_FILE_SIZE_MAX, + &map_str)) < 0) + goto cleanup; + + if (map_str_len == 0) { + ret = 0; + goto cleanup; + } + + if (!(map = virJSONValueFromString(map_str))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("invalid json in file: %s"), + file); + goto cleanup; + } + + if (!virJSONValueIsArray(map)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Malformed file structure: %s"), + file); + goto cleanup; + } + + for (i = 0; i < virJSONValueArraySize(map); i++) { + virJSONValuePtr tmp = virJSONValueArrayGet(map, i); + virJSONValuePtr macs; + const char *domain; + size_t j; + + if (!(domain = virJSONValueObjectGetString(tmp, "domain"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing domain")); + goto cleanup; + } + + if (!(macs = virJSONValueObjectGetArray(tmp, "macs"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing macs")); + goto cleanup; + } + + for (j = 0; j < virJSONValueArraySize(macs); j++) { + virJSONValuePtr macJSON = virJSONValueArrayGet(macs, j); + const char *mac = virJSONValueGetString(macJSON); + + if (virMacMapAddLocked(mgr, domain, mac) < 0) + goto cleanup; + } + } + + ret = 0; + cleanup: + VIR_FREE(map_str); + virJSONValueFree(map); + return ret; +} + + +static int +virMACMapHashDumper(void *payload, + const void *name, + void *data) +{ + virJSONValuePtr obj = NULL; + virJSONValuePtr arr = NULL; + const char **macs = payload; + size_t i; + int ret = -1; + + if (!(obj = virJSONValueNewObject()) || + !(arr = virJSONValueNewArray())) + goto cleanup; + + for (i = 0; macs[i]; i++) { + virJSONValuePtr m = virJSONValueNewString(macs[i]); + + if (!m || + virJSONValueArrayAppend(arr, m) < 0) { + virJSONValueFree(m); + goto cleanup; + } + } + + if (virJSONValueObjectAppendString(obj, "domain", name) < 0 || + virJSONValueObjectAppend(obj, "macs", arr) < 0) + goto cleanup; + arr = NULL; + + if (virJSONValueArrayAppend(data, obj) < 0) + goto cleanup; + obj = NULL; + + ret = 0; + cleanup: + virJSONValueFree(obj); + virJSONValueFree(arr); + return ret; +} + + +static int +virMacMapDumpStrLocked(virMacMapPtr mgr, + char **str) +{ + virJSONValuePtr arr; + int ret = -1; + + if (!(arr = virJSONValueNewArray())) + goto cleanup; + + if (virHashForEach(mgr->macs, virMACMapHashDumper, arr) < 0) + goto cleanup; + + if (!(*str = virJSONValueToString(arr, true))) + goto cleanup; + + ret = 0; + cleanup: + virJSONValueFree(arr); + return ret; +} + + +static int +virMacMapWriteFileLocked(virMacMapPtr mgr, + const char *file) +{ + char *str; + int ret = -1; + + if (virMacMapDumpStrLocked(mgr, &str) < 0) + goto cleanup; + + if (virFileRewriteStr(file, 0644, str) < 0) + goto cleanup; + + ret = 0; + cleanup: + VIR_FREE(str); + return ret; +} + + +#define VIR_MAC_HASH_TABLE_SIZE 10 + +virMacMapPtr +virMacMapNew(const char *file) +{ + virMacMapPtr mgr; + + if (virMacMapInitialize() < 0) + return NULL; + + if (!(mgr = virObjectLockableNew(virMacMapClass))) + return NULL; + + virObjectLock(mgr); + if (!(mgr->macs = virHashCreate(VIR_MAC_HASH_TABLE_SIZE, + virMacMapHashFree))) + goto error; + + if (file && + virMacMapLoadFile(mgr, file) < 0) + goto error; + + virObjectUnlock(mgr); + return mgr; + + error: + virObjectUnlock(mgr); + virObjectUnref(mgr); + return NULL; +} + + +int +virMacMapAdd(virMacMapPtr mgr, + const char *domain, + const char *mac) +{ + int ret; + + virObjectLock(mgr); + ret = virMacMapAddLocked(mgr, domain, mac); + virObjectUnlock(mgr); + return ret; +} + + +int +virMacMapRemove(virMacMapPtr mgr, + const char *domain, + const char *mac) +{ + int ret; + + virObjectLock(mgr); + ret = virMacMapRemoveLocked(mgr, domain, mac); + virObjectUnlock(mgr); + return ret; +} + + +const char *const * +virMacMapLookup(virMacMapPtr mgr, + const char *domain) +{ + const char *const *ret; + + virObjectLock(mgr); + ret = virHashLookup(mgr->macs, domain); + virObjectUnlock(mgr); + return ret; +} + + +int +virMacMapWriteFile(virMacMapPtr mgr, + const char *filename) +{ + int ret; + + virObjectLock(mgr); + ret = virMacMapWriteFileLocked(mgr, filename); + virObjectUnlock(mgr); + return ret; +} + + +int +virMacMapDumpStr(virMacMapPtr mgr, + char **str) +{ + int ret; + + virObjectLock(mgr); + ret = virMacMapDumpStrLocked(mgr, str); + virObjectUnlock(mgr); + return ret; +} diff --git a/src/util/virmacmap.h b/src/util/virmacmap.h new file mode 100644 index 0000000000..82da833004 --- /dev/null +++ b/src/util/virmacmap.h @@ -0,0 +1,48 @@ +/* + * virmacmap.h: MAC address <-> Domain name mapping + * + * Copyright (C) 2016 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 + * . + * + * Authors: + * Michal Privoznik + */ + +#ifndef __VIR_MACMAP_H__ +# define __VIR_MACMAP_H__ + +typedef struct virMacMap virMacMap; +typedef virMacMap *virMacMapPtr; + +virMacMapPtr virMacMapNew(const char *file); + +int virMacMapAdd(virMacMapPtr mgr, + const char *domain, + const char *mac); + +int virMacMapRemove(virMacMapPtr mgr, + const char *domain, + const char *mac); + +const char *const *virMacMapLookup(virMacMapPtr mgr, + const char *domain); + +int virMacMapWriteFile(virMacMapPtr mgr, + const char *filename); + +int virMacMapDumpStr(virMacMapPtr mgr, + char **str); +#endif /* __VIR_MACMAPPING_H__ */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 6a24861ffe..9d5583d430 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -144,6 +144,7 @@ EXTRA_DIST = \ vircgroupdata \ virconfdata \ virfiledata \ + virmacmaptestdata \ virmock.h \ virnetdaemondata \ virnetdevtestdata \ @@ -191,6 +192,7 @@ test_programs = virshtest sockettest \ domainconftest \ virhostdevtest \ vircaps2xmltest \ + virmacmaptest \ virnetdevtest \ virtypedparamtest \ $(NULL) @@ -406,6 +408,7 @@ test_libraries = libshunload.la \ virhostcpumock.la \ nssmock.la \ domaincapsmock.la \ + virmacmapmock.la \ $(NULL) if WITH_QEMU test_libraries += libqemumonitortestutils.la \ @@ -1137,6 +1140,17 @@ nsslinktest_CFLAGS = \ nsslinktest_LDADD = ../tools/nss/libnss_libvirt_impl.la nsslinktest_LDFLAGS = $(NULL) +virmacmapmock_la_SOURCES = \ + virmacmapmock.c +virmacmapmock_la_CFLAGS = $(AM_CFLAGS) +virmacmapmock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS) +virmacmapmock_la_LIBADD = $(MOCKLIBS_LIBS) + +virmacmaptest_SOURCES = \ + virmacmaptest.c testutils.h testutils.c +virmacmaptest_CLFAGS = $(AM_CFLAGS); +virmacmaptest_LDADD = $(LDADDS) + virnetdevtest_SOURCES = \ virnetdevtest.c testutils.h testutils.c virnetdevtest_CFLAGS = $(AM_CFLAGS) $(LIBNL_CFLAGS) diff --git a/tests/virmacmapmock.c b/tests/virmacmapmock.c new file mode 100644 index 0000000000..d01f1c9e46 --- /dev/null +++ b/tests/virmacmapmock.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2016 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 "virrandom.h" + +uint64_t virRandomBits(int nbits ATTRIBUTE_UNUSED) +{ + return 4; /* chosen by fair dice roll. + guaranteed to be random. */ +} diff --git a/tests/virmacmaptest.c b/tests/virmacmaptest.c new file mode 100644 index 0000000000..34609ad44a --- /dev/null +++ b/tests/virmacmaptest.c @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2016 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" +#include "virmacmap.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +struct testData { + const char *file; + const char *domain; + const char * const * macs; + virMacMapPtr mgr; +}; + + +static int +testMACLookup(const void *opaque) +{ + const struct testData *data = opaque; + virMacMapPtr mgr = NULL; + const char * const * macs; + size_t i, j; + char *file = NULL; + int ret = -1; + + if (virAsprintf(&file, "%s/virmacmaptestdata/%s.json", + abs_srcdir, data->file) < 0) + goto cleanup; + + if (!(mgr = virMacMapNew(file))) + goto cleanup; + + macs = virMacMapLookup(mgr, data->domain); + + for (i = 0; macs && macs[i]; i++) { + for (j = 0; data->macs && data->macs[j]; j++) { + if (STREQ(macs[i], data->macs[j])) + break; + } + + if (!data->macs || !data->macs[j]) { + fprintf(stderr, + "Unexpected %s in the returned list of MACs\n", macs[i]); + goto cleanup; + } + } + + for (i = 0; data->macs && data->macs[i]; i++) { + for (j = 0; macs && macs[j]; j++) { + if (STREQ(data->macs[i], macs[j])) + break; + } + + if (!macs || !macs[j]) { + fprintf(stderr, + "Expected %s in the returned list of MACs\n", data->macs[i]); + goto cleanup; + } + } + + ret = 0; + cleanup: + VIR_FREE(file); + virObjectUnref(mgr); + return ret; +} + + +static int +testMACRemove(const void *opaque) +{ + const struct testData *data = opaque; + virMacMapPtr mgr = NULL; + const char * const * macs; + size_t i; + char *file = NULL; + int ret = -1; + + if (virAsprintf(&file, "%s/virmacmaptestdata/%s.json", + abs_srcdir, data->file) < 0) + goto cleanup; + + if (!(mgr = virMacMapNew(file))) + goto cleanup; + + for (i = 0; data->macs && data->macs[i]; i++) { + if (virMacMapRemove(mgr, data->domain, data->macs[i]) < 0) { + fprintf(stderr, + "Error when removing %s from the list of MACs\n", data->macs[i]); + goto cleanup; + } + } + + if ((macs = virMacMapLookup(mgr, data->domain))) { + fprintf(stderr, + "Not removed all MACs for domain %s: %s\n", data->domain, macs[0]); + goto cleanup; + } + + ret = 0; + cleanup: + VIR_FREE(file); + virObjectUnref(mgr); + return ret; +} + + +static int +testMACFlush(const void *opaque) +{ + const struct testData *data = opaque; + char *file = NULL; + char *str = NULL; + int ret = -1; + + if (virAsprintf(&file, "%s/virmacmaptestdata/%s.json", + abs_srcdir, data->file) < 0) + goto cleanup; + + if (virMacMapDumpStr(data->mgr, &str) < 0) + goto cleanup; + + if (virTestCompareToFile(str, file) < 0) + goto cleanup; + + ret = 0; + cleanup: + VIR_FREE(file); + VIR_FREE(str); + return ret; +} + + +static int +mymain(void) +{ + int ret = 0; + virMacMapPtr mgr = NULL; + +#define DO_TEST_BASIC(f, d, ...) \ + do { \ + const char * const m[] = {__VA_ARGS__, NULL }; \ + struct testData data = {.file = f, .domain = d, .macs = m}; \ + if (virTestRun("Lookup " #d " in " #f, \ + testMACLookup, &data) < 0) \ + ret = -1; \ + if (virTestRun("Remove " #d " in " #f, \ + testMACRemove, &data) < 0) \ + ret = -1; \ + } while (0) + +#define DO_TEST_FLUSH_PROLOGUE \ + if (!(mgr = virMacMapNew(NULL))) \ + ret = -1; + +#define DO_TEST_FLUSH(d, ...) \ + do { \ + const char * const m[] = {__VA_ARGS__, NULL }; \ + size_t i; \ + for (i = 0; m[i]; i++) { \ + if (virMacMapAdd(mgr, d, m[i]) < 0) { \ + virObjectUnref(mgr); \ + mgr = NULL; \ + ret = -1; \ + } \ + } \ + } while (0) + + +#define DO_TEST_FLUSH_EPILOGUE(f) \ + do { \ + struct testData data = {.file = f, .mgr = mgr}; \ + if (virTestRun("Flush " #f, testMACFlush, &data) < 0) \ + ret = -1; \ + virObjectUnref(mgr); \ + mgr = NULL; \ + } while (0) + + DO_TEST_BASIC("empty", "none", NULL); + DO_TEST_BASIC("simple", "f24", "aa:bb:cc:dd:ee:ff"); + DO_TEST_BASIC("simple2", "f24", "aa:bb:cc:dd:ee:ff", "a1:b2:c3:d4:e5:f6"); + DO_TEST_BASIC("simple2", "f25", "00:11:22:33:44:55", "aa:bb:cc:00:11:22"); + + DO_TEST_FLUSH_PROLOGUE; + DO_TEST_FLUSH_EPILOGUE("empty"); + + DO_TEST_FLUSH_PROLOGUE; + DO_TEST_FLUSH("f24", "aa:bb:cc:dd:ee:ff"); + DO_TEST_FLUSH_EPILOGUE("simple"); + + DO_TEST_FLUSH_PROLOGUE; + DO_TEST_FLUSH("f24", "aa:bb:cc:dd:ee:ff", "a1:b2:c3:d4:e5:f6"); + DO_TEST_FLUSH("f25", "00:11:22:33:44:55", "aa:bb:cc:00:11:22"); + DO_TEST_FLUSH_EPILOGUE("simple2"); + + DO_TEST_FLUSH_PROLOGUE; + DO_TEST_FLUSH("dom0", "e1:81:5d:f3:41:57", "76:0a:2a:a0:51:86", "01:c7:fc:01:c7:fc"); + DO_TEST_FLUSH("dom0", "8e:82:53:60:32:4a", "14:7a:25:dc:7d:a0", "f8:d7:75:f8:d7:75"); + DO_TEST_FLUSH("dom0", "73:d2:50:fb:0f:b1", "82:ee:a7:9b:e3:69", "a8:b4:cb:a8:b4:cb"); + DO_TEST_FLUSH("dom0", "7e:81:86:0f:0b:fb", "94:e2:00:d9:4c:70", "dc:7b:83:dc:7b:83"); + DO_TEST_FLUSH("dom0", "d1:19:a5:a1:52:a8", "22:03:a0:bf:cb:4a", "e3:c7:f8:e3:c7:f8"); + DO_TEST_FLUSH("dom0", "aa:bf:3f:4f:21:8d", "28:67:45:72:8f:47", "eb:08:cd:eb:08:cd"); + DO_TEST_FLUSH("dom0", "bd:f8:a7:e5:e2:bd", "c7:80:e3:b9:18:4d", "ce:da:c0:ce:da:c0"); + DO_TEST_FLUSH("dom1", "8b:51:1d:9f:2f:29", "7c:ae:4c:3e:e1:11", "c6:68:4e:98:ff:6a"); + DO_TEST_FLUSH("dom1", "43:0e:33:a1:3f:0f", "7a:3e:ed:bb:15:27", "b1:17:fd:95:d2:1b"); + DO_TEST_FLUSH("dom1", "9e:89:49:99:51:0e", "89:b4:3f:08:88:2c", "54:0b:4c:e2:0a:39"); + DO_TEST_FLUSH("dom1", "bb:88:07:19:51:9d", "b7:f1:1a:40:a2:95", "88:94:39:a3:90:b4"); + DO_TEST_FLUSH_EPILOGUE("complex"); + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virmacmapmock.so") diff --git a/tests/virmacmaptestdata/complex.json b/tests/virmacmaptestdata/complex.json new file mode 100644 index 0000000000..192347c3f1 --- /dev/null +++ b/tests/virmacmaptestdata/complex.json @@ -0,0 +1,45 @@ +[ + { + "domain": "dom0", + "macs": [ + "e1:81:5d:f3:41:57", + "76:0a:2a:a0:51:86", + "01:c7:fc:01:c7:fc", + "8e:82:53:60:32:4a", + "14:7a:25:dc:7d:a0", + "f8:d7:75:f8:d7:75", + "73:d2:50:fb:0f:b1", + "82:ee:a7:9b:e3:69", + "a8:b4:cb:a8:b4:cb", + "7e:81:86:0f:0b:fb", + "94:e2:00:d9:4c:70", + "dc:7b:83:dc:7b:83", + "d1:19:a5:a1:52:a8", + "22:03:a0:bf:cb:4a", + "e3:c7:f8:e3:c7:f8", + "aa:bf:3f:4f:21:8d", + "28:67:45:72:8f:47", + "eb:08:cd:eb:08:cd", + "bd:f8:a7:e5:e2:bd", + "c7:80:e3:b9:18:4d", + "ce:da:c0:ce:da:c0" + ] + }, + { + "domain": "dom1", + "macs": [ + "8b:51:1d:9f:2f:29", + "7c:ae:4c:3e:e1:11", + "c6:68:4e:98:ff:6a", + "43:0e:33:a1:3f:0f", + "7a:3e:ed:bb:15:27", + "b1:17:fd:95:d2:1b", + "9e:89:49:99:51:0e", + "89:b4:3f:08:88:2c", + "54:0b:4c:e2:0a:39", + "bb:88:07:19:51:9d", + "b7:f1:1a:40:a2:95", + "88:94:39:a3:90:b4" + ] + } +] diff --git a/tests/virmacmaptestdata/empty.json b/tests/virmacmaptestdata/empty.json new file mode 100644 index 0000000000..41b42e677b --- /dev/null +++ b/tests/virmacmaptestdata/empty.json @@ -0,0 +1,3 @@ +[ + +] diff --git a/tests/virmacmaptestdata/simple.json b/tests/virmacmaptestdata/simple.json new file mode 100644 index 0000000000..ea0fb08360 --- /dev/null +++ b/tests/virmacmaptestdata/simple.json @@ -0,0 +1,8 @@ +[ + { + "domain": "f24", + "macs": [ + "aa:bb:cc:dd:ee:ff" + ] + } +] diff --git a/tests/virmacmaptestdata/simple2.json b/tests/virmacmaptestdata/simple2.json new file mode 100644 index 0000000000..91b2cde0cd --- /dev/null +++ b/tests/virmacmaptestdata/simple2.json @@ -0,0 +1,16 @@ +[ + { + "domain": "f25", + "macs": [ + "00:11:22:33:44:55", + "aa:bb:cc:00:11:22" + ] + }, + { + "domain": "f24", + "macs": [ + "aa:bb:cc:dd:ee:ff", + "a1:b2:c3:d4:e5:f6" + ] + } +]