X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=southbound%2Fsouthbound-it%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fovsdb%2Fsouthbound%2Fit%2FSouthboundIT.java;h=435efbf16a0eafb40783d87ca4d0e1c7d7570cfc;hb=47d11e4b27a3b25104efb0a1e4d835b76370c767;hp=425ba4c9da7820166853926fd5941225a24d143c;hpb=0e14c9cbe290954fc80d445be1eae085aedbf59d;p=ovsdb.git diff --git a/southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/SouthboundIT.java b/southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/SouthboundIT.java index 425ba4c9d..435efbf16 100644 --- a/southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/SouthboundIT.java +++ b/southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/SouthboundIT.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Red Hat, Inc. and others. All rights reserved. + * Copyright © 2015, 2017 Red Hat, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, @@ -7,53 +7,62 @@ */ package org.opendaylight.ovsdb.southbound.it; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeFalse; import static org.ops4j.pax.exam.CoreOptions.composite; import static org.ops4j.pax.exam.CoreOptions.maven; +import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperties; import static org.ops4j.pax.exam.CoreOptions.vmOption; import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut; import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder; import com.google.common.collect.ImmutableBiMap; +import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; - import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.Set; - -import javax.annotation.Nullable; import javax.inject.Inject; - +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; +import org.junit.internal.AssumptionViolatedException; import org.junit.runner.RunWith; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.DataObjectModification; +import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; +import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; +import org.opendaylight.mdsal.binding.api.DataTreeModification; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.ovsdb.lib.notation.Version; import org.opendaylight.ovsdb.southbound.SouthboundConstants; import org.opendaylight.ovsdb.southbound.SouthboundMapper; -import org.opendaylight.ovsdb.southbound.SouthboundProvider; import org.opendaylight.ovsdb.southbound.SouthboundUtil; import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils; import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase; @@ -65,48 +74,101 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbQueueRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeBase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntryKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigsKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIdsKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.Mappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.MappingsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.MappingsKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIdsKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfigKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIdsKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfigKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldpBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldpKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.Identifiable; +import org.opendaylight.yangtools.yang.binding.Identifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.util.BindingMap; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.common.Uint8; import org.ops4j.pax.exam.Configuration; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; @@ -114,12 +176,13 @@ import org.ops4j.pax.exam.karaf.options.LogLevelOption; import org.ops4j.pax.exam.options.MavenUrlReference; import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; import org.ops4j.pax.exam.spi.reactors.PerClass; +import org.ops4j.pax.exam.util.Filter; import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Integration tests for southbound-impl + * Integration tests for southbound-impl. * * @author Sam Hague (shague@redhat.com) */ @@ -131,13 +194,20 @@ public class SouthboundIT extends AbstractMdsalTestBase { private static final int OVSDB_UPDATE_TIMEOUT = 1000; private static final int OVSDB_ROUNDTRIP_TIMEOUT = 10000; private static final String FORMAT_STR = "%s_%s_%d"; + private static final Version AUTOATTACH_FROM_VERSION = Version.fromString("7.11.2"); + private static final Version IF_INDEX_FROM_VERSION = Version.fromString("7.2.1"); + private static final Uint32 MAX_BACKOFF = Uint32.valueOf(10000); + private static final Uint32 INACTIVITY_PROBE = Uint32.valueOf(30000); private static String addressStr; - private static int portNumber; + private static Uint16 portNumber; private static String connectionType; private static boolean setup = false; private static MdsalUtils mdsalUtils = null; private static Node ovsdbNode; private static int testMethodsRemaining; + private static Version schemaVersion; + @Inject @Filter(timeout = 60000) + private static DataBroker dataBroker = null; @Inject private BundleContext bundleContext; @@ -147,51 +217,122 @@ public class SouthboundIT extends AbstractMdsalTestBase { private static final NotifyingDataChangeListener OPERATIONAL_LISTENER = new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL); - private static class NotifyingDataChangeListener implements DataChangeListener { + + private static final class NotifyingDataChangeListener implements DataTreeChangeListener { + private static final int RETRY_WAIT = 100; + private final LogicalDatastoreType type; private final Set> createdIids = new HashSet<>(); private final Set> removedIids = new HashSet<>(); private final Set> updatedIids = new HashSet<>(); + private final InstanceIdentifier iid; + + private NotifyingDataChangeListener(final LogicalDatastoreType type) { + this.type = type; + this.iid = null; + } - private NotifyingDataChangeListener(LogicalDatastoreType type) { + private NotifyingDataChangeListener(final LogicalDatastoreType type, final InstanceIdentifier iid) { this.type = type; + this.iid = iid; } @Override - public void onDataChanged( - AsyncDataChangeEvent, DataObject> asyncDataChangeEvent) { - LOG.info("{} DataChanged: created {}", type, asyncDataChangeEvent.getCreatedData().keySet()); - LOG.info("{} DataChanged: removed {}", type, asyncDataChangeEvent.getRemovedPaths()); - LOG.info("{} DataChanged: updated {}", type, asyncDataChangeEvent.getUpdatedData().keySet()); - createdIids.addAll(asyncDataChangeEvent.getCreatedData().keySet()); - removedIids.addAll(asyncDataChangeEvent.getRemovedPaths()); - updatedIids.addAll(asyncDataChangeEvent.getUpdatedData().keySet()); - // Handled managed iids - for (DataObject obj : asyncDataChangeEvent.getCreatedData().values()) { - if (obj instanceof ManagedNodeEntry) { - ManagedNodeEntry managedNodeEntry = (ManagedNodeEntry) obj; - LOG.info("{} DataChanged: created managed {}", managedNodeEntry.getBridgeRef().getValue()); - createdIids.add(managedNodeEntry.getBridgeRef().getValue()); + public void onDataTreeChanged(final Collection> changes) { + for (DataTreeModification change: changes) { + DataObjectModification rootNode = change.getRootNode(); + final InstanceIdentifier identifier = change.getRootPath().getRootIdentifier(); + switch (rootNode.getModificationType()) { + case SUBTREE_MODIFIED: + case WRITE: + if (rootNode.getDataBefore() == null) { + LOG.info("{} DataTreeChanged: created {}", type, identifier); + createdIids.add(identifier); + + final DataObject obj = rootNode.getDataAfter(); + if (obj instanceof ManagedNodeEntry) { + ManagedNodeEntry managedNodeEntry = (ManagedNodeEntry) obj; + LOG.info("{} DataChanged: created managed {}", + managedNodeEntry.getBridgeRef().getValue()); + createdIids.add(managedNodeEntry.getBridgeRef().getValue()); + } + } else { + LOG.info("{} DataTreeChanged: updated {}", type, identifier); + updatedIids.add(identifier); + } + break; + case DELETE: + LOG.info("{} DataTreeChanged: removed {}", type, identifier); + removedIids.add(identifier); + break; + default: + break; } } - synchronized(this) { + + synchronized (this) { notifyAll(); } } - public boolean isCreated(InstanceIdentifier iid) { - return createdIids.remove(iid); + public boolean isCreated(final InstanceIdentifier path) { + return createdIids.remove(path); + } + + public boolean isRemoved(final InstanceIdentifier path) { + return removedIids.remove(path); + } + + public boolean isUpdated(final InstanceIdentifier path) { + return updatedIids.remove(path); } - public boolean isRemoved(InstanceIdentifier iid) { - return removedIids.remove(iid); + public void clear() { + createdIids.clear(); + removedIids.clear(); + updatedIids.clear(); } - public boolean isUpdated(InstanceIdentifier iid) { - return updatedIids.remove(iid); + public void registerDataChangeListener() { + dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(type, + (InstanceIdentifier)iid), this); + } + + public void waitForCreation(final long timeout) throws InterruptedException { + synchronized (this) { + long start = System.currentTimeMillis(); + LOG.info("Waiting for {} DataChanged creation on {}", type, iid); + while (!isCreated(iid) && System.currentTimeMillis() - start < timeout) { + wait(RETRY_WAIT); + } + LOG.info("Woke up, waited {}ms for creation of {}", System.currentTimeMillis() - start, iid); + } + } + + public void waitForDeletion(final long timeout) throws InterruptedException { + synchronized (this) { + long start = System.currentTimeMillis(); + LOG.info("Waiting for {} DataChanged deletion on {}", type, iid); + while (!isRemoved(iid) && System.currentTimeMillis() - start < timeout) { + wait(RETRY_WAIT); + } + LOG.info("Woke up, waited {}ms for deletion of {}", System.currentTimeMillis() - start, iid); + } + } + + public void waitForUpdate(final long timeout) throws InterruptedException { + synchronized (this) { + long start = System.currentTimeMillis(); + LOG.info("Waiting for {} DataChanged update on {}", type, iid); + while (!isUpdated(iid) && System.currentTimeMillis() - start < timeout) { + wait(RETRY_WAIT); + } + LOG.info("Woke up, waited {}ms for update of {}", System.currentTimeMillis() - start, iid); + } } } + @Override @Configuration public Option[] config() { Option[] options = super.config(); @@ -205,7 +346,7 @@ public class SouthboundIT extends AbstractMdsalTestBase { return combinedOptions; } - private Option[] getOtherOptions() { + private static Option[] getOtherOptions() { return new Option[] { vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"), keepRuntimeFolder() @@ -222,16 +363,6 @@ public class SouthboundIT extends AbstractMdsalTestBase { .getURL(); } - @Override - public String getModuleName() { - return "southbound-impl"; - } - - @Override - public String getInstanceName() { - return "southbound-default"; - } - @Override public MavenUrlReference getFeatureRepo() { return maven() @@ -262,51 +393,51 @@ public class SouthboundIT extends AbstractMdsalTestBase { super.getLoggingOption()); } - private Option[] getPropertiesOptions() { + private static Option[] getPropertiesOptions() { Properties props = new Properties(System.getProperties()); - String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS, + String ipAddressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS, SouthboundITConstants.DEFAULT_SERVER_IPADDRESS); String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT, SouthboundITConstants.DEFAULT_SERVER_PORT); - String connectionType = props.getProperty(SouthboundITConstants.CONNECTION_TYPE, + String connectionTypeStr = props.getProperty(SouthboundITConstants.CONNECTION_TYPE, SouthboundITConstants.CONNECTION_TYPE_ACTIVE); LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}", - connectionType, addressStr, portStr); + connectionTypeStr, ipAddressStr, portStr); return new Option[] { + propagateSystemProperties( + SouthboundITConstants.SERVER_IPADDRESS, + SouthboundITConstants.SERVER_PORT, + SouthboundITConstants.CONNECTION_TYPE), editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES, - SouthboundITConstants.SERVER_IPADDRESS, addressStr), + SouthboundITConstants.SERVER_IPADDRESS, ipAddressStr), editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES, SouthboundITConstants.SERVER_PORT, portStr), editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES, - SouthboundITConstants.CONNECTION_TYPE, connectionType), + SouthboundITConstants.CONNECTION_TYPE, connectionTypeStr), }; } @Before @Override - public void setup() throws InterruptedException { + public void setup() throws Exception { if (setup) { LOG.info("Skipping setup, already initialized"); return; } - try { - super.setup(); - } catch (Exception e) { - e.printStackTrace(); - } - //dataBroker = getSession().getSALService(DataBroker.class); - Thread.sleep(3000); - DataBroker dataBroker = SouthboundProvider.getDb(); - Assert.assertNotNull("db should not be null", dataBroker); + super.setup(); + assertNotNull("db should not be null", dataBroker); + + LOG.info("sleeping for 10s to let the features finish installing"); + Thread.sleep(10000); addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS); String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT); try { - portNumber = Integer.parseInt(portStr); - } catch (NumberFormatException e) { + portNumber = Uint16.valueOf(portStr); + } catch (IllegalArgumentException e) { fail("Invalid port number " + portStr + System.lineSeparator() + usage()); } connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE); @@ -320,14 +451,19 @@ public class SouthboundIT extends AbstractMdsalTestBase { } mdsalUtils = new MdsalUtils(dataBroker); + assertTrue("Did not find " + SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue(), getOvsdbTopology()); final ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); final InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo); - dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, - iid, CONFIGURATION_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE); - dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, - iid, OPERATIONAL_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE); + dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, + (InstanceIdentifier)iid), CONFIGURATION_LISTENER); + dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, + (InstanceIdentifier)iid), OPERATIONAL_LISTENER); ovsdbNode = connectOvsdbNode(connectionInfo); + OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class); + assertNotNull("The OvsdbNodeAugmentation cannot be null", ovsdbNodeAugmentation); + schemaVersion = Version.fromString(ovsdbNodeAugmentation.getDbVersion()); + LOG.info("schemaVersion = {}", schemaVersion); // Let's count the test methods (we need to use this instead of @AfterClass on teardown() since the latter is // useless with pax-exam) @@ -364,11 +500,33 @@ public class SouthboundIT extends AbstractMdsalTestBase { } } + private static Boolean getOvsdbTopology() { + LOG.info("getOvsdbTopology: looking for {}...", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue()); + Boolean found = false; + final TopologyId topologyId = SouthboundUtils.OVSDB_TOPOLOGY_ID; + InstanceIdentifier path = + InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId)); + for (int i = 0; i < 60; i++) { + Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path); + if (topology != null) { + LOG.info("getOvsdbTopology: found {}...", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue()); + found = true; + break; + } else { + LOG.info("getOvsdbTopology: still looking ({})...", i); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + LOG.warn("Interrupted while waiting for {}", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue(), e); + } + } + } + return found; + } + /** * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms. - * - * @throws InterruptedException */ @Test public void testPassiveNode() throws InterruptedException { @@ -378,16 +536,16 @@ public class SouthboundIT extends AbstractMdsalTestBase { } } - private static ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) { + private static ConnectionInfo getConnectionInfo(final String ipAddressStr, final Uint16 portNum) { InetAddress inetAddress = null; try { - inetAddress = InetAddress.getByName(addressStr); + inetAddress = InetAddress.getByName(ipAddressStr); } catch (UnknownHostException e) { - fail("Could not resolve " + addressStr + ": " + e); + fail("Could not resolve " + ipAddressStr + ": " + e); } IpAddress address = SouthboundMapper.createIpAddress(inetAddress); - PortNumber port = new PortNumber(portNumber); + PortNumber port = new PortNumber(portNum); final ConnectionInfo connectionInfo = new ConnectionInfoBuilder() .setRemoteIp(address) @@ -401,13 +559,11 @@ public class SouthboundIT extends AbstractMdsalTestBase { public void testNetworkTopology() throws InterruptedException { NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(NetworkTopology.class)); - Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION, - networkTopology); + assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION, networkTopology); networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(NetworkTopology.class)); - Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL, - networkTopology); + assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL, networkTopology); } @Test @@ -417,68 +573,66 @@ public class SouthboundIT extends AbstractMdsalTestBase { .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID)); Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path); - Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION, - topology); + assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION, topology); topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path); - Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL, - topology); + assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL, topology); } - private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException { + private static Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException { final InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo); - Assert.assertTrue( + assertTrue( mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, SouthboundUtils.createNode(connectionInfo))); waitForOperationalCreation(iid); Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid); - Assert.assertNotNull(node); + assertNotNull(node); LOG.info("Connected to {}", SouthboundUtils.connectionInfoToString(connectionInfo)); return node; } - private void waitForOperationalCreation(InstanceIdentifier iid) throws InterruptedException { + private static void waitForOperationalCreation(final InstanceIdentifier iid) throws InterruptedException { synchronized (OPERATIONAL_LISTENER) { - long _start = System.currentTimeMillis(); + long start = System.currentTimeMillis(); LOG.info("Waiting for OPERATIONAL DataChanged creation on {}", iid); while (!OPERATIONAL_LISTENER.isCreated( - iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) { + iid) && System.currentTimeMillis() - start < OVSDB_ROUNDTRIP_TIMEOUT) { OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT); } - LOG.info("Woke up, waited {} for creation of {}", (System.currentTimeMillis() - _start), iid); + LOG.info("Woke up, waited {} for creation of {}", System.currentTimeMillis() - start, iid); } } - private static void waitForOperationalDeletion(InstanceIdentifier iid) throws InterruptedException { + private static void waitForOperationalDeletion(final InstanceIdentifier iid) throws InterruptedException { synchronized (OPERATIONAL_LISTENER) { - long _start = System.currentTimeMillis(); + long start = System.currentTimeMillis(); LOG.info("Waiting for OPERATIONAL DataChanged deletion on {}", iid); while (!OPERATIONAL_LISTENER.isRemoved( - iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) { + iid) && System.currentTimeMillis() - start < OVSDB_ROUNDTRIP_TIMEOUT) { OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT); } - LOG.info("Woke up, waited {} for deletion of {}", (System.currentTimeMillis() - _start), iid); + LOG.info("Woke up, waited {} for deletion of {}", System.currentTimeMillis() - start, iid); } } - private void waitForOperationalUpdate(InstanceIdentifier iid) throws InterruptedException { + private static void waitForOperationalUpdate(final InstanceIdentifier iid) throws InterruptedException { synchronized (OPERATIONAL_LISTENER) { - long _start = System.currentTimeMillis(); + long start = System.currentTimeMillis(); LOG.info("Waiting for OPERATIONAL DataChanged update on {}", iid); while (!OPERATIONAL_LISTENER.isUpdated( - iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) { + iid) && System.currentTimeMillis() - start < OVSDB_ROUNDTRIP_TIMEOUT) { OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT); } - LOG.info("Woke up, waited {} for update of {}", (System.currentTimeMillis() - _start), iid); + LOG.info("Woke up, waited {} for update of {}", System.currentTimeMillis() - start, iid); } } private static void disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException { final InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo); - Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid)); + assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid)); waitForOperationalDeletion(iid); Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid); - Assert.assertNull(node); + assertNull(node); LOG.info("Disconnected from {}", SouthboundUtils.connectionInfoToString(connectionInfo)); } @@ -493,12 +647,12 @@ public class SouthboundIT extends AbstractMdsalTestBase { @Test public void testDpdkSwitch() throws InterruptedException { ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); - List datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class) - .getDatapathTypeEntry(); + Map datapathTypeEntries = + ovsdbNode.augmentation(OvsdbNodeAugmentation.class).nonnullDatapathTypeEntry(); if (datapathTypeEntries == null) { LOG.info("DPDK not supported on this node."); } else { - for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) { + for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries.values()) { Class dpType = dpTypeEntry.getDatapathType(); String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType); LOG.info("dp type is {}", dpTypeStr); @@ -512,47 +666,42 @@ public class SouthboundIT extends AbstractMdsalTestBase { null)) { // Verify that the device is netdev OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); - Assert.assertEquals(dpType, bridge.getDatapathType()); + assertNotNull(bridge); + assertEquals(dpType, bridge.getDatapathType()); // Add port for all dpdk interface types (dpdkvhost not supported in existing dpdk ovs) - List dpdkTypes = new ArrayList(); + List dpdkTypes = new ArrayList<>(); dpdkTypes.add("dpdk"); dpdkTypes.add("dpdkr"); dpdkTypes.add("dpdkvhostuser"); //dpdkTypes.add("dpdkvhost"); for (String dpdkType : dpdkTypes) { - String testPortname = "test"+dpdkType+"port"; + String testPortname = "test" + dpdkType + "port"; LOG.info("DPDK portname and type is {}, {}", testPortname, dpdkType); - Class dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP - .get(dpdkType); OvsdbTerminationPointAugmentationBuilder ovsdbTerminationpointBuilder = createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(testPortname, - dpdkIfType); - Assert.assertTrue( - addTerminationPoint(bridgeNodeId, testPortname, ovsdbTerminationpointBuilder)); + SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(dpdkType)); + assertTrue(addTerminationPoint(bridgeNodeId, testPortname, ovsdbTerminationpointBuilder)); } // Verify that all DPDK ports are created InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); + assertNotNull(terminationPointNode); // Verify that each termination point has the specific DPDK ifType for (String dpdkType : dpdkTypes) { - String testPortname = "test"+dpdkType+"port"; - Class dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP - .get(dpdkType); - List terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { + String testPortname = "test" + dpdkType + "port"; + Class dpdkIfType = + SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(dpdkType); + for (TerminationPoint terminationPoint + : terminationPointNode.nonnullTerminationPoint().values()) { OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint - .getAugmentation(OvsdbTerminationPointAugmentation.class); + .augmentation(OvsdbTerminationPointAugmentation.class); if (ovsdbTerminationPointAugmentation.getName().equals(testPortname)) { - Class opPort = ovsdbTerminationPointAugmentation - .getInterfaceType(); - Assert.assertEquals(dpdkIfType, opPort); + assertEquals(dpdkIfType, ovsdbTerminationPointAugmentation.getInterfaceType()); } } } @@ -565,18 +714,26 @@ public class SouthboundIT extends AbstractMdsalTestBase { @Test public void testOvsdbNodeOvsVersion() throws InterruptedException { - OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class); - Assert.assertNotNull(ovsdbNodeAugmentation); + OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class); + assertNotNull(ovsdbNodeAugmentation); assertNotNull(ovsdbNodeAugmentation.getOvsVersion()); } + @Test + public void testOvsdbNodeDbVersion() throws InterruptedException { + OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class); + assertNotNull(ovsdbNodeAugmentation); + assertNotNull(ovsdbNodeAugmentation.getDbVersion()); + } + @Test public void testOpenVSwitchOtherConfig() throws InterruptedException { - OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class); - Assert.assertNotNull(ovsdbNodeAugmentation); - List otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs(); + OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class); + assertNotNull(ovsdbNodeAugmentation); + Map otherConfigsList = + ovsdbNodeAugmentation.getOpenvswitchOtherConfigs(); if (otherConfigsList != null) { - for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) { + for (OpenvswitchOtherConfigs otherConfig : otherConfigsList.values()) { if (otherConfig.getOtherConfigKey().equals("local_ip")) { LOG.info("local_ip: {}", otherConfig.getOtherConfigValue()); break; @@ -594,30 +751,34 @@ public class SouthboundIT extends AbstractMdsalTestBase { ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber); String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode); assertNotNull("Failed to get controller target", controllerTarget); - List setControllerEntry = createControllerEntry(controllerTarget); + ControllerEntry setControllerEntry = createControllerEntry(controllerTarget); Uri setUri = new Uri(controllerTarget); try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, - setControllerEntry, null)) { + BindingMap.of(setControllerEntry), null)) { OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME, bridge); - Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(), - bridge.getControllerEntry()); - List getControllerEntries = bridge.getControllerEntry(); - for (ControllerEntry entry : getControllerEntries) { + assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME, bridge); + assertNotNull("ControllerEntry was not found: " + setControllerEntry, bridge.getControllerEntry()); + for (ControllerEntry entry : bridge.getControllerEntry().values()) { if (entry.getTarget() != null) { - Assert.assertEquals(setUri.toString(), entry.getTarget().toString()); + assertEquals(setUri.toString(), entry.getTarget().toString()); + } + if (entry.getMaxBackoff() != null) { + assertEquals(MAX_BACKOFF, entry.getMaxBackoff()); + } + if (entry.getInactivityProbe() != null) { + assertEquals(INACTIVITY_PROBE, entry.getInactivityProbe()); } } } } - private List createControllerEntry(String controllerTarget) { - List controllerEntriesList = new ArrayList<>(); - controllerEntriesList.add(new ControllerEntryBuilder() + private static @NonNull ControllerEntry createControllerEntry(final String controllerTarget) { + return new ControllerEntryBuilder() .setTarget(new Uri(controllerTarget)) - .build()); - return controllerEntriesList; + .setMaxBackoff(MAX_BACKOFF) + .setInactivityProbe(INACTIVITY_PROBE) + .build(); } private static void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder, @@ -626,15 +787,13 @@ public class SouthboundIT extends AbstractMdsalTestBase { ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath)); } - private static List createMdsalProtocols() { - List protocolList = new ArrayList<>(); + private static Map createMdsalProtocols() { ImmutableBiMap> mapper = SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse(); - protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build()); - return protocolList; + return BindingMap.of(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build()); } - private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() { + private static OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() { OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); ovsdbTerminationPointAugmentationBuilder.setInterfaceType( @@ -645,7 +804,7 @@ public class SouthboundIT extends AbstractMdsalTestBase { return ovsdbTerminationPointAugmentationBuilder; } - private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder( + private static OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder( final String portName) { OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = createGenericOvsdbTerminationPointAugmentationBuilder(); @@ -656,32 +815,27 @@ public class SouthboundIT extends AbstractMdsalTestBase { return ovsdbTerminationBuilder; } - private OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder( - String testPortname,Class dpdkIfType) { - OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = - createGenericOvsdbTerminationPointAugmentationBuilder(); - ovsdbTerminationBuilder.setName(testPortname); - ovsdbTerminationBuilder.setInterfaceType(dpdkIfType); - return ovsdbTerminationBuilder; + private static OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder( + final String testPortname, final Class dpdkIfType) { + return createGenericOvsdbTerminationPointAugmentationBuilder() + .setName(testPortname) + .setInterfaceType(dpdkIfType); } - private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName, - final OvsdbTerminationPointAugmentationBuilder - ovsdbTerminationPointAugmentationBuilder) + private static boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName, + final OvsdbTerminationPointAugmentationBuilder + ovsdbTerminationPointAugmentationBuilder) throws InterruptedException { InstanceIdentifier portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId); NodeBuilder portNodeBuilder = new NodeBuilder(); NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid); portNodeBuilder.setNodeId(portNodeId); - TerminationPointBuilder entry = new TerminationPointBuilder(); - entry.setKey(new TerminationPointKey(new TpId(portName))); - entry.addAugmentation( - OvsdbTerminationPointAugmentation.class, - ovsdbTerminationPointAugmentationBuilder.build()); - portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build())); - boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, - portIid, portNodeBuilder.build()); + TerminationPointBuilder entry = new TerminationPointBuilder() + .withKey(new TerminationPointKey(new TpId(portName))) + .addAugmentation(ovsdbTerminationPointAugmentationBuilder.build()); + portNodeBuilder.setTerminationPoint(BindingMap.of(entry.build())); + boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portNodeBuilder.build()); Thread.sleep(OVSDB_UPDATE_TIMEOUT); return result; } @@ -704,13 +858,13 @@ public class SouthboundIT extends AbstractMdsalTestBase { * @param externalIds The external identifiers if any. * @param otherConfigs The other configuration items if any. */ - public TestBridge(final ConnectionInfo connectionInfo, @Nullable InstanceIdentifier bridgeIid, + TestBridge(final ConnectionInfo connectionInfo, @Nullable InstanceIdentifier bridgeIid, final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries, final Class failMode, final boolean setManagedBy, @Nullable final Class dpType, - @Nullable final List externalIds, - @Nullable final List controllerEntries, - @Nullable final List otherConfigs) { + @Nullable final Map externalIds, + @Nullable final Map controllerEntries, + @Nullable final Map otherConfigs) { this.connectionInfo = connectionInfo; this.bridgeName = bridgeName; NodeBuilder bridgeNodeBuilder = new NodeBuilder(); @@ -734,10 +888,9 @@ public class SouthboundIT extends AbstractMdsalTestBase { ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds); ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries); ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs); - bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build()); - LOG.debug("Built with the intent to store bridge data {}", ovsdbBridgeAugmentationBuilder.toString()); - Assert.assertTrue( - mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build())); + bridgeNodeBuilder.addAugmentation(ovsdbBridgeAugmentationBuilder.build()); + LOG.debug("Built with the intent to store bridge data {}", ovsdbBridgeAugmentationBuilder); + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build())); try { Thread.sleep(OVSDB_UPDATE_TIMEOUT); } catch (InterruptedException e) { @@ -745,7 +898,7 @@ public class SouthboundIT extends AbstractMdsalTestBase { } } - public TestBridge(final ConnectionInfo connectionInfo, final String bridgeName) { + TestBridge(final ConnectionInfo connectionInfo, final String bridgeName) { this(connectionInfo, null, bridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null); } @@ -754,7 +907,7 @@ public class SouthboundIT extends AbstractMdsalTestBase { public void close() { final InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)); - Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid)); + assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid)); try { Thread.sleep(OVSDB_UPDATE_TIMEOUT); } catch (InterruptedException e) { @@ -763,7 +916,312 @@ public class SouthboundIT extends AbstractMdsalTestBase { } } - private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) { + private static class TestAutoAttach implements AutoCloseable { + private final ConnectionInfo connectionInfo; + private final Uri autoattachId; + private final Uri bridgeId; + + TestAutoAttach(final ConnectionInfo connectionInfo, + final Uri autoattachId, + final Uri bridgeId, + @Nullable final String systemName, + @Nullable final String systemDescription, + @Nullable final Map mappings, + @Nullable final Map externalIds) { + this.connectionInfo = connectionInfo; + this.autoattachId = autoattachId; + this.bridgeId = bridgeId; + + Autoattach aaEntry = new AutoattachBuilder() + .setAutoattachId(autoattachId) + .setBridgeId(bridgeId) + .setSystemName(systemName) + .setSystemDescription(systemDescription) + .setMappings(mappings) + .setAutoattachExternalIds(externalIds) + .build(); + InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Autoattach.class, aaEntry.key()); + final NotifyingDataChangeListener aaOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid); + aaOperationalListener.registerDataChangeListener(); + + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, aaEntry)); + try { + aaOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for queue {}", iid, e); + } + } + + @Override + public void close() { + final InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Autoattach.class, new AutoattachKey(this.autoattachId)); + final NotifyingDataChangeListener aaOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid); + aaOperationalListener.registerDataChangeListener(); + + assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid)); + try { + aaOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", iid, e); + } + } + } + + @Test + public void testCRUDAutoAttach() throws InterruptedException { + final boolean isOldSchema = schemaVersion.compareTo(AUTOATTACH_FROM_VERSION) < 0; + + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + String testAutoattachId = "testAutoattachEntry"; + String testSystemName = "testSystemName"; + String testSystemDescription = "testSystemDescription"; + String testAutoattachExternalKey = "testAutoattachExternalKey"; + String testAutoattachExternalValue = "testAutoattachExternalValue"; + + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + assertNotNull(bridge); + + // CREATE: Create Autoattach table + NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( + connectionInfo, bridge.getBridgeName())); + String bridgeId = nodeId.getValue(); + try (TestAutoAttach testAutoattach = new TestAutoAttach(connectionInfo, new Uri(testAutoattachId), + new Uri(bridgeId), testSystemName, testSystemDescription, null, null)) { + // READ: Read md-sal operational datastore to see if the AutoAttach table was created + // and if Bridge table was updated with AutoAttach Uuid + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Autoattach operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId)); + + // skip tests after verifying that Autoattach doesn't break with unsupported schema + assumeFalse(isOldSchema); + + // FIXME: Remove once CRUD is supported + assumeFalse(operAa == null); + + assertNotNull(operAa); + assertEquals(testSystemName, operAa.getSystemName()); + bridge = getBridge(connectionInfo); + Uuid aaUuid = new Uuid(operAa.getAutoattachUuid().getValue()); + assertEquals(aaUuid, bridge.getAutoAttach()); + + // UPDATE: Update mappings column of AutoAttach table that was created + Map mappings = BindingMap.of(new MappingsBuilder() + .setMappingsKey(Uint32.valueOf(100)) + .setMappingsValue(Uint16.valueOf(200)) + .build()); + Autoattach updatedAa = new AutoattachBuilder() + .setAutoattachId(new Uri(testAutoattachId)) + .setMappings(mappings) + .build(); + InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Autoattach.class, updatedAa.key()); + final NotifyingDataChangeListener aaOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid); + aaOperationalListener.registerDataChangeListener(); + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, updatedAa)); + aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // UPDATE: Update external_ids column of AutoAttach table that was created + BindingMap.Builder externalIds = BindingMap.builder(); + externalIds.add(new AutoattachExternalIdsBuilder() + .setAutoattachExternalIdKey(testAutoattachExternalKey) + .setAutoattachExternalIdValue(testAutoattachExternalValue) + .build()); + updatedAa = new AutoattachBuilder() + .setAutoattachId(new Uri(testAutoattachId)) + .setAutoattachExternalIds(externalIds.build()) + .build(); + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, updatedAa)); + aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: Read the updated AutoAttach table for latest mappings and external_ids column value + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId)); + assertNotNull(operAa); + Map operMappingsList = operAa.getMappings(); + for (Mappings operMappings : operMappingsList.values()) { + assertTrue(mappings.containsValue(operMappings)); + } + Map operExternalIds = + operAa.getAutoattachExternalIds(); + final Collection ids = externalIds.add(new AutoattachExternalIdsBuilder() + .setAutoattachExternalIdKey(SouthboundConstants.AUTOATTACH_ID_EXTERNAL_ID_KEY) + .setAutoattachExternalIdValue(operAa.getAutoattachId().getValue()) + .build()) + .build().values(); + + for (AutoattachExternalIds operExternalId : operExternalIds.values()) { + assertTrue(ids.contains(operExternalId)); + } + + // DELETE: Delete AutoAttach table + assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid)); + aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, LogicalDatastoreType.OPERATIONAL); + operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId)); + assertNull(operAa); + } catch (AssumptionViolatedException e) { + LOG.warn("Skipped test for Autoattach due to unsupported schema", e); + } + } + } + + private static Autoattach getAutoAttach(final OvsdbNodeAugmentation ovsdbNodeAugmentation, final Uri uri) { + for (Autoattach aa : ovsdbNodeAugmentation.nonnullAutoattach().values()) { + if (aa.key().getAutoattachId().equals(uri)) { + return aa; + } + } + return null; + } + + private static class TestQos implements AutoCloseable { + private final ConnectionInfo connectionInfo; + private final Uri qosId; + + /** + * Creates a test qos entry which can be automatically removed when no longer necessary. + * + * @param connectionInfo The connection information. + * @param qosId The Qos identifier. + * @param qosType The qos type. + * @param externalIds The external identifiers if any. + * @param otherConfigs The other configuration items if any. + */ + TestQos(final ConnectionInfo connectionInfo, + final Uri qosId, + final Class qosType, + final @Nullable Map externalIds, + final @Nullable Map otherConfigs) { + this.connectionInfo = connectionInfo; + this.qosId = qosId; + + QosEntries qosEntry = new QosEntriesBuilder() + .setQosId(qosId) + .setQosType(qosType) + .setQosExternalIds(externalIds) + .setQosOtherConfig(otherConfigs) + .build(); + InstanceIdentifier qeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(QosEntries.class, qosEntry.key()); + final NotifyingDataChangeListener qosOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qeIid); + qosOperationalListener.registerDataChangeListener(); + + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, qeIid, qosEntry)); + + try { + qosOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for queue {}", qeIid, e); + } + + } + + @Override + public void close() { + final InstanceIdentifier qeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(QosEntries.class, new QosEntriesKey(this.qosId)); + final NotifyingDataChangeListener qosOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qeIid); + qosOperationalListener.registerDataChangeListener(); + + assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qeIid)); + try { + qosOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", qeIid, e); + } + } + } + + private static class TestQueue implements AutoCloseable { + private final ConnectionInfo connectionInfo; + private final Uri queueId; + private final InstanceIdentifier queueIid; + + /** + * Creates a test queue entry which can be automatically removed when no longer necessary. + * + * @param connectionInfo The connection information. + * @param queueId The Queue identifier. + * @param queueDscp The queue dscp value. + * @param externalIds The external identifiers if any. + * @param otherConfigs The other configuration items if any. + */ + TestQueue(final ConnectionInfo connectionInfo, final Uri queueId, final Uint8 queueDscp, + final @Nullable Map externalIds, + final @Nullable Map otherConfigs) { + this.connectionInfo = connectionInfo; + this.queueId = queueId; + + Queues queue = new QueuesBuilder() + .setQueueId(queueId) + .setDscp(queueDscp) + .setQueuesExternalIds(externalIds) + .setQueuesOtherConfig(otherConfigs) + .build(); + queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Queues.class, queue.key()); + final NotifyingDataChangeListener queueOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid); + queueOperationalListener.registerDataChangeListener(); + + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, queueIid, queue)); + + try { + queueOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for queue {}", queueId, e); + } + } + + public InstanceIdentifier getInstanceIdentifier() { + return queueIid; + } + + @Override + public void close() { + InstanceIdentifier queuesIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Queues.class, new QueuesKey(this.queueId)); + final NotifyingDataChangeListener queueOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queuesIid); + queueOperationalListener.registerDataChangeListener(); + + assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, queuesIid)); + try { + queueOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for queue deletion (queue {})", queueId, e); + } + } + } + + private static OvsdbNodeAugmentation getOvsdbNode(final ConnectionInfo connectionInfo, + final LogicalDatastoreType store) { + InstanceIdentifier nodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo); + Node node = mdsalUtils.read(store, nodeIid); + assertNotNull(node); + OvsdbNodeAugmentation ovsdbNodeAugmentation = node.augmentation(OvsdbNodeAugmentation.class); + assertNotNull(ovsdbNodeAugmentation); + return ovsdbNodeAugmentation; + } + + private static OvsdbBridgeAugmentation getBridge(final ConnectionInfo connectionInfo) { return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME); } @@ -776,38 +1234,39 @@ public class SouthboundIT extends AbstractMdsalTestBase { * @param store defined by the LogicalDatastoreType enumeration * @return store type data store contents */ - private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName, - LogicalDatastoreType store) { + private static OvsdbBridgeAugmentation getBridge(final ConnectionInfo connectionInfo, final String bridgeName, + final LogicalDatastoreType store) { Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store); - Assert.assertNotNull(bridgeNode); - OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class); - Assert.assertNotNull(ovsdbBridgeAugmentation); + assertNotNull(bridgeNode); + OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.augmentation(OvsdbBridgeAugmentation.class); + assertNotNull(ovsdbBridgeAugmentation); return ovsdbBridgeAugmentation; } /** * extract the LogicalDataStoreType.OPERATIONAL type data store contents for the particular bridge - * identified by bridgeName + * identified by bridgeName. * * @param connectionInfo the connection information * @param bridgeName the bridge name - * @see SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType) + * @see SouthboundIT#getBridge(ConnectionInfo, String, LogicalDatastoreType) * @return LogicalDatastoreType.OPERATIONAL type data store contents */ - private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) { + private static OvsdbBridgeAugmentation getBridge(final ConnectionInfo connectionInfo, final String bridgeName) { return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL); } /** * Extract the node contents from store type data store for the - * bridge identified by bridgeName + * bridge identified by bridgeName. * * @param connectionInfo the connection information * @param bridgeName the bridge name * @param store defined by the LogicalDatastoreType enumeration * @return store type data store contents */ - private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) { + private static Node getBridgeNode(final ConnectionInfo connectionInfo, final String bridgeName, + final LogicalDatastoreType store) { InstanceIdentifier bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)); return mdsalUtils.read(store, bridgeIid); @@ -815,13 +1274,13 @@ public class SouthboundIT extends AbstractMdsalTestBase { /** * Extract the node contents from LogicalDataStoreType.OPERATIONAL data store for the - * bridge identified by bridgeName + * bridge identified by bridgeName. * * @param connectionInfo the connection information * @param bridgeName the bridge name * @return LogicalDatastoreType.OPERATIONAL type data store contents */ - private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) { + private static Node getBridgeNode(final ConnectionInfo connectionInfo, final String bridgeName) { return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL); } @@ -831,18 +1290,19 @@ public class SouthboundIT extends AbstractMdsalTestBase { try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); + assertNotNull(bridge); LOG.info("bridge: {}", bridge); } } - private InstanceIdentifier getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) { + private static InstanceIdentifier getTpIid(final ConnectionInfo connectionInfo, + final OvsdbBridgeAugmentation bridge) { return SouthboundUtils.createInstanceIdentifier(connectionInfo, bridge.getBridgeName()); } /** * Extracts the TerminationPointAugmentation for the index TerminationPoint - * on bridgeName + * on bridgeName. * * @param connectionInfo the connection information * @param bridgeName the bridge name @@ -850,26 +1310,66 @@ public class SouthboundIT extends AbstractMdsalTestBase { * @param index the index we're interested in * @return the augmentation (or {@code null} if none) */ - private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation( - ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) { + private static OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation( + final ConnectionInfo connectionInfo, final String bridgeName, final LogicalDatastoreType store, + final int index) { - List tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint(); + Map tpList = getBridgeNode(connectionInfo, bridgeName, store) + .getTerminationPoint(); if (tpList == null) { return null; } - return tpList.get(index).getAugmentation(OvsdbTerminationPointAugmentation.class); + return Iterables.get(tpList.values(), index).augmentation(OvsdbTerminationPointAugmentation.class); + } + + @Test + public void testCRUDTerminationPointIfIndex() throws InterruptedException { + final boolean isOldSchema = schemaVersion.compareTo(IF_INDEX_FROM_VERSION) < 0; + assumeFalse(isOldSchema); + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + + // Test create ifIndex + try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME, null, true, + SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), + true, SouthboundMapper.createDatapathType("netdev"), null, null, null)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + assertNotNull(bridge); + LOG.info("bridge: {}", bridge); + NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( + connectionInfo, bridge.getBridgeName())); + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); + String portName = "testIfIndex"; + ovsdbTerminationBuilder.setName(portName); + + assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); + Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + assertNotNull(terminationPointNode); + + // Test read ifIndex + for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) { + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = + terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class); + if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { + Long ifIndex = ovsdbTerminationPointAugmentation.getIfindex().toJava(); + assertNotNull(ifIndex); + LOG.info("ifIndex: {} for the port:{}", ifIndex, portName); + } + } + } } @Test public void testCRDTerminationPointOfPort() throws InterruptedException { - final Long OFPORT_EXPECTED = 45002L; + final Uint32 ofportExpected = Uint32.valueOf(45002); ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); // CREATE try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); + assertNotNull(bridge); LOG.info("bridge: {}", bridge); NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( connectionInfo, bridge.getBridgeName())); @@ -878,28 +1378,27 @@ public class SouthboundIT extends AbstractMdsalTestBase { String portName = "testOfPort"; ovsdbTerminationBuilder.setName(portName); - ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED); - Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + ovsdbTerminationBuilder.setOfport(ofportExpected); + assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); + assertNotNull(terminationPointNode); // READ - List terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { + for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) { OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class); if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { - Long ofPort = ovsdbTerminationPointAugmentation.getOfport(); + Uint32 ofPort = ovsdbTerminationPointAugmentation.getOfport(); // if ephemeral port 45002 is in use, ofPort is set to 1 - Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L)); + assertTrue(ofPort.equals(ofportExpected) || ofPort.equals(Uint32.ONE)); LOG.info("ofPort: {}", ofPort); } } // UPDATE- Not Applicable. From the OpenVSwitch Documentation: - // "A client should ideally set this column’s value in the same database transaction that it uses to create - // the interface." + // "A client should ideally set this column’s value in the same database transaction that it uses to + // create the interface." // DELETE handled by TestBridge } @@ -907,42 +1406,41 @@ public class SouthboundIT extends AbstractMdsalTestBase { @Test public void testCRDTerminationPointOfPortRequest() throws InterruptedException { - final Long OFPORT_EXPECTED = 45008L; - final Long OFPORT_INPUT = 45008L; + final Uint32 ofportExpected = Uint32.valueOf(45008); + final Uint32 ofportInput = Uint32.valueOf(45008); ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); // CREATE try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); - NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( + assertNotNull(bridge); + final NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( connectionInfo, bridge.getBridgeName())); OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = createGenericOvsdbTerminationPointAugmentationBuilder(); String portName = "testOfPortRequest"; ovsdbTerminationBuilder.setName(portName); - Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue(); - ovsdbTerminationBuilder.setOfport(OFPORT_INPUT); + Uint16 ofPortRequestExpected = ofportExpected.toUint16(); + ovsdbTerminationBuilder.setOfport(ofportInput); ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected); - Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); + assertNotNull(terminationPointNode); // READ - List terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { + for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) { OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class); if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { - Long ofPort = ovsdbTerminationPointAugmentation.getOfport(); + Uint32 ofPort = ovsdbTerminationPointAugmentation.getOfport(); // if ephemeral port 45008 is in use, ofPort is set to 1 - Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L)); + assertTrue(ofPort.equals(ofportExpected) || ofPort.equals(Uint32.ONE)); LOG.info("ofPort: {}", ofPort); - Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest(); - Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected)); + Uint16 ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest(); + assertEquals(ofPortRequestExpected, ofPortRequest); LOG.info("ofPortRequest: {}", ofPortRequest); } } @@ -955,17 +1453,19 @@ public class SouthboundIT extends AbstractMdsalTestBase { } } - private void assertExpectedExist(List expected, List test) { + private static , T extends Identifiable> void assertExpectedExist( + final Map expected, final Map test) { if (expected != null && test != null) { - for (T exp : expected) { - Assert.assertTrue("The retrieved values don't contain " + exp, test.contains(exp)); + for (T exp : expected.values()) { + assertTrue("The retrieved values don't contain " + exp, test.containsValue(exp)); } } } - private interface SouthboundTerminationPointHelper { - void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List values); - List readValues(OvsdbTerminationPointAugmentation augmentation); + private interface SouthboundTerminationPointHelper, T extends Identifiable> { + void writeValues(OvsdbTerminationPointAugmentationBuilder builder, Map values); + + Map readValues(OvsdbTerminationPointAugmentation augmentation); } /* @@ -973,20 +1473,20 @@ public class SouthboundIT extends AbstractMdsalTestBase { * * @see SouthboundIT.generatePortExternalIdsTestCases() for specific test case information */ - private void testCRUDTerminationPoint( - KeyValueBuilder builder, String prefix, SouthboundTerminationPointHelper helper) + private static , T extends Identifiable> void testCRUDTerminationPoint( + final KeyValueBuilder builder, final String prefix, final SouthboundTerminationPointHelper helper) throws InterruptedException { - final int TERMINATION_POINT_TEST_INDEX = 0; + final int terminationPointTestIndex = 0; ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after // the update has been performed. - List> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From"); - List> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To"); + List> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From"); + List> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To"); - for (SouthboundTestCase updateFromTestCase : updateFromTestCases) { - for (SouthboundTestCase updateToTestCase : updateToTestCases) { + for (SouthboundTestCase updateFromTestCase : updateFromTestCases) { + for (SouthboundTestCase updateToTestCase : updateToTestCases) { String testBridgeAndPortName = String.format("%s_%s", prefix, updateToTestCase.name); // CREATE: Create the test bridge @@ -1000,24 +1500,24 @@ public class SouthboundIT extends AbstractMdsalTestBase { createGenericOvsdbTerminationPointAugmentationBuilder(); tpCreateAugmentationBuilder.setName(testBridgeAndPortName); helper.writeValues(tpCreateAugmentationBuilder, updateFromTestCase.inputValues); - Assert.assertTrue( + assertTrue( addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder)); // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store, // then repeat for OPERATIONAL data store OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation = getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName, - LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX); + LogicalDatastoreType.CONFIGURATION, terminationPointTestIndex); if (updateFromConfigurationTerminationPointAugmentation != null) { - List updateFromConfigurationValues = + Map updateFromConfigurationValues = helper.readValues(updateFromConfigurationTerminationPointAugmentation); assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues); } OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation = getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName, - LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX); + LogicalDatastoreType.OPERATIONAL, terminationPointTestIndex); if (updateFromOperationalTerminationPointAugmentation != null) { - List updateFromOperationalValues = + Map updateFromOperationalValues = helper.readValues(updateFromOperationalTerminationPointAugmentation); assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues); } @@ -1032,12 +1532,10 @@ public class SouthboundIT extends AbstractMdsalTestBase { NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid); portUpdateNodeBuilder.setNodeId(portUpdateNodeId); TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder(); - tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName))); - tpUpdateBuilder.addAugmentation( - OvsdbTerminationPointAugmentation.class, - tpUpdateAugmentationBuilder.build()); - portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build())); - Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(testBridgeAndPortName))); + tpUpdateBuilder.addAugmentation(tpUpdateAugmentationBuilder.build()); + portUpdateNodeBuilder.setTerminationPoint(BindingMap.of(tpUpdateBuilder.build())); + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build())); Thread.sleep(OVSDB_UPDATE_TIMEOUT); @@ -1045,18 +1543,18 @@ public class SouthboundIT extends AbstractMdsalTestBase { // then repeat for OPERATIONAL data store OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation = getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName, - LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX); + LogicalDatastoreType.CONFIGURATION, terminationPointTestIndex); if (updateToConfigurationTerminationPointAugmentation != null) { - List updateToConfigurationValues = + Map updateToConfigurationValues = helper.readValues(updateToConfigurationTerminationPointAugmentation); assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues); assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationValues); } OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation = getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName, - LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX); + LogicalDatastoreType.OPERATIONAL, terminationPointTestIndex); if (updateToOperationalTerminationPointAugmentation != null) { - List updateToOperationalValues = + Map updateToOperationalValues = helper.readValues(updateToOperationalTerminationPointAugmentation); if (updateFromTestCase.expectedValues != null) { assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues); @@ -1092,6 +1590,17 @@ public class SouthboundIT extends AbstractMdsalTestBase { new InterfaceExternalIdsSouthboundHelper()); } + /* + * Tests the CRUD operations for Interface lldp. + * + * @see SouthboundIT.generateInterfaceLldpTestCases() for specific test case information + */ + @Test + public void testCRUDTerminationPointInterfaceLldp() throws InterruptedException { + testCRUDTerminationPoint(new SouthboundInterfaceLldpBuilder(), "TPInterfaceLldp", + new InterfaceLldpSouthboundHelper()); + } + /* * Tests the CRUD operations for TerminationPoint options. * @@ -1124,40 +1633,121 @@ public class SouthboundIT extends AbstractMdsalTestBase { new PortOtherConfigsSouthboundHelper()); } + @Test + public void testCRUDTerminationPoints() throws InterruptedException { + String port1 = "vx1"; + String port2 = "vxlanport"; + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME); + assertNotNull(bridge); + NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( + connectionInfo, bridge.getBridgeName())); + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); + + // add and delete a single port + String portName = port1; + ovsdbTerminationBuilder.setName(portName); + assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); + Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + assertNotNull(terminationPointNode); + + SouthboundUtils.createInstanceIdentifier(connectionInfo, + new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME)); + portName = port1; + InstanceIdentifier nodePath = + SouthboundUtils.createInstanceIdentifier(connectionInfo, + new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME)) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName))); + + assertTrue("failed to delete port " + portName, + mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath)); + LOG.info("shague: waiting for delete {}", portName); + Thread.sleep(1000); + TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath); + assertNull(terminationPoint); + + // add two ports, then delete them + portName = port1; + ovsdbTerminationBuilder.setName(portName); + assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + terminationPointIid = getTpIid(connectionInfo, bridge); + terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + assertNotNull(terminationPointNode); + + portName = port2; + ovsdbTerminationBuilder.setName(portName); + assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + terminationPointIid = getTpIid(connectionInfo, bridge); + terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + assertNotNull(terminationPointNode); + + SouthboundUtils.createInstanceIdentifier(connectionInfo, + new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME)); + portName = port1; + nodePath = + SouthboundUtils.createInstanceIdentifier(connectionInfo, + new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME)) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName))); + + assertTrue("failed to delete port " + portName, + mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath)); + LOG.info("shague: waiting for delete {}", portName); + Thread.sleep(1000); + terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath); + assertNull(terminationPoint); + + portName = port2; + nodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo, + new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME)) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName))); + + assertTrue("failed to delete port " + portName, + mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath)); + LOG.info("shague: waiting for delete {}", portName); + Thread.sleep(1000); + terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath); + assertNull(terminationPoint); + + // DELETE handled by TestBridge + } + } + @Test public void testCRUDTerminationPointVlan() throws InterruptedException { - final Integer CREATED_VLAN_ID = 4000; - final Integer UPDATED_VLAN_ID = 4001; + final Uint16 createdVlanId = Uint16.valueOf(4000); + final Uint16 updatedVlanId = Uint16.valueOf(4001); ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); // CREATE try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME); - Assert.assertNotNull(bridge); + assertNotNull(bridge); NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( connectionInfo, bridge.getBridgeName())); OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = createGenericOvsdbTerminationPointAugmentationBuilder(); String portName = "testTerminationPointVlanId"; ovsdbTerminationBuilder.setName(portName); - ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID)); - Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + ovsdbTerminationBuilder.setVlanTag(new VlanId(createdVlanId)); + assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); + assertNotNull(terminationPointNode); // READ - List terminationPoints = terminationPointNode.getTerminationPoint(); OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation; - for (TerminationPoint terminationPoint : terminationPoints) { - ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation( + for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) { + ovsdbTerminationPointAugmentation = terminationPoint.augmentation( OvsdbTerminationPointAugmentation.class); if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag(); - Assert.assertNotNull(actualVlanId); - Integer actualVlanIdInt = actualVlanId.getValue(); - Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt); + assertNotNull(actualVlanId); + assertEquals(createdVlanId, actualVlanId.getValue()); } } @@ -1165,32 +1755,28 @@ public class SouthboundIT extends AbstractMdsalTestBase { NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId(); OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); - tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID)); + tpUpdateAugmentationBuilder.setVlanTag(new VlanId(updatedVlanId)); InstanceIdentifier portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId); NodeBuilder portUpdateNodeBuilder = new NodeBuilder(); NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid); portUpdateNodeBuilder.setNodeId(portUpdateNodeId); TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder(); - tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName))); - tpUpdateBuilder.addAugmentation( - OvsdbTerminationPointAugmentation.class, - tpUpdateAugmentationBuilder.build()); + tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName))); + tpUpdateBuilder.addAugmentation(tpUpdateAugmentationBuilder.build()); tpUpdateBuilder.setTpId(new TpId(portName)); - portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build())); - Assert.assertTrue( + portUpdateNodeBuilder.setTerminationPoint(BindingMap.of(tpUpdateBuilder.build())); + assertTrue( mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build())); Thread.sleep(OVSDB_UPDATE_TIMEOUT); terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { - ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation( + for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) { + ovsdbTerminationPointAugmentation = terminationPoint.augmentation( OvsdbTerminationPointAugmentation.class); if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag(); - Assert.assertNotNull(actualVlanId); - Integer actualVlanIdInt = actualVlanId.getValue(); - Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt); + assertNotNull(actualVlanId); + assertEquals(updatedVlanId, actualVlanId.getValue()); } } @@ -1200,14 +1786,14 @@ public class SouthboundIT extends AbstractMdsalTestBase { @Test public void testCRUDTerminationPointVlanModes() throws InterruptedException { - final VlanMode UPDATED_VLAN_MODE = VlanMode.Access; + final VlanMode updatedVlanMode = VlanMode.Access; ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); VlanMode []vlanModes = VlanMode.values(); for (VlanMode vlanMode : vlanModes) { // CREATE try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); + assertNotNull(bridge); NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( connectionInfo, bridge.getBridgeName())); OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = @@ -1215,19 +1801,18 @@ public class SouthboundIT extends AbstractMdsalTestBase { String portName = "testTerminationPointVlanMode" + vlanMode.toString(); ovsdbTerminationBuilder.setName(portName); ovsdbTerminationBuilder.setVlanMode(vlanMode); - Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); + assertNotNull(terminationPointNode); // READ - List terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { + for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) { OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class); if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { //test - Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode)); + assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode)); } } @@ -1235,30 +1820,27 @@ public class SouthboundIT extends AbstractMdsalTestBase { NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId(); OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); - tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE); + tpUpdateAugmentationBuilder.setVlanMode(updatedVlanMode); InstanceIdentifier portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId); NodeBuilder portUpdateNodeBuilder = new NodeBuilder(); NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid); portUpdateNodeBuilder.setNodeId(portUpdateNodeId); TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder(); - tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName))); - tpUpdateBuilder.addAugmentation( - OvsdbTerminationPointAugmentation.class, - tpUpdateAugmentationBuilder.build()); + tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName))); + tpUpdateBuilder.addAugmentation(tpUpdateAugmentationBuilder.build()); tpUpdateBuilder.setTpId(new TpId(portName)); - portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build())); - Assert.assertTrue( + portUpdateNodeBuilder.setTerminationPoint(BindingMap.of(tpUpdateBuilder.build())); + assertTrue( mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build())); Thread.sleep(OVSDB_UPDATE_TIMEOUT); terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { + for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) { OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class); if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { //test - Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode()); + assertEquals(updatedVlanMode, ovsdbTerminationPointAugmentation.getVlanMode()); } } @@ -1267,38 +1849,36 @@ public class SouthboundIT extends AbstractMdsalTestBase { } } - @SuppressWarnings("unchecked") - private List> generateVlanSets() { + private static List> generateVlanSets() { int min = 0; int max = 4095; return Lists.newArrayList( - Collections.emptySet(), - Sets.newHashSet(2222), - Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2)); + Collections.emptySet(), + Collections.singleton(Uint16.valueOf(2222)), + Sets.newHashSet(Uint16.valueOf(min), Uint16.valueOf(max), Uint16.valueOf(min + 1), + Uint16.valueOf(max - 1), Uint16.valueOf((max - min) / 2))); } - private List buildTrunkList(Set trunkSet) { - List trunkList = Lists.newArrayList(); - for (Integer trunk : trunkSet) { - TrunksBuilder trunkBuilder = new TrunksBuilder(); - trunkBuilder.setTrunk(new VlanId(trunk)); - trunkList.add(trunkBuilder.build()); + private static List buildTrunkList(final Set trunkSet) { + List trunkList = new ArrayList<>(); + for (Uint16 trunk : trunkSet) { + trunkList.add(new TrunksBuilder().setTrunk(new VlanId(trunk)).build()); } return trunkList; } @Test public void testCRUDTerminationPointVlanTrunks() throws InterruptedException { - final List UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011)); + final List updatedTrunks = buildTrunkList(Collections.singleton(Uint16.valueOf(2011))); ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); - Iterable> vlanSets = generateVlanSets(); + Iterable> vlanSets = generateVlanSets(); int testCase = 0; - for (Set vlanSet : vlanSets) { + for (Set vlanSet : vlanSets) { ++testCase; // CREATE try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); + assertNotNull(bridge); NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName()); OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = createGenericOvsdbTerminationPointAugmentationBuilder(); @@ -1306,20 +1886,21 @@ public class SouthboundIT extends AbstractMdsalTestBase { ovsdbTerminationBuilder.setName(portName); List trunks = buildTrunkList(vlanSet); ovsdbTerminationBuilder.setTrunks(trunks); - Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); + assertNotNull(terminationPointNode); // READ - List terminationPoints = terminationPointNode.getTerminationPoint(); + Collection terminationPoints = + terminationPointNode.nonnullTerminationPoint().values(); for (TerminationPoint terminationPoint : terminationPoints) { OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class); if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { List actualTrunks = ovsdbTerminationPointAugmentation.getTrunks(); for (Trunks trunk : trunks) { - Assert.assertTrue(actualTrunks.contains(trunk)); + assertTrue(actualTrunks.contains(trunk)); } } } @@ -1329,30 +1910,27 @@ public class SouthboundIT extends AbstractMdsalTestBase { NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId(); OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); - tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS); + tpUpdateAugmentationBuilder.setTrunks(updatedTrunks); InstanceIdentifier portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId); NodeBuilder portUpdateNodeBuilder = new NodeBuilder(); NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid); portUpdateNodeBuilder.setNodeId(portUpdateNodeId); TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder(); - tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName))); - tpUpdateBuilder.addAugmentation( - OvsdbTerminationPointAugmentation.class, - tpUpdateAugmentationBuilder.build()); + tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName))); + tpUpdateBuilder.addAugmentation(tpUpdateAugmentationBuilder.build()); tpUpdateBuilder.setTpId(new TpId(portName)); - portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build())); - Assert.assertTrue( + portUpdateNodeBuilder.setTerminationPoint(BindingMap.of(tpUpdateBuilder.build())); + assertTrue( mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build())); Thread.sleep(OVSDB_UPDATE_TIMEOUT); terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { + for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) { OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class); if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { //test - Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks()); + assertEquals(updatedTrunks, ovsdbTerminationPointAugmentation.getTrunks()); } } @@ -1361,6 +1939,59 @@ public class SouthboundIT extends AbstractMdsalTestBase { } } + /* + * Tests setting and deleting qos field in a port. + */ + @Test + public void testCRUDTerminationPointQos() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + String testQosId = "testQosEntry"; + + // CREATE + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME); + TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId), + SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HFSC), null, null)) { + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation); + assertNotNull(operQos); + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + assertNotNull(bridge); + NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName()); + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); + String portName = "testTerminationPointQos"; + ovsdbTerminationBuilder.setName(portName); + assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + + + // READ and check that qos uuid has been added to the port + InstanceIdentifier tpEntryIid = getTpIid(connectionInfo, bridge) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName))); + TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid); + assertNotNull(terminationPoint); + + // UPDATE - remove the qos entry from the port + OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = + new OvsdbTerminationPointAugmentationBuilder(); + tpUpdateAugmentationBuilder.setName(portName); + TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder(); + tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName))); + tpUpdateBuilder.addAugmentation(tpUpdateAugmentationBuilder.build()); + tpUpdateBuilder.setTpId(new TpId(portName)); + + assertTrue( + mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpEntryIid, tpUpdateBuilder.build())); + Thread.sleep(OVSDB_UPDATE_TIMEOUT); + + // READ and verify that qos uuid has been removed from port + TerminationPoint terminationPointUpdate = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid); + assertNotNull(terminationPointUpdate); + + // DELETE handled by TestBridge + } + } + @Test public void testGetOvsdbNodes() throws InterruptedException { ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); @@ -1370,18 +2001,18 @@ public class SouthboundIT extends AbstractMdsalTestBase { Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath); InstanceIdentifier expectedNodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo); - NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId(); + NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class).getNodeId(); Node foundNode = null; - Assert.assertNotNull("Expected to find topology: " + topologyPath, topology); - Assert.assertNotNull("Expected to find some nodes" + topology.getNode()); + assertNotNull("Expected to find topology: " + topologyPath, topology); + assertNotNull("Expected to find some nodes" + topology.getNode()); LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode()); - for (Node node : topology.getNode()) { + for (Node node : topology.nonnullNode().values()) { if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) { foundNode = node; break; } } - Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode); + assertNotNull("Expected to find Node: " + expectedNodeId, foundNode); } /* @@ -1393,20 +2024,21 @@ public class SouthboundIT extends AbstractMdsalTestBase { new BridgeOtherConfigsSouthboundHelper()); } - private interface SouthboundBridgeHelper { - void writeValues(OvsdbBridgeAugmentationBuilder builder, List values); - List readValues(OvsdbBridgeAugmentation augmentation); + private interface SouthboundBridgeHelper, T extends Identifiable> { + void writeValues(OvsdbBridgeAugmentationBuilder builder, Map values); + + Map readValues(OvsdbBridgeAugmentation augmentation); } - private void testCRUDBridge(String prefix, KeyValueBuilder builder, SouthboundBridgeHelper helper) - throws InterruptedException { + private static , T extends Identifiable> void testCRUDBridge(final String prefix, + final KeyValueBuilder builder, final SouthboundBridgeHelper helper) throws InterruptedException { ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after // the update has been performed. - List> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From"); - List> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To"); - for (SouthboundTestCase updateFromTestCase : updateFromTestCases) { - for (SouthboundTestCase updateToTestCase : updateToTestCases) { + List> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From"); + List> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To"); + for (SouthboundTestCase updateFromTestCase : updateFromTestCases) { + for (SouthboundTestCase updateToTestCase : updateToTestCases) { String testBridgeName = String.format("%s_%s", prefix, updateToTestCase.name); // CREATE: Create the test bridge @@ -1423,19 +2055,19 @@ public class SouthboundIT extends AbstractMdsalTestBase { SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure")); setManagedBy(bridgeCreateAugmentationBuilder, connectionInfo); helper.writeValues(bridgeCreateAugmentationBuilder, updateFromTestCase.inputValues); - bridgeCreateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, - bridgeCreateAugmentationBuilder.build()); - LOG.debug("Built with the intent to store bridge data {}", bridgeCreateAugmentationBuilder.toString()); - Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, + bridgeCreateNodeBuilder.addAugmentation(bridgeCreateAugmentationBuilder.build()); + LOG.debug("Built with the intent to store bridge data {}", bridgeCreateAugmentationBuilder); + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeCreateNodeBuilder.build())); Thread.sleep(OVSDB_UPDATE_TIMEOUT); // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store, // then repeat for OPERATIONAL data store - List updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName, - LogicalDatastoreType.CONFIGURATION)); + Map updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, + testBridgeName, LogicalDatastoreType.CONFIGURATION)); assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationExternalIds); - List updateFromOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName)); + Map updateFromOperationalExternalIds = helper.readValues(getBridge(connectionInfo, + testBridgeName)); assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalExternalIds); // UPDATE: update the values @@ -1445,27 +2077,26 @@ public class SouthboundIT extends AbstractMdsalTestBase { final NodeBuilder bridgeUpdateNodeBuilder = new NodeBuilder(); final Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName); bridgeUpdateNodeBuilder.setNodeId(bridgeNode.getNodeId()); - bridgeUpdateNodeBuilder.setKey(bridgeNode.getKey()); - bridgeUpdateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, - bridgeUpdateAugmentationBuilder.build()); - Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, + bridgeUpdateNodeBuilder.withKey(bridgeNode.key()); + bridgeUpdateNodeBuilder.addAugmentation(bridgeUpdateAugmentationBuilder.build()); + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeUpdateNodeBuilder.build())); Thread.sleep(OVSDB_UPDATE_TIMEOUT); // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store, // then repeat for OPERATIONAL data store - List updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName, + Map updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName, LogicalDatastoreType.CONFIGURATION)); assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationExternalIds); assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationExternalIds); - List updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName)); + Map updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName)); if (updateFromTestCase.expectedValues != null) { assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalExternalIds); assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalExternalIds); } // DELETE - Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid)); + assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid)); Thread.sleep(OVSDB_UPDATE_TIMEOUT); } } @@ -1480,6 +2111,471 @@ public class SouthboundIT extends AbstractMdsalTestBase { new BridgeExternalIdsSouthboundHelper()); } + @Test + public void testAddDeleteQos() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + OvsdbNodeAugmentation ovsdbNodeAugmentation; + Uri qosUri = new Uri("QOS-ROW"); + List typeList = new ArrayList<>(); + typeList.add(SouthboundConstants.QOS_LINUX_HTB); + typeList.add(SouthboundConstants.QOS_LINUX_HFSC); + + for (String qosType : typeList) { + try (TestQos testQos = new TestQos(connectionInfo, qosUri, SouthboundMapper.createQosType(qosType), + null, null)) { + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation); + assertNotNull(operQosHtb); + } + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation); + assertNull(operQosHtb); + } + } + + @Test + public void testAddDeleteQueue() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + Uri queueUri = new Uri("QUEUE-A1"); + + try (TestQueue testQueue = new TestQueue(connectionInfo, queueUri, Uint8.valueOf(25), null, null)) { + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation); + assertNotNull(operQueue); + } + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation); + assertNull(operQueue); + } + + private static class SouthboundQueuesExternalIdsHelper + implements SouthboundQueueHelper { + @Override + public void writeValues(final QueuesBuilder builder, + final Map values) { + builder.setQueuesExternalIds(values); + } + + @Override + public Map readValues(final Queues queue) { + return queue.getQueuesExternalIds(); + } + } + + private static class SouthboundQueuesOtherConfigHelper + implements SouthboundQueueHelper { + @Override + public void writeValues(final QueuesBuilder builder, + final Map values) { + builder.setQueuesOtherConfig(values); + } + + @Override + public Map readValues(final Queues queue) { + return queue.getQueuesOtherConfig(); + } + } + + private interface SouthboundQueueHelper, T extends Identifiable> { + void writeValues(QueuesBuilder builder, Map values); + + Map readValues(Queues queue); + } + + private static Queues getQueue(final Uri queueId, final OvsdbNodeAugmentation node) { + for (Queues queue : node.nonnullQueues().values()) { + if (queue.key().getQueueId().getValue().equals(queueId.getValue())) { + return queue; + } + } + return null; + } + + private static class SouthboundQosExternalIdsHelper + implements SouthboundQosHelper { + @Override + public void writeValues(final QosEntriesBuilder builder, final Map values) { + builder.setQosExternalIds(values); + } + + @Override + public Map readValues(final QosEntries qos) { + return qos.getQosExternalIds(); + } + } + + private static class SouthboundQosOtherConfigHelper + implements SouthboundQosHelper { + @Override + public void writeValues(final QosEntriesBuilder builder, final Map values) { + builder.setQosOtherConfig(values); + } + + @Override + public Map readValues(final QosEntries qos) { + return qos.getQosOtherConfig(); + } + } + + private interface SouthboundQosHelper, T extends Identifiable> { + void writeValues(QosEntriesBuilder builder, Map values); + + Map readValues(QosEntries qos); + } + + private static QosEntries getQos(final Uri qosId, final OvsdbNodeAugmentation node) { + for (QosEntries qos : node.nonnullQosEntries().values()) { + if (qos.key().getQosId().equals(qosId)) { + return qos; + } + } + return null; + } + + private static , T extends Identifiable> void testCRUDQueue( + final KeyValueBuilder builder, final String prefix, final SouthboundQueueHelper helper) + throws InterruptedException { + + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + + // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after + // the update has been performed. + List> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From"); + List> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To"); + + for (SouthboundTestCase updateFromTestCase : updateFromTestCases) { + for (SouthboundTestCase updateToTestCase : updateToTestCases) { + String testQueueId = String.format("%s_%s", prefix, updateToTestCase.name); + + // CREATE: and update the test queue with starting values. + try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), + Uint8.valueOf(45), null, null)) { + QueuesBuilder queuesBuilder = new QueuesBuilder(); + queuesBuilder.setQueueId(new Uri(testQueueId)); + InstanceIdentifier queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Queues.class, queuesBuilder.build().key()); + final NotifyingDataChangeListener queueConfigurationListener = + new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, queueIid); + queueConfigurationListener.registerDataChangeListener(); + final NotifyingDataChangeListener queueOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid); + queueOperationalListener.registerDataChangeListener(); + + helper.writeValues(queuesBuilder, updateFromTestCase.inputValues); + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + queueIid, queuesBuilder.build())); + queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.CONFIGURATION); + Queues queueFromConfig = + getQueue(new Uri(testQueueId), updateFromConfigurationOvsdbNodeAugmentation); + if (queueFromConfig != null) { + assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(queueFromConfig)); + } + + queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Queues queueFromOper = getQueue(new Uri(testQueueId), updateFromOperationalOvsdbNodeAugmentation); + if (queueFromOper != null) { + assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(queueFromOper)); + } + + // UPDATE: update the values + QueuesBuilder queuesUpdateBuilder = new QueuesBuilder(); + queuesUpdateBuilder.setQueueId(new Uri(testQueueId)); + helper.writeValues(queuesUpdateBuilder, updateToTestCase.inputValues); + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + queueIid, queuesUpdateBuilder.build())); + queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.CONFIGURATION); + Queues queueToConfig = getQueue(new Uri(testQueueId), updateToConfigurationOvsdbNodeAugmentation); + if (queueToConfig != null) { + assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(queueToConfig)); + } + + queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Queues queueToOper = getQueue(new Uri(testQueueId), updateToOperationalOvsdbNodeAugmentation); + if (queueToOper != null) { + assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(queueToOper)); + } + + // DELETE handled by TestQueue + } + } + } + } + + @Test + public void testCRUDQueueExternalIds() throws InterruptedException { + testCRUDQueue(new SouthboundQueuesExternalIdsBuilder(), "QueueExternalIds", + new SouthboundQueuesExternalIdsHelper()); + } + + @Test + public void testCRUDQueueOtherConfig() throws InterruptedException { + testCRUDQueue(new SouthboundQueuesOtherConfigBuilder(), "QueueOtherConfig", + new SouthboundQueuesOtherConfigHelper()); + } + + @Test + public void testCRUDQueueDscp() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + String testQueueId = "testQueueDscp"; + + // CREATE: and update the test queue with starting values. + try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), Uint8.ZERO, null, null)) { + for (short dscp = 1; dscp < 64; dscp++) { + QueuesBuilder queuesBuilder = new QueuesBuilder(); + queuesBuilder.setQueueId(new Uri(testQueueId)); + InstanceIdentifier queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Queues.class, queuesBuilder.build().key()); + final NotifyingDataChangeListener queueOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid); + queueOperationalListener.registerDataChangeListener(); + + queuesBuilder.setDscp(Uint8.valueOf(dscp)); + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + queueIid, queuesBuilder.build())); + queueOperationalListener.waitForUpdate(OVSDB_ROUNDTRIP_TIMEOUT); + + // READ: Read the test queue and ensure changes are propagated to the OPERATIONAL data store + // assumption is that CONFIGURATION was updated if OPERATIONAL is correct + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Queues operQueue = getQueue(new Uri(testQueueId), ovsdbNodeAugmentation); + assertNotNull(operQueue); + assertEquals(dscp, operQueue.getDscp().toJava()); + } + + // DELETE handled by TestQueue + } + + } + + private static , T extends Identifiable> void testCRUDQos( + final KeyValueBuilder builder, final String prefix, final SouthboundQosHelper helper) + throws InterruptedException { + + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + + // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after + // the update has been performed. + List> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From"); + List> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To"); + + for (SouthboundTestCase updateFromTestCase : updateFromTestCases) { + for (SouthboundTestCase updateToTestCase : updateToTestCases) { + String testQosId = String.format("%s_%s", prefix, updateToTestCase.name); + + // CREATE: and update the test qos with starting values. + try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId), + SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null)) { + QosEntriesBuilder qosBuilder = new QosEntriesBuilder(); + qosBuilder.setQosId(new Uri(testQosId)); + InstanceIdentifier qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(QosEntries.class, qosBuilder.build().key()); + final NotifyingDataChangeListener qosConfigurationListener = + new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, qosIid); + qosConfigurationListener.registerDataChangeListener(); + final NotifyingDataChangeListener qosOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid); + qosOperationalListener.registerDataChangeListener(); + + helper.writeValues(qosBuilder, updateFromTestCase.inputValues); + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + qosIid, qosBuilder.build())); + qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.CONFIGURATION); + QosEntries qosFromConfig = getQos(new Uri(testQosId), updateFromConfigurationOvsdbNodeAugmentation); + if (qosFromConfig != null) { + assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(qosFromConfig)); + } + + qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries qosFromOper = getQos(new Uri(testQosId), updateFromOperationalOvsdbNodeAugmentation); + if (qosFromOper != null) { + assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(qosFromOper)); + } + + // UPDATE: update the values + QosEntriesBuilder qosUpdateBuilder = new QosEntriesBuilder(); + qosUpdateBuilder.setQosId(new Uri(testQosId)); + helper.writeValues(qosUpdateBuilder, updateToTestCase.inputValues); + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + qosIid, qosUpdateBuilder.build())); + qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.CONFIGURATION); + QosEntries qosToConfig = getQos(new Uri(testQosId), updateToConfigurationOvsdbNodeAugmentation); + if (qosToConfig != null) { + assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(qosToConfig)); + } + + qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries qosToOper = getQos(new Uri(testQosId), updateToOperationalOvsdbNodeAugmentation); + if (qosToOper != null) { + assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(qosToOper)); + } + + // DELETE handled by TestQueue + } + } + } + } + + @Test + public void testCRUDQosExternalIds() throws InterruptedException { + testCRUDQos(new SouthboundQosExternalIdsBuilder(), "QosExternalIds", + new SouthboundQosExternalIdsHelper()); + } + + @Test + public void testCRUDQosOtherConfig() throws InterruptedException { + testCRUDQos(new SouthboundQosOtherConfigBuilder(), "QosOtherConfig", + new SouthboundQosOtherConfigHelper()); + } + + @Test + public void testCRUDQosQueues() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + String testQosId = "testQosQueues"; + + // CREATE: and update the test queue with starting values. + try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId), + SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null); + TestQueue testQueue1 = new TestQueue(connectionInfo, new Uri("queue1"), Uint8.valueOf(12), null, + null); + TestQueue testQueue2 = new TestQueue(connectionInfo, new Uri("queue2"), Uint8.valueOf(35), null, + null)) { + QosEntriesBuilder qosBuilder = new QosEntriesBuilder(); + qosBuilder.setQosId(new Uri(testQosId)); + InstanceIdentifier qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(QosEntries.class, qosBuilder.build().key()); + final NotifyingDataChangeListener qosOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid); + qosOperationalListener.registerDataChangeListener(); + + // READ, UPDATE: Read the UUIDs of the Queue rows and add them to the + // configuration of the Qos row. + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + + Queues operQueue1 = getQueue(new Uri("queue1"), ovsdbNodeAugmentation); + + assertNotNull(operQueue1); + + InstanceIdentifier queue1Iid = testQueue1.getInstanceIdentifier(); + OvsdbQueueRef queue1Ref = new OvsdbQueueRef(queue1Iid); + + Queues operQueue2 = getQueue(new Uri("queue2"), ovsdbNodeAugmentation); + assertNotNull(operQueue2); + InstanceIdentifier queue2Iid = testQueue2.getInstanceIdentifier(); + OvsdbQueueRef queue2Ref = new OvsdbQueueRef(queue2Iid); + + Map queueList = BindingMap.of( + new QueueListBuilder().setQueueNumber(Uint32.ONE).setQueueRef(queue1Ref).build(), + new QueueListBuilder().setQueueNumber(Uint32.TWO).setQueueRef(queue2Ref).build()); + + qosBuilder.setQueueList(queueList); + + assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + qosIid, qosBuilder.build())); + qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store + // assumption is that CONFIGURATION was updated if OPERATIONAL is correct + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation); + assertNotNull(operQos); + Map operQueueList = operQos.getQueueList(); + assertNotNull(operQueueList); + for (QueueList queueEntry : queueList.values()) { + assertTrue(isQueueInList(operQueueList, queueEntry)); + } + + // DELETE one queue from queue list and check that one remains + KeyedInstanceIdentifier qosQueueIid = qosIid + .child(QueueList.class, new QueueListKey(Uint32.ONE)); + assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid)); + qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store + // assumption is that CONFIGURATION was updated if OPERATIONAL is correct + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation); + assertNotNull(operQos); + operQueueList = operQos.getQueueList(); + assertNotNull(operQueueList); + + for (QueueList queueEntry : queueList.values()) { + if (queueEntry.getQueueRef().equals(queue2Ref)) { + assertTrue(isQueueInList(operQueueList, queueEntry)); + } else if (queueEntry.getQueueRef().equals(queue1Ref)) { + assertFalse(isQueueInList(operQueueList, queueEntry)); + } else { + assertTrue("Unknown queue entry in qos queue list", false); + } + } + + // DELETE queue list and check that list is empty + qosQueueIid = qosIid + .child(QueueList.class, new QueueListKey(Uint32.ONE)); + assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid)); + qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation); + assertNotNull(operQos); + operQueueList = operQos.getQueueList(); + assertNotNull(operQueueList); + assertTrue(operQueueList.isEmpty()); + } + } + + + + private static Boolean isQueueInList(final Map queueList, final QueueList queue) { + for (QueueList queueEntry : queueList.values()) { + if (queueEntry.getQueueNumber().equals(queue.getQueueNumber()) + && queueEntry.getQueueRef().equals(queue.getQueueRef())) { + return true; + } + } + return false; + } + /** *

* Representation of a southbound test case. Each test case has a name, a list of input values and a list of @@ -1492,10 +2588,10 @@ public class SouthboundIT extends AbstractMdsalTestBase { * * @param The type of data used for the test case. */ - private static final class SouthboundTestCase { + private static final class SouthboundTestCase, T extends Identifiable> { private final String name; - private final List inputValues; - private final List expectedValues; + private final Map inputValues; + private final Map expectedValues; /** * Creates an instance of a southbound test case. @@ -1504,11 +2600,10 @@ public class SouthboundIT extends AbstractMdsalTestBase { * @param inputValues The input values (provided as input to the underlying augmentation builder). * @param expectedValues The expected values (checked against the output of the underlying augmentation). */ - public SouthboundTestCase( - final String name, final List inputValues, final List expectedValues) { + SouthboundTestCase(final String name, final List inputValues, final List expectedValues) { this.name = name; - this.inputValues = inputValues; - this.expectedValues = expectedValues; + this.inputValues = BindingMap.ordered(inputValues); + this.expectedValues = BindingMap.of(expectedValues); } } @@ -1517,7 +2612,7 @@ public class SouthboundIT extends AbstractMdsalTestBase { * * @param The type of data used for the test case. */ - private static final class SouthboundTestCaseBuilder { + private static final class SouthboundTestCaseBuilder, T extends Identifiable> { private String name; private List inputValues; private List expectedValues; @@ -1526,30 +2621,30 @@ public class SouthboundIT extends AbstractMdsalTestBase { * Creates a builder. Builders may be reused, the generated immutable instances are independent of the * builders. There are no default values. */ - public SouthboundTestCaseBuilder() { + SouthboundTestCaseBuilder() { // Nothing to do } /** * Sets the test case's name. * - * @param name The test case's name. + * @param value The test case's name. * @return The builder. */ - public SouthboundTestCaseBuilder name(final String name) { - this.name = name; + public SouthboundTestCaseBuilder name(final String value) { + this.name = value; return this; } /** * Sets the input values. * - * @param inputValues The input values. + * @param values The input values. * @return The builder. */ @SafeVarargs - public final SouthboundTestCaseBuilder input(final T... inputValues) { - this.inputValues = Lists.newArrayList(inputValues); + public final SouthboundTestCaseBuilder input(final T... values) { + this.inputValues = Lists.newArrayList(values); return this; } @@ -1558,7 +2653,7 @@ public class SouthboundIT extends AbstractMdsalTestBase { * * @return The builder. */ - public SouthboundTestCaseBuilder expectInputAsOutput() { + public SouthboundTestCaseBuilder expectInputAsOutput() { this.expectedValues = this.inputValues; return this; } @@ -1568,7 +2663,7 @@ public class SouthboundIT extends AbstractMdsalTestBase { * * @return The builder. */ - public SouthboundTestCaseBuilder expectNoOutput() { + public SouthboundTestCaseBuilder expectNoOutput() { this.expectedValues = null; return this; } @@ -1578,8 +2673,7 @@ public class SouthboundIT extends AbstractMdsalTestBase { * * @return The test case. */ - @SuppressWarnings("unchecked") - public SouthboundTestCase build() { + public SouthboundTestCase build() { return new SouthboundTestCase<>(name, inputValues, expectedValues); } } @@ -1594,6 +2688,8 @@ public class SouthboundIT extends AbstractMdsalTestBase { protected abstract void setValue(Builder builder, String value); + protected abstract boolean isValueMandatory(); + public final T build(final String testName, final String key, final String value) { final Builder builder = builder(); this.counter++; @@ -1611,6 +2707,94 @@ public class SouthboundIT extends AbstractMdsalTestBase { } } + private static final class SouthboundQueuesExternalIdsBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new QueuesExternalIdsBuilder(); + } + + @Override + protected void setKey(final Builder builder, final String key) { + ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdKey(key); + } + + @Override + protected void setValue(final Builder builder, final String value) { + ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdValue(value); + } + + @Override + protected boolean isValueMandatory() { + return true; + } + } + + private static final class SouthboundQueuesOtherConfigBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new QueuesOtherConfigBuilder(); + } + + @Override + protected void setKey(final Builder builder, final String key) { + ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigKey(key); + } + + @Override + protected void setValue(final Builder builder, final String value) { + ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigValue(value); + } + + @Override + protected boolean isValueMandatory() { + return false; + } + } + + private static final class SouthboundQosExternalIdsBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new QosExternalIdsBuilder(); + } + + @Override + protected void setKey(final Builder builder, final String key) { + ((QosExternalIdsBuilder) builder).setQosExternalIdKey(key); + } + + @Override + protected void setValue(final Builder builder, final String value) { + ((QosExternalIdsBuilder) builder).setQosExternalIdValue(value); + } + + @Override + protected boolean isValueMandatory() { + return true; + } + } + + private static final class SouthboundQosOtherConfigBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new QosOtherConfigBuilder(); + } + + @Override + protected void setKey(final Builder builder, final String key) { + ((QosOtherConfigBuilder) builder).setOtherConfigKey(key); + } + + @Override + protected void setValue(final Builder builder, final String value) { + ((QosOtherConfigBuilder) builder).setOtherConfigValue(value); + } + + @Override + protected boolean isValueMandatory() { + return false; + } + } + private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder { @Override protected Builder builder() { @@ -1618,14 +2802,19 @@ public class SouthboundIT extends AbstractMdsalTestBase { } @Override - protected void setKey(Builder builder, String key) { + protected void setKey(final Builder builder, final String key) { ((PortExternalIdsBuilder) builder).setExternalIdKey(key); } @Override - protected void setValue(Builder builder, String value) { + protected void setValue(final Builder builder, final String value) { ((PortExternalIdsBuilder) builder).setExternalIdValue(value); } + + @Override + protected boolean isValueMandatory() { + return true; + } } private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder { @@ -1635,14 +2824,41 @@ public class SouthboundIT extends AbstractMdsalTestBase { } @Override - protected void setKey(Builder builder, String key) { + protected void setKey(final Builder builder, final String key) { ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key); } @Override - protected void setValue(Builder builder, String value) { + protected void setValue(final Builder builder, final String value) { ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value); } + + @Override + protected boolean isValueMandatory() { + return true; + } + } + + private static final class SouthboundInterfaceLldpBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new InterfaceLldpBuilder(); + } + + @Override + protected void setKey(final Builder builder, final String key) { + ((InterfaceLldpBuilder) builder).setLldpKey(key); + } + + @Override + protected void setValue(final Builder builder, final String value) { + ((InterfaceLldpBuilder) builder).setLldpValue(value); + } + + @Override + protected boolean isValueMandatory() { + return true; + } } private static final class SouthboundOptionsBuilder extends KeyValueBuilder { @@ -1652,14 +2868,19 @@ public class SouthboundIT extends AbstractMdsalTestBase { } @Override - protected void setKey(Builder builder, String key) { + protected void setKey(final Builder builder, final String key) { ((OptionsBuilder) builder).setOption(key); } @Override - protected void setValue(Builder builder, String value) { + protected void setValue(final Builder builder, final String value) { ((OptionsBuilder) builder).setValue(value); } + + @Override + protected boolean isValueMandatory() { + return false; + } } private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder { @@ -1669,14 +2890,19 @@ public class SouthboundIT extends AbstractMdsalTestBase { } @Override - protected void setKey(Builder builder, String key) { + protected void setKey(final Builder builder, final String key) { ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key); } @Override - protected void setValue(Builder builder, String value) { + protected void setValue(final Builder builder, final String value) { ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value); } + + @Override + protected boolean isValueMandatory() { + return false; + } } private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder { @@ -1686,14 +2912,19 @@ public class SouthboundIT extends AbstractMdsalTestBase { } @Override - protected void setKey(Builder builder, String key) { + protected void setKey(final Builder builder, final String key) { ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key); } @Override - protected void setValue(Builder builder, String value) { + protected void setValue(final Builder builder, final String value) { ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value); } + + @Override + protected boolean isValueMandatory() { + return false; + } } private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder { @@ -1703,14 +2934,19 @@ public class SouthboundIT extends AbstractMdsalTestBase { } @Override - protected void setKey(Builder builder, String key) { + protected void setKey(final Builder builder, final String key) { ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key); } @Override - protected void setValue(Builder builder, String value) { + protected void setValue(final Builder builder, final String value) { ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value); } + + @Override + protected boolean isValueMandatory() { + return false; + } } private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder { @@ -1720,27 +2956,32 @@ public class SouthboundIT extends AbstractMdsalTestBase { } @Override - protected void setKey(Builder builder, String key) { + protected void setKey(final Builder builder, final String key) { ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key); } @Override - protected void setValue(Builder builder, String value) { + protected void setValue(final Builder builder, final String value) { ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value); } + + @Override + protected boolean isValueMandatory() { + return true; + } } /* * Generates the test cases involved in testing key-value-based data. See inline comments for descriptions of * the particular cases considered. */ - private static List> generateKeyValueTestCases( - KeyValueBuilder builder, String testName) { - List> testCases = new ArrayList<>(); + private static , T extends Identifiable> List> + generateKeyValueTestCases(final KeyValueBuilder builder, final String testName) { + List> testCases = new ArrayList<>(); - final String GOOD_KEY = "GoodKey"; - final String GOOD_VALUE = "GoodValue"; - final String NO_VALUE_FOR_KEY = "NoValueForKey"; + final String goodKey = "GoodKey"; + final String goodValue = "GoodValue"; + final String noValueForKey = "NoValueForKey"; final String idKey = testName + "Key"; final String idValue = testName + "Value"; @@ -1750,19 +2991,19 @@ public class SouthboundIT extends AbstractMdsalTestBase { // Description: Create a termination point with one value // Expected: A port is created with the single value specified below final String testOneName = "TestOne" + testName; - testCases.add(new SouthboundTestCaseBuilder() + testCases.add(new SouthboundTestCaseBuilder() .name(testOneName) .input(builder.build(testOneName, idKey, idValue)) .expectInputAsOutput() .build()); + builder.reset(); // Test Case 2: TestFive // Test Type: Positive // Description: Create a termination point with multiple (five) values // Expected: A port is created with the five values specified below final String testFiveName = "TestFive" + testName; - builder.reset(); - testCases.add(new SouthboundTestCaseBuilder() + testCases.add(new SouthboundTestCaseBuilder() .name(testFiveName) .input( builder.build(testFiveName, idKey, idValue), @@ -1772,129 +3013,146 @@ public class SouthboundIT extends AbstractMdsalTestBase { builder.build(testFiveName, idKey, idValue)) .expectInputAsOutput() .build()); + builder.reset(); - if ((builder instanceof SouthboundBridgeExternalIdsBuilder) || - (builder instanceof SouthboundInterfaceExternalIdsBuilder) || - (builder instanceof SouthboundPortExternalIdsBuilder)) { - LOG.info("generateKeyValueTestCases: instance skipping test case 3 TestOneGoodOneMalformedValue"); + if (!builder.isValueMandatory()) { + // Test Case 3: TestOneGoodOneMalformedValue + // Test Type: Negative + // Description: + // One perfectly fine input + // (TestOneGoodOneMalformedValue_GoodKey_1, + // TestOneGoodOneMalformedValue_GoodValue_1) + // and one malformed input which only has key specified + // (TestOneGoodOneMalformedValue_NoValueForKey_2, + // UNSPECIFIED) + // Expected: A port is created without any values + final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName; + testCases.add(new SouthboundTestCaseBuilder() + .name(testOneGoodOneMalformedValueName) + .input( + builder.build(testOneGoodOneMalformedValueName, goodKey, goodValue), + builder.build(testOneGoodOneMalformedValueName, noValueForKey, null)) + .expectNoOutput() + .build()); builder.reset(); - - return testCases; + } else { + LOG.info("generateKeyValueTestCases: skipping test case 3 for {}", builder.getClass().getSimpleName()); } - // Test Case 3: TestOneGoodOneMalformedValue - // Test Type: Negative - // Description: - // One perfectly fine input - // (TestOneGoodOneMalformedValue_GoodKey_1, - // TestOneGoodOneMalformedValue_GoodValue_1) - // and one malformed input which only has key specified - // (TestOneGoodOneMalformedValue_NoValueForKey_2, - // UNSPECIFIED) - // Expected: A port is created without any values - final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName; - builder.reset(); - testCases.add(new SouthboundTestCaseBuilder() - .name(testOneGoodOneMalformedValueName) - .input( - builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE), - builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null)) - .expectNoOutput() - .build()); - builder.reset(); - return testCases; } - private static class PortExternalIdsSouthboundHelper implements SouthboundTerminationPointHelper { + private static class PortExternalIdsSouthboundHelper + implements SouthboundTerminationPointHelper { @Override - public void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List values) { + public void writeValues(final OvsdbTerminationPointAugmentationBuilder builder, + final Map values) { builder.setPortExternalIds(values); } @Override - public List readValues(OvsdbTerminationPointAugmentation augmentation) { + public Map readValues( + final OvsdbTerminationPointAugmentation augmentation) { return augmentation.getPortExternalIds(); } } - private static class InterfaceExternalIdsSouthboundHelper implements - SouthboundTerminationPointHelper { + private static class InterfaceExternalIdsSouthboundHelper + implements SouthboundTerminationPointHelper { @Override - public void writeValues( - OvsdbTerminationPointAugmentationBuilder builder, List values) { + public void writeValues(final OvsdbTerminationPointAugmentationBuilder builder, + final Map values) { builder.setInterfaceExternalIds(values); } @Override - public List readValues(OvsdbTerminationPointAugmentation augmentation) { + public Map readValues( + final OvsdbTerminationPointAugmentation augmentation) { return augmentation.getInterfaceExternalIds(); } } - private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper { + private static class InterfaceLldpSouthboundHelper + implements SouthboundTerminationPointHelper { + @Override + public void writeValues(final OvsdbTerminationPointAugmentationBuilder builder, + final Map values) { + builder.setInterfaceLldp(values); + } + + @Override + public Map readValues(final OvsdbTerminationPointAugmentation augmentation) { + return augmentation.getInterfaceLldp(); + } + } + + private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper { @Override - public void writeValues( - OvsdbTerminationPointAugmentationBuilder builder, List values) { + public void writeValues(final OvsdbTerminationPointAugmentationBuilder builder, + final Map values) { builder.setOptions(values); } @Override - public List readValues(OvsdbTerminationPointAugmentation augmentation) { + public Map readValues(final OvsdbTerminationPointAugmentation augmentation) { return augmentation.getOptions(); } } - private static class InterfaceOtherConfigsSouthboundHelper implements - SouthboundTerminationPointHelper { + private static class InterfaceOtherConfigsSouthboundHelper + implements SouthboundTerminationPointHelper { @Override - public void writeValues( - OvsdbTerminationPointAugmentationBuilder builder, List values) { + public void writeValues(final OvsdbTerminationPointAugmentationBuilder builder, + final Map values) { builder.setInterfaceOtherConfigs(values); } @Override - public List readValues(OvsdbTerminationPointAugmentation augmentation) { + public Map readValues( + final OvsdbTerminationPointAugmentation augmentation) { return augmentation.getInterfaceOtherConfigs(); } } private static class PortOtherConfigsSouthboundHelper implements - SouthboundTerminationPointHelper { + SouthboundTerminationPointHelper { @Override - public void writeValues( - OvsdbTerminationPointAugmentationBuilder builder, List values) { + public void writeValues(final OvsdbTerminationPointAugmentationBuilder builder, + final Map values) { builder.setPortOtherConfigs(values); } @Override - public List readValues(OvsdbTerminationPointAugmentation augmentation) { + public Map readValues( + final OvsdbTerminationPointAugmentation augmentation) { return augmentation.getPortOtherConfigs(); } } - private static class BridgeExternalIdsSouthboundHelper implements SouthboundBridgeHelper { + private static class BridgeExternalIdsSouthboundHelper + implements SouthboundBridgeHelper { @Override - public void writeValues( - OvsdbBridgeAugmentationBuilder builder, List values) { + public void writeValues(final OvsdbBridgeAugmentationBuilder builder, + final Map values) { builder.setBridgeExternalIds(values); } @Override - public List readValues(OvsdbBridgeAugmentation augmentation) { + public Map readValues(final OvsdbBridgeAugmentation augmentation) { return augmentation.getBridgeExternalIds(); } } - private static class BridgeOtherConfigsSouthboundHelper implements SouthboundBridgeHelper { + private static class BridgeOtherConfigsSouthboundHelper + implements SouthboundBridgeHelper { @Override - public void writeValues( - OvsdbBridgeAugmentationBuilder builder, List values) { + public void writeValues(final OvsdbBridgeAugmentationBuilder builder, + final Map values) { builder.setBridgeOtherConfigs(values); } @Override - public List readValues(OvsdbBridgeAugmentation augmentation) { + public Map readValues(final OvsdbBridgeAugmentation augmentation) { return augmentation.getBridgeOtherConfigs(); } }