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