2 * Copyright © 2015, 2017 Red Hat, Inc. and others. All rights reserved.
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
8 package org.opendaylight.ovsdb.southbound.it;
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;
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.Sets;
25 import java.lang.annotation.Annotation;
26 import java.lang.reflect.Method;
27 import java.net.InetAddress;
28 import java.net.UnknownHostException;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.HashSet;
33 import java.util.List;
35 import java.util.Properties;
37 import javax.inject.Inject;
38 import jersey.repackaged.com.google.common.collect.Maps;
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.ControllerMdsalUtils;
60 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbQueueRef;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeBase;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsKey;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachKey;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntryKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigsKey;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesKey;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIds;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIdsBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIdsKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.Mappings;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.MappingsBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.MappingsKey;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIds;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIdsBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIdsKey;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfig;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfigBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfigKey;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueList;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListKey;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIds;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIdsBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIdsKey;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfig;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfigBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfigKey;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsKey;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldp;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldpBuilder;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldpKey;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsKey;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsKey;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
148 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
149 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
150 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
151 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
152 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
153 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
154 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
155 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
156 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
157 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
158 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
159 import org.opendaylight.yangtools.concepts.Builder;
160 import org.opendaylight.yangtools.yang.binding.DataObject;
161 import org.opendaylight.yangtools.yang.binding.Identifiable;
162 import org.opendaylight.yangtools.yang.binding.Identifier;
163 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
164 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
165 import org.opendaylight.yangtools.yang.common.Uint32;
166 import org.ops4j.pax.exam.Configuration;
167 import org.ops4j.pax.exam.Option;
168 import org.ops4j.pax.exam.junit.PaxExam;
169 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
170 import org.ops4j.pax.exam.options.MavenUrlReference;
171 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
172 import org.ops4j.pax.exam.spi.reactors.PerClass;
173 import org.ops4j.pax.exam.util.Filter;
174 import org.osgi.framework.BundleContext;
175 import org.slf4j.Logger;
176 import org.slf4j.LoggerFactory;
179 * Integration tests for southbound-impl.
181 * @author Sam Hague (shague@redhat.com)
183 @RunWith(PaxExam.class)
184 @ExamReactorStrategy(PerClass.class)
185 public class SouthboundIT extends AbstractMdsalTestBase {
186 private static final String NETDEV_DP_TYPE = "netdev";
187 private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
188 private static final int OVSDB_UPDATE_TIMEOUT = 1000;
189 private static final int OVSDB_ROUNDTRIP_TIMEOUT = 10000;
190 private static final String FORMAT_STR = "%s_%s_%d";
191 private static final Version AUTOATTACH_FROM_VERSION = Version.fromString("7.11.2");
192 private static final Version IF_INDEX_FROM_VERSION = Version.fromString("7.2.1");
193 private static final Long MAX_BACKOFF = 10000L;
194 private static final Long INACTIVITY_PROBE = 30000L;
195 private static String addressStr;
196 private static int portNumber;
197 private static String connectionType;
198 private static boolean setup = false;
199 private static ControllerMdsalUtils mdsalUtils = null;
200 private static Node ovsdbNode;
201 private static int testMethodsRemaining;
202 private static Version schemaVersion;
203 @Inject @Filter(timeout = 60000)
204 private static DataBroker dataBroker = null;
207 private BundleContext bundleContext;
209 private static final NotifyingDataChangeListener CONFIGURATION_LISTENER =
210 new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION);
211 private static final NotifyingDataChangeListener OPERATIONAL_LISTENER =
212 new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL);
215 private static final class NotifyingDataChangeListener implements DataTreeChangeListener<DataObject> {
216 private static final int RETRY_WAIT = 100;
218 private final LogicalDatastoreType type;
219 private final Set<InstanceIdentifier<?>> createdIids = new HashSet<>();
220 private final Set<InstanceIdentifier<?>> removedIids = new HashSet<>();
221 private final Set<InstanceIdentifier<?>> updatedIids = new HashSet<>();
222 private final InstanceIdentifier<?> iid;
224 private NotifyingDataChangeListener(LogicalDatastoreType type) {
229 private NotifyingDataChangeListener(LogicalDatastoreType type, InstanceIdentifier<?> iid) {
235 public void onDataTreeChanged(Collection<DataTreeModification<DataObject>> changes) {
236 for (DataTreeModification<DataObject> change: changes) {
237 DataObjectModification<DataObject> rootNode = change.getRootNode();
238 final InstanceIdentifier<DataObject> identifier = change.getRootPath().getRootIdentifier();
239 switch (rootNode.getModificationType()) {
240 case SUBTREE_MODIFIED:
242 if (rootNode.getDataBefore() == null) {
243 LOG.info("{} DataTreeChanged: created {}", type, identifier);
244 createdIids.add(identifier);
246 final DataObject obj = rootNode.getDataAfter();
247 if (obj instanceof ManagedNodeEntry) {
248 ManagedNodeEntry managedNodeEntry = (ManagedNodeEntry) obj;
249 LOG.info("{} DataChanged: created managed {}",
250 managedNodeEntry.getBridgeRef().getValue());
251 createdIids.add(managedNodeEntry.getBridgeRef().getValue());
254 LOG.info("{} DataTreeChanged: updated {}", type, identifier);
255 updatedIids.add(identifier);
259 LOG.info("{} DataTreeChanged: removed {}", type, identifier);
260 removedIids.add(identifier);
267 synchronized (this) {
272 public boolean isCreated(InstanceIdentifier<?> path) {
273 return createdIids.remove(path);
276 public boolean isRemoved(InstanceIdentifier<?> path) {
277 return removedIids.remove(path);
280 public boolean isUpdated(InstanceIdentifier<?> path) {
281 return updatedIids.remove(path);
284 public void clear() {
290 public void registerDataChangeListener() {
291 dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(type,
292 (InstanceIdentifier)iid), this);
295 public void waitForCreation(long timeout) throws InterruptedException {
296 synchronized (this) {
297 long start = System.currentTimeMillis();
298 LOG.info("Waiting for {} DataChanged creation on {}", type, iid);
299 while (!isCreated(iid) && System.currentTimeMillis() - start < timeout) {
302 LOG.info("Woke up, waited {}ms for creation of {}", System.currentTimeMillis() - start, iid);
306 public void waitForDeletion(long timeout) throws InterruptedException {
307 synchronized (this) {
308 long start = System.currentTimeMillis();
309 LOG.info("Waiting for {} DataChanged deletion on {}", type, iid);
310 while (!isRemoved(iid) && System.currentTimeMillis() - start < timeout) {
313 LOG.info("Woke up, waited {}ms for deletion of {}", System.currentTimeMillis() - start, iid);
317 public void waitForUpdate(long timeout) throws InterruptedException {
318 synchronized (this) {
319 long start = System.currentTimeMillis();
320 LOG.info("Waiting for {} DataChanged update on {}", type, iid);
321 while (!isUpdated(iid) && System.currentTimeMillis() - start < timeout) {
324 LOG.info("Woke up, waited {}ms for update of {}", System.currentTimeMillis() - start, iid);
331 public Option[] config() {
332 Option[] options = super.config();
333 Option[] propertyOptions = getPropertiesOptions();
334 Option[] otherOptions = getOtherOptions();
335 Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
336 System.arraycopy(options, 0, combinedOptions, 0, options.length);
337 System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
338 System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
339 otherOptions.length);
340 return combinedOptions;
343 private Option[] getOtherOptions() {
344 return new Option[] {
345 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
351 public String getKarafDistro() {
353 .groupId("org.opendaylight.ovsdb")
354 .artifactId("southbound-karaf")
355 .versionAsInProject()
361 public MavenUrlReference getFeatureRepo() {
363 .groupId("org.opendaylight.ovsdb")
364 .artifactId("southbound-features")
365 .classifier("features")
367 .versionAsInProject();
371 public String getFeatureName() {
372 return "odl-ovsdb-southbound-test";
375 protected String usage() {
376 return "Integration Test needs a valid connection configuration as follows :\n"
377 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
378 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
382 public Option getLoggingOption() {
384 editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
385 "log4j.logger.org.opendaylight.ovsdb",
386 LogLevelOption.LogLevel.TRACE.name()),
387 super.getLoggingOption());
390 private Option[] getPropertiesOptions() {
391 Properties props = new Properties(System.getProperties());
392 String ipAddressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
393 SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
394 String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
395 SouthboundITConstants.DEFAULT_SERVER_PORT);
396 String connectionTypeStr = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
397 SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
399 LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
400 connectionTypeStr, ipAddressStr, portStr);
402 return new Option[] {
403 propagateSystemProperties(
404 SouthboundITConstants.SERVER_IPADDRESS,
405 SouthboundITConstants.SERVER_PORT,
406 SouthboundITConstants.CONNECTION_TYPE),
407 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
408 SouthboundITConstants.SERVER_IPADDRESS, ipAddressStr),
409 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
410 SouthboundITConstants.SERVER_PORT, portStr),
411 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
412 SouthboundITConstants.CONNECTION_TYPE, connectionTypeStr),
418 public void setup() throws Exception {
420 LOG.info("Skipping setup, already initialized");
425 Assert.assertNotNull("db should not be null", dataBroker);
427 LOG.info("sleeping for 10s to let the features finish installing");
430 addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
431 String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
433 portNumber = Integer.parseInt(portStr);
434 } catch (NumberFormatException e) {
435 fail("Invalid port number " + portStr + System.lineSeparator() + usage());
437 connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
439 LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
440 connectionType, addressStr, portNumber);
441 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
442 if (addressStr == null) {
447 mdsalUtils = new ControllerMdsalUtils(dataBroker);
448 assertTrue("Did not find " + SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue(), getOvsdbTopology());
449 final ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
450 final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
451 dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION,
452 (InstanceIdentifier)iid), CONFIGURATION_LISTENER);
453 dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL,
454 (InstanceIdentifier)iid), OPERATIONAL_LISTENER);
456 ovsdbNode = connectOvsdbNode(connectionInfo);
457 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class);
458 assertNotNull("The OvsdbNodeAugmentation cannot be null", ovsdbNodeAugmentation);
459 schemaVersion = Version.fromString(ovsdbNodeAugmentation.getDbVersion());
460 LOG.info("schemaVersion = {}", schemaVersion);
462 // Let's count the test methods (we need to use this instead of @AfterClass on teardown() since the latter is
463 // useless with pax-exam)
464 for (Method method : getClass().getMethods()) {
465 boolean testMethod = false;
466 boolean ignoreMethod = false;
467 for (Annotation annotation : method.getAnnotations()) {
468 if (Test.class.equals(annotation.annotationType())) {
471 if (Ignore.class.equals(annotation.annotationType())) {
475 if (testMethod && !ignoreMethod) {
476 testMethodsRemaining++;
479 LOG.info("{} test methods to run", testMethodsRemaining);
485 public void teardown() {
486 testMethodsRemaining--;
487 LOG.info("{} test methods remaining", testMethodsRemaining);
488 if (testMethodsRemaining == 0) {
490 disconnectOvsdbNode(getConnectionInfo(addressStr, portNumber));
491 } catch (InterruptedException e) {
492 LOG.warn("Interrupted while disconnecting", e);
497 private Boolean getOvsdbTopology() {
498 LOG.info("getOvsdbTopology: looking for {}...", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue());
499 Boolean found = false;
500 final TopologyId topologyId = SouthboundUtils.OVSDB_TOPOLOGY_ID;
501 InstanceIdentifier<Topology> path =
502 InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId));
503 for (int i = 0; i < 60; i++) {
504 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
505 if (topology != null) {
506 LOG.info("getOvsdbTopology: found {}...", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue());
510 LOG.info("getOvsdbTopology: still looking ({})...", i);
513 } catch (InterruptedException e) {
514 LOG.warn("Interrupted while waiting for {}", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue(), e);
522 * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
523 * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms.
526 public void testPassiveNode() throws InterruptedException {
527 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
528 //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
529 Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
533 private static ConnectionInfo getConnectionInfo(final String ipAddressStr, final int portNum) {
534 InetAddress inetAddress = null;
536 inetAddress = InetAddress.getByName(ipAddressStr);
537 } catch (UnknownHostException e) {
538 fail("Could not resolve " + ipAddressStr + ": " + e);
541 IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
542 PortNumber port = new PortNumber(portNum);
544 final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
545 .setRemoteIp(address)
548 LOG.info("connectionInfo: {}", connectionInfo);
549 return connectionInfo;
553 public void testNetworkTopology() throws InterruptedException {
554 NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
555 InstanceIdentifier.create(NetworkTopology.class));
556 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
559 networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
560 InstanceIdentifier.create(NetworkTopology.class));
561 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
566 public void testOvsdbTopology() throws InterruptedException {
567 InstanceIdentifier<Topology> path = InstanceIdentifier
568 .create(NetworkTopology.class)
569 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
571 Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
572 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
575 topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
577 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
581 private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
582 final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
584 mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, SouthboundUtils.createNode(connectionInfo)));
585 waitForOperationalCreation(iid);
586 Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
587 Assert.assertNotNull(node);
588 LOG.info("Connected to {}", SouthboundUtils.connectionInfoToString(connectionInfo));
592 private void waitForOperationalCreation(InstanceIdentifier<Node> iid) throws InterruptedException {
593 synchronized (OPERATIONAL_LISTENER) {
594 long start = System.currentTimeMillis();
595 LOG.info("Waiting for OPERATIONAL DataChanged creation on {}", iid);
596 while (!OPERATIONAL_LISTENER.isCreated(
597 iid) && System.currentTimeMillis() - start < OVSDB_ROUNDTRIP_TIMEOUT) {
598 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
600 LOG.info("Woke up, waited {} for creation of {}", System.currentTimeMillis() - start, iid);
604 private static void waitForOperationalDeletion(InstanceIdentifier<Node> iid) throws InterruptedException {
605 synchronized (OPERATIONAL_LISTENER) {
606 long start = System.currentTimeMillis();
607 LOG.info("Waiting for OPERATIONAL DataChanged deletion on {}", iid);
608 while (!OPERATIONAL_LISTENER.isRemoved(
609 iid) && System.currentTimeMillis() - start < OVSDB_ROUNDTRIP_TIMEOUT) {
610 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
612 LOG.info("Woke up, waited {} for deletion of {}", System.currentTimeMillis() - start, iid);
616 private void waitForOperationalUpdate(InstanceIdentifier<Node> iid) throws InterruptedException {
617 synchronized (OPERATIONAL_LISTENER) {
618 long start = System.currentTimeMillis();
619 LOG.info("Waiting for OPERATIONAL DataChanged update on {}", iid);
620 while (!OPERATIONAL_LISTENER.isUpdated(
621 iid) && System.currentTimeMillis() - start < OVSDB_ROUNDTRIP_TIMEOUT) {
622 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
624 LOG.info("Woke up, waited {} for update of {}", System.currentTimeMillis() - start, iid);
628 private static void disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
629 final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
630 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
631 waitForOperationalDeletion(iid);
632 Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
633 Assert.assertNull(node);
634 LOG.info("Disconnected from {}", SouthboundUtils.connectionInfoToString(connectionInfo));
638 public void testAddDeleteOvsdbNode() throws InterruptedException {
639 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
640 // At this point we're connected, disconnect and reconnect (the connection will be removed at the very end)
641 disconnectOvsdbNode(connectionInfo);
642 connectOvsdbNode(connectionInfo);
646 public void testDpdkSwitch() throws InterruptedException {
647 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
648 Map<DatapathTypeEntryKey, DatapathTypeEntry> datapathTypeEntries =
649 ovsdbNode.augmentation(OvsdbNodeAugmentation.class).nonnullDatapathTypeEntry();
650 if (datapathTypeEntries == null) {
651 LOG.info("DPDK not supported on this node.");
653 for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries.values()) {
654 Class<? extends DatapathTypeBase> dpType = dpTypeEntry.getDatapathType();
655 String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType);
656 LOG.info("dp type is {}", dpTypeStr);
657 if (dpTypeStr.equals(NETDEV_DP_TYPE)) {
658 LOG.info("Found a DPDK node; adding a corresponding netdev device");
659 InstanceIdentifier<Node> bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo,
660 new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
661 NodeId bridgeNodeId = SouthboundUtils.createManagedNodeId(bridgeIid);
662 try (TestBridge testBridge = new TestBridge(connectionInfo, bridgeIid,
663 SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null, true, dpType, null, null,
665 // Verify that the device is netdev
666 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
667 Assert.assertNotNull(bridge);
668 Assert.assertEquals(dpType, bridge.getDatapathType());
670 // Add port for all dpdk interface types (dpdkvhost not supported in existing dpdk ovs)
671 List<String> dpdkTypes = new ArrayList<>();
672 dpdkTypes.add("dpdk");
673 dpdkTypes.add("dpdkr");
674 dpdkTypes.add("dpdkvhostuser");
675 //dpdkTypes.add("dpdkvhost");
677 for (String dpdkType : dpdkTypes) {
678 String testPortname = "test" + dpdkType + "port";
679 LOG.info("DPDK portname and type is {}, {}", testPortname, dpdkType);
680 Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
682 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationpointBuilder =
683 createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(testPortname,
686 addTerminationPoint(bridgeNodeId, testPortname, ovsdbTerminationpointBuilder));
689 // Verify that all DPDK ports are created
690 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
691 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
692 terminationPointIid);
693 Assert.assertNotNull(terminationPointNode);
695 // Verify that each termination point has the specific DPDK ifType
696 for (String dpdkType : dpdkTypes) {
697 String testPortname = "test" + dpdkType + "port";
698 Class<? extends InterfaceTypeBase> dpdkIfType =
699 SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(dpdkType);
700 for (TerminationPoint terminationPoint
701 : terminationPointNode.nonnullTerminationPoint().values()) {
702 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
703 .augmentation(OvsdbTerminationPointAugmentation.class);
704 if (ovsdbTerminationPointAugmentation.getName().equals(testPortname)) {
705 Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
707 Assert.assertEquals(dpdkIfType, opPort);
719 public void testOvsdbNodeOvsVersion() throws InterruptedException {
720 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class);
721 Assert.assertNotNull(ovsdbNodeAugmentation);
722 assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
726 public void testOvsdbNodeDbVersion() throws InterruptedException {
727 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class);
728 Assert.assertNotNull(ovsdbNodeAugmentation);
729 assertNotNull(ovsdbNodeAugmentation.getDbVersion());
733 public void testOpenVSwitchOtherConfig() throws InterruptedException {
734 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.augmentation(OvsdbNodeAugmentation.class);
735 Assert.assertNotNull(ovsdbNodeAugmentation);
736 Map<OpenvswitchOtherConfigsKey, OpenvswitchOtherConfigs> otherConfigsList =
737 ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
738 if (otherConfigsList != null) {
739 for (OpenvswitchOtherConfigs otherConfig : otherConfigsList.values()) {
740 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
741 LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
744 LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
748 LOG.info("other_config is not present");
753 public void testOvsdbBridgeControllerInfo() throws InterruptedException {
754 ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber);
755 String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
756 assertNotNull("Failed to get controller target", controllerTarget);
757 List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
758 Uri setUri = new Uri(controllerTarget);
759 try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
760 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
761 setControllerEntry, null)) {
762 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
763 Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME, bridge);
764 Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
765 bridge.getControllerEntry());
766 for (ControllerEntry entry : bridge.getControllerEntry().values()) {
767 if (entry.getTarget() != null) {
768 Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
770 if (entry.getMaxBackoff() != null) {
771 Assert.assertEquals(entry.getMaxBackoff(), MAX_BACKOFF);
773 if (entry.getInactivityProbe() != null) {
774 Assert.assertEquals(entry.getInactivityProbe(),INACTIVITY_PROBE);
780 private List<ControllerEntry> createControllerEntry(String controllerTarget) {
781 List<ControllerEntry> controllerEntriesList = new ArrayList<>();
782 controllerEntriesList.add(new ControllerEntryBuilder()
783 .setTarget(new Uri(controllerTarget))
784 .setMaxBackoff(MAX_BACKOFF)
785 .setInactivityProbe(INACTIVITY_PROBE)
787 return controllerEntriesList;
790 private static void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
791 final ConnectionInfo connectionInfo) {
792 InstanceIdentifier<Node> connectionNodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo);
793 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
796 private static List<ProtocolEntry> createMdsalProtocols() {
797 List<ProtocolEntry> protocolList = new ArrayList<>();
798 ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
799 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
800 protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
804 private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
805 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
806 new OvsdbTerminationPointAugmentationBuilder();
807 ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
808 new InterfaceTypeEntryBuilder()
810 SouthboundMapper.createInterfaceType("internal"))
811 .build().getInterfaceType());
812 return ovsdbTerminationPointAugmentationBuilder;
815 private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
816 final String portName) {
817 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
818 createGenericOvsdbTerminationPointAugmentationBuilder();
819 ovsdbTerminationBuilder.setName(portName);
820 Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
822 ovsdbTerminationBuilder.setInterfaceType(ifType);
823 return ovsdbTerminationBuilder;
826 private OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(
827 String testPortname,Class<? extends InterfaceTypeBase> dpdkIfType) {
828 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
829 createGenericOvsdbTerminationPointAugmentationBuilder();
830 ovsdbTerminationBuilder.setName(testPortname);
831 ovsdbTerminationBuilder.setInterfaceType(dpdkIfType);
832 return ovsdbTerminationBuilder;
835 private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
836 final OvsdbTerminationPointAugmentationBuilder
837 ovsdbTerminationPointAugmentationBuilder)
838 throws InterruptedException {
840 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
841 NodeBuilder portNodeBuilder = new NodeBuilder();
842 NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
843 portNodeBuilder.setNodeId(portNodeId);
844 TerminationPointBuilder entry = new TerminationPointBuilder();
845 entry.withKey(new TerminationPointKey(new TpId(portName)));
846 entry.addAugmentation(
847 OvsdbTerminationPointAugmentation.class,
848 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);
856 private static class TestBridge implements AutoCloseable {
857 private final ConnectionInfo connectionInfo;
858 private final String bridgeName;
861 * Creates a test bridge which can be automatically removed when no longer necessary.
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.
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));
887 if (bridgeNodeId == null) {
888 bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
890 bridgeNodeBuilder.setNodeId(bridgeNodeId);
891 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
892 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
893 if (setProtocolEntries) {
894 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
896 ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
898 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
900 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
901 ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
902 ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
903 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
904 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
905 LOG.debug("Built with the intent to store bridge data {}", ovsdbBridgeAugmentationBuilder);
907 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build()));
909 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
910 } catch (InterruptedException e) {
911 LOG.warn("Sleep interrupted while waiting for bridge creation (bridge {})", bridgeName, e);
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);
921 public void close() {
922 final InstanceIdentifier<Node> iid =
923 SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
924 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
926 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
927 } catch (InterruptedException e) {
928 LOG.warn("Sleep interrupted while waiting for bridge deletion (bridge {})", bridgeName, e);
933 private static class TestAutoAttach implements AutoCloseable {
934 private final ConnectionInfo connectionInfo;
935 private final Uri autoattachId;
936 private final Uri bridgeId;
938 TestAutoAttach(final ConnectionInfo connectionInfo,
939 final Uri autoattachId,
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;
949 Autoattach aaEntry = new AutoattachBuilder()
950 .setAutoattachId(autoattachId)
951 .setBridgeId(bridgeId)
952 .setSystemName(systemName)
953 .setSystemDescription(systemDescription)
954 .setMappings(mappings)
955 .setAutoattachExternalIds(externalIds)
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();
964 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, aaEntry));
966 aaOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
967 } catch (InterruptedException e) {
968 LOG.warn("Sleep interrupted while waiting for queue {}", iid, e);
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();
981 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
983 aaOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
984 } catch (InterruptedException e) {
985 LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", iid, e);
991 public void testCRUDAutoAttach() throws InterruptedException {
992 final boolean isOldSchema = schemaVersion.compareTo(AUTOATTACH_FROM_VERSION) < 0;
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";
1001 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1002 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1003 Assert.assertNotNull(bridge);
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));
1017 // skip tests after verifying that Autoattach doesn't break with unsupported schema
1018 Assume.assumeFalse(isOldSchema);
1020 // FIXME: Remove once CRUD is supported
1021 Assume.assumeFalse(operAa == null);
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());
1029 // UPDATE: Update mappings column of AutoAttach table that was created
1030 List<Mappings> mappings = ImmutableList.of(new MappingsBuilder().setMappingsKey(100L)
1031 .setMappingsValue(200).build());
1032 Autoattach updatedAa = new AutoattachBuilder()
1033 .setAutoattachId(new Uri(testAutoattachId))
1034 .setMappings(mappings)
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);
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)
1051 updatedAa = new AutoattachBuilder()
1052 .setAutoattachId(new Uri(testAutoattachId))
1053 .setAutoattachExternalIds(externalIds)
1055 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, updatedAa));
1056 aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
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));
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())
1073 for (AutoattachExternalIds operExternalId : operExternalIds.values()) {
1074 Assert.assertTrue(externalIds.contains(operExternalId));
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);
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)) {
1102 private static class TestQos implements AutoCloseable {
1103 private final ConnectionInfo connectionInfo;
1104 private final Uri qosId;
1107 * Creates a test qos entry which can be automatically removed when no longer necessary.
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.
1115 TestQos(final ConnectionInfo connectionInfo,
1117 final Class<? extends QosTypeBase> qosType,
1118 @Nullable final List<QosExternalIds> externalIds,
1119 @Nullable final List<QosOtherConfig> otherConfigs) {
1120 this.connectionInfo = connectionInfo;
1123 QosEntries qosEntry = new QosEntriesBuilder()
1125 .setQosType(qosType)
1126 .setQosExternalIds(externalIds)
1127 .setQosOtherConfig(otherConfigs)
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();
1137 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1141 qosOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
1142 } catch (InterruptedException e) {
1143 LOG.warn("Sleep interrupted while waiting for queue {}", qeIid, e);
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();
1157 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qeIid));
1159 qosOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
1160 } catch (InterruptedException e) {
1161 LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", qeIid, e);
1166 private static class TestQueue implements AutoCloseable {
1167 private final ConnectionInfo connectionInfo;
1168 private final Uri queueId;
1169 private final InstanceIdentifier<Queues> queueIid;
1172 * Creates a test queue entry which can be automatically removed when no longer necessary.
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.
1180 TestQueue(final ConnectionInfo connectionInfo,
1182 final Short queueDscp,
1183 @Nullable final List<QueuesExternalIds> externalIds,
1184 @Nullable final List<QueuesOtherConfig> otherConfigs) {
1185 this.connectionInfo = connectionInfo;
1186 this.queueId = queueId;
1188 Queues queue = new QueuesBuilder()
1189 .setQueueId(queueId)
1191 .setQueuesExternalIds(externalIds)
1192 .setQueuesOtherConfig(otherConfigs)
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();
1202 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1206 queueOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
1207 } catch (InterruptedException e) {
1208 LOG.warn("Sleep interrupted while waiting for queue {}", queueId, e);
1212 public InstanceIdentifier<Queues> getInstanceIdentifier() {
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();
1225 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, queuesIid));
1227 queueOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
1228 } catch (InterruptedException e) {
1229 LOG.warn("Sleep interrupted while waiting for queue deletion (queue {})", queueId, e);
1234 private 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;
1243 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
1244 return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1248 * Extract the <code>store</code> type data store contents for the particular bridge identified by
1249 * <code>bridgeName</code>.
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
1256 private 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;
1266 * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
1267 * identified by <code>bridgeName</code>.
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
1274 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
1275 return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
1279 * Extract the node contents from <code>store</code> type data store for the
1280 * bridge identified by <code>bridgeName</code>.
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
1287 private 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);
1294 * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
1295 * bridge identified by <code>bridgeName</code>.
1297 * @param connectionInfo the connection information
1298 * @param bridgeName the bridge name
1299 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
1301 private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
1302 return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
1306 public void testAddDeleteBridge() throws InterruptedException {
1307 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1309 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1310 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1311 Assert.assertNotNull(bridge);
1312 LOG.info("bridge: {}", bridge);
1316 private static InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
1317 return SouthboundUtils.createInstanceIdentifier(connectionInfo, bridge.getBridgeName());
1321 * Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
1322 * on <code>bridgeName</code>.
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)
1330 private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
1331 ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) {
1333 Map<TerminationPointKey, TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store)
1334 .nonnullTerminationPoint();
1335 if (tpList == null) {
1338 return Iterables.get(tpList.values(), index).augmentation(OvsdbTerminationPointAugmentation.class);
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);
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);
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);
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);
1380 public void testCRDTerminationPointOfPort() throws InterruptedException {
1381 final Long ofportExpected = 45002L;
1383 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
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);
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);
1404 for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1405 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1406 terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1407 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1408 Long ofPort = ovsdbTerminationPointAugmentation.getOfport().toJava();
1409 // if ephemeral port 45002 is in use, ofPort is set to 1
1410 Assert.assertTrue(ofPort.equals(ofportExpected) || ofPort.equals(1L));
1411 LOG.info("ofPort: {}", ofPort);
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."
1419 // DELETE handled by TestBridge
1424 public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
1425 final Long ofportExpected = 45008L;
1426 final Long ofportInput = 45008L;
1428 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
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 Integer ofPortRequestExpected = ofportExpected.intValue();
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);
1449 for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1450 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1451 terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1452 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1453 Long ofPort = ovsdbTerminationPointAugmentation.getOfport().toJava();
1454 // if ephemeral port 45008 is in use, ofPort is set to 1
1455 Assert.assertTrue(ofPort.equals(ofportExpected) || ofPort.equals(1L));
1456 LOG.info("ofPort: {}", ofPort);
1458 Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest().toJava();
1459 Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
1460 LOG.info("ofPortRequest: {}", ofPortRequest);
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. "
1468 // DELETE handled by TestBridge
1472 private static <I extends Identifier<T>, T extends Identifiable<I>> void assertExpectedExist(Map<I, T> expected,
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));
1481 private interface SouthboundTerminationPointHelper<I extends Identifier<T>, T extends Identifiable<I>> {
1482 void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<T> values);
1484 Map<I, T> readValues(OvsdbTerminationPointAugmentation augmentation);
1488 * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
1490 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1492 private <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;
1497 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
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");
1504 for (SouthboundTestCase<I, T> updateFromTestCase : updateFromTestCases) {
1505 for (SouthboundTestCase<I, T> updateToTestCase : updateToTestCases) {
1506 String testBridgeAndPortName = String.format("%s_%s", prefix, updateToTestCase.name);
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,
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);
1520 addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
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);
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);
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(
1553 OvsdbTerminationPointAugmentation.class,
1554 tpUpdateAugmentationBuilder.build());
1555 portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1556 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1557 portIid, portUpdateNodeBuilder.build()));
1558 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1560 // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1561 // then repeat for OPERATIONAL data store
1562 OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1563 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1564 LogicalDatastoreType.CONFIGURATION, terminationPointTestIndex);
1565 if (updateToConfigurationTerminationPointAugmentation != null) {
1566 Map<I, T> updateToConfigurationValues =
1567 helper.readValues(updateToConfigurationTerminationPointAugmentation);
1568 assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
1569 assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationValues);
1571 OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1572 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1573 LogicalDatastoreType.OPERATIONAL, terminationPointTestIndex);
1574 if (updateToOperationalTerminationPointAugmentation != null) {
1575 Map<I, T> updateToOperationalValues =
1576 helper.readValues(updateToOperationalTerminationPointAugmentation);
1577 if (updateFromTestCase.expectedValues != null) {
1578 assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
1579 assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalValues);
1583 // DELETE handled by TestBridge
1590 * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
1592 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1595 public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
1596 testCRUDTerminationPoint(new SouthboundPortExternalIdsBuilder(), "TPPortExternalIds",
1597 new PortExternalIdsSouthboundHelper());
1601 * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1603 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1606 public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
1607 testCRUDTerminationPoint(new SouthboundInterfaceExternalIdsBuilder(), "TPInterfaceExternalIds",
1608 new InterfaceExternalIdsSouthboundHelper());
1612 * Tests the CRUD operations for <code>Interface</code> <code>lldp</code>.
1614 * @see <code>SouthboundIT.generateInterfaceLldpTestCases()</code> for specific test case information
1617 public void testCRUDTerminationPointInterfaceLldp() throws InterruptedException {
1618 testCRUDTerminationPoint(new SouthboundInterfaceLldpBuilder(), "TPInterfaceLldp",
1619 new InterfaceLldpSouthboundHelper());
1623 * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1625 * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1628 public void testCRUDTerminationPointOptions() throws InterruptedException {
1629 testCRUDTerminationPoint(new SouthboundOptionsBuilder(), "TPOptions", new OptionsSouthboundHelper());
1633 * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
1635 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1638 public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
1639 testCRUDTerminationPoint(new SouthboundInterfaceOtherConfigsBuilder(), "TPInterfaceOtherConfigs",
1640 new InterfaceOtherConfigsSouthboundHelper());
1644 * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
1646 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1649 public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
1650 testCRUDTerminationPoint(new SouthboundPortOtherConfigsBuilder(), "TPPortOtherConfigs",
1651 new PortOtherConfigsSouthboundHelper());
1655 public void testCRUDTerminationPoints() throws InterruptedException {
1656 String port1 = "vx1";
1657 String port2 = "vxlanport";
1658 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1660 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1661 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1662 Assert.assertNotNull(bridge);
1663 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1664 connectionInfo, bridge.getBridgeName()));
1665 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1666 createGenericOvsdbTerminationPointAugmentationBuilder();
1668 // add and delete a single port
1669 String portName = port1;
1670 ovsdbTerminationBuilder.setName(portName);
1671 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1672 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1673 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1674 Assert.assertNotNull(terminationPointNode);
1676 SouthboundUtils.createInstanceIdentifier(connectionInfo,
1677 new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
1679 InstanceIdentifier<TerminationPoint> nodePath =
1680 SouthboundUtils.createInstanceIdentifier(connectionInfo,
1681 new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1682 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1684 Assert.assertTrue("failed to delete port " + portName,
1685 mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1686 LOG.info("shague: waiting for delete {}", portName);
1688 TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1689 Assert.assertNull(terminationPoint);
1691 // add two ports, then delete them
1693 ovsdbTerminationBuilder.setName(portName);
1694 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1695 terminationPointIid = getTpIid(connectionInfo, bridge);
1696 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1697 Assert.assertNotNull(terminationPointNode);
1700 ovsdbTerminationBuilder.setName(portName);
1701 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1702 terminationPointIid = getTpIid(connectionInfo, bridge);
1703 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1704 Assert.assertNotNull(terminationPointNode);
1706 SouthboundUtils.createInstanceIdentifier(connectionInfo,
1707 new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
1710 SouthboundUtils.createInstanceIdentifier(connectionInfo,
1711 new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1712 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1714 Assert.assertTrue("failed to delete port " + portName,
1715 mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1716 LOG.info("shague: waiting for delete {}", portName);
1718 terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1719 Assert.assertNull(terminationPoint);
1722 nodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo,
1723 new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1724 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1726 Assert.assertTrue("failed to delete port " + portName,
1727 mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1728 LOG.info("shague: waiting for delete {}", portName);
1730 terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1731 Assert.assertNull(terminationPoint);
1733 // DELETE handled by TestBridge
1738 public void testCRUDTerminationPointVlan() throws InterruptedException {
1739 final Integer createdVlanId = 4000;
1740 final Integer updatedVlanId = 4001;
1742 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1745 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1746 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1747 Assert.assertNotNull(bridge);
1748 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1749 connectionInfo, bridge.getBridgeName()));
1750 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1751 createGenericOvsdbTerminationPointAugmentationBuilder();
1752 String portName = "testTerminationPointVlanId";
1753 ovsdbTerminationBuilder.setName(portName);
1754 ovsdbTerminationBuilder.setVlanTag(new VlanId(createdVlanId));
1755 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1756 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1757 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1758 Assert.assertNotNull(terminationPointNode);
1761 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
1762 for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1763 ovsdbTerminationPointAugmentation = terminationPoint.augmentation(
1764 OvsdbTerminationPointAugmentation.class);
1765 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1766 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1767 Assert.assertNotNull(actualVlanId);
1768 Integer actualVlanIdInt = actualVlanId.getValue().toJava();
1769 Assert.assertEquals(createdVlanId, actualVlanIdInt);
1774 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1775 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1776 new OvsdbTerminationPointAugmentationBuilder();
1777 tpUpdateAugmentationBuilder.setVlanTag(new VlanId(updatedVlanId));
1778 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1779 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1780 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1781 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1782 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1783 tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName)));
1784 tpUpdateBuilder.addAugmentation(
1785 OvsdbTerminationPointAugmentation.class,
1786 tpUpdateAugmentationBuilder.build());
1787 tpUpdateBuilder.setTpId(new TpId(portName));
1788 portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1790 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1791 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1793 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1794 for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1795 ovsdbTerminationPointAugmentation = terminationPoint.augmentation(
1796 OvsdbTerminationPointAugmentation.class);
1797 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1798 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1799 Assert.assertNotNull(actualVlanId);
1800 Integer actualVlanIdInt = actualVlanId.getValue().toJava();
1801 Assert.assertEquals(updatedVlanId, actualVlanIdInt);
1805 // DELETE handled by TestBridge
1810 public void testCRUDTerminationPointVlanModes() throws InterruptedException {
1811 final VlanMode updatedVlanMode = VlanMode.Access;
1812 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1813 VlanMode []vlanModes = VlanMode.values();
1814 for (VlanMode vlanMode : vlanModes) {
1816 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1817 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1818 Assert.assertNotNull(bridge);
1819 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1820 connectionInfo, bridge.getBridgeName()));
1821 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1822 createGenericOvsdbTerminationPointAugmentationBuilder();
1823 String portName = "testTerminationPointVlanMode" + vlanMode.toString();
1824 ovsdbTerminationBuilder.setName(portName);
1825 ovsdbTerminationBuilder.setVlanMode(vlanMode);
1826 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1827 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1828 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1829 Assert.assertNotNull(terminationPointNode);
1832 for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1833 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1834 terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1835 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1837 Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
1842 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1843 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1844 new OvsdbTerminationPointAugmentationBuilder();
1845 tpUpdateAugmentationBuilder.setVlanMode(updatedVlanMode);
1846 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1847 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1848 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1849 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1850 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1851 tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName)));
1852 tpUpdateBuilder.addAugmentation(
1853 OvsdbTerminationPointAugmentation.class,
1854 tpUpdateAugmentationBuilder.build());
1855 tpUpdateBuilder.setTpId(new TpId(portName));
1856 portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1858 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1859 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1861 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1862 for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1863 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1864 terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1865 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1867 Assert.assertEquals(updatedVlanMode, ovsdbTerminationPointAugmentation.getVlanMode());
1871 // DELETE handled by TestBridge
1876 private List<Set<Integer>> generateVlanSets() {
1879 return Lists.newArrayList(
1880 Collections.<Integer>emptySet(),
1881 Collections.singleton(2222),
1882 Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2));
1885 private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
1886 List<Trunks> trunkList = new ArrayList<>();
1887 for (Integer trunk : trunkSet) {
1888 TrunksBuilder trunkBuilder = new TrunksBuilder();
1889 trunkBuilder.setTrunk(new VlanId(trunk));
1890 trunkList.add(trunkBuilder.build());
1896 public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
1897 final List<Trunks> updatedTrunks = buildTrunkList(Collections.singleton(2011));
1898 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1899 Iterable<Set<Integer>> vlanSets = generateVlanSets();
1901 for (Set<Integer> vlanSet : vlanSets) {
1904 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1905 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1906 Assert.assertNotNull(bridge);
1907 NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName());
1908 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1909 createGenericOvsdbTerminationPointAugmentationBuilder();
1910 String portName = "testTerminationPointVlanTrunks" + testCase;
1911 ovsdbTerminationBuilder.setName(portName);
1912 List<Trunks> trunks = buildTrunkList(vlanSet);
1913 ovsdbTerminationBuilder.setTrunks(trunks);
1914 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1915 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1916 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1917 Assert.assertNotNull(terminationPointNode);
1920 Collection<TerminationPoint> terminationPoints =
1921 terminationPointNode.nonnullTerminationPoint().values();
1922 for (TerminationPoint terminationPoint : terminationPoints) {
1923 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1924 terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1925 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1926 List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
1927 for (Trunks trunk : trunks) {
1928 Assert.assertTrue(actualTrunks.contains(trunk));
1935 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1936 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1937 new OvsdbTerminationPointAugmentationBuilder();
1938 tpUpdateAugmentationBuilder.setTrunks(updatedTrunks);
1939 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1940 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1941 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1942 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1943 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1944 tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName)));
1945 tpUpdateBuilder.addAugmentation(
1946 OvsdbTerminationPointAugmentation.class,
1947 tpUpdateAugmentationBuilder.build());
1948 tpUpdateBuilder.setTpId(new TpId(portName));
1949 portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1951 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1952 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1954 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1955 for (TerminationPoint terminationPoint : terminationPointNode.nonnullTerminationPoint().values()) {
1956 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1957 terminationPoint.augmentation(OvsdbTerminationPointAugmentation.class);
1958 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1960 Assert.assertEquals(updatedTrunks, ovsdbTerminationPointAugmentation.getTrunks());
1964 // DELETE handled by TestBridge
1970 * Tests setting and deleting <code>qos</code> field in a <code>port</code>.
1973 public void testCRUDTerminationPointQos() throws InterruptedException {
1974 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1975 String testQosId = "testQosEntry";
1978 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1979 TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId),
1980 SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HFSC), null, null)) {
1981 OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
1982 LogicalDatastoreType.OPERATIONAL);
1983 QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
1984 Assert.assertNotNull(operQos);
1985 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1986 Assert.assertNotNull(bridge);
1987 NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName());
1988 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1989 createGenericOvsdbTerminationPointAugmentationBuilder();
1990 String portName = "testTerminationPointQos";
1991 ovsdbTerminationBuilder.setName(portName);
1992 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1995 // READ and check that qos uuid has been added to the port
1996 InstanceIdentifier<TerminationPoint> tpEntryIid = getTpIid(connectionInfo, bridge)
1997 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1998 TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid);
1999 Assert.assertNotNull(terminationPoint);
2001 // UPDATE - remove the qos entry from the port
2002 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
2003 new OvsdbTerminationPointAugmentationBuilder();
2004 tpUpdateAugmentationBuilder.setName(portName);
2005 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
2006 tpUpdateBuilder.withKey(new TerminationPointKey(new TpId(portName)));
2007 tpUpdateBuilder.addAugmentation(
2008 OvsdbTerminationPointAugmentation.class,
2009 tpUpdateAugmentationBuilder.build());
2010 tpUpdateBuilder.setTpId(new TpId(portName));
2013 mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpEntryIid, tpUpdateBuilder.build()));
2014 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2016 // READ and verify that qos uuid has been removed from port
2017 TerminationPoint terminationPointUpdate = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid);
2018 Assert.assertNotNull(terminationPointUpdate);
2020 // DELETE handled by TestBridge
2025 public void testGetOvsdbNodes() throws InterruptedException {
2026 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2027 InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
2028 .create(NetworkTopology.class)
2029 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
2031 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
2032 InstanceIdentifier<Node> expectedNodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
2033 NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class).getNodeId();
2034 Node foundNode = null;
2035 Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
2036 Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
2037 LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
2038 for (Node node : topology.nonnullNode().values()) {
2039 if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
2044 Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
2048 * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
2051 public void testCRUDBridgeOtherConfigs() throws InterruptedException {
2052 testCRUDBridge("BridgeOtherConfigs", new SouthboundBridgeOtherConfigsBuilder(),
2053 new BridgeOtherConfigsSouthboundHelper());
2056 private interface SouthboundBridgeHelper<I extends Identifier<T>, T extends Identifiable<I>> {
2057 void writeValues(OvsdbBridgeAugmentationBuilder builder, List<T> values);
2059 Map<I, T> readValues(OvsdbBridgeAugmentation augmentation);
2062 private <I extends Identifier<T>, T extends Identifiable<I>> void testCRUDBridge(String prefix,
2063 KeyValueBuilder<T> builder, SouthboundBridgeHelper<I, T> helper) throws InterruptedException {
2064 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2065 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
2066 // the update has been performed.
2067 List<SouthboundTestCase<I, T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2068 List<SouthboundTestCase<I, T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2069 for (SouthboundTestCase<I, T> updateFromTestCase : updateFromTestCases) {
2070 for (SouthboundTestCase<I, T> updateToTestCase : updateToTestCases) {
2071 String testBridgeName = String.format("%s_%s", prefix, updateToTestCase.name);
2073 // CREATE: Create the test bridge
2074 final OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(testBridgeName);
2075 final InstanceIdentifier<Node> bridgeIid =
2076 SouthboundUtils.createInstanceIdentifier(connectionInfo, ovsdbBridgeName);
2077 final NodeId bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
2078 final NodeBuilder bridgeCreateNodeBuilder = new NodeBuilder();
2079 bridgeCreateNodeBuilder.setNodeId(bridgeNodeId);
2080 OvsdbBridgeAugmentationBuilder bridgeCreateAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
2081 bridgeCreateAugmentationBuilder.setBridgeName(ovsdbBridgeName);
2082 bridgeCreateAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
2083 bridgeCreateAugmentationBuilder.setFailMode(
2084 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
2085 setManagedBy(bridgeCreateAugmentationBuilder, connectionInfo);
2086 helper.writeValues(bridgeCreateAugmentationBuilder, updateFromTestCase.inputValues);
2087 bridgeCreateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
2088 bridgeCreateAugmentationBuilder.build());
2089 LOG.debug("Built with the intent to store bridge data {}", bridgeCreateAugmentationBuilder);
2090 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2091 bridgeCreateNodeBuilder.build()));
2092 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2094 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2095 // then repeat for OPERATIONAL data store
2096 Map<I, T> updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo,
2097 testBridgeName, LogicalDatastoreType.CONFIGURATION));
2098 assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationExternalIds);
2099 Map<I, T> updateFromOperationalExternalIds = helper.readValues(getBridge(connectionInfo,
2101 assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalExternalIds);
2103 // UPDATE: update the values
2104 final OvsdbBridgeAugmentationBuilder bridgeUpdateAugmentationBuilder =
2105 new OvsdbBridgeAugmentationBuilder();
2106 helper.writeValues(bridgeUpdateAugmentationBuilder, updateToTestCase.inputValues);
2107 final NodeBuilder bridgeUpdateNodeBuilder = new NodeBuilder();
2108 final Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
2109 bridgeUpdateNodeBuilder.setNodeId(bridgeNode.getNodeId());
2110 bridgeUpdateNodeBuilder.withKey(bridgeNode.key());
2111 bridgeUpdateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
2112 bridgeUpdateAugmentationBuilder.build());
2113 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2114 bridgeUpdateNodeBuilder.build()));
2115 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2117 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2118 // then repeat for OPERATIONAL data store
2119 Map<I, T> updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
2120 LogicalDatastoreType.CONFIGURATION));
2121 assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationExternalIds);
2122 assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationExternalIds);
2123 Map<I, T> updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
2124 if (updateFromTestCase.expectedValues != null) {
2125 assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalExternalIds);
2126 assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalExternalIds);
2130 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid));
2131 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2137 * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
2140 public void testCRUDBridgeExternalIds() throws InterruptedException {
2141 testCRUDBridge("BridgeExternalIds", new SouthboundBridgeExternalIdsBuilder(),
2142 new BridgeExternalIdsSouthboundHelper());
2146 public void testAddDeleteQos() throws InterruptedException {
2147 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2148 OvsdbNodeAugmentation ovsdbNodeAugmentation;
2149 Uri qosUri = new Uri("QOS-ROW");
2150 List<String> typeList = new ArrayList<>();
2151 typeList.add(SouthboundConstants.QOS_LINUX_HTB);
2152 typeList.add(SouthboundConstants.QOS_LINUX_HFSC);
2154 for (String qosType : typeList) {
2155 try (TestQos testQos = new TestQos(connectionInfo, qosUri, SouthboundMapper.createQosType(qosType),
2157 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2158 LogicalDatastoreType.OPERATIONAL);
2159 QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation);
2160 Assert.assertNotNull(operQosHtb);
2162 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2163 LogicalDatastoreType.OPERATIONAL);
2164 QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation);
2165 Assert.assertNull(operQosHtb);
2170 public void testAddDeleteQueue() throws InterruptedException {
2171 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2172 Uri queueUri = new Uri("QUEUE-A1");
2174 try (TestQueue testQueue = new TestQueue(connectionInfo, queueUri, Short.valueOf("25"), null, null)) {
2175 OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2176 LogicalDatastoreType.OPERATIONAL);
2177 Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation);
2178 Assert.assertNotNull(operQueue);
2180 OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2181 LogicalDatastoreType.OPERATIONAL);
2182 Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation);
2183 Assert.assertNull(operQueue);
2186 private static class SouthboundQueuesExternalIdsHelper
2187 implements SouthboundQueueHelper<QueuesExternalIdsKey, QueuesExternalIds> {
2189 public void writeValues(QueuesBuilder builder, List<QueuesExternalIds> values) {
2190 builder.setQueuesExternalIds(values);
2194 public Map<QueuesExternalIdsKey, QueuesExternalIds> readValues(Queues queue) {
2195 return queue.getQueuesExternalIds();
2199 private static class SouthboundQueuesOtherConfigHelper
2200 implements SouthboundQueueHelper<QueuesOtherConfigKey, QueuesOtherConfig> {
2202 public void writeValues(QueuesBuilder builder, List<QueuesOtherConfig> values) {
2203 builder.setQueuesOtherConfig(values);
2207 public Map<QueuesOtherConfigKey, QueuesOtherConfig> readValues(Queues queue) {
2208 return queue.getQueuesOtherConfig();
2212 private interface SouthboundQueueHelper<I extends Identifier<T>, T extends Identifiable<I>> {
2213 void writeValues(QueuesBuilder builder, List<T> values);
2215 Map<I, T> readValues(Queues queue);
2218 private static Queues getQueue(Uri queueId, OvsdbNodeAugmentation node) {
2219 for (Queues queue : node.nonnullQueues().values()) {
2220 if (queue.key().getQueueId().getValue().equals(queueId.getValue())) {
2227 private static class SouthboundQosExternalIdsHelper
2228 implements SouthboundQosHelper<QosExternalIdsKey, QosExternalIds> {
2230 public void writeValues(QosEntriesBuilder builder, List<QosExternalIds> values) {
2231 builder.setQosExternalIds(values);
2235 public Map<QosExternalIdsKey, QosExternalIds> readValues(QosEntries qos) {
2236 return qos.getQosExternalIds();
2240 private static class SouthboundQosOtherConfigHelper
2241 implements SouthboundQosHelper<QosOtherConfigKey, QosOtherConfig> {
2243 public void writeValues(QosEntriesBuilder builder, List<QosOtherConfig> values) {
2244 builder.setQosOtherConfig(values);
2248 public Map<QosOtherConfigKey, QosOtherConfig> readValues(QosEntries qos) {
2249 return qos.getQosOtherConfig();
2253 private interface SouthboundQosHelper<I extends Identifier<T>, T extends Identifiable<I>> {
2254 void writeValues(QosEntriesBuilder builder, List<T> values);
2256 Map<I, T> readValues(QosEntries qos);
2259 private static QosEntries getQos(Uri qosId, OvsdbNodeAugmentation node) {
2260 for (QosEntries qos : node.nonnullQosEntries().values()) {
2261 if (qos.key().getQosId().equals(qosId)) {
2268 private <I extends Identifier<T>, T extends Identifiable<I>> void testCRUDQueue(
2269 KeyValueBuilder<T> builder, String prefix, SouthboundQueueHelper<I, T> helper)
2270 throws InterruptedException {
2272 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2274 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
2275 // the update has been performed.
2276 List<SouthboundTestCase<I, T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2277 List<SouthboundTestCase<I, T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2279 for (SouthboundTestCase<I, T> updateFromTestCase : updateFromTestCases) {
2280 for (SouthboundTestCase<I, T> updateToTestCase : updateToTestCases) {
2281 String testQueueId = String.format("%s_%s", prefix, updateToTestCase.name);
2283 // CREATE: and update the test queue with starting values.
2284 try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId),
2285 Short.valueOf("45"), null, null)) {
2286 QueuesBuilder queuesBuilder = new QueuesBuilder();
2287 queuesBuilder.setQueueId(new Uri(testQueueId));
2288 InstanceIdentifier<Queues> queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2289 .augmentation(OvsdbNodeAugmentation.class)
2290 .child(Queues.class, queuesBuilder.build().key());
2291 final NotifyingDataChangeListener queueConfigurationListener =
2292 new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, queueIid);
2293 queueConfigurationListener.registerDataChangeListener();
2294 final NotifyingDataChangeListener queueOperationalListener =
2295 new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid);
2296 queueOperationalListener.registerDataChangeListener();
2298 helper.writeValues(queuesBuilder, updateFromTestCase.inputValues);
2299 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2300 queueIid, queuesBuilder.build()));
2301 queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2303 // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store,
2304 // then repeat for OPERATIONAL data store
2305 OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2306 LogicalDatastoreType.CONFIGURATION);
2307 Queues queueFromConfig =
2308 getQueue(new Uri(testQueueId), updateFromConfigurationOvsdbNodeAugmentation);
2309 if (queueFromConfig != null) {
2310 assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(queueFromConfig));
2313 queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2314 OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2315 LogicalDatastoreType.OPERATIONAL);
2316 Queues queueFromOper = getQueue(new Uri(testQueueId), updateFromOperationalOvsdbNodeAugmentation);
2317 if (queueFromOper != null) {
2318 assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(queueFromOper));
2321 // UPDATE: update the values
2322 QueuesBuilder queuesUpdateBuilder = new QueuesBuilder();
2323 queuesUpdateBuilder.setQueueId(new Uri(testQueueId));
2324 helper.writeValues(queuesUpdateBuilder, updateToTestCase.inputValues);
2325 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2326 queueIid, queuesUpdateBuilder.build()));
2327 queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2329 // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store,
2330 // then repeat for OPERATIONAL data store
2331 OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2332 LogicalDatastoreType.CONFIGURATION);
2333 Queues queueToConfig = getQueue(new Uri(testQueueId), updateToConfigurationOvsdbNodeAugmentation);
2334 if (queueToConfig != null) {
2335 assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(queueToConfig));
2338 queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2339 OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2340 LogicalDatastoreType.OPERATIONAL);
2341 Queues queueToOper = getQueue(new Uri(testQueueId), updateToOperationalOvsdbNodeAugmentation);
2342 if (queueToOper != null) {
2343 assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(queueToOper));
2346 // DELETE handled by TestQueue
2353 public void testCRUDQueueExternalIds() throws InterruptedException {
2354 testCRUDQueue(new SouthboundQueuesExternalIdsBuilder(), "QueueExternalIds",
2355 new SouthboundQueuesExternalIdsHelper());
2359 public void testCRUDQueueOtherConfig() throws InterruptedException {
2360 testCRUDQueue(new SouthboundQueuesOtherConfigBuilder(), "QueueOtherConfig",
2361 new SouthboundQueuesOtherConfigHelper());
2365 public void testCRUDQueueDscp() throws InterruptedException {
2366 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2367 String testQueueId = "testQueueDscp";
2369 // CREATE: and update the test queue with starting values.
2370 try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), (short) 0, null, null)) {
2371 for (Short dscp = 1; dscp < 64; dscp++) {
2372 QueuesBuilder queuesBuilder = new QueuesBuilder();
2373 queuesBuilder.setQueueId(new Uri(testQueueId));
2374 InstanceIdentifier<Queues> queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2375 .augmentation(OvsdbNodeAugmentation.class)
2376 .child(Queues.class, queuesBuilder.build().key());
2377 final NotifyingDataChangeListener queueOperationalListener =
2378 new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid);
2379 queueOperationalListener.registerDataChangeListener();
2381 queuesBuilder.setDscp(dscp);
2382 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2383 queueIid, queuesBuilder.build()));
2384 queueOperationalListener.waitForUpdate(OVSDB_ROUNDTRIP_TIMEOUT);
2386 // READ: Read the test queue and ensure changes are propagated to the OPERATIONAL data store
2387 // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2388 OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2389 LogicalDatastoreType.OPERATIONAL);
2390 Queues operQueue = getQueue(new Uri(testQueueId), ovsdbNodeAugmentation);
2391 Assert.assertNotNull(operQueue);
2392 Short operDscp = operQueue.getDscp().toJava();
2393 Assert.assertNotNull(operDscp);
2394 Assert.assertEquals(dscp, operDscp);
2397 // DELETE handled by TestQueue
2402 private <I extends Identifier<T>, T extends Identifiable<I>> void testCRUDQos(
2403 KeyValueBuilder<T> builder, String prefix, SouthboundQosHelper<I, T> helper)
2404 throws InterruptedException {
2406 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2408 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
2409 // the update has been performed.
2410 List<SouthboundTestCase<I, T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2411 List<SouthboundTestCase<I, T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2413 for (SouthboundTestCase<I, T> updateFromTestCase : updateFromTestCases) {
2414 for (SouthboundTestCase<I, T> updateToTestCase : updateToTestCases) {
2415 String testQosId = String.format("%s_%s", prefix, updateToTestCase.name);
2417 // CREATE: and update the test qos with starting values.
2418 try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId),
2419 SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null)) {
2420 QosEntriesBuilder qosBuilder = new QosEntriesBuilder();
2421 qosBuilder.setQosId(new Uri(testQosId));
2422 InstanceIdentifier<QosEntries> qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2423 .augmentation(OvsdbNodeAugmentation.class)
2424 .child(QosEntries.class, qosBuilder.build().key());
2425 final NotifyingDataChangeListener qosConfigurationListener =
2426 new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, qosIid);
2427 qosConfigurationListener.registerDataChangeListener();
2428 final NotifyingDataChangeListener qosOperationalListener =
2429 new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid);
2430 qosOperationalListener.registerDataChangeListener();
2432 helper.writeValues(qosBuilder, updateFromTestCase.inputValues);
2433 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2434 qosIid, qosBuilder.build()));
2435 qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2437 // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store,
2438 // then repeat for OPERATIONAL data store
2439 OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2440 LogicalDatastoreType.CONFIGURATION);
2441 QosEntries qosFromConfig = getQos(new Uri(testQosId), updateFromConfigurationOvsdbNodeAugmentation);
2442 if (qosFromConfig != null) {
2443 assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(qosFromConfig));
2446 qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2447 OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2448 LogicalDatastoreType.OPERATIONAL);
2449 QosEntries qosFromOper = getQos(new Uri(testQosId), updateFromOperationalOvsdbNodeAugmentation);
2450 if (qosFromOper != null) {
2451 assertExpectedExist(updateFromTestCase.expectedValues, helper.readValues(qosFromOper));
2454 // UPDATE: update the values
2455 QosEntriesBuilder qosUpdateBuilder = new QosEntriesBuilder();
2456 qosUpdateBuilder.setQosId(new Uri(testQosId));
2457 helper.writeValues(qosUpdateBuilder, updateToTestCase.inputValues);
2458 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2459 qosIid, qosUpdateBuilder.build()));
2460 qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2462 // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store,
2463 // then repeat for OPERATIONAL data store
2464 OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2465 LogicalDatastoreType.CONFIGURATION);
2466 QosEntries qosToConfig = getQos(new Uri(testQosId), updateToConfigurationOvsdbNodeAugmentation);
2467 if (qosToConfig != null) {
2468 assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(qosToConfig));
2471 qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2472 OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2473 LogicalDatastoreType.OPERATIONAL);
2474 QosEntries qosToOper = getQos(new Uri(testQosId), updateToOperationalOvsdbNodeAugmentation);
2475 if (qosToOper != null) {
2476 assertExpectedExist(updateToTestCase.expectedValues, helper.readValues(qosToOper));
2479 // DELETE handled by TestQueue
2486 public void testCRUDQosExternalIds() throws InterruptedException {
2487 testCRUDQos(new SouthboundQosExternalIdsBuilder(), "QosExternalIds",
2488 new SouthboundQosExternalIdsHelper());
2492 public void testCRUDQosOtherConfig() throws InterruptedException {
2493 testCRUDQos(new SouthboundQosOtherConfigBuilder(), "QosOtherConfig",
2494 new SouthboundQosOtherConfigHelper());
2498 public void testCRUDQosQueues() throws InterruptedException {
2499 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2500 String testQosId = "testQosQueues";
2502 // CREATE: and update the test queue with starting values.
2503 try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId),
2504 SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null);
2505 TestQueue testQueue1 = new TestQueue(connectionInfo, new Uri("queue1"), Short.valueOf("12"), null,
2507 TestQueue testQueue2 = new TestQueue(connectionInfo, new Uri("queue2"), Short.valueOf("35"), null,
2509 QosEntriesBuilder qosBuilder = new QosEntriesBuilder();
2510 qosBuilder.setQosId(new Uri(testQosId));
2511 InstanceIdentifier<QosEntries> qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2512 .augmentation(OvsdbNodeAugmentation.class)
2513 .child(QosEntries.class, qosBuilder.build().key());
2514 final NotifyingDataChangeListener qosOperationalListener =
2515 new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid);
2516 qosOperationalListener.registerDataChangeListener();
2518 // READ, UPDATE: Read the UUIDs of the Queue rows and add them to the
2519 // configuration of the Qos row.
2520 OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2521 LogicalDatastoreType.OPERATIONAL);
2523 Queues operQueue1 = getQueue(new Uri("queue1"), ovsdbNodeAugmentation);
2525 Assert.assertNotNull(operQueue1);
2527 InstanceIdentifier<Queues> queue1Iid = testQueue1.getInstanceIdentifier();
2528 OvsdbQueueRef queue1Ref = new OvsdbQueueRef(queue1Iid);
2530 Queues operQueue2 = getQueue(new Uri("queue2"), ovsdbNodeAugmentation);
2531 Assert.assertNotNull(operQueue2);
2532 InstanceIdentifier<Queues> queue2Iid = testQueue2.getInstanceIdentifier();
2533 OvsdbQueueRef queue2Ref = new OvsdbQueueRef(queue2Iid);
2535 List<QueueList> queueList = new ArrayList<>();
2536 queueList.add(new QueueListBuilder().setQueueNumber(Uint32.ONE).setQueueRef(queue1Ref).build());
2537 queueList.add(new QueueListBuilder().setQueueNumber(Uint32.TWO).setQueueRef(queue2Ref).build());
2539 qosBuilder.setQueueList(queueList);
2541 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2542 qosIid, qosBuilder.build()));
2543 qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2545 // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store
2546 // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2547 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2548 LogicalDatastoreType.OPERATIONAL);
2549 QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2550 Assert.assertNotNull(operQos);
2551 Map<QueueListKey, QueueList> operQueueList = operQos.getQueueList();
2552 Assert.assertNotNull(operQueueList);
2553 for (QueueList queueEntry : queueList) {
2554 Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
2557 // DELETE one queue from queue list and check that one remains
2558 KeyedInstanceIdentifier<QueueList, QueueListKey> qosQueueIid = qosIid
2559 .child(QueueList.class, new QueueListKey(Uint32.ONE));
2560 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid));
2561 qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2563 // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store
2564 // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2565 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2566 LogicalDatastoreType.OPERATIONAL);
2567 operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2568 Assert.assertNotNull(operQos);
2569 operQueueList = operQos.getQueueList();
2570 Assert.assertNotNull(operQueueList);
2572 for (QueueList queueEntry : queueList) {
2573 if (queueEntry.getQueueRef().equals(queue2Ref)) {
2574 Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
2575 } else if (queueEntry.getQueueRef().equals(queue1Ref)) {
2576 Assert.assertFalse(isQueueInList(operQueueList, queueEntry));
2578 Assert.assertTrue("Unknown queue entry in qos queue list", false);
2582 // DELETE queue list and check that list is empty
2583 qosQueueIid = qosIid
2584 .child(QueueList.class, new QueueListKey(Uint32.ONE));
2585 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid));
2586 qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2588 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2589 LogicalDatastoreType.OPERATIONAL);
2590 operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2591 Assert.assertNotNull(operQos);
2592 operQueueList = operQos.getQueueList();
2593 Assert.assertNotNull(operQueueList);
2594 Assert.assertTrue(operQueueList.isEmpty());
2600 private static Boolean isQueueInList(Map<QueueListKey, QueueList> queueList, QueueList queue) {
2601 for (QueueList queueEntry : queueList.values()) {
2602 if (queueEntry.getQueueNumber().equals(queue.getQueueNumber())
2603 && queueEntry.getQueueRef().equals(queue.getQueueRef())) {
2612 * Representation of a southbound test case. Each test case has a name, a list of input values and a list of
2613 * expected values. The input values are provided to the augmentation builder, and the expected values are checked
2614 * against the output of the resulting augmentation.
2617 * Instances of this class are immutable.
2620 * @param <T> The type of data used for the test case.
2622 private static final class SouthboundTestCase<I extends Identifier<T>, T extends Identifiable<I>> {
2623 private final String name;
2624 private final List<T> inputValues;
2625 private final Map<I, T> expectedValues;
2628 * Creates an instance of a southbound test case.
2630 * @param name The test case's name.
2631 * @param inputValues The input values (provided as input to the underlying augmentation builder).
2632 * @param expectedValues The expected values (checked against the output of the underlying augmentation).
2634 SouthboundTestCase(final String name, final List<T> inputValues, final List<T> expectedValues) {
2636 this.inputValues = inputValues;
2637 this.expectedValues = Maps.uniqueIndex(expectedValues, Identifiable::key);
2642 * Southbound test case builder.
2644 * @param <T> The type of data used for the test case.
2646 private static final class SouthboundTestCaseBuilder<I extends Identifier<T>, T extends Identifiable<I>> {
2647 private String name;
2648 private List<T> inputValues;
2649 private List<T> expectedValues;
2652 * Creates a builder. Builders may be reused, the generated immutable instances are independent of the
2653 * builders. There are no default values.
2655 SouthboundTestCaseBuilder() {
2660 * Sets the test case's name.
2662 * @param value The test case's name.
2663 * @return The builder.
2665 public SouthboundTestCaseBuilder<I, T> name(final String value) {
2671 * Sets the input values.
2673 * @param values The input values.
2674 * @return The builder.
2677 public final SouthboundTestCaseBuilder<I, T> input(final T... values) {
2678 this.inputValues = Lists.newArrayList(values);
2683 * Indicates that the provided input values should be expected as output values.
2685 * @return The builder.
2687 public SouthboundTestCaseBuilder<I, T> expectInputAsOutput() {
2688 this.expectedValues = this.inputValues;
2693 * Indicates that no output should be expected.
2695 * @return The builder.
2697 public SouthboundTestCaseBuilder<I, T> expectNoOutput() {
2698 this.expectedValues = null;
2703 * Builds an immutable instance representing the test case.
2705 * @return The test case.
2707 public SouthboundTestCase<I, T> build() {
2708 return new SouthboundTestCase<>(name, inputValues, expectedValues);
2712 private abstract static class KeyValueBuilder<T> {
2713 private static final int COUNTER_START = 0;
2714 private int counter = COUNTER_START;
2716 protected abstract Builder<T> builder();
2718 protected abstract void setKey(Builder<T> builder, String key);
2720 protected abstract void setValue(Builder<T> builder, String value);
2722 protected abstract boolean isValueMandatory();
2724 public final T build(final String testName, final String key, final String value) {
2725 final Builder<T> builder = builder();
2728 setKey(builder, String.format(FORMAT_STR, testName, key, this.counter));
2730 if (value != null) {
2731 setValue(builder, String.format(FORMAT_STR, testName, value, this.counter));
2733 return builder.build();
2736 public final void reset() {
2737 this.counter = COUNTER_START;
2741 private static final class SouthboundQueuesExternalIdsBuilder extends KeyValueBuilder<QueuesExternalIds> {
2743 protected Builder<QueuesExternalIds> builder() {
2744 return new QueuesExternalIdsBuilder();
2748 protected void setKey(Builder<QueuesExternalIds> builder, String key) {
2749 ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdKey(key);
2753 protected void setValue(Builder<QueuesExternalIds> builder, String value) {
2754 ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdValue(value);
2758 protected boolean isValueMandatory() {
2763 private static final class SouthboundQueuesOtherConfigBuilder extends KeyValueBuilder<QueuesOtherConfig> {
2765 protected Builder<QueuesOtherConfig> builder() {
2766 return new QueuesOtherConfigBuilder();
2770 protected void setKey(Builder<QueuesOtherConfig> builder, String key) {
2771 ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigKey(key);
2775 protected void setValue(Builder<QueuesOtherConfig> builder, String value) {
2776 ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigValue(value);
2780 protected boolean isValueMandatory() {
2785 private static final class SouthboundQosExternalIdsBuilder extends KeyValueBuilder<QosExternalIds> {
2787 protected Builder<QosExternalIds> builder() {
2788 return new QosExternalIdsBuilder();
2792 protected void setKey(Builder<QosExternalIds> builder, String key) {
2793 ((QosExternalIdsBuilder) builder).setQosExternalIdKey(key);
2797 protected void setValue(Builder<QosExternalIds> builder, String value) {
2798 ((QosExternalIdsBuilder) builder).setQosExternalIdValue(value);
2802 protected boolean isValueMandatory() {
2807 private static final class SouthboundQosOtherConfigBuilder extends KeyValueBuilder<QosOtherConfig> {
2809 protected Builder<QosOtherConfig> builder() {
2810 return new QosOtherConfigBuilder();
2814 protected void setKey(Builder<QosOtherConfig> builder, String key) {
2815 ((QosOtherConfigBuilder) builder).setOtherConfigKey(key);
2819 protected void setValue(Builder<QosOtherConfig> builder, String value) {
2820 ((QosOtherConfigBuilder) builder).setOtherConfigValue(value);
2824 protected boolean isValueMandatory() {
2829 private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder<PortExternalIds> {
2831 protected Builder<PortExternalIds> builder() {
2832 return new PortExternalIdsBuilder();
2836 protected void setKey(Builder<PortExternalIds> builder, String key) {
2837 ((PortExternalIdsBuilder) builder).setExternalIdKey(key);
2841 protected void setValue(Builder<PortExternalIds> builder, String value) {
2842 ((PortExternalIdsBuilder) builder).setExternalIdValue(value);
2846 protected boolean isValueMandatory() {
2851 private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder<InterfaceExternalIds> {
2853 protected Builder<InterfaceExternalIds> builder() {
2854 return new InterfaceExternalIdsBuilder();
2858 protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
2859 ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
2863 protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
2864 ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
2868 protected boolean isValueMandatory() {
2873 private static final class SouthboundInterfaceLldpBuilder extends KeyValueBuilder<InterfaceLldp> {
2875 protected Builder<InterfaceLldp> builder() {
2876 return new InterfaceLldpBuilder();
2880 protected void setKey(Builder<InterfaceLldp> builder, String key) {
2881 ((InterfaceLldpBuilder) builder).setLldpKey(key);
2885 protected void setValue(Builder<InterfaceLldp> builder, String value) {
2886 ((InterfaceLldpBuilder) builder).setLldpValue(value);
2890 protected boolean isValueMandatory() {
2895 private static final class SouthboundOptionsBuilder extends KeyValueBuilder<Options> {
2897 protected Builder<Options> builder() {
2898 return new OptionsBuilder();
2902 protected void setKey(Builder<Options> builder, String key) {
2903 ((OptionsBuilder) builder).setOption(key);
2907 protected void setValue(Builder<Options> builder, String value) {
2908 ((OptionsBuilder) builder).setValue(value);
2912 protected boolean isValueMandatory() {
2917 private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder<InterfaceOtherConfigs> {
2919 protected Builder<InterfaceOtherConfigs> builder() {
2920 return new InterfaceOtherConfigsBuilder();
2924 protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
2925 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
2929 protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
2930 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
2934 protected boolean isValueMandatory() {
2939 private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder<PortOtherConfigs> {
2941 protected Builder<PortOtherConfigs> builder() {
2942 return new PortOtherConfigsBuilder();
2946 protected void setKey(Builder<PortOtherConfigs> builder, String key) {
2947 ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
2951 protected void setValue(Builder<PortOtherConfigs> builder, String value) {
2952 ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
2956 protected boolean isValueMandatory() {
2961 private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder<BridgeOtherConfigs> {
2963 protected Builder<BridgeOtherConfigs> builder() {
2964 return new BridgeOtherConfigsBuilder();
2968 protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
2969 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
2973 protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
2974 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
2978 protected boolean isValueMandatory() {
2983 private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder<BridgeExternalIds> {
2985 protected Builder<BridgeExternalIds> builder() {
2986 return new BridgeExternalIdsBuilder();
2990 protected void setKey(Builder<BridgeExternalIds> builder, String key) {
2991 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
2995 protected void setValue(Builder<BridgeExternalIds> builder, String value) {
2996 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
3000 protected boolean isValueMandatory() {
3006 * Generates the test cases involved in testing key-value-based data. See inline comments for descriptions of
3007 * the particular cases considered.
3009 private static <I extends Identifier<T>, T extends Identifiable<I>> List<SouthboundTestCase<I, T>>
3010 generateKeyValueTestCases(KeyValueBuilder<T> builder, String testName) {
3011 List<SouthboundTestCase<I, T>> testCases = new ArrayList<>();
3013 final String goodKey = "GoodKey";
3014 final String goodValue = "GoodValue";
3015 final String noValueForKey = "NoValueForKey";
3017 final String idKey = testName + "Key";
3018 final String idValue = testName + "Value";
3020 // Test Case 1: TestOne
3021 // Test Type: Positive
3022 // Description: Create a termination point with one value
3023 // Expected: A port is created with the single value specified below
3024 final String testOneName = "TestOne" + testName;
3025 testCases.add(new SouthboundTestCaseBuilder<I, T>()
3027 .input(builder.build(testOneName, idKey, idValue))
3028 .expectInputAsOutput()
3032 // Test Case 2: TestFive
3033 // Test Type: Positive
3034 // Description: Create a termination point with multiple (five) values
3035 // Expected: A port is created with the five values specified below
3036 final String testFiveName = "TestFive" + testName;
3037 testCases.add(new SouthboundTestCaseBuilder<I, T>()
3040 builder.build(testFiveName, idKey, idValue),
3041 builder.build(testFiveName, idKey, idValue),
3042 builder.build(testFiveName, idKey, idValue),
3043 builder.build(testFiveName, idKey, idValue),
3044 builder.build(testFiveName, idKey, idValue))
3045 .expectInputAsOutput()
3049 if (!builder.isValueMandatory()) {
3050 // Test Case 3: TestOneGoodOneMalformedValue
3051 // Test Type: Negative
3053 // One perfectly fine input
3054 // (TestOneGoodOneMalformedValue_GoodKey_1,
3055 // TestOneGoodOneMalformedValue_GoodValue_1)
3056 // and one malformed input which only has key specified
3057 // (TestOneGoodOneMalformedValue_NoValueForKey_2,
3059 // Expected: A port is created without any values
3060 final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName;
3061 testCases.add(new SouthboundTestCaseBuilder<I, T>()
3062 .name(testOneGoodOneMalformedValueName)
3064 builder.build(testOneGoodOneMalformedValueName, goodKey, goodValue),
3065 builder.build(testOneGoodOneMalformedValueName, noValueForKey, null))
3070 LOG.info("generateKeyValueTestCases: skipping test case 3 for {}", builder.getClass().getSimpleName());
3076 private static class PortExternalIdsSouthboundHelper
3077 implements SouthboundTerminationPointHelper<PortExternalIdsKey, PortExternalIds> {
3079 public void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<PortExternalIds> values) {
3080 builder.setPortExternalIds(values);
3084 public Map<PortExternalIdsKey, PortExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
3085 return augmentation.getPortExternalIds();
3089 private static class InterfaceExternalIdsSouthboundHelper
3090 implements SouthboundTerminationPointHelper<InterfaceExternalIdsKey, InterfaceExternalIds> {
3092 public void writeValues(
3093 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceExternalIds> values) {
3094 builder.setInterfaceExternalIds(values);
3098 public Map<InterfaceExternalIdsKey, InterfaceExternalIds> readValues(
3099 OvsdbTerminationPointAugmentation augmentation) {
3100 return augmentation.getInterfaceExternalIds();
3104 private static class InterfaceLldpSouthboundHelper
3105 implements SouthboundTerminationPointHelper<InterfaceLldpKey, InterfaceLldp> {
3107 public void writeValues(
3108 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceLldp> values) {
3109 builder.setInterfaceLldp(values);
3113 public Map<InterfaceLldpKey, InterfaceLldp> readValues(OvsdbTerminationPointAugmentation augmentation) {
3114 return augmentation.getInterfaceLldp();
3118 private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper<OptionsKey, Options> {
3120 public void writeValues(
3121 OvsdbTerminationPointAugmentationBuilder builder, List<Options> values) {
3122 builder.setOptions(values);
3126 public Map<OptionsKey, Options> readValues(OvsdbTerminationPointAugmentation augmentation) {
3127 return augmentation.getOptions();
3131 private static class InterfaceOtherConfigsSouthboundHelper
3132 implements SouthboundTerminationPointHelper<InterfaceOtherConfigsKey, InterfaceOtherConfigs> {
3134 public void writeValues(
3135 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceOtherConfigs> values) {
3136 builder.setInterfaceOtherConfigs(values);
3140 public Map<InterfaceOtherConfigsKey, InterfaceOtherConfigs> readValues(
3141 OvsdbTerminationPointAugmentation augmentation) {
3142 return augmentation.getInterfaceOtherConfigs();
3146 private static class PortOtherConfigsSouthboundHelper implements
3147 SouthboundTerminationPointHelper<PortOtherConfigsKey, PortOtherConfigs> {
3149 public void writeValues(
3150 OvsdbTerminationPointAugmentationBuilder builder, List<PortOtherConfigs> values) {
3151 builder.setPortOtherConfigs(values);
3155 public Map<PortOtherConfigsKey, PortOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
3156 return augmentation.getPortOtherConfigs();
3160 private static class BridgeExternalIdsSouthboundHelper
3161 implements SouthboundBridgeHelper<BridgeExternalIdsKey, BridgeExternalIds> {
3163 public void writeValues(
3164 OvsdbBridgeAugmentationBuilder builder, List<BridgeExternalIds> values) {
3165 builder.setBridgeExternalIds(values);
3169 public Map<BridgeExternalIdsKey, BridgeExternalIds> readValues(OvsdbBridgeAugmentation augmentation) {
3170 return augmentation.getBridgeExternalIds();
3174 private static class BridgeOtherConfigsSouthboundHelper
3175 implements SouthboundBridgeHelper<BridgeOtherConfigsKey, BridgeOtherConfigs> {
3177 public void writeValues(
3178 OvsdbBridgeAugmentationBuilder builder, List<BridgeOtherConfigs> values) {
3179 builder.setBridgeOtherConfigs(values);
3183 public Map<BridgeOtherConfigsKey, BridgeOtherConfigs> readValues(OvsdbBridgeAugmentation augmentation) {
3184 return augmentation.getBridgeOtherConfigs();