Make methods static
[ovsdb.git] / southbound / southbound-it / src / test / java / org / opendaylight / ovsdb / southbound / it / SouthboundIT.java
1 /*
2  * Copyright © 2015, 2017 Red Hat, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.ovsdb.southbound.it;
9
10 import static org.junit.Assert.assertNotNull;
11 import static org.junit.Assert.assertTrue;
12 import static org.junit.Assert.fail;
13 import static org.ops4j.pax.exam.CoreOptions.composite;
14 import static org.ops4j.pax.exam.CoreOptions.maven;
15 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperties;
16 import static org.ops4j.pax.exam.CoreOptions.vmOption;
17 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
18 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
19
20 import com.google.common.collect.ImmutableBiMap;
21 import com.google.common.collect.ImmutableList;
22 import com.google.common.collect.Iterables;
23 import com.google.common.collect.Lists;
24 import com.google.common.collect.Maps;
25 import com.google.common.collect.Sets;
26 import java.lang.annotation.Annotation;
27 import java.lang.reflect.Method;
28 import java.net.InetAddress;
29 import java.net.UnknownHostException;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.HashSet;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Properties;
37 import java.util.Set;
38 import javax.inject.Inject;
39 import org.eclipse.jdt.annotation.Nullable;
40 import org.junit.After;
41 import org.junit.Assert;
42 import org.junit.Assume;
43 import org.junit.Before;
44 import org.junit.Ignore;
45 import org.junit.Test;
46 import org.junit.internal.AssumptionViolatedException;
47 import org.junit.runner.RunWith;
48 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
49 import org.opendaylight.mdsal.binding.api.DataBroker;
50 import org.opendaylight.mdsal.binding.api.DataObjectModification;
51 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
52 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
53 import org.opendaylight.mdsal.binding.api.DataTreeModification;
54 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
55 import org.opendaylight.ovsdb.lib.notation.Version;
56 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
57 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
58 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
59 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
60 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbQueueRef;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeBase;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsKey;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachKey;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntryKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigsKey;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesKey;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIds;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIdsBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIdsKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.Mappings;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.MappingsBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.MappingsKey;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIds;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIdsBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIdsKey;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfig;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfigBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfigKey;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueList;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListKey;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIds;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIdsBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIdsKey;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfig;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfigBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfigKey;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsKey;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldp;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldpBuilder;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldpKey;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsKey;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsKey;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
148 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
149 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
150 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
151 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
152 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
153 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
154 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
155 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
156 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
157 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
158 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
159 import org.opendaylight.yangtools.concepts.Builder;
160 import org.opendaylight.yangtools.yang.binding.DataObject;
161 import org.opendaylight.yangtools.yang.binding.Identifiable;
162 import org.opendaylight.yangtools.yang.binding.Identifier;
163 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
164 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
165 import org.opendaylight.yangtools.yang.common.Uint32;
166 import org.ops4j.pax.exam.Configuration;
167 import org.ops4j.pax.exam.Option;
168 import org.ops4j.pax.exam.junit.PaxExam;
169 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
170 import org.ops4j.pax.exam.options.MavenUrlReference;
171 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
172 import org.ops4j.pax.exam.spi.reactors.PerClass;
173 import org.ops4j.pax.exam.util.Filter;
174 import org.osgi.framework.BundleContext;
175 import org.slf4j.Logger;
176 import org.slf4j.LoggerFactory;
177
178 /**
179  * Integration tests for southbound-impl.
180  *
181  * @author Sam Hague (shague@redhat.com)
182  */
183 @RunWith(PaxExam.class)
184 @ExamReactorStrategy(PerClass.class)
185 public class SouthboundIT extends AbstractMdsalTestBase {
186     private static final String NETDEV_DP_TYPE = "netdev";
187     private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
188     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
189     private static final int OVSDB_ROUNDTRIP_TIMEOUT = 10000;
190     private static final String FORMAT_STR = "%s_%s_%d";
191     private static final Version AUTOATTACH_FROM_VERSION = Version.fromString("7.11.2");
192     private static final Version IF_INDEX_FROM_VERSION = Version.fromString("7.2.1");
193     private static final Long MAX_BACKOFF = 10000L;
194     private static final Long INACTIVITY_PROBE = 30000L;
195     private static String addressStr;
196     private static int portNumber;
197     private static String connectionType;
198     private static boolean setup = false;
199     private static MdsalUtils mdsalUtils = null;
200     private static Node ovsdbNode;
201     private static int testMethodsRemaining;
202     private static Version schemaVersion;
203     @Inject @Filter(timeout = 60000)
204     private static DataBroker dataBroker = null;
205
206     @Inject
207     private BundleContext bundleContext;
208
209     private static final NotifyingDataChangeListener CONFIGURATION_LISTENER =
210             new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION);
211     private static final NotifyingDataChangeListener OPERATIONAL_LISTENER =
212             new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL);
213
214
215     private static final class NotifyingDataChangeListener implements DataTreeChangeListener<DataObject> {
216         private static final int RETRY_WAIT = 100;
217
218         private final LogicalDatastoreType type;
219         private final Set<InstanceIdentifier<?>> createdIids = new HashSet<>();
220         private final Set<InstanceIdentifier<?>> removedIids = new HashSet<>();
221         private final Set<InstanceIdentifier<?>> updatedIids = new HashSet<>();
222         private final InstanceIdentifier<?> iid;
223
224         private NotifyingDataChangeListener(LogicalDatastoreType type) {
225             this.type = type;
226             this.iid = null;
227         }
228
229         private NotifyingDataChangeListener(LogicalDatastoreType type, InstanceIdentifier<?> iid) {
230             this.type = type;
231             this.iid = iid;
232         }
233
234         @Override
235         public void onDataTreeChanged(Collection<DataTreeModification<DataObject>> changes) {
236             for (DataTreeModification<DataObject> change: changes) {
237                 DataObjectModification<DataObject> rootNode = change.getRootNode();
238                 final InstanceIdentifier<DataObject> identifier = change.getRootPath().getRootIdentifier();
239                 switch (rootNode.getModificationType()) {
240                     case SUBTREE_MODIFIED:
241                     case WRITE:
242                         if (rootNode.getDataBefore() == null) {
243                             LOG.info("{} DataTreeChanged: created {}", type, identifier);
244                             createdIids.add(identifier);
245
246                             final DataObject obj = rootNode.getDataAfter();
247                             if (obj instanceof ManagedNodeEntry) {
248                                 ManagedNodeEntry managedNodeEntry = (ManagedNodeEntry) obj;
249                                 LOG.info("{} DataChanged: created managed {}",
250                                         managedNodeEntry.getBridgeRef().getValue());
251                                 createdIids.add(managedNodeEntry.getBridgeRef().getValue());
252                             }
253                         } else {
254                             LOG.info("{} DataTreeChanged: updated {}", type, identifier);
255                             updatedIids.add(identifier);
256                         }
257                         break;
258                     case DELETE:
259                         LOG.info("{} DataTreeChanged: removed {}", type, identifier);
260                         removedIids.add(identifier);
261                         break;
262                     default:
263                         break;
264                 }
265             }
266
267             synchronized (this) {
268                 notifyAll();
269             }
270         }
271
272         public boolean isCreated(InstanceIdentifier<?> path) {
273             return createdIids.remove(path);
274         }
275
276         public boolean isRemoved(InstanceIdentifier<?> path) {
277             return removedIids.remove(path);
278         }
279
280         public boolean isUpdated(InstanceIdentifier<?> path) {
281             return updatedIids.remove(path);
282         }
283
284         public void clear() {
285             createdIids.clear();
286             removedIids.clear();
287             updatedIids.clear();
288         }
289
290         public void registerDataChangeListener() {
291             dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(type,
292                     (InstanceIdentifier)iid), this);
293         }
294
295         public void waitForCreation(long timeout) throws InterruptedException {
296             synchronized (this) {
297                 long start = System.currentTimeMillis();
298                 LOG.info("Waiting for {} DataChanged creation on {}", type, iid);
299                 while (!isCreated(iid) && System.currentTimeMillis() - start < timeout) {
300                     wait(RETRY_WAIT);
301                 }
302                 LOG.info("Woke up, waited {}ms for creation of {}", System.currentTimeMillis() - start, iid);
303             }
304         }
305
306         public void waitForDeletion(long timeout) throws InterruptedException {
307             synchronized (this) {
308                 long start = System.currentTimeMillis();
309                 LOG.info("Waiting for {} DataChanged deletion on {}", type, iid);
310                 while (!isRemoved(iid) && System.currentTimeMillis() - start < timeout) {
311                     wait(RETRY_WAIT);
312                 }
313                 LOG.info("Woke up, waited {}ms for deletion of {}", System.currentTimeMillis() - start, iid);
314             }
315         }
316
317         public void waitForUpdate(long timeout) throws InterruptedException {
318             synchronized (this) {
319                 long start = System.currentTimeMillis();
320                 LOG.info("Waiting for {} DataChanged update on {}", type, iid);
321                 while (!isUpdated(iid) && System.currentTimeMillis() - start < timeout) {
322                     wait(RETRY_WAIT);
323                 }
324                 LOG.info("Woke up, waited {}ms for update of {}", System.currentTimeMillis() - start, iid);
325             }
326         }
327     }
328
329     @Override
330     @Configuration
331     public Option[] config() {
332         Option[] options = super.config();
333         Option[] propertyOptions = getPropertiesOptions();
334         Option[] otherOptions = getOtherOptions();
335         Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
336         System.arraycopy(options, 0, combinedOptions, 0, options.length);
337         System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
338         System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
339                 otherOptions.length);
340         return combinedOptions;
341     }
342
343     private static Option[] getOtherOptions() {
344         return new Option[] {
345                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
346                 keepRuntimeFolder()
347         };
348     }
349
350     @Override
351     public String getKarafDistro() {
352         return maven()
353                 .groupId("org.opendaylight.ovsdb")
354                 .artifactId("southbound-karaf")
355                 .versionAsInProject()
356                 .type("zip")
357                 .getURL();
358     }
359
360     @Override
361     public MavenUrlReference getFeatureRepo() {
362         return maven()
363                 .groupId("org.opendaylight.ovsdb")
364                 .artifactId("southbound-features")
365                 .classifier("features")
366                 .type("xml")
367                 .versionAsInProject();
368     }
369
370     @Override
371     public String getFeatureName() {
372         return "odl-ovsdb-southbound-test";
373     }
374
375     protected String usage() {
376         return "Integration Test needs a valid connection configuration as follows :\n"
377                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
378                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
379     }
380
381     @Override
382     public Option getLoggingOption() {
383         return composite(
384                 editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
385                         "log4j.logger.org.opendaylight.ovsdb",
386                         LogLevelOption.LogLevel.TRACE.name()),
387                 super.getLoggingOption());
388     }
389
390     private static Option[] getPropertiesOptions() {
391         Properties props = new Properties(System.getProperties());
392         String ipAddressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
393                 SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
394         String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
395                 SouthboundITConstants.DEFAULT_SERVER_PORT);
396         String connectionTypeStr = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
397                 SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
398
399         LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
400                 connectionTypeStr, ipAddressStr, portStr);
401
402         return new Option[] {
403                 propagateSystemProperties(
404                         SouthboundITConstants.SERVER_IPADDRESS,
405                         SouthboundITConstants.SERVER_PORT,
406                         SouthboundITConstants.CONNECTION_TYPE),
407                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
408                         SouthboundITConstants.SERVER_IPADDRESS, ipAddressStr),
409                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
410                         SouthboundITConstants.SERVER_PORT, portStr),
411                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
412                         SouthboundITConstants.CONNECTION_TYPE, connectionTypeStr),
413         };
414     }
415
416     @Before
417     @Override
418     public void setup() throws Exception {
419         if (setup) {
420             LOG.info("Skipping setup, already initialized");
421             return;
422         }
423
424         super.setup();
425         Assert.assertNotNull("db should not be null", dataBroker);
426
427         LOG.info("sleeping for 10s to let the features finish installing");
428         Thread.sleep(10000);
429
430         addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
431         String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
432         try {
433             portNumber = Integer.parseInt(portStr);
434         } catch (NumberFormatException e) {
435             fail("Invalid port number " + portStr + System.lineSeparator() + usage());
436         }
437         connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
438
439         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
440                 connectionType, addressStr, portNumber);
441         if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
442             if (addressStr == null) {
443                 fail(usage());
444             }
445         }
446
447         mdsalUtils = new MdsalUtils(dataBroker);
448         assertTrue("Did not find " + SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue(), getOvsdbTopology());
449         final ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
450         final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
451         dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION,
452                 (InstanceIdentifier)iid), CONFIGURATION_LISTENER);
453         dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL,
454                 (InstanceIdentifier)iid), OPERATIONAL_LISTENER);
455
456         ovsdbNode = connectOvsdbNode(connectionInfo);
457         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class);
458         assertNotNull("The OvsdbNodeAugmentation cannot be null", ovsdbNodeAugmentation);
459         schemaVersion = Version.fromString(ovsdbNodeAugmentation.getDbVersion());
460         LOG.info("schemaVersion = {}", schemaVersion);
461
462         // Let's count the test methods (we need to use this instead of @AfterClass on teardown() since the latter is
463         // useless with pax-exam)
464         for (Method method : getClass().getMethods()) {
465             boolean testMethod = false;
466             boolean ignoreMethod = false;
467             for (Annotation annotation : method.getAnnotations()) {
468                 if (Test.class.equals(annotation.annotationType())) {
469                     testMethod = true;
470                 }
471                 if (Ignore.class.equals(annotation.annotationType())) {
472                     ignoreMethod = true;
473                 }
474             }
475             if (testMethod && !ignoreMethod) {
476                 testMethodsRemaining++;
477             }
478         }
479         LOG.info("{} test methods to run", testMethodsRemaining);
480
481         setup = true;
482     }
483
484     @After
485     public void teardown() {
486         testMethodsRemaining--;
487         LOG.info("{} test methods remaining", testMethodsRemaining);
488         if (testMethodsRemaining == 0) {
489             try {
490                 disconnectOvsdbNode(getConnectionInfo(addressStr, portNumber));
491             } catch (InterruptedException e) {
492                 LOG.warn("Interrupted while disconnecting", e);
493             }
494         }
495     }
496
497     private static Boolean getOvsdbTopology() {
498         LOG.info("getOvsdbTopology: looking for {}...", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue());
499         Boolean found = false;
500         final TopologyId topologyId = SouthboundUtils.OVSDB_TOPOLOGY_ID;
501         InstanceIdentifier<Topology> path =
502                 InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId));
503         for (int i = 0; i < 60; i++) {
504             Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
505             if (topology != null) {
506                 LOG.info("getOvsdbTopology: found {}...", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue());
507                 found = true;
508                 break;
509             } else {
510                 LOG.info("getOvsdbTopology: still looking ({})...", i);
511                 try {
512                     Thread.sleep(1000);
513                 } catch (InterruptedException e) {
514                     LOG.warn("Interrupted while waiting for {}", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue(), e);
515                 }
516             }
517         }
518         return found;
519     }
520
521     /**
522      * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
523      * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms.
524      */
525     @Test
526     public void testPassiveNode() throws InterruptedException {
527         if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
528             //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
529             Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
530         }
531     }
532
533     private static ConnectionInfo getConnectionInfo(final String ipAddressStr, final int portNum) {
534         InetAddress inetAddress = null;
535         try {
536             inetAddress = InetAddress.getByName(ipAddressStr);
537         } catch (UnknownHostException e) {
538             fail("Could not resolve " + ipAddressStr + ": " + e);
539         }
540
541         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
542         PortNumber port = new PortNumber(portNum);
543
544         final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
545                 .setRemoteIp(address)
546                 .setRemotePort(port)
547                 .build();
548         LOG.info("connectionInfo: {}", connectionInfo);
549         return connectionInfo;
550     }
551
552     @Test
553     public void testNetworkTopology() throws InterruptedException {
554         NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
555                 InstanceIdentifier.create(NetworkTopology.class));
556         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
557                 networkTopology);
558
559         networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
560                 InstanceIdentifier.create(NetworkTopology.class));
561         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
562                 networkTopology);
563     }
564
565     @Test
566     public void testOvsdbTopology() throws InterruptedException {
567         InstanceIdentifier<Topology> path = InstanceIdentifier
568                 .create(NetworkTopology.class)
569                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
570
571         Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
572         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
573                 topology);
574
575         topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
576
577         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
578                 topology);
579     }
580
581     private static Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
582         final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
583         Assert.assertTrue(
584                 mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, SouthboundUtils.createNode(connectionInfo)));
585         waitForOperationalCreation(iid);
586         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
587         Assert.assertNotNull(node);
588         LOG.info("Connected to {}", SouthboundUtils.connectionInfoToString(connectionInfo));
589         return node;
590     }
591
592     private static void waitForOperationalCreation(InstanceIdentifier<Node> iid) throws InterruptedException {
593         synchronized (OPERATIONAL_LISTENER) {
594             long start = System.currentTimeMillis();
595             LOG.info("Waiting for OPERATIONAL DataChanged creation on {}", iid);
596             while (!OPERATIONAL_LISTENER.isCreated(
597                     iid) && System.currentTimeMillis() - start < OVSDB_ROUNDTRIP_TIMEOUT) {
598                 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
599             }
600             LOG.info("Woke up, waited {} for creation of {}", System.currentTimeMillis() - start, iid);
601         }
602     }
603
604     private static void waitForOperationalDeletion(InstanceIdentifier<Node> iid) throws InterruptedException {
605         synchronized (OPERATIONAL_LISTENER) {
606             long start = System.currentTimeMillis();
607             LOG.info("Waiting for OPERATIONAL DataChanged deletion on {}", iid);
608             while (!OPERATIONAL_LISTENER.isRemoved(
609                     iid) && System.currentTimeMillis() - start < OVSDB_ROUNDTRIP_TIMEOUT) {
610                 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
611             }
612             LOG.info("Woke up, waited {} for deletion of {}", System.currentTimeMillis() - start, iid);
613         }
614     }
615
616     private static void waitForOperationalUpdate(InstanceIdentifier<Node> iid) throws InterruptedException {
617         synchronized (OPERATIONAL_LISTENER) {
618             long start = System.currentTimeMillis();
619             LOG.info("Waiting for OPERATIONAL DataChanged update on {}", iid);
620             while (!OPERATIONAL_LISTENER.isUpdated(
621                     iid) && System.currentTimeMillis() - start < OVSDB_ROUNDTRIP_TIMEOUT) {
622                 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
623             }
624             LOG.info("Woke up, waited {} for update of {}", System.currentTimeMillis() - start, iid);
625         }
626     }
627
628     private static void disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
629         final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
630         Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
631         waitForOperationalDeletion(iid);
632         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
633         Assert.assertNull(node);
634         LOG.info("Disconnected from {}", SouthboundUtils.connectionInfoToString(connectionInfo));
635     }
636
637     @Test
638     public void testAddDeleteOvsdbNode() throws InterruptedException {
639         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
640         // At this point we're connected, disconnect and reconnect (the connection will be removed at the very end)
641         disconnectOvsdbNode(connectionInfo);
642         connectOvsdbNode(connectionInfo);
643     }
644
645     @Test
646     public void testDpdkSwitch() throws InterruptedException {
647         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
648         Map<DatapathTypeEntryKey, DatapathTypeEntry> datapathTypeEntries =
649                 ovsdbNode.augmentation(OvsdbNodeAugmentation.class).nonnullDatapathTypeEntry();
650         if (datapathTypeEntries == null) {
651             LOG.info("DPDK not supported on this node.");
652         } else {
653             for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries.values()) {
654                 Class<? extends DatapathTypeBase> dpType = dpTypeEntry.getDatapathType();
655                 String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType);
656                 LOG.info("dp type is {}", dpTypeStr);
657                 if (dpTypeStr.equals(NETDEV_DP_TYPE)) {
658                     LOG.info("Found a DPDK node; adding a corresponding netdev device");
659                     InstanceIdentifier<Node> bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo,
660                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
661                     NodeId bridgeNodeId = SouthboundUtils.createManagedNodeId(bridgeIid);
662                     try (TestBridge testBridge = new TestBridge(connectionInfo, bridgeIid,
663                             SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null, true, dpType, null, null,
664                             null)) {
665                         // Verify that the device is netdev
666                         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
667                         Assert.assertNotNull(bridge);
668                         Assert.assertEquals(dpType, bridge.getDatapathType());
669
670                         // Add port for all dpdk interface types (dpdkvhost not supported in existing dpdk ovs)
671                         List<String> dpdkTypes = new ArrayList<>();
672                         dpdkTypes.add("dpdk");
673                         dpdkTypes.add("dpdkr");
674                         dpdkTypes.add("dpdkvhostuser");
675                         //dpdkTypes.add("dpdkvhost");
676
677                         for (String dpdkType : dpdkTypes) {
678                             String testPortname = "test" + dpdkType + "port";
679                             LOG.info("DPDK portname and type is {}, {}", testPortname, dpdkType);
680                             Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
681                                     .get(dpdkType);
682                             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationpointBuilder =
683                                     createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(testPortname,
684                                             dpdkIfType);
685                             Assert.assertTrue(
686                                     addTerminationPoint(bridgeNodeId, testPortname, ovsdbTerminationpointBuilder));
687                         }
688
689                         // Verify that all DPDK ports are created
690                         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
691                         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
692                                 terminationPointIid);
693                         Assert.assertNotNull(terminationPointNode);
694
695                         // Verify that each termination point has the specific DPDK ifType
696                         for (String dpdkType : dpdkTypes) {
697                             String testPortname = "test" + dpdkType + "port";
698                             Class<? extends InterfaceTypeBase> dpdkIfType =
699                                     SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(dpdkType);
700                             for (TerminationPoint terminationPoint
701                                     : terminationPointNode.nonnullTerminationPoint().values()) {
702                                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
703                                         .augmentation(OvsdbTerminationPointAugmentation.class);
704                                 if (ovsdbTerminationPointAugmentation.getName().equals(testPortname)) {
705                                     Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
706                                             .getInterfaceType();
707                                     Assert.assertEquals(dpdkIfType, opPort);
708                                 }
709                             }
710                         }
711                     }
712                 }
713                 break;
714             }
715         }
716     }
717
718     @Test
719     public void testOvsdbNodeOvsVersion() throws InterruptedException {
720         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class);
721         Assert.assertNotNull(ovsdbNodeAugmentation);
722         assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
723     }
724
725     @Test
726     public void testOvsdbNodeDbVersion() throws InterruptedException {
727         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class);
728         Assert.assertNotNull(ovsdbNodeAugmentation);
729         assertNotNull(ovsdbNodeAugmentation.getDbVersion());
730     }
731
732     @Test
733     public void testOpenVSwitchOtherConfig() throws InterruptedException {
734         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class);
735         Assert.assertNotNull(ovsdbNodeAugmentation);
736         Map<OpenvswitchOtherConfigsKey, OpenvswitchOtherConfigs> otherConfigsList =
737                 ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
738         if (otherConfigsList != null) {
739             for (OpenvswitchOtherConfigs otherConfig : otherConfigsList.values()) {
740                 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
741                     LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
742                     break;
743                 } else {
744                     LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
745                 }
746             }
747         } else {
748             LOG.info("other_config is not present");
749         }
750     }
751
752     @Test
753     public void testOvsdbBridgeControllerInfo() throws InterruptedException {
754         ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber);
755         String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
756         assertNotNull("Failed to get controller target", controllerTarget);
757         List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
758         Uri setUri = new Uri(controllerTarget);
759         try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
760                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
761                 setControllerEntry, null)) {
762             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
763             Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME,  bridge);
764             Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
765                     bridge.getControllerEntry());
766             for (ControllerEntry entry : bridge.getControllerEntry().values()) {
767                 if (entry.getTarget() != null) {
768                     Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
769                 }
770                 if (entry.getMaxBackoff() != null) {
771                     Assert.assertEquals(entry.getMaxBackoff(), MAX_BACKOFF);
772                 }
773                 if (entry.getInactivityProbe() != null) {
774                     Assert.assertEquals(entry.getInactivityProbe(),INACTIVITY_PROBE);
775                 }
776             }
777         }
778     }
779
780     private static List<ControllerEntry> createControllerEntry(String controllerTarget) {
781         List<ControllerEntry> controllerEntriesList = new ArrayList<>();
782         controllerEntriesList.add(new ControllerEntryBuilder()
783                 .setTarget(new Uri(controllerTarget))
784                 .setMaxBackoff(MAX_BACKOFF)
785                 .setInactivityProbe(INACTIVITY_PROBE)
786                 .build());
787         return controllerEntriesList;
788     }
789
790     private static void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
791                               final ConnectionInfo connectionInfo) {
792         InstanceIdentifier<Node> connectionNodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo);
793         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
794     }
795
796     private static List<ProtocolEntry> createMdsalProtocols() {
797         List<ProtocolEntry> protocolList = new ArrayList<>();
798         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
799                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
800         protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
801         return protocolList;
802     }
803
804     private static OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
805         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
806                 new OvsdbTerminationPointAugmentationBuilder();
807         ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
808                 new InterfaceTypeEntryBuilder()
809                         .setInterfaceType(
810                                 SouthboundMapper.createInterfaceType("internal"))
811                         .build().getInterfaceType());
812         return ovsdbTerminationPointAugmentationBuilder;
813     }
814
815     private static OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
816             final String portName) {
817         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
818                 createGenericOvsdbTerminationPointAugmentationBuilder();
819         ovsdbTerminationBuilder.setName(portName);
820         Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
821                 .get("dpdk");
822         ovsdbTerminationBuilder.setInterfaceType(ifType);
823         return ovsdbTerminationBuilder;
824     }
825
826     private static OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(
827             String testPortname,Class<? extends InterfaceTypeBase> dpdkIfType) {
828         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
829                 createGenericOvsdbTerminationPointAugmentationBuilder();
830         ovsdbTerminationBuilder.setName(testPortname);
831         ovsdbTerminationBuilder.setInterfaceType(dpdkIfType);
832         return ovsdbTerminationBuilder;
833     }
834
835     private static boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
836                                                final OvsdbTerminationPointAugmentationBuilder
837                                                    ovsdbTerminationPointAugmentationBuilder)
838             throws InterruptedException {
839
840         InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
841         NodeBuilder portNodeBuilder = new NodeBuilder();
842         NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
843         portNodeBuilder.setNodeId(portNodeId);
844         TerminationPointBuilder entry = new TerminationPointBuilder()
845                 .withKey(new TerminationPointKey(new TpId(portName)))
846                 .addAugmentation(ovsdbTerminationPointAugmentationBuilder.build());
847         portNodeBuilder.setTerminationPoint(Collections.singletonList(entry.build()));
848         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
849                 portIid, portNodeBuilder.build());
850         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
851         return result;
852     }
853
854     private static class TestBridge implements AutoCloseable {
855         private final ConnectionInfo connectionInfo;
856         private final String bridgeName;
857
858         /**
859          * Creates a test bridge which can be automatically removed when no longer necessary.
860          *
861          * @param connectionInfo The connection information.
862          * @param bridgeIid The bridge identifier; if {@code null}, one is created based on {@code bridgeName}.
863          * @param bridgeName The bridge name; must be provided.
864          * @param bridgeNodeId The bridge node identifier; if {@code null}, one is created based on {@code bridgeIid}.
865          * @param setProtocolEntries {@code true} to set default protocol entries for the bridge.
866          * @param failMode The fail mode to set for the bridge.
867          * @param setManagedBy {@code true} to specify {@code setManagedBy} for the bridge.
868          * @param dpType The datapath type.
869          * @param externalIds The external identifiers if any.
870          * @param otherConfigs The other configuration items if any.
871          */
872         TestBridge(final ConnectionInfo connectionInfo, @Nullable InstanceIdentifier<Node> bridgeIid,
873                                   final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
874                                   final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
875                                   @Nullable final Class<? extends DatapathTypeBase> dpType,
876                                   @Nullable final List<BridgeExternalIds> externalIds,
877                                   @Nullable final List<ControllerEntry> controllerEntries,
878                                   @Nullable final List<BridgeOtherConfigs> otherConfigs) {
879             this.connectionInfo = connectionInfo;
880             this.bridgeName = bridgeName;
881             NodeBuilder bridgeNodeBuilder = new NodeBuilder();
882             if (bridgeIid == null) {
883                 bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
884             }
885             if (bridgeNodeId == null) {
886                 bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
887             }
888             bridgeNodeBuilder.setNodeId(bridgeNodeId);
889             OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
890             ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
891             if (setProtocolEntries) {
892                 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
893             }
894             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
895             if (setManagedBy) {
896                 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
897             }
898             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
899             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
900             ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
901             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
902             bridgeNodeBuilder.addAugmentation(ovsdbBridgeAugmentationBuilder.build());
903             LOG.debug("Built with the intent to store bridge data {}", ovsdbBridgeAugmentationBuilder);
904             Assert.assertTrue(
905                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build()));
906             try {
907                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
908             } catch (InterruptedException e) {
909                 LOG.warn("Sleep interrupted while waiting for bridge creation (bridge {})", bridgeName, e);
910             }
911         }
912
913         TestBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
914             this(connectionInfo, null, bridgeName, null, true,
915                     SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
916         }
917
918         @Override
919         public void close() {
920             final InstanceIdentifier<Node> iid =
921                     SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
922             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
923             try {
924                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
925             } catch (InterruptedException e) {
926                 LOG.warn("Sleep interrupted while waiting for bridge deletion (bridge {})", bridgeName, e);
927             }
928         }
929     }
930
931     private static class TestAutoAttach implements AutoCloseable {
932         private final ConnectionInfo connectionInfo;
933         private final Uri autoattachId;
934         private final Uri bridgeId;
935
936         TestAutoAttach(final ConnectionInfo connectionInfo,
937                 final Uri autoattachId,
938                 final Uri bridgeId,
939                 @Nullable final String systemName,
940                 @Nullable final String systemDescription,
941                 @Nullable final List<Mappings> mappings,
942                 @Nullable final List<AutoattachExternalIds> externalIds) {
943             this.connectionInfo = connectionInfo;
944             this.autoattachId = autoattachId;
945             this.bridgeId = bridgeId;
946
947             Autoattach aaEntry = new AutoattachBuilder()
948                     .setAutoattachId(autoattachId)
949                     .setBridgeId(bridgeId)
950                     .setSystemName(systemName)
951                     .setSystemDescription(systemDescription)
952                     .setMappings(mappings)
953                     .setAutoattachExternalIds(externalIds)
954                     .build();
955             InstanceIdentifier<Autoattach> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
956                     .augmentation(OvsdbNodeAugmentation.class)
957                     .child(Autoattach.class, aaEntry.key());
958             final NotifyingDataChangeListener aaOperationalListener =
959                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid);
960             aaOperationalListener.registerDataChangeListener();
961
962             Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, aaEntry));
963             try {
964                 aaOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
965             } catch (InterruptedException e) {
966                 LOG.warn("Sleep interrupted while waiting for queue {}", iid, e);
967             }
968         }
969
970         @Override
971         public void close() {
972             final InstanceIdentifier<Autoattach> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
973                     .augmentation(OvsdbNodeAugmentation.class)
974                     .child(Autoattach.class, new AutoattachKey(this.autoattachId));
975             final NotifyingDataChangeListener aaOperationalListener =
976                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid);
977             aaOperationalListener.registerDataChangeListener();
978
979             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
980             try {
981                 aaOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
982             } catch (InterruptedException e) {
983                 LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", iid, e);
984             }
985         }
986     }
987
988     @Test
989     public void testCRUDAutoAttach() throws InterruptedException {
990         final boolean isOldSchema = schemaVersion.compareTo(AUTOATTACH_FROM_VERSION) < 0;
991
992         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
993         String testAutoattachId = "testAutoattachEntry";
994         String testSystemName = "testSystemName";
995         String testSystemDescription = "testSystemDescription";
996         String testAutoattachExternalKey = "testAutoattachExternalKey";
997         String testAutoattachExternalValue = "testAutoattachExternalValue";
998
999         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1000             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1001             Assert.assertNotNull(bridge);
1002
1003             // CREATE: Create Autoattach table
1004             NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1005                     connectionInfo, bridge.getBridgeName()));
1006             String bridgeId = nodeId.getValue();
1007             try (TestAutoAttach testAutoattach = new TestAutoAttach(connectionInfo, new Uri(testAutoattachId),
1008                     new Uri(bridgeId), testSystemName, testSystemDescription, null, null)) {
1009                 // READ: Read md-sal operational datastore to see if the AutoAttach table was created
1010                 // and if Bridge table was updated with AutoAttach Uuid
1011                 OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
1012                         LogicalDatastoreType.OPERATIONAL);
1013                 Autoattach operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId));
1014
1015                 // skip tests after verifying that Autoattach doesn't break with unsupported schema
1016                 Assume.assumeFalse(isOldSchema);
1017
1018                 // FIXME: Remove once CRUD is supported
1019                 Assume.assumeFalse(operAa == null);
1020
1021                 Assert.assertNotNull(operAa);
1022                 Assert.assertEquals(testSystemName, operAa.getSystemName());
1023                 bridge = getBridge(connectionInfo);
1024                 Uuid aaUuid = new Uuid(operAa.getAutoattachUuid().getValue());
1025                 Assert.assertEquals(aaUuid, bridge.getAutoAttach());
1026
1027                 // UPDATE: Update mappings column of AutoAttach table that was created
1028                 List<Mappings> mappings = ImmutableList.of(new MappingsBuilder().setMappingsKey(100L)
1029                         .setMappingsValue(200).build());
1030                 Autoattach updatedAa = new AutoattachBuilder()
1031                         .setAutoattachId(new Uri(testAutoattachId))
1032                         .setMappings(mappings)
1033                         .build();
1034                 InstanceIdentifier<Autoattach> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1035                         .augmentation(OvsdbNodeAugmentation.class)
1036                         .child(Autoattach.class, updatedAa.key());
1037                 final NotifyingDataChangeListener aaOperationalListener =
1038                         new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid);
1039                 aaOperationalListener.registerDataChangeListener();
1040                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, updatedAa));
1041                 aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
1042
1043                 // UPDATE: Update external_ids column of AutoAttach table that was created
1044                 List<AutoattachExternalIds> externalIds = new ArrayList<>();
1045                 externalIds.add(new AutoattachExternalIdsBuilder()
1046                         .setAutoattachExternalIdKey(testAutoattachExternalKey)
1047                         .setAutoattachExternalIdValue(testAutoattachExternalValue)
1048                         .build());
1049                 updatedAa = new AutoattachBuilder()
1050                         .setAutoattachId(new Uri(testAutoattachId))
1051                         .setAutoattachExternalIds(externalIds)
1052                         .build();
1053                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, updatedAa));
1054                 aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
1055
1056                 // READ: Read the updated AutoAttach table for latest mappings and external_ids column value
1057                 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
1058                         LogicalDatastoreType.OPERATIONAL);
1059                 operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId));
1060                 Assert.assertNotNull(operAa);
1061                 Map<MappingsKey, Mappings> operMappingsList = operAa.getMappings();
1062                 for (Mappings operMappings : operMappingsList.values()) {
1063                     Assert.assertTrue(mappings.contains(operMappings));
1064                 }
1065                 Map<AutoattachExternalIdsKey, AutoattachExternalIds> operExternalIds =
1066                         operAa.getAutoattachExternalIds();
1067                 externalIds.add(new AutoattachExternalIdsBuilder()
1068                         .setAutoattachExternalIdKey(SouthboundConstants.AUTOATTACH_ID_EXTERNAL_ID_KEY)
1069                         .setAutoattachExternalIdValue(operAa.getAutoattachId().getValue())
1070                         .build());
1071                 for (AutoattachExternalIds operExternalId : operExternalIds.values()) {
1072                     Assert.assertTrue(externalIds.contains(operExternalId));
1073                 }
1074
1075                 // DELETE: Delete AutoAttach table
1076                 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
1077                 aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
1078                 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
1079                         LogicalDatastoreType.OPERATIONAL);
1080                 operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId));
1081                 Assert.assertNull(operAa);
1082             } catch (AssumptionViolatedException e) {
1083                 LOG.warn("Skipped test for Autoattach due to unsupported schema", e);
1084             }
1085         }
1086     }
1087
1088     private static Autoattach getAutoAttach(OvsdbNodeAugmentation ovsdbNodeAugmentation, Uri uri) {
1089         if (ovsdbNodeAugmentation.getAutoattach() != null
1090                 && !ovsdbNodeAugmentation.getAutoattach().isEmpty()) {
1091             for (Autoattach aa : ovsdbNodeAugmentation.getAutoattach().values()) {
1092                 if (aa.key().getAutoattachId().equals(uri)) {
1093                     return aa;
1094                 }
1095             }
1096         }
1097         return null;
1098     }
1099
1100     private static class TestQos implements AutoCloseable {
1101         private final ConnectionInfo connectionInfo;
1102         private final Uri qosId;
1103
1104         /**
1105          * Creates a test qos entry which can be automatically removed when no longer necessary.
1106          *
1107          * @param connectionInfo The connection information.
1108          * @param qosId The Qos identifier.
1109          * @param qosType The qos type.
1110          * @param externalIds The external identifiers if any.
1111          * @param otherConfigs The other configuration items if any.
1112          */
1113         TestQos(final ConnectionInfo connectionInfo,
1114                                   final Uri qosId,
1115                                   final Class<? extends QosTypeBase> qosType,
1116                                   @Nullable final List<QosExternalIds> externalIds,
1117                                   @Nullable final List<QosOtherConfig> otherConfigs) {
1118             this.connectionInfo = connectionInfo;
1119             this.qosId = qosId;
1120
1121             QosEntries qosEntry = new QosEntriesBuilder()
1122                 .setQosId(qosId)
1123                 .setQosType(qosType)
1124                 .setQosExternalIds(externalIds)
1125                 .setQosOtherConfig(otherConfigs)
1126                 .build();
1127             InstanceIdentifier<QosEntries> qeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1128                     .augmentation(OvsdbNodeAugmentation.class)
1129                     .child(QosEntries.class, qosEntry.key());
1130             final NotifyingDataChangeListener qosOperationalListener =
1131                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qeIid);
1132             qosOperationalListener.registerDataChangeListener();
1133
1134             Assert.assertTrue(
1135                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1136                     qeIid, qosEntry));
1137
1138             try {
1139                 qosOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
1140             } catch (InterruptedException e) {
1141                 LOG.warn("Sleep interrupted while waiting for queue {}", qeIid, e);
1142             }
1143
1144         }
1145
1146         @Override
1147         public void close() {
1148             final InstanceIdentifier<QosEntries> qeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1149                     .augmentation(OvsdbNodeAugmentation.class)
1150                     .child(QosEntries.class, new QosEntriesKey(this.qosId));
1151             final NotifyingDataChangeListener qosOperationalListener =
1152                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qeIid);
1153             qosOperationalListener.registerDataChangeListener();
1154
1155             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qeIid));
1156             try {
1157                 qosOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
1158             } catch (InterruptedException e) {
1159                 LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", qeIid, e);
1160             }
1161         }
1162     }
1163
1164     private static class TestQueue implements AutoCloseable {
1165         private final ConnectionInfo connectionInfo;
1166         private final Uri queueId;
1167         private final InstanceIdentifier<Queues> queueIid;
1168
1169         /**
1170          * Creates a test queue entry which can be automatically removed when no longer necessary.
1171          *
1172          * @param connectionInfo The connection information.
1173          * @param queueId The Queue identifier.
1174          * @param queueDscp The queue dscp value.
1175          * @param externalIds The external identifiers if any.
1176          * @param otherConfigs The other configuration items if any.
1177          */
1178         TestQueue(final ConnectionInfo connectionInfo,
1179                                   final Uri queueId,
1180                                   final Short queueDscp,
1181                                   @Nullable final List<QueuesExternalIds> externalIds,
1182                                   @Nullable final List<QueuesOtherConfig> otherConfigs) {
1183             this.connectionInfo = connectionInfo;
1184             this.queueId = queueId;
1185
1186             Queues queue = new QueuesBuilder()
1187                 .setQueueId(queueId)
1188                 .setDscp(queueDscp)
1189                 .setQueuesExternalIds(externalIds)
1190                 .setQueuesOtherConfig(otherConfigs)
1191                 .build();
1192             queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1193                     .augmentation(OvsdbNodeAugmentation.class)
1194                     .child(Queues.class, queue.key());
1195             final NotifyingDataChangeListener queueOperationalListener =
1196                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid);
1197             queueOperationalListener.registerDataChangeListener();
1198
1199             Assert.assertTrue(
1200                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1201                     queueIid, queue));
1202
1203             try {
1204                 queueOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
1205             } catch (InterruptedException e) {
1206                 LOG.warn("Sleep interrupted while waiting for queue {}", queueId, e);
1207             }
1208         }
1209
1210         public InstanceIdentifier<Queues> getInstanceIdentifier() {
1211             return queueIid;
1212         }
1213
1214         @Override
1215         public void close() {
1216             InstanceIdentifier<Queues> queuesIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1217                     .augmentation(OvsdbNodeAugmentation.class)
1218                     .child(Queues.class, new QueuesKey(this.queueId));
1219             final NotifyingDataChangeListener queueOperationalListener =
1220                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queuesIid);
1221             queueOperationalListener.registerDataChangeListener();
1222
1223             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, queuesIid));
1224             try {
1225                 queueOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
1226             } catch (InterruptedException e) {
1227                 LOG.warn("Sleep interrupted while waiting for queue deletion (queue {})", queueId, e);
1228             }
1229         }
1230     }
1231
1232     private static OvsdbNodeAugmentation getOvsdbNode(ConnectionInfo connectionInfo, LogicalDatastoreType store) {
1233         InstanceIdentifier<Node> nodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
1234         Node node = mdsalUtils.read(store, nodeIid);
1235         Assert.assertNotNull(node);
1236         OvsdbNodeAugmentation ovsdbNodeAugmentation = node.augmentation(OvsdbNodeAugmentation.class);
1237         Assert.assertNotNull(ovsdbNodeAugmentation);
1238         return ovsdbNodeAugmentation;
1239     }
1240
1241     private static OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
1242         return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1243     }
1244
1245     /**
1246      * Extract the <code>store</code> type data store contents for the particular bridge identified by
1247      * <code>bridgeName</code>.
1248      *
1249      * @param connectionInfo the connection information
1250      * @param bridgeName the bridge name
1251      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
1252      * @return <code>store</code> type data store contents
1253      */
1254     private static OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
1255                                                      LogicalDatastoreType store) {
1256         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
1257         Assert.assertNotNull(bridgeNode);
1258         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.augmentation(OvsdbBridgeAugmentation.class);
1259         Assert.assertNotNull(ovsdbBridgeAugmentation);
1260         return ovsdbBridgeAugmentation;
1261     }
1262
1263     /**
1264      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
1265      * identified by <code>bridgeName</code>.
1266      *
1267      * @param connectionInfo the connection information
1268      * @param bridgeName the bridge name
1269      * @see SouthboundIT#getBridge(ConnectionInfo, String, LogicalDatastoreType)
1270      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
1271      */
1272     private static OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
1273         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
1274     }
1275
1276     /**
1277      * Extract the node contents from <code>store</code> type data store for the
1278      * bridge identified by <code>bridgeName</code>.
1279      *
1280      * @param connectionInfo the connection information
1281      * @param bridgeName the bridge name
1282      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
1283      * @return <code>store</code> type data store contents
1284      */
1285     private static Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
1286         InstanceIdentifier<Node> bridgeIid =
1287                 SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
1288         return mdsalUtils.read(store, bridgeIid);
1289     }
1290
1291     /**
1292      * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
1293      * bridge identified by <code>bridgeName</code>.
1294      *
1295      * @param connectionInfo the connection information
1296      * @param bridgeName the bridge name
1297      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
1298      */
1299     private static Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
1300         return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
1301     }
1302
1303     @Test
1304     public void testAddDeleteBridge() throws InterruptedException {
1305         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1306
1307         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1308             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1309             Assert.assertNotNull(bridge);
1310             LOG.info("bridge: {}", bridge);
1311         }
1312     }
1313
1314     private static InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
1315         return SouthboundUtils.createInstanceIdentifier(connectionInfo, bridge.getBridgeName());
1316     }
1317
1318     /**
1319      * Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
1320      * on <code>bridgeName</code>.
1321      *
1322      * @param connectionInfo the connection information
1323      * @param bridgeName the bridge name
1324      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
1325      * @param index the index we're interested in
1326      * @return the augmentation (or {@code null} if none)
1327      */
1328     private static OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
1329             ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) {
1330
1331         Map<TerminationPointKey, TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store)
1332                 .getTerminationPoint();
1333         if (tpList == null) {
1334             return null;
1335         }
1336         return Iterables.get(tpList.values(), index).augmentation(OvsdbTerminationPointAugmentation.class);
1337     }
1338
1339     @Test
1340     public void testCRUDTerminationPointIfIndex() throws InterruptedException {
1341         final boolean isOldSchema = schemaVersion.compareTo(IF_INDEX_FROM_VERSION) < 0;
1342         Assume.assumeFalse(isOldSchema);
1343         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1344
1345         // Test create ifIndex
1346         try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME, null, true,
1347                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1348                 true, SouthboundMapper.createDatapathType("netdev"), null, null, null)) {
1349             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1350             Assert.assertNotNull(bridge);
1351             LOG.info("bridge: {}", bridge);
1352             NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1353                     connectionInfo, bridge.getBridgeName()));
1354             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1355                     createGenericOvsdbTerminationPointAugmentationBuilder();
1356             String portName = "testIfIndex";
1357             ovsdbTerminationBuilder.setName(portName);
1358
1359             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1360             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1361             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1362             Assert.assertNotNull(terminationPointNode);
1363
1364             // Test read ifIndex
1365             for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1366                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1367                         terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1368                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1369                     Long ifIndex = ovsdbTerminationPointAugmentation.getIfindex().toJava();
1370                     Assert.assertNotNull(ifIndex);
1371                     LOG.info("ifIndex: {} for the port:{}", ifIndex, portName);
1372                 }
1373             }
1374         }
1375     }
1376
1377     @Test
1378     public void testCRDTerminationPointOfPort() throws InterruptedException {
1379         final Long ofportExpected = 45002L;
1380
1381         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1382
1383         // CREATE
1384         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1385             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1386             Assert.assertNotNull(bridge);
1387             LOG.info("bridge: {}", bridge);
1388             NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1389                     connectionInfo, bridge.getBridgeName()));
1390             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1391                     createGenericOvsdbTerminationPointAugmentationBuilder();
1392             String portName = "testOfPort";
1393             ovsdbTerminationBuilder.setName(portName);
1394
1395             ovsdbTerminationBuilder.setOfport(ofportExpected);
1396             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1397             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1398             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1399             Assert.assertNotNull(terminationPointNode);
1400
1401             // READ
1402             for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1403                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1404                         terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1405                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1406                     Long ofPort = ovsdbTerminationPointAugmentation.getOfport().toJava();
1407                     // if ephemeral port 45002 is in use, ofPort is set to 1
1408                     Assert.assertTrue(ofPort.equals(ofportExpected) || ofPort.equals(1L));
1409                     LOG.info("ofPort: {}", ofPort);
1410                 }
1411             }
1412
1413             // UPDATE- Not Applicable.  From the OpenVSwitch Documentation:
1414             //   "A client should ideally set this column’s value in the same database transaction that it uses to
1415             //   create the interface."
1416
1417             // DELETE handled by TestBridge
1418         }
1419     }
1420
1421     @Test
1422     public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
1423         final Long ofportExpected = 45008L;
1424         final Long ofportInput = 45008L;
1425
1426         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1427
1428         // CREATE
1429         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1430             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1431             Assert.assertNotNull(bridge);
1432             final NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1433                     connectionInfo, bridge.getBridgeName()));
1434             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1435                     createGenericOvsdbTerminationPointAugmentationBuilder();
1436             String portName = "testOfPortRequest";
1437             ovsdbTerminationBuilder.setName(portName);
1438             Integer ofPortRequestExpected = ofportExpected.intValue();
1439             ovsdbTerminationBuilder.setOfport(ofportInput);
1440             ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
1441             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1442             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1443             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1444             Assert.assertNotNull(terminationPointNode);
1445
1446             // READ
1447             for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1448                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1449                         terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1450                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1451                     Long ofPort = ovsdbTerminationPointAugmentation.getOfport().toJava();
1452                     // if ephemeral port 45008 is in use, ofPort is set to 1
1453                     Assert.assertTrue(ofPort.equals(ofportExpected) || ofPort.equals(1L));
1454                     LOG.info("ofPort: {}", ofPort);
1455
1456                     Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest().toJava();
1457                     Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
1458                     LOG.info("ofPortRequest: {}", ofPortRequest);
1459                 }
1460             }
1461
1462             // UPDATE- Not Applicable.  From the OpenVSwitch documentation:
1463             //   "A client should ideally set this column’s value in the same database transaction that it uses to
1464             //   create the interface. "
1465
1466             // DELETE handled by TestBridge
1467         }
1468     }
1469
1470     private static <I extends Identifier<T>, T extends Identifiable<I>> void assertExpectedExist(Map<I, T> expected,
1471             Map<I, T> test) {
1472         if (expected != null && test != null) {
1473             for (T exp : expected.values()) {
1474                 Assert.assertTrue("The retrieved values don't contain " + exp, test.containsValue(exp));
1475             }
1476         }
1477     }
1478
1479     private interface SouthboundTerminationPointHelper<I extends Identifier<T>, T extends Identifiable<I>> {
1480         void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<T> values);
1481
1482         Map<I, T> readValues(OvsdbTerminationPointAugmentation augmentation);
1483     }
1484
1485     /*
1486      * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
1487      *
1488      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1489      */
1490     private static <I extends Identifier<T>, T extends Identifiable<I>> void testCRUDTerminationPoint(
1491             KeyValueBuilder<T> builder, String prefix, SouthboundTerminationPointHelper<I, T> helper)
1492             throws InterruptedException {
1493         final int terminationPointTestIndex = 0;
1494
1495         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1496
1497         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1498         // the update has been performed.
1499         List<SouthboundTestCase<I, T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
1500         List<SouthboundTestCase<I, T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
1501
1502         for (SouthboundTestCase<I, T> updateFromTestCase : updateFromTestCases) {
1503             for (SouthboundTestCase<I, T> updateToTestCase : updateToTestCases) {
1504                 String testBridgeAndPortName = String.format("%s_%s", prefix, updateToTestCase.name);
1505
1506                 // CREATE: Create the test bridge
1507                 try (TestBridge testBridge = new TestBridge(connectionInfo, null, testBridgeAndPortName, null, true,
1508                         SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null,
1509                         null)) {
1510                     NodeId testBridgeNodeId = SouthboundUtils.createManagedNodeId(
1511                             SouthboundUtils.createInstanceIdentifier(connectionInfo,
1512                                     new OvsdbBridgeName(testBridgeAndPortName)));
1513                     OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1514                             createGenericOvsdbTerminationPointAugmentationBuilder();
1515                     tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
1516                     helper.writeValues(tpCreateAugmentationBuilder, updateFromTestCase.inputValues);
1517                     Assert.assertTrue(
1518                             addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
1519
1520                     // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
1521                     // then repeat for OPERATIONAL data store
1522                     OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1523                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1524                                     LogicalDatastoreType.CONFIGURATION, terminationPointTestIndex);
1525                     if (updateFromConfigurationTerminationPointAugmentation != null) {
1526                         Map<I, T> updateFromConfigurationValues =
1527                                 helper.readValues(updateFromConfigurationTerminationPointAugmentation);
1528                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
1529                     }
1530                     OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
1531                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1532                                     LogicalDatastoreType.OPERATIONAL, terminationPointTestIndex);
1533                     if (updateFromOperationalTerminationPointAugmentation != null) {
1534                         Map<I, T> updateFromOperationalValues =
1535                                 helper.readValues(updateFromOperationalTerminationPointAugmentation);
1536                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
1537                     }
1538
1539                     // UPDATE:  update the values
1540                     testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
1541                     OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1542                             new OvsdbTerminationPointAugmentationBuilder();
1543                     helper.writeValues(tpUpdateAugmentationBuilder, updateToTestCase.inputValues);
1544                     InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1545                     NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1546                     NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1547                     portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1548                     TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1549                     tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
1550                     tpUpdateBuilder.addAugmentation(tpUpdateAugmentationBuilder.build());
1551                     portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1552                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1553                             portIid, portUpdateNodeBuilder.build()));
1554                     Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1555
1556                     // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1557                     // then repeat for OPERATIONAL data store
1558                     OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1559                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1560                                     LogicalDatastoreType.CONFIGURATION, terminationPointTestIndex);
1561                     if (updateToConfigurationTerminationPointAugmentation != null) {
1562                         Map<I, T> updateToConfigurationValues =
1563                                 helper.readValues(updateToConfigurationTerminationPointAugmentation);
1564                         assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
1565                         assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationValues);
1566                     }
1567                     OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1568                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1569                                     LogicalDatastoreType.OPERATIONAL, terminationPointTestIndex);
1570                     if (updateToOperationalTerminationPointAugmentation != null) {
1571                         Map<I, T> updateToOperationalValues =
1572                                 helper.readValues(updateToOperationalTerminationPointAugmentation);
1573                         if (updateFromTestCase.expectedValues != null) {
1574                             assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
1575                             assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalValues);
1576                         }
1577                     }
1578
1579                     // DELETE handled by TestBridge
1580                 }
1581             }
1582         }
1583     }
1584
1585     /*
1586      * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
1587      *
1588      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1589      */
1590     @Test
1591     public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
1592         testCRUDTerminationPoint(new SouthboundPortExternalIdsBuilder(), "TPPortExternalIds",
1593                 new PortExternalIdsSouthboundHelper());
1594     }
1595
1596     /*
1597      * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1598      *
1599      * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1600      */
1601     @Test
1602     public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
1603         testCRUDTerminationPoint(new SouthboundInterfaceExternalIdsBuilder(), "TPInterfaceExternalIds",
1604                 new InterfaceExternalIdsSouthboundHelper());
1605     }
1606
1607     /*
1608      * Tests the CRUD operations for <code>Interface</code> <code>lldp</code>.
1609      *
1610      * @see <code>SouthboundIT.generateInterfaceLldpTestCases()</code> for specific test case information
1611      */
1612     @Test
1613     public void testCRUDTerminationPointInterfaceLldp() throws InterruptedException {
1614         testCRUDTerminationPoint(new SouthboundInterfaceLldpBuilder(), "TPInterfaceLldp",
1615                 new InterfaceLldpSouthboundHelper());
1616     }
1617
1618     /*
1619      * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1620      *
1621      * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1622      */
1623     @Test
1624     public void testCRUDTerminationPointOptions() throws InterruptedException {
1625         testCRUDTerminationPoint(new SouthboundOptionsBuilder(), "TPOptions", new OptionsSouthboundHelper());
1626     }
1627
1628     /*
1629      * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
1630      *
1631      * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1632      */
1633     @Test
1634     public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
1635         testCRUDTerminationPoint(new SouthboundInterfaceOtherConfigsBuilder(), "TPInterfaceOtherConfigs",
1636                 new InterfaceOtherConfigsSouthboundHelper());
1637     }
1638
1639     /*
1640      * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
1641      *
1642      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1643      */
1644     @Test
1645     public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
1646         testCRUDTerminationPoint(new SouthboundPortOtherConfigsBuilder(), "TPPortOtherConfigs",
1647                 new PortOtherConfigsSouthboundHelper());
1648     }
1649
1650     @Test
1651     public void testCRUDTerminationPoints() throws InterruptedException {
1652         String port1 = "vx1";
1653         String port2 = "vxlanport";
1654         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1655
1656         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1657             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1658             Assert.assertNotNull(bridge);
1659             NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1660                     connectionInfo, bridge.getBridgeName()));
1661             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1662                     createGenericOvsdbTerminationPointAugmentationBuilder();
1663
1664             // add and delete a single port
1665             String portName = port1;
1666             ovsdbTerminationBuilder.setName(portName);
1667             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1668             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1669             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1670             Assert.assertNotNull(terminationPointNode);
1671
1672             SouthboundUtils.createInstanceIdentifier(connectionInfo,
1673                     new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
1674             portName = port1;
1675             InstanceIdentifier<TerminationPoint> nodePath =
1676                     SouthboundUtils.createInstanceIdentifier(connectionInfo,
1677                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1678                             .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1679
1680             Assert.assertTrue("failed to delete port " + portName,
1681                     mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1682             LOG.info("shague: waiting for delete {}", portName);
1683             Thread.sleep(1000);
1684             TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1685             Assert.assertNull(terminationPoint);
1686
1687             // add two ports, then delete them
1688             portName = port1;
1689             ovsdbTerminationBuilder.setName(portName);
1690             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1691             terminationPointIid = getTpIid(connectionInfo, bridge);
1692             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1693             Assert.assertNotNull(terminationPointNode);
1694
1695             portName = port2;
1696             ovsdbTerminationBuilder.setName(portName);
1697             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1698             terminationPointIid = getTpIid(connectionInfo, bridge);
1699             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1700             Assert.assertNotNull(terminationPointNode);
1701
1702             SouthboundUtils.createInstanceIdentifier(connectionInfo,
1703                     new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
1704             portName = port1;
1705             nodePath =
1706                     SouthboundUtils.createInstanceIdentifier(connectionInfo,
1707                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1708                             .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1709
1710             Assert.assertTrue("failed to delete port " + portName,
1711                     mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1712             LOG.info("shague: waiting for delete {}", portName);
1713             Thread.sleep(1000);
1714             terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1715             Assert.assertNull(terminationPoint);
1716
1717             portName = port2;
1718             nodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo,
1719                     new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1720                     .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1721
1722             Assert.assertTrue("failed to delete port " + portName,
1723                     mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1724             LOG.info("shague: waiting for delete {}", portName);
1725             Thread.sleep(1000);
1726             terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1727             Assert.assertNull(terminationPoint);
1728
1729             // DELETE handled by TestBridge
1730         }
1731     }
1732
1733     @Test
1734     public void testCRUDTerminationPointVlan() throws InterruptedException {
1735         final Integer createdVlanId = 4000;
1736         final Integer updatedVlanId = 4001;
1737
1738         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1739
1740         // CREATE
1741         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1742             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1743             Assert.assertNotNull(bridge);
1744             NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1745                     connectionInfo, bridge.getBridgeName()));
1746             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1747                     createGenericOvsdbTerminationPointAugmentationBuilder();
1748             String portName = "testTerminationPointVlanId";
1749             ovsdbTerminationBuilder.setName(portName);
1750             ovsdbTerminationBuilder.setVlanTag(new VlanId(createdVlanId));
1751             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1752             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1753             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1754             Assert.assertNotNull(terminationPointNode);
1755
1756             // READ
1757             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
1758             for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1759                 ovsdbTerminationPointAugmentation = terminationPoint.augmentation(
1760                         OvsdbTerminationPointAugmentation.class);
1761                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1762                     VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1763                     Assert.assertNotNull(actualVlanId);
1764                     Integer actualVlanIdInt = actualVlanId.getValue().toJava();
1765                     Assert.assertEquals(createdVlanId, actualVlanIdInt);
1766                 }
1767             }
1768
1769             // UPDATE
1770             NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1771             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1772                     new OvsdbTerminationPointAugmentationBuilder();
1773             tpUpdateAugmentationBuilder.setVlanTag(new VlanId(updatedVlanId));
1774             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1775             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1776             NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1777             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1778             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1779             tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName)));
1780             tpUpdateBuilder.addAugmentation(tpUpdateAugmentationBuilder.build());
1781             tpUpdateBuilder.setTpId(new TpId(portName));
1782             portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1783             Assert.assertTrue(
1784                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1785             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1786
1787             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1788             for (TerminationPoint terminationPoint :  terminationPointNode.nonnullTerminationPoint().values()) {
1789                 ovsdbTerminationPointAugmentation = terminationPoint.augmentation(
1790                         OvsdbTerminationPointAugmentation.class);
1791                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1792                     VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1793                     Assert.assertNotNull(actualVlanId);
1794                     Integer actualVlanIdInt = actualVlanId.getValue().toJava();
1795                     Assert.assertEquals(updatedVlanId, actualVlanIdInt);
1796                 }
1797             }
1798
1799             // DELETE handled by TestBridge
1800         }
1801     }
1802
1803     @Test
1804     public void testCRUDTerminationPointVlanModes() throws InterruptedException {
1805         final VlanMode updatedVlanMode = VlanMode.Access;
1806         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1807         VlanMode []vlanModes = VlanMode.values();
1808         for (VlanMode vlanMode : vlanModes) {
1809             // CREATE
1810             try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1811                 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1812                 Assert.assertNotNull(bridge);
1813                 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1814                         connectionInfo, bridge.getBridgeName()));
1815                 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1816                         createGenericOvsdbTerminationPointAugmentationBuilder();
1817                 String portName = "testTerminationPointVlanMode" + vlanMode.toString();
1818                 ovsdbTerminationBuilder.setName(portName);
1819                 ovsdbTerminationBuilder.setVlanMode(vlanMode);
1820                 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1821                 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1822                 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1823                 Assert.assertNotNull(terminationPointNode);
1824
1825                 // READ
1826                 for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1827                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1828                             terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1829                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1830                         //test
1831                         Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
1832                     }
1833                 }
1834
1835                 // UPDATE
1836                 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1837                 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1838                         new OvsdbTerminationPointAugmentationBuilder();
1839                 tpUpdateAugmentationBuilder.setVlanMode(updatedVlanMode);
1840                 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1841                 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1842                 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1843                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1844                 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1845                 tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName)));
1846                 tpUpdateBuilder.addAugmentation(tpUpdateAugmentationBuilder.build());
1847                 tpUpdateBuilder.setTpId(new TpId(portName));
1848                 portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1849                 Assert.assertTrue(
1850                         mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1851                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1852
1853                 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1854                 for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1855                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1856                             terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1857                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1858                         //test
1859                         Assert.assertEquals(updatedVlanMode, ovsdbTerminationPointAugmentation.getVlanMode());
1860                     }
1861                 }
1862
1863                 // DELETE handled by TestBridge
1864             }
1865         }
1866     }
1867
1868     private static List<Set<Integer>> generateVlanSets() {
1869         int min = 0;
1870         int max = 4095;
1871         return Lists.newArrayList(
1872                 Collections.<Integer>emptySet(),
1873                 Collections.singleton(2222),
1874                 Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2));
1875     }
1876
1877     private static List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
1878         List<Trunks> trunkList = new ArrayList<>();
1879         for (Integer trunk : trunkSet) {
1880             TrunksBuilder trunkBuilder = new TrunksBuilder();
1881             trunkBuilder.setTrunk(new VlanId(trunk));
1882             trunkList.add(trunkBuilder.build());
1883         }
1884         return trunkList;
1885     }
1886
1887     @Test
1888     public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
1889         final List<Trunks> updatedTrunks = buildTrunkList(Collections.singleton(2011));
1890         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1891         Iterable<Set<Integer>> vlanSets = generateVlanSets();
1892         int testCase = 0;
1893         for (Set<Integer> vlanSet : vlanSets) {
1894             ++testCase;
1895             // CREATE
1896             try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1897                 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1898                 Assert.assertNotNull(bridge);
1899                 NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName());
1900                 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1901                         createGenericOvsdbTerminationPointAugmentationBuilder();
1902                 String portName = "testTerminationPointVlanTrunks" + testCase;
1903                 ovsdbTerminationBuilder.setName(portName);
1904                 List<Trunks> trunks = buildTrunkList(vlanSet);
1905                 ovsdbTerminationBuilder.setTrunks(trunks);
1906                 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1907                 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1908                 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1909                 Assert.assertNotNull(terminationPointNode);
1910
1911                 // READ
1912                 Collection<TerminationPoint> terminationPoints =
1913                         terminationPointNode.nonnullTerminationPoint().values();
1914                 for (TerminationPoint terminationPoint : terminationPoints) {
1915                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1916                             terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1917                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1918                         List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
1919                         for (Trunks trunk : trunks) {
1920                             Assert.assertTrue(actualTrunks.contains(trunk));
1921                         }
1922                     }
1923                 }
1924
1925
1926                 // UPDATE
1927                 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1928                 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1929                         new OvsdbTerminationPointAugmentationBuilder();
1930                 tpUpdateAugmentationBuilder.setTrunks(updatedTrunks);
1931                 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1932                 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1933                 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1934                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1935                 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1936                 tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName)));
1937                 tpUpdateBuilder.addAugmentation(tpUpdateAugmentationBuilder.build());
1938                 tpUpdateBuilder.setTpId(new TpId(portName));
1939                 portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1940                 Assert.assertTrue(
1941                         mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1942                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1943
1944                 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1945                 for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1946                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1947                             terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1948                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1949                         //test
1950                         Assert.assertEquals(updatedTrunks, ovsdbTerminationPointAugmentation.getTrunks());
1951                     }
1952                 }
1953
1954                 // DELETE handled by TestBridge
1955             }
1956         }
1957     }
1958
1959     /*
1960      * Tests setting and deleting <code>qos</code> field in a <code>port</code>.
1961      */
1962     @Test
1963     public void testCRUDTerminationPointQos() throws InterruptedException {
1964         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1965         String testQosId = "testQosEntry";
1966
1967         // CREATE
1968         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1969                 TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId),
1970                         SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HFSC), null, null)) {
1971             OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
1972                     LogicalDatastoreType.OPERATIONAL);
1973             QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
1974             Assert.assertNotNull(operQos);
1975             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1976             Assert.assertNotNull(bridge);
1977             NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName());
1978             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1979                     createGenericOvsdbTerminationPointAugmentationBuilder();
1980             String portName = "testTerminationPointQos";
1981             ovsdbTerminationBuilder.setName(portName);
1982             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1983
1984
1985            // READ and check that qos uuid has been added to the port
1986             InstanceIdentifier<TerminationPoint> tpEntryIid = getTpIid(connectionInfo, bridge)
1987                     .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1988             TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid);
1989             Assert.assertNotNull(terminationPoint);
1990
1991             // UPDATE - remove the qos entry from the port
1992             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1993                     new OvsdbTerminationPointAugmentationBuilder();
1994             tpUpdateAugmentationBuilder.setName(portName);
1995             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1996             tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName)));
1997             tpUpdateBuilder.addAugmentation(tpUpdateAugmentationBuilder.build());
1998             tpUpdateBuilder.setTpId(new TpId(portName));
1999
2000             Assert.assertTrue(
2001                     mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpEntryIid, tpUpdateBuilder.build()));
2002             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2003
2004             // READ and verify that qos uuid has been removed from port
2005             TerminationPoint terminationPointUpdate = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid);
2006             Assert.assertNotNull(terminationPointUpdate);
2007
2008             // DELETE handled by TestBridge
2009         }
2010     }
2011
2012     @Test
2013     public void testGetOvsdbNodes() throws InterruptedException {
2014         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2015         InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
2016                 .create(NetworkTopology.class)
2017                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
2018
2019         Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
2020         InstanceIdentifier<Node> expectedNodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
2021         NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class).getNodeId();
2022         Node foundNode = null;
2023         Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
2024         Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
2025         LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
2026         for (Node node : topology.nonnullNode().values()) {
2027             if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
2028                 foundNode = node;
2029                 break;
2030             }
2031         }
2032         Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
2033     }
2034
2035     /*
2036      * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
2037      */
2038     @Test
2039     public void testCRUDBridgeOtherConfigs() throws InterruptedException {
2040         testCRUDBridge("BridgeOtherConfigs", new SouthboundBridgeOtherConfigsBuilder(),
2041                 new BridgeOtherConfigsSouthboundHelper());
2042     }
2043
2044     private interface SouthboundBridgeHelper<I extends Identifier<T>, T extends Identifiable<I>> {
2045         void writeValues(OvsdbBridgeAugmentationBuilder builder, List<T> values);
2046
2047         Map<I, T> readValues(OvsdbBridgeAugmentation augmentation);
2048     }
2049
2050     private static <I extends Identifier<T>, T extends Identifiable<I>> void testCRUDBridge(String prefix,
2051             KeyValueBuilder<T> builder, SouthboundBridgeHelper<I, T> helper) throws InterruptedException {
2052         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2053         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2054         // the update has been performed.
2055         List<SouthboundTestCase<I, T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2056         List<SouthboundTestCase<I, T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2057         for (SouthboundTestCase<I, T> updateFromTestCase : updateFromTestCases) {
2058             for (SouthboundTestCase<I, T> updateToTestCase : updateToTestCases) {
2059                 String testBridgeName = String.format("%s_%s", prefix, updateToTestCase.name);
2060
2061                 // CREATE: Create the test bridge
2062                 final OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(testBridgeName);
2063                 final InstanceIdentifier<Node> bridgeIid =
2064                         SouthboundUtils.createInstanceIdentifier(connectionInfo, ovsdbBridgeName);
2065                 final NodeId bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
2066                 final NodeBuilder bridgeCreateNodeBuilder = new NodeBuilder();
2067                 bridgeCreateNodeBuilder.setNodeId(bridgeNodeId);
2068                 OvsdbBridgeAugmentationBuilder bridgeCreateAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
2069                 bridgeCreateAugmentationBuilder.setBridgeName(ovsdbBridgeName);
2070                 bridgeCreateAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
2071                 bridgeCreateAugmentationBuilder.setFailMode(
2072                         SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
2073                 setManagedBy(bridgeCreateAugmentationBuilder, connectionInfo);
2074                 helper.writeValues(bridgeCreateAugmentationBuilder, updateFromTestCase.inputValues);
2075                 bridgeCreateNodeBuilder.addAugmentation(bridgeCreateAugmentationBuilder.build());
2076                 LOG.debug("Built with the intent to store bridge data {}", bridgeCreateAugmentationBuilder);
2077                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2078                         bridgeCreateNodeBuilder.build()));
2079                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2080
2081                 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2082                 // then repeat for OPERATIONAL data store
2083                 Map<I, T> updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo,
2084                         testBridgeName, LogicalDatastoreType.CONFIGURATION));
2085                 assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationExternalIds);
2086                 Map<I, T> updateFromOperationalExternalIds = helper.readValues(getBridge(connectionInfo,
2087                         testBridgeName));
2088                 assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalExternalIds);
2089
2090                 // UPDATE:  update the values
2091                 final OvsdbBridgeAugmentationBuilder bridgeUpdateAugmentationBuilder =
2092                         new OvsdbBridgeAugmentationBuilder();
2093                 helper.writeValues(bridgeUpdateAugmentationBuilder, updateToTestCase.inputValues);
2094                 final NodeBuilder bridgeUpdateNodeBuilder = new NodeBuilder();
2095                 final Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
2096                 bridgeUpdateNodeBuilder.setNodeId(bridgeNode.getNodeId());
2097                 bridgeUpdateNodeBuilder.withKey(bridgeNode.key());
2098                 bridgeUpdateNodeBuilder.addAugmentation(bridgeUpdateAugmentationBuilder.build());
2099                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2100                         bridgeUpdateNodeBuilder.build()));
2101                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2102
2103                 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2104                 // then repeat for OPERATIONAL data store
2105                 Map<I, T> updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
2106                         LogicalDatastoreType.CONFIGURATION));
2107                 assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationExternalIds);
2108                 assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationExternalIds);
2109                 Map<I, T> updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
2110                 if (updateFromTestCase.expectedValues != null) {
2111                     assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalExternalIds);
2112                     assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalExternalIds);
2113                 }
2114
2115                 // DELETE
2116                 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid));
2117                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2118             }
2119         }
2120     }
2121
2122     /*
2123      * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
2124      */
2125     @Test
2126     public void testCRUDBridgeExternalIds() throws InterruptedException {
2127         testCRUDBridge("BridgeExternalIds", new SouthboundBridgeExternalIdsBuilder(),
2128                 new BridgeExternalIdsSouthboundHelper());
2129     }
2130
2131     @Test
2132     public void testAddDeleteQos() throws InterruptedException {
2133         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2134         OvsdbNodeAugmentation ovsdbNodeAugmentation;
2135         Uri qosUri = new Uri("QOS-ROW");
2136         List<String> typeList = new ArrayList<>();
2137         typeList.add(SouthboundConstants.QOS_LINUX_HTB);
2138         typeList.add(SouthboundConstants.QOS_LINUX_HFSC);
2139
2140         for (String qosType : typeList) {
2141             try (TestQos testQos = new TestQos(connectionInfo, qosUri, SouthboundMapper.createQosType(qosType),
2142                     null, null)) {
2143                 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2144                         LogicalDatastoreType.OPERATIONAL);
2145                 QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation);
2146                 Assert.assertNotNull(operQosHtb);
2147             }
2148             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2149                     LogicalDatastoreType.OPERATIONAL);
2150             QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation);
2151             Assert.assertNull(operQosHtb);
2152         }
2153     }
2154
2155     @Test
2156     public void testAddDeleteQueue() throws InterruptedException {
2157         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2158         Uri queueUri = new Uri("QUEUE-A1");
2159
2160         try (TestQueue testQueue = new TestQueue(connectionInfo, queueUri, Short.valueOf("25"), null, null)) {
2161             OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2162                     LogicalDatastoreType.OPERATIONAL);
2163             Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation);
2164             Assert.assertNotNull(operQueue);
2165         }
2166         OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2167                 LogicalDatastoreType.OPERATIONAL);
2168         Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation);
2169         Assert.assertNull(operQueue);
2170     }
2171
2172     private static class SouthboundQueuesExternalIdsHelper
2173             implements SouthboundQueueHelper<QueuesExternalIdsKey, QueuesExternalIds> {
2174         @Override
2175         public void writeValues(QueuesBuilder builder, List<QueuesExternalIds> values) {
2176             builder.setQueuesExternalIds(values);
2177         }
2178
2179         @Override
2180         public Map<QueuesExternalIdsKey, QueuesExternalIds> readValues(Queues queue) {
2181             return queue.getQueuesExternalIds();
2182         }
2183     }
2184
2185     private static class SouthboundQueuesOtherConfigHelper
2186             implements SouthboundQueueHelper<QueuesOtherConfigKey, QueuesOtherConfig> {
2187         @Override
2188         public void writeValues(QueuesBuilder builder, List<QueuesOtherConfig> values) {
2189             builder.setQueuesOtherConfig(values);
2190         }
2191
2192         @Override
2193         public Map<QueuesOtherConfigKey, QueuesOtherConfig> readValues(Queues queue) {
2194             return queue.getQueuesOtherConfig();
2195         }
2196     }
2197
2198     private interface SouthboundQueueHelper<I extends Identifier<T>, T extends Identifiable<I>> {
2199         void writeValues(QueuesBuilder builder, List<T> values);
2200
2201         Map<I, T> readValues(Queues queue);
2202     }
2203
2204     private static Queues getQueue(Uri queueId, OvsdbNodeAugmentation node) {
2205         for (Queues queue : node.nonnullQueues().values()) {
2206             if (queue.key().getQueueId().getValue().equals(queueId.getValue())) {
2207                 return queue;
2208             }
2209         }
2210         return null;
2211     }
2212
2213     private static class SouthboundQosExternalIdsHelper
2214             implements SouthboundQosHelper<QosExternalIdsKey, QosExternalIds> {
2215         @Override
2216         public void writeValues(QosEntriesBuilder builder, List<QosExternalIds> values) {
2217             builder.setQosExternalIds(values);
2218         }
2219
2220         @Override
2221         public Map<QosExternalIdsKey, QosExternalIds> readValues(QosEntries qos) {
2222             return qos.getQosExternalIds();
2223         }
2224     }
2225
2226     private static class SouthboundQosOtherConfigHelper
2227             implements SouthboundQosHelper<QosOtherConfigKey, QosOtherConfig> {
2228         @Override
2229         public void writeValues(QosEntriesBuilder builder, List<QosOtherConfig> values) {
2230             builder.setQosOtherConfig(values);
2231         }
2232
2233         @Override
2234         public Map<QosOtherConfigKey, QosOtherConfig> readValues(QosEntries qos) {
2235             return qos.getQosOtherConfig();
2236         }
2237     }
2238
2239     private interface SouthboundQosHelper<I extends Identifier<T>, T extends Identifiable<I>> {
2240         void writeValues(QosEntriesBuilder builder, List<T> values);
2241
2242         Map<I, T> readValues(QosEntries qos);
2243     }
2244
2245     private static QosEntries getQos(Uri qosId, OvsdbNodeAugmentation node) {
2246         for (QosEntries qos : node.nonnullQosEntries().values()) {
2247             if (qos.key().getQosId().equals(qosId)) {
2248                 return qos;
2249             }
2250         }
2251         return null;
2252     }
2253
2254     private static <I extends Identifier<T>, T extends Identifiable<I>> void testCRUDQueue(
2255             KeyValueBuilder<T> builder, String prefix, SouthboundQueueHelper<I, T> helper)
2256             throws InterruptedException {
2257
2258         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2259
2260         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2261         // the update has been performed.
2262         List<SouthboundTestCase<I, T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2263         List<SouthboundTestCase<I, T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2264
2265         for (SouthboundTestCase<I, T> updateFromTestCase : updateFromTestCases) {
2266             for (SouthboundTestCase<I, T> updateToTestCase : updateToTestCases) {
2267                 String testQueueId = String.format("%s_%s", prefix, updateToTestCase.name);
2268
2269                 // CREATE: and update the test queue with starting values.
2270                 try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId),
2271                         Short.valueOf("45"), null, null)) {
2272                     QueuesBuilder queuesBuilder = new QueuesBuilder();
2273                     queuesBuilder.setQueueId(new Uri(testQueueId));
2274                     InstanceIdentifier<Queues> queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2275                             .augmentation(OvsdbNodeAugmentation.class)
2276                             .child(Queues.class, queuesBuilder.build().key());
2277                     final NotifyingDataChangeListener queueConfigurationListener =
2278                             new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, queueIid);
2279                     queueConfigurationListener.registerDataChangeListener();
2280                     final NotifyingDataChangeListener queueOperationalListener =
2281                             new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid);
2282                     queueOperationalListener.registerDataChangeListener();
2283
2284                     helper.writeValues(queuesBuilder, updateFromTestCase.inputValues);
2285                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2286                             queueIid, queuesBuilder.build()));
2287                     queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2288
2289                     // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store,
2290                     // then repeat for OPERATIONAL data store
2291                     OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2292                             LogicalDatastoreType.CONFIGURATION);
2293                     Queues queueFromConfig =
2294                             getQueue(new Uri(testQueueId), updateFromConfigurationOvsdbNodeAugmentation);
2295                     if (queueFromConfig != null) {
2296                         assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(queueFromConfig));
2297                     }
2298
2299                     queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2300                     OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2301                             LogicalDatastoreType.OPERATIONAL);
2302                     Queues queueFromOper = getQueue(new Uri(testQueueId), updateFromOperationalOvsdbNodeAugmentation);
2303                     if (queueFromOper != null) {
2304                         assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(queueFromOper));
2305                     }
2306
2307                     // UPDATE:  update the values
2308                     QueuesBuilder queuesUpdateBuilder = new QueuesBuilder();
2309                     queuesUpdateBuilder.setQueueId(new Uri(testQueueId));
2310                     helper.writeValues(queuesUpdateBuilder, updateToTestCase.inputValues);
2311                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2312                             queueIid, queuesUpdateBuilder.build()));
2313                     queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2314
2315                     // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store,
2316                     // then repeat for OPERATIONAL data store
2317                     OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2318                             LogicalDatastoreType.CONFIGURATION);
2319                     Queues queueToConfig = getQueue(new Uri(testQueueId), updateToConfigurationOvsdbNodeAugmentation);
2320                     if (queueToConfig != null) {
2321                         assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(queueToConfig));
2322                     }
2323
2324                     queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2325                     OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2326                             LogicalDatastoreType.OPERATIONAL);
2327                     Queues queueToOper = getQueue(new Uri(testQueueId), updateToOperationalOvsdbNodeAugmentation);
2328                     if (queueToOper != null) {
2329                         assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(queueToOper));
2330                     }
2331
2332                     // DELETE handled by TestQueue
2333                 }
2334             }
2335         }
2336     }
2337
2338     @Test
2339     public void testCRUDQueueExternalIds() throws InterruptedException {
2340         testCRUDQueue(new SouthboundQueuesExternalIdsBuilder(), "QueueExternalIds",
2341                 new SouthboundQueuesExternalIdsHelper());
2342     }
2343
2344     @Test
2345     public void testCRUDQueueOtherConfig() throws InterruptedException {
2346         testCRUDQueue(new SouthboundQueuesOtherConfigBuilder(), "QueueOtherConfig",
2347                 new SouthboundQueuesOtherConfigHelper());
2348     }
2349
2350     @Test
2351     public void testCRUDQueueDscp() throws InterruptedException {
2352         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2353         String testQueueId = "testQueueDscp";
2354
2355         // CREATE: and update the test queue with starting values.
2356         try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), (short) 0, null, null)) {
2357             for (Short dscp = 1; dscp < 64; dscp++) {
2358                 QueuesBuilder queuesBuilder = new QueuesBuilder();
2359                 queuesBuilder.setQueueId(new Uri(testQueueId));
2360                 InstanceIdentifier<Queues> queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2361                         .augmentation(OvsdbNodeAugmentation.class)
2362                         .child(Queues.class, queuesBuilder.build().key());
2363                 final NotifyingDataChangeListener queueOperationalListener =
2364                         new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid);
2365                 queueOperationalListener.registerDataChangeListener();
2366
2367                 queuesBuilder.setDscp(dscp);
2368                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2369                         queueIid, queuesBuilder.build()));
2370                 queueOperationalListener.waitForUpdate(OVSDB_ROUNDTRIP_TIMEOUT);
2371
2372                 // READ: Read the test queue and ensure changes are propagated to the OPERATIONAL data store
2373                 // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2374                 OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2375                         LogicalDatastoreType.OPERATIONAL);
2376                 Queues operQueue = getQueue(new Uri(testQueueId), ovsdbNodeAugmentation);
2377                 Assert.assertNotNull(operQueue);
2378                 Short operDscp = operQueue.getDscp().toJava();
2379                 Assert.assertNotNull(operDscp);
2380                 Assert.assertEquals(dscp, operDscp);
2381             }
2382
2383             // DELETE handled by TestQueue
2384         }
2385
2386     }
2387
2388     private static <I extends Identifier<T>, T extends Identifiable<I>> void testCRUDQos(
2389             KeyValueBuilder<T> builder, String prefix, SouthboundQosHelper<I, T> helper)
2390             throws InterruptedException {
2391
2392         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2393
2394         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2395         // the update has been performed.
2396         List<SouthboundTestCase<I, T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2397         List<SouthboundTestCase<I, T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2398
2399         for (SouthboundTestCase<I, T> updateFromTestCase : updateFromTestCases) {
2400             for (SouthboundTestCase<I, T> updateToTestCase : updateToTestCases) {
2401                 String testQosId = String.format("%s_%s", prefix, updateToTestCase.name);
2402
2403                 // CREATE: and update the test qos with starting values.
2404                 try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId),
2405                         SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null)) {
2406                     QosEntriesBuilder qosBuilder = new QosEntriesBuilder();
2407                     qosBuilder.setQosId(new Uri(testQosId));
2408                     InstanceIdentifier<QosEntries> qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2409                             .augmentation(OvsdbNodeAugmentation.class)
2410                             .child(QosEntries.class, qosBuilder.build().key());
2411                     final NotifyingDataChangeListener qosConfigurationListener =
2412                             new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, qosIid);
2413                     qosConfigurationListener.registerDataChangeListener();
2414                     final NotifyingDataChangeListener qosOperationalListener =
2415                             new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid);
2416                     qosOperationalListener.registerDataChangeListener();
2417
2418                     helper.writeValues(qosBuilder, updateFromTestCase.inputValues);
2419                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2420                             qosIid, qosBuilder.build()));
2421                     qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2422
2423                     // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store,
2424                     // then repeat for OPERATIONAL data store
2425                     OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2426                             LogicalDatastoreType.CONFIGURATION);
2427                     QosEntries qosFromConfig = getQos(new Uri(testQosId), updateFromConfigurationOvsdbNodeAugmentation);
2428                     if (qosFromConfig != null) {
2429                         assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(qosFromConfig));
2430                     }
2431
2432                     qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2433                     OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2434                             LogicalDatastoreType.OPERATIONAL);
2435                     QosEntries qosFromOper = getQos(new Uri(testQosId), updateFromOperationalOvsdbNodeAugmentation);
2436                     if (qosFromOper != null) {
2437                         assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(qosFromOper));
2438                     }
2439
2440                     // UPDATE:  update the values
2441                     QosEntriesBuilder qosUpdateBuilder = new QosEntriesBuilder();
2442                     qosUpdateBuilder.setQosId(new Uri(testQosId));
2443                     helper.writeValues(qosUpdateBuilder, updateToTestCase.inputValues);
2444                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2445                             qosIid, qosUpdateBuilder.build()));
2446                     qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2447
2448                     // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store,
2449                     // then repeat for OPERATIONAL data store
2450                     OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2451                             LogicalDatastoreType.CONFIGURATION);
2452                     QosEntries qosToConfig = getQos(new Uri(testQosId), updateToConfigurationOvsdbNodeAugmentation);
2453                     if (qosToConfig != null) {
2454                         assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(qosToConfig));
2455                     }
2456
2457                     qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2458                     OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2459                             LogicalDatastoreType.OPERATIONAL);
2460                     QosEntries qosToOper = getQos(new Uri(testQosId), updateToOperationalOvsdbNodeAugmentation);
2461                     if (qosToOper != null) {
2462                         assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(qosToOper));
2463                     }
2464
2465                     // DELETE handled by TestQueue
2466                 }
2467             }
2468         }
2469     }
2470
2471     @Test
2472     public void testCRUDQosExternalIds() throws InterruptedException {
2473         testCRUDQos(new SouthboundQosExternalIdsBuilder(), "QosExternalIds",
2474                 new SouthboundQosExternalIdsHelper());
2475     }
2476
2477     @Test
2478     public void testCRUDQosOtherConfig() throws InterruptedException {
2479         testCRUDQos(new SouthboundQosOtherConfigBuilder(), "QosOtherConfig",
2480                 new SouthboundQosOtherConfigHelper());
2481     }
2482
2483     @Test
2484     public void testCRUDQosQueues() throws InterruptedException {
2485         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2486         String testQosId = "testQosQueues";
2487
2488         // CREATE: and update the test queue with starting values.
2489         try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId),
2490                 SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null);
2491                 TestQueue testQueue1 = new TestQueue(connectionInfo, new Uri("queue1"), Short.valueOf("12"), null,
2492                     null);
2493                 TestQueue testQueue2 = new TestQueue(connectionInfo, new Uri("queue2"), Short.valueOf("35"), null,
2494                     null)) {
2495             QosEntriesBuilder qosBuilder = new QosEntriesBuilder();
2496             qosBuilder.setQosId(new Uri(testQosId));
2497             InstanceIdentifier<QosEntries> qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2498                     .augmentation(OvsdbNodeAugmentation.class)
2499                     .child(QosEntries.class, qosBuilder.build().key());
2500             final NotifyingDataChangeListener qosOperationalListener =
2501                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid);
2502             qosOperationalListener.registerDataChangeListener();
2503
2504             // READ, UPDATE:  Read the UUIDs of the Queue rows and add them to the
2505             // configuration of the Qos row.
2506             OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2507                     LogicalDatastoreType.OPERATIONAL);
2508
2509             Queues operQueue1 = getQueue(new Uri("queue1"), ovsdbNodeAugmentation);
2510
2511             Assert.assertNotNull(operQueue1);
2512
2513             InstanceIdentifier<Queues> queue1Iid = testQueue1.getInstanceIdentifier();
2514             OvsdbQueueRef queue1Ref = new OvsdbQueueRef(queue1Iid);
2515
2516             Queues operQueue2 = getQueue(new Uri("queue2"), ovsdbNodeAugmentation);
2517             Assert.assertNotNull(operQueue2);
2518             InstanceIdentifier<Queues> queue2Iid = testQueue2.getInstanceIdentifier();
2519             OvsdbQueueRef queue2Ref = new OvsdbQueueRef(queue2Iid);
2520
2521             List<QueueList> queueList = new ArrayList<>();
2522             queueList.add(new QueueListBuilder().setQueueNumber(Uint32.ONE).setQueueRef(queue1Ref).build());
2523             queueList.add(new QueueListBuilder().setQueueNumber(Uint32.TWO).setQueueRef(queue2Ref).build());
2524
2525             qosBuilder.setQueueList(queueList);
2526
2527             Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2528                     qosIid, qosBuilder.build()));
2529             qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2530
2531             // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store
2532             // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2533             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2534                     LogicalDatastoreType.OPERATIONAL);
2535             QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2536             Assert.assertNotNull(operQos);
2537             Map<QueueListKey, QueueList> operQueueList = operQos.getQueueList();
2538             Assert.assertNotNull(operQueueList);
2539             for (QueueList queueEntry : queueList) {
2540                 Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
2541             }
2542
2543             // DELETE one queue from queue list and check that one remains
2544             KeyedInstanceIdentifier<QueueList, QueueListKey> qosQueueIid = qosIid
2545                     .child(QueueList.class, new QueueListKey(Uint32.ONE));
2546             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid));
2547             qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2548
2549             // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store
2550             // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2551             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2552                     LogicalDatastoreType.OPERATIONAL);
2553             operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2554             Assert.assertNotNull(operQos);
2555             operQueueList = operQos.getQueueList();
2556             Assert.assertNotNull(operQueueList);
2557
2558             for (QueueList queueEntry : queueList) {
2559                 if (queueEntry.getQueueRef().equals(queue2Ref)) {
2560                     Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
2561                 } else if (queueEntry.getQueueRef().equals(queue1Ref)) {
2562                     Assert.assertFalse(isQueueInList(operQueueList, queueEntry));
2563                 } else {
2564                     Assert.assertTrue("Unknown queue entry in qos queue list", false);
2565                 }
2566             }
2567
2568             // DELETE  queue list and check that list is empty
2569             qosQueueIid = qosIid
2570                     .child(QueueList.class, new QueueListKey(Uint32.ONE));
2571             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid));
2572             qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2573
2574             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2575                     LogicalDatastoreType.OPERATIONAL);
2576             operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2577             Assert.assertNotNull(operQos);
2578             operQueueList = operQos.getQueueList();
2579             Assert.assertNotNull(operQueueList);
2580             Assert.assertTrue(operQueueList.isEmpty());
2581         }
2582     }
2583
2584
2585
2586     private static Boolean isQueueInList(Map<QueueListKey, QueueList> queueList, QueueList queue) {
2587         for (QueueList queueEntry : queueList.values()) {
2588             if (queueEntry.getQueueNumber().equals(queue.getQueueNumber())
2589                     && queueEntry.getQueueRef().equals(queue.getQueueRef())) {
2590                 return true;
2591             }
2592         }
2593         return false;
2594     }
2595
2596     /**
2597      * <p>
2598      * Representation of a southbound test case. Each test case has a name, a list of input values and a list of
2599      * expected values. The input values are provided to the augmentation builder, and the expected values are checked
2600      * against the output of the resulting augmentation.
2601      * </p>
2602      * <p>
2603      * Instances of this class are immutable.
2604      * </p>
2605      *
2606      * @param <T> The type of data used for the test case.
2607      */
2608     private static final class SouthboundTestCase<I extends Identifier<T>, T extends Identifiable<I>> {
2609         private final String name;
2610         private final List<T> inputValues;
2611         private final Map<I, T> expectedValues;
2612
2613         /**
2614          * Creates an instance of a southbound test case.
2615          *
2616          * @param name The test case's name.
2617          * @param inputValues The input values (provided as input to the underlying augmentation builder).
2618          * @param expectedValues The expected values (checked against the output of the underlying augmentation).
2619          */
2620         SouthboundTestCase(final String name, final List<T> inputValues, final List<T> expectedValues) {
2621             this.name = name;
2622             this.inputValues = inputValues;
2623             this.expectedValues = Maps.uniqueIndex(expectedValues, Identifiable::key);
2624         }
2625     }
2626
2627     /**
2628      * Southbound test case builder.
2629      *
2630      * @param <T> The type of data used for the test case.
2631      */
2632     private static final class SouthboundTestCaseBuilder<I extends Identifier<T>, T extends Identifiable<I>> {
2633         private String name;
2634         private List<T> inputValues;
2635         private List<T> expectedValues;
2636
2637         /**
2638          * Creates a builder. Builders may be reused, the generated immutable instances are independent of the
2639          * builders. There are no default values.
2640          */
2641         SouthboundTestCaseBuilder() {
2642             // Nothing to do
2643         }
2644
2645         /**
2646          * Sets the test case's name.
2647          *
2648          * @param value The test case's name.
2649          * @return The builder.
2650          */
2651         public SouthboundTestCaseBuilder<I, T> name(final String value) {
2652             this.name = value;
2653             return this;
2654         }
2655
2656         /**
2657          * Sets the input values.
2658          *
2659          * @param values The input values.
2660          * @return The builder.
2661          */
2662         @SafeVarargs
2663         public final SouthboundTestCaseBuilder<I, T> input(final T... values) {
2664             this.inputValues = Lists.newArrayList(values);
2665             return this;
2666         }
2667
2668         /**
2669          * Indicates that the provided input values should be expected as output values.
2670          *
2671          * @return The builder.
2672          */
2673         public SouthboundTestCaseBuilder<I, T> expectInputAsOutput() {
2674             this.expectedValues = this.inputValues;
2675             return this;
2676         }
2677
2678         /**
2679          * Indicates that no output should be expected.
2680          *
2681          * @return The builder.
2682          */
2683         public SouthboundTestCaseBuilder<I, T> expectNoOutput() {
2684             this.expectedValues = null;
2685             return this;
2686         }
2687
2688         /**
2689          * Builds an immutable instance representing the test case.
2690          *
2691          * @return The test case.
2692          */
2693         public SouthboundTestCase<I, T> build() {
2694             return new SouthboundTestCase<>(name, inputValues, expectedValues);
2695         }
2696     }
2697
2698     private abstract static class KeyValueBuilder<T> {
2699         private static final int COUNTER_START = 0;
2700         private int counter = COUNTER_START;
2701
2702         protected abstract Builder<T> builder();
2703
2704         protected abstract void setKey(Builder<T> builder, String key);
2705
2706         protected abstract void setValue(Builder<T> builder, String value);
2707
2708         protected abstract boolean isValueMandatory();
2709
2710         public final T build(final String testName, final String key, final String value) {
2711             final Builder<T> builder = builder();
2712             this.counter++;
2713             if (key != null) {
2714                 setKey(builder, String.format(FORMAT_STR, testName, key, this.counter));
2715             }
2716             if (value != null) {
2717                 setValue(builder, String.format(FORMAT_STR, testName, value, this.counter));
2718             }
2719             return builder.build();
2720         }
2721
2722         public final void reset() {
2723             this.counter = COUNTER_START;
2724         }
2725     }
2726
2727     private static final class SouthboundQueuesExternalIdsBuilder extends KeyValueBuilder<QueuesExternalIds> {
2728         @Override
2729         protected Builder<QueuesExternalIds> builder() {
2730             return new QueuesExternalIdsBuilder();
2731         }
2732
2733         @Override
2734         protected void setKey(Builder<QueuesExternalIds> builder, String key) {
2735             ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdKey(key);
2736         }
2737
2738         @Override
2739         protected void setValue(Builder<QueuesExternalIds> builder, String value) {
2740             ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdValue(value);
2741         }
2742
2743         @Override
2744         protected boolean isValueMandatory() {
2745             return true;
2746         }
2747     }
2748
2749     private static final class SouthboundQueuesOtherConfigBuilder extends KeyValueBuilder<QueuesOtherConfig> {
2750         @Override
2751         protected Builder<QueuesOtherConfig> builder() {
2752             return new QueuesOtherConfigBuilder();
2753         }
2754
2755         @Override
2756         protected void setKey(Builder<QueuesOtherConfig> builder, String key) {
2757             ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigKey(key);
2758         }
2759
2760         @Override
2761         protected void setValue(Builder<QueuesOtherConfig> builder, String value) {
2762             ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigValue(value);
2763         }
2764
2765         @Override
2766         protected boolean isValueMandatory() {
2767             return false;
2768         }
2769     }
2770
2771     private static final class SouthboundQosExternalIdsBuilder extends KeyValueBuilder<QosExternalIds> {
2772         @Override
2773         protected Builder<QosExternalIds> builder() {
2774             return new QosExternalIdsBuilder();
2775         }
2776
2777         @Override
2778         protected void setKey(Builder<QosExternalIds> builder, String key) {
2779             ((QosExternalIdsBuilder) builder).setQosExternalIdKey(key);
2780         }
2781
2782         @Override
2783         protected void setValue(Builder<QosExternalIds> builder, String value) {
2784             ((QosExternalIdsBuilder) builder).setQosExternalIdValue(value);
2785         }
2786
2787         @Override
2788         protected boolean isValueMandatory() {
2789             return true;
2790         }
2791     }
2792
2793     private static final class SouthboundQosOtherConfigBuilder extends KeyValueBuilder<QosOtherConfig> {
2794         @Override
2795         protected Builder<QosOtherConfig> builder() {
2796             return new QosOtherConfigBuilder();
2797         }
2798
2799         @Override
2800         protected void setKey(Builder<QosOtherConfig> builder, String key) {
2801             ((QosOtherConfigBuilder) builder).setOtherConfigKey(key);
2802         }
2803
2804         @Override
2805         protected void setValue(Builder<QosOtherConfig> builder, String value) {
2806             ((QosOtherConfigBuilder) builder).setOtherConfigValue(value);
2807         }
2808
2809         @Override
2810         protected boolean isValueMandatory() {
2811             return false;
2812         }
2813     }
2814
2815     private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder<PortExternalIds> {
2816         @Override
2817         protected Builder<PortExternalIds> builder() {
2818             return new PortExternalIdsBuilder();
2819         }
2820
2821         @Override
2822         protected void setKey(Builder<PortExternalIds> builder, String key) {
2823             ((PortExternalIdsBuilder) builder).setExternalIdKey(key);
2824         }
2825
2826         @Override
2827         protected void setValue(Builder<PortExternalIds> builder, String value) {
2828             ((PortExternalIdsBuilder) builder).setExternalIdValue(value);
2829         }
2830
2831         @Override
2832         protected boolean isValueMandatory() {
2833             return true;
2834         }
2835     }
2836
2837     private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder<InterfaceExternalIds> {
2838         @Override
2839         protected Builder<InterfaceExternalIds> builder() {
2840             return new InterfaceExternalIdsBuilder();
2841         }
2842
2843         @Override
2844         protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
2845             ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
2846         }
2847
2848         @Override
2849         protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
2850             ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
2851         }
2852
2853         @Override
2854         protected boolean isValueMandatory() {
2855             return true;
2856         }
2857     }
2858
2859     private static final class SouthboundInterfaceLldpBuilder extends KeyValueBuilder<InterfaceLldp> {
2860         @Override
2861         protected Builder<InterfaceLldp> builder() {
2862             return new InterfaceLldpBuilder();
2863         }
2864
2865         @Override
2866         protected void setKey(Builder<InterfaceLldp> builder, String key) {
2867             ((InterfaceLldpBuilder) builder).setLldpKey(key);
2868         }
2869
2870         @Override
2871         protected void setValue(Builder<InterfaceLldp> builder, String value) {
2872             ((InterfaceLldpBuilder) builder).setLldpValue(value);
2873         }
2874
2875         @Override
2876         protected boolean isValueMandatory() {
2877             return true;
2878         }
2879     }
2880
2881     private static final class SouthboundOptionsBuilder extends KeyValueBuilder<Options> {
2882         @Override
2883         protected Builder<Options> builder() {
2884             return new OptionsBuilder();
2885         }
2886
2887         @Override
2888         protected void setKey(Builder<Options> builder, String key) {
2889             ((OptionsBuilder) builder).setOption(key);
2890         }
2891
2892         @Override
2893         protected void setValue(Builder<Options> builder, String value) {
2894             ((OptionsBuilder) builder).setValue(value);
2895         }
2896
2897         @Override
2898         protected boolean isValueMandatory() {
2899             return false;
2900         }
2901     }
2902
2903     private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder<InterfaceOtherConfigs> {
2904         @Override
2905         protected Builder<InterfaceOtherConfigs> builder() {
2906             return new InterfaceOtherConfigsBuilder();
2907         }
2908
2909         @Override
2910         protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
2911             ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
2912         }
2913
2914         @Override
2915         protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
2916             ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
2917         }
2918
2919         @Override
2920         protected boolean isValueMandatory() {
2921             return false;
2922         }
2923     }
2924
2925     private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder<PortOtherConfigs> {
2926         @Override
2927         protected Builder<PortOtherConfigs> builder() {
2928             return new PortOtherConfigsBuilder();
2929         }
2930
2931         @Override
2932         protected void setKey(Builder<PortOtherConfigs> builder, String key) {
2933             ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
2934         }
2935
2936         @Override
2937         protected void setValue(Builder<PortOtherConfigs> builder, String value) {
2938             ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
2939         }
2940
2941         @Override
2942         protected boolean isValueMandatory() {
2943             return false;
2944         }
2945     }
2946
2947     private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder<BridgeOtherConfigs> {
2948         @Override
2949         protected Builder<BridgeOtherConfigs> builder() {
2950             return new BridgeOtherConfigsBuilder();
2951         }
2952
2953         @Override
2954         protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
2955             ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
2956         }
2957
2958         @Override
2959         protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
2960             ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
2961         }
2962
2963         @Override
2964         protected boolean isValueMandatory() {
2965             return false;
2966         }
2967     }
2968
2969     private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder<BridgeExternalIds> {
2970         @Override
2971         protected Builder<BridgeExternalIds> builder() {
2972             return new BridgeExternalIdsBuilder();
2973         }
2974
2975         @Override
2976         protected void setKey(Builder<BridgeExternalIds> builder, String key) {
2977             ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
2978         }
2979
2980         @Override
2981         protected void setValue(Builder<BridgeExternalIds> builder, String value) {
2982             ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
2983         }
2984
2985         @Override
2986         protected boolean isValueMandatory() {
2987             return true;
2988         }
2989     }
2990
2991     /*
2992      * Generates the test cases involved in testing key-value-based data.  See inline comments for descriptions of
2993      * the particular cases considered.
2994      */
2995     private static <I extends Identifier<T>, T extends Identifiable<I>> List<SouthboundTestCase<I, T>>
2996             generateKeyValueTestCases(KeyValueBuilder<T> builder, String testName) {
2997         List<SouthboundTestCase<I, T>> testCases = new ArrayList<>();
2998
2999         final String goodKey = "GoodKey";
3000         final String goodValue = "GoodValue";
3001         final String noValueForKey = "NoValueForKey";
3002
3003         final String idKey = testName + "Key";
3004         final String idValue = testName + "Value";
3005
3006         // Test Case 1:  TestOne
3007         // Test Type:    Positive
3008         // Description:  Create a termination point with one value
3009         // Expected:     A port is created with the single value specified below
3010         final String testOneName = "TestOne" + testName;
3011         testCases.add(new SouthboundTestCaseBuilder<I, T>()
3012                 .name(testOneName)
3013                 .input(builder.build(testOneName, idKey, idValue))
3014                 .expectInputAsOutput()
3015                 .build());
3016         builder.reset();
3017
3018         // Test Case 2:  TestFive
3019         // Test Type:    Positive
3020         // Description:  Create a termination point with multiple (five) values
3021         // Expected:     A port is created with the five values specified below
3022         final String testFiveName = "TestFive" + testName;
3023         testCases.add(new SouthboundTestCaseBuilder<I, T>()
3024                 .name(testFiveName)
3025                 .input(
3026                         builder.build(testFiveName, idKey, idValue),
3027                         builder.build(testFiveName, idKey, idValue),
3028                         builder.build(testFiveName, idKey, idValue),
3029                         builder.build(testFiveName, idKey, idValue),
3030                         builder.build(testFiveName, idKey, idValue))
3031                 .expectInputAsOutput()
3032                 .build());
3033         builder.reset();
3034
3035         if (!builder.isValueMandatory()) {
3036             // Test Case 3:  TestOneGoodOneMalformedValue
3037             // Test Type:    Negative
3038             // Description:
3039             //     One perfectly fine input
3040             //        (TestOneGoodOneMalformedValue_GoodKey_1,
3041             //        TestOneGoodOneMalformedValue_GoodValue_1)
3042             //     and one malformed input which only has key specified
3043             //        (TestOneGoodOneMalformedValue_NoValueForKey_2,
3044             //        UNSPECIFIED)
3045             // Expected:     A port is created without any values
3046             final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName;
3047             testCases.add(new SouthboundTestCaseBuilder<I, T>()
3048                     .name(testOneGoodOneMalformedValueName)
3049                     .input(
3050                             builder.build(testOneGoodOneMalformedValueName, goodKey, goodValue),
3051                             builder.build(testOneGoodOneMalformedValueName, noValueForKey, null))
3052                     .expectNoOutput()
3053                     .build());
3054             builder.reset();
3055         } else {
3056             LOG.info("generateKeyValueTestCases: skipping test case 3 for {}", builder.getClass().getSimpleName());
3057         }
3058
3059         return testCases;
3060     }
3061
3062     private static class PortExternalIdsSouthboundHelper
3063             implements SouthboundTerminationPointHelper<PortExternalIdsKey, PortExternalIds> {
3064         @Override
3065         public void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<PortExternalIds> values) {
3066             builder.setPortExternalIds(values);
3067         }
3068
3069         @Override
3070         public Map<PortExternalIdsKey, PortExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
3071             return augmentation.getPortExternalIds();
3072         }
3073     }
3074
3075     private static class InterfaceExternalIdsSouthboundHelper
3076             implements SouthboundTerminationPointHelper<InterfaceExternalIdsKey, InterfaceExternalIds> {
3077         @Override
3078         public void writeValues(
3079                 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceExternalIds> values) {
3080             builder.setInterfaceExternalIds(values);
3081         }
3082
3083         @Override
3084         public Map<InterfaceExternalIdsKey, InterfaceExternalIds> readValues(
3085                 OvsdbTerminationPointAugmentation augmentation) {
3086             return augmentation.getInterfaceExternalIds();
3087         }
3088     }
3089
3090     private static class InterfaceLldpSouthboundHelper
3091             implements SouthboundTerminationPointHelper<InterfaceLldpKey, InterfaceLldp> {
3092         @Override
3093         public void writeValues(
3094                 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceLldp> values) {
3095             builder.setInterfaceLldp(values);
3096         }
3097
3098         @Override
3099         public Map<InterfaceLldpKey, InterfaceLldp> readValues(OvsdbTerminationPointAugmentation augmentation) {
3100             return augmentation.getInterfaceLldp();
3101         }
3102     }
3103
3104     private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper<OptionsKey, Options> {
3105         @Override
3106         public void writeValues(
3107                 OvsdbTerminationPointAugmentationBuilder builder, List<Options> values) {
3108             builder.setOptions(values);
3109         }
3110
3111         @Override
3112         public Map<OptionsKey, Options> readValues(OvsdbTerminationPointAugmentation augmentation) {
3113             return augmentation.getOptions();
3114         }
3115     }
3116
3117     private static class InterfaceOtherConfigsSouthboundHelper
3118             implements SouthboundTerminationPointHelper<InterfaceOtherConfigsKey, InterfaceOtherConfigs> {
3119         @Override
3120         public void writeValues(
3121                 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceOtherConfigs> values) {
3122             builder.setInterfaceOtherConfigs(values);
3123         }
3124
3125         @Override
3126         public Map<InterfaceOtherConfigsKey, InterfaceOtherConfigs> readValues(
3127                 OvsdbTerminationPointAugmentation augmentation) {
3128             return augmentation.getInterfaceOtherConfigs();
3129         }
3130     }
3131
3132     private static class PortOtherConfigsSouthboundHelper implements
3133             SouthboundTerminationPointHelper<PortOtherConfigsKey, PortOtherConfigs> {
3134         @Override
3135         public void writeValues(
3136                 OvsdbTerminationPointAugmentationBuilder builder, List<PortOtherConfigs> values) {
3137             builder.setPortOtherConfigs(values);
3138         }
3139
3140         @Override
3141         public Map<PortOtherConfigsKey, PortOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
3142             return augmentation.getPortOtherConfigs();
3143         }
3144     }
3145
3146     private static class BridgeExternalIdsSouthboundHelper
3147             implements SouthboundBridgeHelper<BridgeExternalIdsKey, BridgeExternalIds> {
3148         @Override
3149         public void writeValues(
3150                 OvsdbBridgeAugmentationBuilder builder, List<BridgeExternalIds> values) {
3151             builder.setBridgeExternalIds(values);
3152         }
3153
3154         @Override
3155         public Map<BridgeExternalIdsKey, BridgeExternalIds> readValues(OvsdbBridgeAugmentation augmentation) {
3156             return augmentation.getBridgeExternalIds();
3157         }
3158     }
3159
3160     private static class BridgeOtherConfigsSouthboundHelper
3161             implements SouthboundBridgeHelper<BridgeOtherConfigsKey, BridgeOtherConfigs> {
3162         @Override
3163         public void writeValues(
3164                 OvsdbBridgeAugmentationBuilder builder, List<BridgeOtherConfigs> values) {
3165             builder.setBridgeOtherConfigs(values);
3166         }
3167
3168         @Override
3169         public Map<BridgeOtherConfigsKey, BridgeOtherConfigs> readValues(OvsdbBridgeAugmentation augmentation) {
3170             return augmentation.getBridgeOtherConfigs();
3171         }
3172     }
3173 }