MRI version bump for Aluminium
[genius.git] / interfacemanager / interfacemanager-impl / src / test / java / org / opendaylight / genius / interfacemanager / test / InterfaceManagerConfigurationTest.java
1 /*
2  * Copyright (c) 2016, 2017 Red Hat, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.genius.interfacemanager.test;
9
10 import static java.util.concurrent.TimeUnit.MINUTES;
11 import static org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.BatchingUtils.EntityType.DEFAULT_OPERATIONAL;
12 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.DPN_ID_1;
13 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.DPN_ID_2;
14 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.INTERFACE_NAME;
15 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.INTERFACE_NAME_1;
16 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.INTERFACE_NAME_2;
17 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.PARENT_INTERFACE;
18 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.PARENT_INTERFACE_1;
19 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.PARENT_INTERFACE_2;
20 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.PORT_NO_1;
21 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.TRUNK_INTERFACE_NAME;
22 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.TUNNEL_INTERFACE_NAME;
23 import static org.opendaylight.genius.interfacemanager.test.InterfaceManagerTestUtil.waitTillOperationCompletes;
24 import static org.opendaylight.genius.mdsalutil.NwConstants.DEFAULT_EGRESS_SERVICE_INDEX;
25 import static org.opendaylight.genius.mdsalutil.NwConstants.VLAN_INTERFACE_INGRESS_TABLE;
26 import static org.opendaylight.mdsal.binding.testutils.AssertDataObjects.assertEqualBeans;
27 import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION;
28 import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.OPERATIONAL;
29
30 import java.util.ArrayList;
31 import java.util.Comparator;
32 import java.util.List;
33 import java.util.Optional;
34 import java.util.concurrent.ExecutionException;
35 import java.util.concurrent.Future;
36 import javax.inject.Inject;
37 import org.junit.After;
38 import org.junit.Assert;
39 import org.junit.Before;
40 import org.junit.Ignore;
41 import org.junit.Rule;
42 import org.junit.Test;
43 import org.junit.rules.MethodRule;
44 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
45 import org.opendaylight.genius.datastoreutils.testutils.AsyncEventsWaiter;
46 import org.opendaylight.genius.datastoreutils.testutils.JobCoordinatorCountedEventsWaiter;
47 import org.opendaylight.genius.datastoreutils.testutils.JobCoordinatorTestModule;
48 import org.opendaylight.genius.datastoreutils.testutils.TestableDataTreeChangeListenerModule;
49 import org.opendaylight.genius.interfacemanager.IfmUtil;
50 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
51 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
52 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
53 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.BatchingUtils;
54 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
55 import org.opendaylight.genius.interfacemanager.test.xtend.DpnFromInterfaceOutput;
56 import org.opendaylight.genius.interfacemanager.test.xtend.EgressActionsForInterfaceOutput;
57 import org.opendaylight.genius.interfacemanager.test.xtend.EgressInstructionsForInterfaceOutput;
58 import org.opendaylight.genius.interfacemanager.test.xtend.EndPointIpFromDpn;
59 import org.opendaylight.genius.interfacemanager.test.xtend.ExpectedBoundServiceState;
60 import org.opendaylight.genius.interfacemanager.test.xtend.ExpectedFlowEntries;
61 import org.opendaylight.genius.interfacemanager.test.xtend.ExpectedInterfaceChildEntry;
62 import org.opendaylight.genius.interfacemanager.test.xtend.ExpectedInterfaceConfig;
63 import org.opendaylight.genius.interfacemanager.test.xtend.ExpectedInterfaceInfo;
64 import org.opendaylight.genius.interfacemanager.test.xtend.ExpectedInterfaceListFromDpn;
65 import org.opendaylight.genius.interfacemanager.test.xtend.ExpectedInterfaceState;
66 import org.opendaylight.genius.interfacemanager.test.xtend.ExpectedOvsdbBridge;
67 import org.opendaylight.genius.interfacemanager.test.xtend.ExpectedServicesInfo;
68 import org.opendaylight.genius.interfacemanager.test.xtend.ExpectedTerminationPoint;
69 import org.opendaylight.genius.interfacemanager.test.xtend.InterfaceMeta;
70 import org.opendaylight.genius.interfacemanager.test.xtend.InterfaceTypeOutput;
71 import org.opendaylight.genius.interfacemanager.test.xtend.NodeconnectorIdFromInterfaceOutput;
72 import org.opendaylight.genius.interfacemanager.test.xtend.PortFromInterfaceOutput;
73 import org.opendaylight.genius.interfacemanager.test.xtend.TunnelTypeOutput;
74 import org.opendaylight.genius.mdsalutil.NwConstants;
75 import org.opendaylight.genius.mdsalutil.interfaces.testutils.FlowAssertTestUtils;
76 import org.opendaylight.genius.utils.ServiceIndex;
77 import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule;
78 import org.opendaylight.infrautils.testutils.LogCaptureRule;
79 import org.opendaylight.infrautils.testutils.LogRule;
80 import org.opendaylight.infrautils.testutils.concurrent.TestableQueues;
81 import org.opendaylight.mdsal.binding.api.DataBroker;
82 import org.opendaylight.mdsal.binding.api.WriteTransaction;
83 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
84 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan;
85 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel;
86 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
87 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.DpnToInterfaceList;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntryKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntryKey;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterface;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterfaceKey;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntry;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntryBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntryKey;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpnInterfaceListInput;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpnInterfaceListInputBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpnInterfaceListOutput;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInput;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressInstructionsForInterfaceInput;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressInstructionsForInterfaceInputBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressInstructionsForInterfaceOutput;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInput;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInputBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnOutput;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceTypeInput;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceTypeInputBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceTypeOutput;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetNodeconnectorIdFromInterfaceInput;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetNodeconnectorIdFromInterfaceInputBuilder;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetNodeconnectorIdFromInterfaceOutput;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetTunnelTypeInput;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetTunnelTypeInputBuilder;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetTunnelTypeOutput;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.get.dpn._interface.list.output.Interfaces;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlan;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfd;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
155 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
156 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
157 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
158 import org.opendaylight.yangtools.yang.common.RpcResult;
159 import org.opendaylight.yangtools.yang.common.Uint64;
160
161 /**
162  * Component tests for interface manager.
163  *
164  * @author Michael Vorburger
165  * @author Faseela K
166  */
167 @SuppressWarnings("deprecation")
168 public class InterfaceManagerConfigurationTest {
169
170     // Uncomment this, temporarily (never commit!), to see concurrency issues:
171     // public static @ClassRule RunUntilFailureClassRule classRepeater = new RunUntilFailureClassRule();
172     // public @Rule RunUntilFailureRule repeater = new RunUntilFailureRule(classRepeater);
173
174     public @Rule LogRule logRule = new LogRule();
175     public @Rule LogCaptureRule logCaptureRule = new LogCaptureRule();
176
177     public @Rule MethodRule guice = new GuiceRule(InterfaceManagerTestModule.class,
178         TestableDataTreeChangeListenerModule.class, JobCoordinatorTestModule.class);
179
180     @Inject DataBroker dataBroker;
181     @Inject OdlInterfaceRpcService odlInterfaceRpcService;
182     @Inject IInterfaceManager interfaceManager;
183     @Inject JobCoordinatorCountedEventsWaiter coordinatorEventsWaiter;
184     @Inject AsyncEventsWaiter asyncEventsWaiter;
185     @Inject InterfaceMetaUtils interfaceMetaUtils;
186     @Inject BatchingUtils batchingUtils;
187     @Inject FlowAssertTestUtils flowAssertTestUtils;
188
189     SingleTransactionDataBroker db;
190
191     @Before
192     public void start() throws InterruptedException, ExecutionException {
193         db = new SingleTransactionDataBroker(dataBroker);
194
195         // Create the bridge and make sure it is ready
196         setupAndAssertBridgeCreation();
197     }
198
199     @After
200     public void stop() throws InterruptedException, ExecutionException {
201         setupAndAssertBridgeDeletion();
202     }
203
204     private void setupAndAssertBridgeDeletion() throws InterruptedException, ExecutionException {
205         OvsdbSouthboundTestUtil.deleteBridge(dataBroker);
206         InterfaceManagerTestUtil.waitTillOperationCompletes("bridge deletion",
207                 coordinatorEventsWaiter,2, asyncEventsWaiter);
208         assertEqualBeans(interfaceMetaUtils.getBridgeRefEntryFromOperationalDS(DPN_ID_1), null);
209     }
210
211     private void setupAndAssertBridgeCreation() throws InterruptedException, ExecutionException {
212         OvsdbSouthboundTestUtil.createBridge(dataBroker);
213         // a) Check bridgeRefEntry in cache and OperDS are same and use the
214         // right DPN_ID
215         BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(DPN_ID_1);
216         InstanceIdentifier<BridgeRefEntry> bridgeRefEntryIid = InterfaceMetaUtils
217                 .getBridgeRefEntryIdentifier(bridgeRefEntryKey);
218         InterfaceManagerTestUtil.waitTillOperationCompletes("bridge creation",
219                 coordinatorEventsWaiter,3, asyncEventsWaiter);
220         BridgeRefEntry bridgeRefEntry = IfmUtil
221                 .read(LogicalDatastoreType.OPERATIONAL, bridgeRefEntryIid, dataBroker)
222                 .orElse(null);
223         assertEqualBeans(bridgeRefEntry.getDpid(), DPN_ID_1);
224         // FIXME AsyncEventsWaiter does not help in this case, need to enhance -- TODO
225         //assertEqualBeans(interfaceMetaUtils.getBridgeRefEntryFromCache(DPN_ID_1), bridgeRefEntry);
226
227     }
228
229     @Test
230     public void testBinding() {
231
232     }
233
234     @Test
235     @Ignore // TODO re-enable when stable, see https://jira.opendaylight.org/browse/GENIUS-120
236     public void newl2vlanInterfaceTests() throws Exception {
237         // 1. When
238         // i) parent-interface specified in above vlan configuration comes in operational/ietf-interfaces-state
239         OvsdbSouthboundTestUtil.createTerminationPoint(dataBroker, PARENT_INTERFACE, null, INTERFACE_NAME);
240         InterfaceManagerTestUtil.createFlowCapableNodeConnector(dataBroker, PARENT_INTERFACE, null);
241
242         // ii) Vlan interface written to config/ietf-interfaces DS and
243         // corresponding parent-interface is not present
244         // in operational/ietf-interface-state
245         ParentRefs parentRefs = new ParentRefsBuilder().setParentInterface(PARENT_INTERFACE).build();
246         InterfaceManagerTestUtil.putInterfaceConfig(dataBroker, INTERFACE_NAME, parentRefs, L2vlan.class);
247
248         InterfaceManagerTestUtil.waitTillOperationCompletes("create interface configuration",
249                 coordinatorEventsWaiter,11, asyncEventsWaiter);
250
251         // 3. Then
252         // a) check expected interface-child entry mapping in
253         // odl-interface-meta/config/interface-child-info was created
254         InstanceIdentifier<InterfaceChildEntry> interfaceChildEntryInstanceIdentifier = InterfaceMetaUtils
255                 .getInterfaceChildEntryIdentifier(new InterfaceParentEntryKey(PARENT_INTERFACE),
256                         new InterfaceChildEntryKey(INTERFACE_NAME));
257         assertEqualBeans(ExpectedInterfaceChildEntry.interfaceChildEntry(INTERFACE_NAME),
258                 dataBroker.newReadOnlyTransaction().read(CONFIGURATION,
259                         interfaceChildEntryInstanceIdentifier).get());
260
261         // Then
262         // a) check if operational/ietf-interfaces-state is populated for the vlan interface
263         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
264             .interfaces.state.Interface ifaceState =
265                 dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
266                 IfmUtil.buildStateInterfaceId(INTERFACE_NAME)).get().get();
267
268         assertEqualBeans(ExpectedInterfaceState.newInterfaceState(ifaceState.getIfIndex(),
269             INTERFACE_NAME, Interface.OperStatus.Up, L2vlan.class, DPN_ID_1.toString(),
270                 ifaceState.getStatistics().getDiscontinuityTime()), ifaceState);
271
272
273         // FIXME can assert this only once ResourceBatchingManager becomes testable
274         // b) check if lport-tag to interface mapping is created
275         /*(InstanceIdentifier<IfIndexInterface> ifIndexInterfaceInstanceIdentifier = InstanceIdentifier
276                 .builder(IfIndexesInterfaceMap.class)
277                 .child(IfIndexInterface.class, new IfIndexInterfaceKey(ifaceState.getIfIndex())).build();
278         Assert.assertEquals(INTERFACE_NAME, dataBroker.newReadOnlyTransaction()
279                 .read(OPERATIONAL, ifIndexInterfaceInstanceIdentifier).get().getInterfaceName());*/
280
281         // c) check expected flow entries were created in Interface Ingress
282         // Table
283         Uint64 dpnId = Uint64.ONE;
284         String ingressFlowRef = FlowBasedServicesUtils.getFlowRef(VLAN_INTERFACE_INGRESS_TABLE, dpnId, INTERFACE_NAME);
285         FlowKey ingressFlowKey = new FlowKey(new FlowId(ingressFlowRef));
286         Node nodeDpn = InterfaceManagerTestUtil.buildInventoryDpnNode(dpnId);
287         InstanceIdentifier<Flow> ingressFlowInstanceId = InstanceIdentifier.builder(Nodes.class)
288                 .child(Node.class, nodeDpn.key()).augmentation(FlowCapableNode.class)
289                 .child(Table.class, new TableKey(VLAN_INTERFACE_INGRESS_TABLE)).child(Flow.class, ingressFlowKey)
290                 .build();
291
292         flowAssertTestUtils.assertFlowsInAnyOrder(ExpectedFlowEntries.newIngressFlow(),
293                 dataBroker.newReadOnlyTransaction().read(CONFIGURATION, ingressFlowInstanceId).get().get());
294
295         // d) check if default egress service is bound on the interface
296         InstanceIdentifier<BoundServices> boundServicesInstanceIdentifier = InstanceIdentifier
297                 .builder(ServiceBindings.class)
298                 .child(ServicesInfo.class, new ServicesInfoKey(INTERFACE_NAME, ServiceModeEgress.class))
299                 .child(BoundServices.class, new BoundServicesKey(DEFAULT_EGRESS_SERVICE_INDEX)).build();
300         assertEqualBeans(ExpectedServicesInfo.newboundService(), dataBroker.newReadOnlyTransaction()
301                 .read(CONFIGURATION, boundServicesInstanceIdentifier).get());
302
303         // Test all RPCs related to vlan-interfaces
304         checkVlanRpcs();
305
306         // Test all APIs exposed by interface-manager
307         checkVlanApis();
308
309         //Update config test
310         // i) vlan interface admin-state updated
311         InterfaceManagerTestUtil.updateInterfaceAdminState(dataBroker, INTERFACE_NAME, false);
312
313         InterfaceManagerTestUtil.waitTillOperationCompletes("disable interface admin state",
314                 coordinatorEventsWaiter, 1, asyncEventsWaiter);
315         // Then
316         // a) check if operational/ietf-interfaces-state is updated for vlan interface
317         ifaceState = dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
318             IfmUtil.buildStateInterfaceId(INTERFACE_NAME)).get().get();
319         assertEqualBeans(ExpectedInterfaceState.newInterfaceState(ifaceState.getIfIndex(), INTERFACE_NAME, Interface
320             .OperStatus.Down, L2vlan.class, DPN_ID_1.toString(),
321                 ifaceState.getStatistics().getDiscontinuityTime()), ifaceState);
322
323         // Restore the opState back to UP for proceeding with further tests
324         InterfaceManagerTestUtil.updateInterfaceAdminState(dataBroker, INTERFACE_NAME, true);
325         InterfaceManagerTestUtil.waitTillOperationCompletes("enable interface admin state",
326                 coordinatorEventsWaiter, 1, asyncEventsWaiter);
327
328
329         //state modification tests
330         // 1. Make the operational state of port as DOWN
331         InterfaceManagerTestUtil.updateFlowCapableNodeConnectorState(dataBroker, PARENT_INTERFACE, L2vlan.class, false);
332         waitTillOperationCompletes("disable interface op state", coordinatorEventsWaiter, 2, asyncEventsWaiter);
333
334         ifaceState = dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
335             IfmUtil.buildStateInterfaceId(INTERFACE_NAME)).get().get();
336         // Verify if operational/ietf-interface-state is marked down
337         assertEqualBeans(ExpectedInterfaceState.newInterfaceState(ifaceState.getIfIndex(),
338             INTERFACE_NAME, Interface.OperStatus.Down, L2vlan.class, DPN_ID_1.toString(),
339                 ifaceState.getStatistics().getDiscontinuityTime()), ifaceState);
340
341         // 4. Delete the southbound OF port
342         InterfaceManagerTestUtil.removeFlowCapableNodeConnectorState(dataBroker, L2vlan.class);
343         waitTillOperationCompletes("remove flow capable node connector",
344                 coordinatorEventsWaiter, 5, asyncEventsWaiter);
345
346         // Verify if interfaces are deleted from oper/ietf-interfaces-state
347         Assert.assertEquals(Optional.empty(), dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
348             IfmUtil.buildStateInterfaceId(PARENT_INTERFACE)).get());
349         Assert.assertEquals(Optional.empty(), dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
350             IfmUtil.buildStateInterfaceId(INTERFACE_NAME)).get());
351
352         // 3. Re-create the OF port to proceeed with vlan-member tests
353         InterfaceManagerTestUtil.createFlowCapableNodeConnector(dataBroker, PARENT_INTERFACE, null);
354         waitTillOperationCompletes("remove flow capable node connector",
355                 coordinatorEventsWaiter, 7, asyncEventsWaiter);
356
357         testVlanMemberInterface();
358
359         //Delete test
360         // iii) vlan interface is deleted from config/ietf-interfaces
361         InterfaceManagerTestUtil.deleteInterfaceConfig(dataBroker, INTERFACE_NAME);
362         InterfaceManagerTestUtil.waitTillOperationCompletes("delete interface configuration",
363                 coordinatorEventsWaiter, 6, asyncEventsWaiter);
364         // 3. Then
365         // a) check expected interface-child entry mapping in
366         // odl-interface-meta/config/interface-child-info is deleted
367
368         // TODO Later use nicer abstraction for DB access here.. see
369         // ElanServiceTest
370         Assert.assertEquals(Optional.empty(),
371                 dataBroker.newReadOnlyTransaction().read(CONFIGURATION, interfaceChildEntryInstanceIdentifier).get());
372
373         // Then
374         // a) check if operational/ietf-interfaces-state is deleted for the vlan
375         // interface
376         Assert.assertEquals(Optional.empty(), dataBroker.newReadOnlyTransaction()
377                 .read(OPERATIONAL, IfmUtil.buildStateInterfaceId(INTERFACE_NAME)).get());
378
379         // b) check if lport-tag to interface mapping is deleted
380         /*Assert.assertEquals(Optional.empty(),
381                 dataBroker.newReadOnlyTransaction().read(OPERATIONAL, ifIndexInterfaceInstanceIdentifier).get());*/
382     }
383
384     @Ignore
385     @Test
386     public void newTunnelInterface() throws Exception {
387         // 3. Update DPN-ID of the bridge
388         OvsdbSouthboundTestUtil.updateBridge(dataBroker, "00:00:00:00:00:00:00:02");
389         waitTillOperationCompletes(coordinatorEventsWaiter, asyncEventsWaiter);
390         BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(DPN_ID_2);
391         InstanceIdentifier<BridgeRefEntry> bridgeRefEntryIid = InterfaceMetaUtils
392             .getBridgeRefEntryIdentifier(bridgeRefEntryKey);
393         // Verify if DPN-ID is updated in corresponding DS and cache
394         BridgeRefEntry bridgeRefEntry = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeRefEntryIid, dataBroker)
395             .orElse(null);
396         assertEqualBeans(interfaceMetaUtils.getBridgeRefEntryFromCache(DPN_ID_2), bridgeRefEntry);
397
398         // 1. Given
399         // 2. When
400         // i) dpn-id specified above configuration comes in
401         // operational/network-topology
402         // ii) Vlan interface written to config/ietf-interfaces DS and
403         // corresponding parent-interface is not present
404         // in operational/ietf-interface-state
405         ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(DPN_ID_2).build();
406         InterfaceManagerTestUtil.putInterfaceConfig(dataBroker, TUNNEL_INTERFACE_NAME, parentRefs, Tunnel.class);
407         Thread.sleep(5000);
408
409         // 3. Then
410         // a) check expected bridge-interface mapping in
411         // odl-interface-meta/config/bridge-interface-info was created
412         BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(DPN_ID_2);
413         BridgeInterfaceEntryKey bridgeInterfaceEntryKey = new BridgeInterfaceEntryKey(TUNNEL_INTERFACE_NAME);
414         InstanceIdentifier<BridgeInterfaceEntry> bridgeInterfaceEntryIid = InterfaceMetaUtils
415                 .getBridgeInterfaceEntryIdentifier(bridgeEntryKey, bridgeInterfaceEntryKey);
416         // TODO Later use nicer abstraction for DB access here.. see
417         // ElanServiceTest
418         assertEqualBeans(InterfaceMeta.newBridgeInterface(),
419                 dataBroker.newReadOnlyTransaction().read(CONFIGURATION, bridgeInterfaceEntryIid).get());
420
421         // Then
422         // a) check if termination end point is created in
423         // config/network-topology
424         final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params
425             .xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> bridgeIid = OvsdbSouthboundTestUtil
426                 .createInstanceIdentifier("192.168.56.101", 6640, "s2");
427         InstanceIdentifier<TerminationPoint> tpIid = InterfaceManagerTestUtil.getTerminationPointId(bridgeIid,
428                 TUNNEL_INTERFACE_NAME);
429         assertEqualTerminationPoints(ExpectedTerminationPoint.newTerminationPoint(), db.syncRead(CONFIGURATION, tpIid));
430
431         // When termination end point is populated in network-topology
432         OvsdbSouthboundTestUtil.createTerminationPoint(dataBroker, TUNNEL_INTERFACE_NAME, InterfaceTypeVxlan.class,
433             null);
434         InterfaceManagerTestUtil.createFlowCapableNodeConnector(dataBroker, TUNNEL_INTERFACE_NAME, Tunnel.class);
435         waitTillOperationCompletes(coordinatorEventsWaiter, asyncEventsWaiter);
436         Thread.sleep(3000);
437         TestableQueues.awaitEmpty(batchingUtils.getQueue(DEFAULT_OPERATIONAL), 1, MINUTES);
438
439         // Then
440         // a) check if operational/ietf-interfaces-state is populated for the tunnel interface
441         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
442             .interfaces.state.Interface ifaceState =
443             dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
444                 IfmUtil.buildStateInterfaceId(TUNNEL_INTERFACE_NAME)).get().get();
445         assertEqualBeans(ExpectedInterfaceState.newInterfaceState(ifaceState.getIfIndex(),
446             TUNNEL_INTERFACE_NAME, Interface.OperStatus.Up, Tunnel.class, DPN_ID_2.toString(),
447                 ifaceState.getStatistics().getDiscontinuityTime()), ifaceState);
448
449         // Test all RPCs related to tunnel interfaces
450         checkTunnelRpcs();
451
452         checkTunnelApis();
453
454         // Update test
455         // i) Enable Tunnel Monitoring
456         InterfaceManagerTestUtil.updateTunnelMonitoringAttributes(dataBroker, TUNNEL_INTERFACE_NAME);
457         InterfaceManagerTestUtil.waitTillOperationCompletes(coordinatorEventsWaiter, asyncEventsWaiter);
458         // Then verify if bfd attributes are updated in topology config DS
459         assertEqualTerminationPoints(ExpectedTerminationPoint.newBfdEnabledTerminationPoint(),
460                 db.syncRead(CONFIGURATION, tpIid));
461
462         //state modification tests
463         // 1. Make the operational state of port as DOWN
464         InterfaceManagerTestUtil.updateFlowCapableNodeConnectorState(dataBroker, TUNNEL_INTERFACE_NAME, Tunnel
465             .class, false);
466         waitTillOperationCompletes(coordinatorEventsWaiter, asyncEventsWaiter);
467
468         ifaceState = dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
469             IfmUtil.buildStateInterfaceId(TUNNEL_INTERFACE_NAME)).get().get();
470         // Verify if operational/ietf-interface-state is still up
471         assertEqualBeans(ExpectedInterfaceState.newInterfaceState(ifaceState.getIfIndex(),
472             TUNNEL_INTERFACE_NAME, Interface.OperStatus.Up, Tunnel.class, DPN_ID_2.toString(),
473                 ifaceState.getStatistics().getDiscontinuityTime()), ifaceState);
474
475         // 2. Make BFD staus of tunnel port as down
476         OvsdbSouthboundTestUtil.updateTerminationPoint(dataBroker, TUNNEL_INTERFACE_NAME, InterfaceTypeVxlan.class);
477         waitTillOperationCompletes(coordinatorEventsWaiter, asyncEventsWaiter);
478
479         ifaceState = dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
480             IfmUtil.buildStateInterfaceId(TUNNEL_INTERFACE_NAME)).get().get();
481         // Verify if operational/ietf-interface-state is marked down
482         assertEqualBeans(ExpectedInterfaceState.newInterfaceState(ifaceState.getIfIndex(),
483             TUNNEL_INTERFACE_NAME, Interface.OperStatus.Down, Tunnel.class, DPN_ID_2.toString(),
484                 ifaceState.getStatistics().getDiscontinuityTime()), ifaceState);
485
486
487         // 2. Delete the Node
488         InterfaceManagerTestUtil.removeNode(dataBroker);
489         waitTillOperationCompletes(coordinatorEventsWaiter, asyncEventsWaiter);
490         ifaceState = dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
491             IfmUtil.buildStateInterfaceId(TUNNEL_INTERFACE_NAME)).get().get();
492         // Verify if operational/ietf-interface-state is marked unknown
493         assertEqualBeans(ExpectedInterfaceState.newInterfaceState(ifaceState.getIfIndex(),
494             TUNNEL_INTERFACE_NAME, Interface.OperStatus.Unknown, Tunnel.class, DPN_ID_2.toString(),
495                 ifaceState.getStatistics().getDiscontinuityTime()), ifaceState);
496
497         // Re-create port to proceed with further tests
498         InterfaceManagerTestUtil.createFlowCapableNodeConnector(dataBroker, TUNNEL_INTERFACE_NAME, Tunnel.class);
499         waitTillOperationCompletes(coordinatorEventsWaiter, asyncEventsWaiter);
500
501
502         // 2. Delete the OF port
503         InterfaceManagerTestUtil.removeFlowCapableNodeConnectorState(dataBroker, Tunnel.class);
504         waitTillOperationCompletes(coordinatorEventsWaiter, asyncEventsWaiter);
505
506         // Verify if operational-states are deleted
507         Assert.assertEquals(Optional.empty(), dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
508             IfmUtil.buildStateInterfaceId(TUNNEL_INTERFACE_NAME)).get());
509         Assert.assertEquals(Optional.empty(), dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
510             IfmUtil.buildStateInterfaceId(TUNNEL_INTERFACE_NAME)).get());
511
512         // Delete test
513         // iii) tunnel interface is deleted from config/ietf-interfaces
514         InterfaceManagerTestUtil.deleteInterfaceConfig(dataBroker, TUNNEL_INTERFACE_NAME);
515         InterfaceManagerTestUtil.waitTillOperationCompletes(coordinatorEventsWaiter, asyncEventsWaiter);
516
517         // Then
518         // a) check if tunnel is deleted from bridge-interface-info
519         Assert.assertEquals(Optional.empty(),
520                 dataBroker.newReadOnlyTransaction().read(CONFIGURATION, bridgeInterfaceEntryIid).get());
521
522         // b) check if termination end point is deleted in
523         // config/network-topology
524         Assert.assertEquals(Optional.empty(), dataBroker.newReadOnlyTransaction().read(CONFIGURATION, tpIid).get());
525         waitTillOperationCompletes(coordinatorEventsWaiter, asyncEventsWaiter);
526     }
527
528     private void assertEqualTerminationPoints(TerminationPoint expected, TerminationPoint actual) {
529         // Re-create the termination points to avoid re-deserialising the augmentations
530         assertEqualBeans(rebuildTerminationPoint(expected), rebuildTerminationPoint(actual));
531     }
532
533     private TerminationPoint rebuildTerminationPoint(TerminationPoint tp) {
534         // The problem we're fixing here is that, in MD-SAL binding v1, YANG lists are represented
535         // as Java lists but they don't preserve order (unless they specify “ordered-by user”).
536         // YANG keyed lists in particular are backed by maps, so you can store such a list in the
537         // MD-SAL and get it back in a different order.
538         // When comparing beans involving such lists, we need to sort the lists before comparing
539         // them. Retrieving the augmentation gives a modifiable list, so it's tempting to just
540         // sort that — but the list is re-created every time the augmentation is retrieved, so
541         // the sort is lost.
542         // To avoid all this, we rebuild instances of TerminationPoint, and sort the affected lists
543         // in the augmentations, with full augmentation rebuilds too (since the lists in a built
544         // augmentation might be unmodifiable).
545         TerminationPointBuilder newTpBuilder = new TerminationPointBuilder(tp);
546         OvsdbTerminationPointAugmentation ovsdbTpAugmentation =
547                 tp.augmentation(OvsdbTerminationPointAugmentation.class);
548         if (ovsdbTpAugmentation != null) {
549             OvsdbTerminationPointAugmentationBuilder newOvsdbTpAugmentationBuilder =
550                     new OvsdbTerminationPointAugmentationBuilder(ovsdbTpAugmentation);
551             if (ovsdbTpAugmentation.getOptions() != null) {
552                 List<Options> options = new ArrayList<>(ovsdbTpAugmentation.getOptions().values());
553                 options.sort(Comparator.comparing(o -> o.key().toString()));
554                 newOvsdbTpAugmentationBuilder.setOptions(options);
555             }
556             if (ovsdbTpAugmentation.getInterfaceBfd() != null) {
557                 List<InterfaceBfd> interfaceBfd = new ArrayList<>(ovsdbTpAugmentation.getInterfaceBfd().values());
558                 interfaceBfd.sort(Comparator.comparing(o -> o.key().toString()));
559                 newOvsdbTpAugmentationBuilder.setInterfaceBfd(interfaceBfd);
560             }
561             newTpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class,
562                     newOvsdbTpAugmentationBuilder.build());
563         }
564         return newTpBuilder.build();
565     }
566
567     private void checkVlanApis() throws Exception {
568         // 1. Test port-no corresponding to interface
569         long portNo = interfaceManager.getPortForInterface(INTERFACE_NAME);
570         Assert.assertEquals(PORT_NO_1, portNo);
571
572         // 2. fetch interface config from datastore API
573         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
574             interfaceInfo = interfaceManager.getInterfaceInfoFromConfigDataStore(INTERFACE_NAME);
575         // FIXME change this once augmentation sorting fix lands
576         assertEqualBeans(INTERFACE_NAME, interfaceInfo.getName());
577         assertEqualBeans(PARENT_INTERFACE, interfaceInfo.augmentation(ParentRefs.class).getParentInterface());
578
579         // 3. fetch dpn-id corresponding to an interface
580         Uint64 dpnId = interfaceManager.getDpnForInterface(INTERFACE_NAME);
581         Assert.assertEquals(DPN_ID_1, dpnId);
582
583         // 4. fetch parent-interface corresponding to an interface
584         Assert.assertEquals(PARENT_INTERFACE, interfaceManager.getParentRefNameForInterface(INTERFACE_NAME));
585
586         //5. get interface information
587         assertEqualBeans(ExpectedInterfaceInfo.newVlanInterfaceInfo(), interfaceManager
588             .getInterfaceInfo(INTERFACE_NAME));
589
590         Assert.assertEquals(org.opendaylight.genius.interfacemanager.globals.IfmConstants.VXLAN_GROUPID_MIN + 1,
591             interfaceManager.getLogicalTunnelSelectGroupId(1));
592
593         // 6. Test bind ingress service
594         BoundServices serviceInfo = InterfaceManagerTestUtil.buildServicesInfo("ELAN", NwConstants.ELAN_SERVICE_INDEX);
595         interfaceManager.bindService(INTERFACE_NAME, ServiceModeIngress.class, serviceInfo);
596
597         waitTillOperationCompletes("test bind ingress service api",
598                 coordinatorEventsWaiter, 1, asyncEventsWaiter);
599
600         String lportDispatcherFlowRef = String.valueOf(dpnId) + NwConstants.FLOWID_SEPARATOR
601                 + NwConstants.LPORT_DISPATCHER_TABLE + NwConstants.FLOWID_SEPARATOR + INTERFACE_NAME
602                 + NwConstants.FLOWID_SEPARATOR + NwConstants.DEFAULT_SERVICE_INDEX;
603         FlowKey lportDispatcherFlowKey = new FlowKey(new FlowId(lportDispatcherFlowRef));
604         Node nodeDpn = InterfaceManagerTestUtil.buildInventoryDpnNode(dpnId);
605         InstanceIdentifier<Flow> lportDispatcherFlowId = InstanceIdentifier.builder(Nodes.class)
606             .child(Node.class, nodeDpn.key()).augmentation(FlowCapableNode.class)
607             .child(Table.class, new TableKey(NwConstants.LPORT_DISPATCHER_TABLE)).child(Flow.class,
608                 lportDispatcherFlowKey).build();
609         flowAssertTestUtils.assertFlowsInAnyOrder(ExpectedFlowEntries.newLportDispatcherFlow(),
610                 dataBroker.newReadOnlyTransaction().read(CONFIGURATION, lportDispatcherFlowId).get().get());
611
612         // check whether service-binding state cache is populated
613         assertEqualBeans(ExpectedBoundServiceState.newBoundServiceState(), FlowBasedServicesUtils
614             .getBoundServicesState(dataBroker.newReadOnlyTransaction(), INTERFACE_NAME, ServiceModeIngress.class));
615
616         //7. test check whether service is bound on ingress
617         Assert.assertTrue(interfaceManager.isServiceBoundOnInterfaceForIngress(NwConstants.ELAN_SERVICE_INDEX,
618             INTERFACE_NAME));
619
620         //8. test unbind ingress service
621         interfaceManager.unbindService(INTERFACE_NAME, ServiceModeIngress.class, serviceInfo);
622         waitTillOperationCompletes("test unbind ingress service api",
623                 coordinatorEventsWaiter, 2, asyncEventsWaiter);
624
625         Assert.assertEquals(Optional.empty(),
626             dataBroker.newReadOnlyTransaction().read(CONFIGURATION, lportDispatcherFlowId).get());
627
628         // check service-state cache is cleaned up
629         // 9. Test bind egress service
630         short egressACLIndex = ServiceIndex.getIndex(NwConstants.EGRESS_ACL_SERVICE_NAME,
631             NwConstants.EGRESS_ACL_SERVICE_INDEX);
632         serviceInfo = InterfaceManagerTestUtil.buildServicesInfo("EGRESS_ACL", egressACLIndex);
633         interfaceManager.bindService(INTERFACE_NAME, ServiceModeEgress.class, serviceInfo);
634         waitTillOperationCompletes("test bind egress service api",
635                 coordinatorEventsWaiter, 1, asyncEventsWaiter);
636
637         String egressDispatcherFlowRef = String.valueOf(dpnId) + NwConstants.FLOWID_SEPARATOR
638                 + NwConstants.EGRESS_LPORT_DISPATCHER_TABLE + NwConstants.FLOWID_SEPARATOR
639                 + INTERFACE_NAME + NwConstants.FLOWID_SEPARATOR + NwConstants.DEFAULT_EGRESS_SERVICE_INDEX;
640
641         FlowKey egressDispatcherFlowKey = new FlowKey(new FlowId(egressDispatcherFlowRef));
642         InstanceIdentifier<Flow> egressDispatcherFlowId = InstanceIdentifier.builder(Nodes.class)
643             .child(Node.class, nodeDpn.key()).augmentation(FlowCapableNode.class)
644             .child(Table.class, new TableKey(NwConstants.EGRESS_LPORT_DISPATCHER_TABLE)).child(Flow.class,
645                 egressDispatcherFlowKey).build();
646
647         // FIXME the extend file getting generated had some import issues, will revist  later
648         //assertEqualBeans(null,
649         //    dataBroker.newReadOnlyTransaction().read(CONFIGURATION, egressDispatcherFlowId).get());
650
651         Assert.assertNotNull(dataBroker.newReadOnlyTransaction().read(CONFIGURATION,
652             egressDispatcherFlowId).get());
653
654         //10. test check whether service is bound on egress
655         Assert.assertTrue(interfaceManager.isServiceBoundOnInterfaceForEgress(NwConstants.EGRESS_ACL_SERVICE_INDEX,
656             INTERFACE_NAME));
657
658         // 11. Test unbinding of egress service
659         interfaceManager.unbindService(INTERFACE_NAME, ServiceModeEgress.class, serviceInfo);
660         waitTillOperationCompletes("test unbind egress service api",
661                 coordinatorEventsWaiter, 2, asyncEventsWaiter);
662         Assert.assertEquals(Optional.empty(), dataBroker.newReadOnlyTransaction().read(CONFIGURATION,
663             egressDispatcherFlowId).get());
664
665         // 12. Test fetching child interfaces of an interface
666         // FIXME change the below assert once sorted augmentation fix lands
667         assertEqualBeans(INTERFACE_NAME, interfaceManager.getChildInterfaces(PARENT_INTERFACE).get(0).getName());
668
669         // 13. Test fetching interface-info from operational DS
670         assertEqualBeans(ExpectedInterfaceInfo.newInterfaceInfo(1, INTERFACE_NAME, PARENT_INTERFACE, null),
671             interfaceManager.getInterfaceInfoFromOperationalDataStore(INTERFACE_NAME));
672
673         // 14. Test fetching of interface-info from oper DS, given interface-type
674         assertEqualBeans(ExpectedInterfaceInfo.newInterfaceInfo(1, INTERFACE_NAME, INTERFACE_NAME, InterfaceInfo
675             .InterfaceType.VLAN_INTERFACE), interfaceManager.getInterfaceInfoFromOperationalDataStore(
676                 INTERFACE_NAME, InterfaceInfo.InterfaceType.VLAN_INTERFACE));
677
678         // 15.Test fetching of interface-info from cache
679         assertEqualBeans(ExpectedInterfaceInfo.newInterfaceInfo(1, INTERFACE_NAME, PARENT_INTERFACE, null),
680             interfaceManager.getInterfaceInfoFromOperationalDSCache(INTERFACE_NAME));
681
682         // 16. Test creation of VLAN interface
683         // FIXME Make IInterfaceManager truly async
684         interfaceManager.createVLANInterface(INTERFACE_NAME_1, PARENT_INTERFACE_1, null, INTERFACE_NAME_1,
685             IfL2vlan.L2vlanMode.Trunk);
686         //waitTillOperationCompletes(coordinatorEventsWaiter, 1, asyncEventsWaiter);
687
688         //assertEqualBeans(ExpectedInterfaceConfig.newVlanInterfaceConfig(INTERFACE_NAME_1, null),
689         //    dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, IfmUtil.buildId(
690         //        INTERFACE_NAME_1)).get());
691
692         // 17. Update Parent Refs for VLAN interface
693         // FIXME Make IInterfaceManager truly async
694         //interfaceManager.updateInterfaceParentRef(INTERFACE_NAME_1, PARENT_INTERFACE_1);
695         waitTillOperationCompletes("create vlan interface api",
696                 coordinatorEventsWaiter, 4, asyncEventsWaiter);
697
698         assertEqualBeans(ExpectedInterfaceConfig.newVlanInterfaceConfig(INTERFACE_NAME_1, PARENT_INTERFACE_1),
699             dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, IfmUtil
700                 .buildId(INTERFACE_NAME_1)).get());
701
702         // 18. Test creation of external l2vlan interfaces
703         // FIXME Make IInterfaceManager truly async
704         interfaceManager.createVLANInterface(INTERFACE_NAME_2, PARENT_INTERFACE_2, null, INTERFACE_NAME_2,
705             IfL2vlan.L2vlanMode.Trunk, true);
706         //waitTillOperationCompletes(coordinatorEventsWaiter, 1, asyncEventsWaiter);
707
708         // FIXME need to wait for https://git.opendaylight.org/gerrit/#/c/54811/ this to land
709         // to do proper assertion
710         //Assert.assertNotNull(dataBroker
711         //    .newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, IfmUtil
712         //    .buildId(INTERFACE_NAME_2)).get().augmentation(IfExternal.class));
713
714         // 19. update parent-refs
715         //interfaceManager.updateInterfaceParentRef(INTERFACE_NAME_2, PARENT_INTERFACE_2, true);
716         waitTillOperationCompletes("create external vlan interface api",
717                 coordinatorEventsWaiter, 4, asyncEventsWaiter);
718         Assert.assertEquals(PARENT_INTERFACE_2, dataBroker
719             .newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, IfmUtil
720                 .buildId(INTERFACE_NAME_2)).get().get().augmentation(ParentRefs.class).getParentInterface());
721
722         // 20. get list of vlan interfaces
723         // FIXME need to wait for https://git.opendaylight.org/gerrit/#/c/54811/ this to land
724         // to do proper assertion
725         assertEqualBeans(3, interfaceManager.getVlanInterfaces().size());
726
727         // 21. check if an interface is external interface
728         Assert.assertTrue(interfaceManager.isExternalInterface(INTERFACE_NAME_2));
729
730         // 22. check port name for an interface, given dpn-id and interface-name
731         assertEqualBeans(PARENT_INTERFACE, interfaceManager.getPortNameForInterface(DPN_ID_1.toString(),
732             PARENT_INTERFACE));
733
734         // 23. check port name for an interface, given nodeconnectorid
735         assertEqualBeans(PARENT_INTERFACE, interfaceManager.getPortNameForInterface(new NodeConnectorId("openflow:1:2"),
736             PARENT_INTERFACE));
737
738         // 24. get termination-points from cache
739         Assert.assertNotNull(interfaceManager.getTerminationPointCache().get(INTERFACE_NAME));
740
741         // 25. fetch termination point for interface
742         assertEqualBeans(ExpectedTerminationPoint.newOvsdbTerminationPointAugmentation(), interfaceManager
743             .getTerminationPointForInterface(INTERFACE_NAME));
744
745         // 26. fetch ovsdb bridge corresponding to an interface
746         assertEqualBeans(ExpectedOvsdbBridge.newOvsdbBridge(),
747             interfaceManager.getOvsdbBridgeForInterface(INTERFACE_NAME));
748
749         // 27. fetch ovsdb bridge corresponding to nodeIid
750         assertEqualBeans(ExpectedOvsdbBridge.newOvsdbBridge(), interfaceManager.getOvsdbBridgeForNodeIid(
751             OvsdbSouthboundTestUtil.createInstanceIdentifier("192.168.56.101", 6640, "s2")));
752     }
753
754     private void checkVlanRpcs() throws Exception {
755         //1. Test dpn-id fetching from interface
756         GetDpidFromInterfaceInput dpidFromInterfaceInput = new GetDpidFromInterfaceInputBuilder()
757                 .setIntfName(INTERFACE_NAME).build();
758         Future<RpcResult<GetDpidFromInterfaceOutput>> dpidFromInterfaceOutput =
759             odlInterfaceRpcService.getDpidFromInterface(dpidFromInterfaceInput);
760         Assert.assertEquals(DpnFromInterfaceOutput.newDpnFromInterfaceOutput(),
761                 dpidFromInterfaceOutput.get().getResult());
762
763         //3. Test egress actions fetching for interface
764         GetEgressActionsForInterfaceInput egressActionsForInterfaceInput = new
765             GetEgressActionsForInterfaceInputBuilder().setIntfName(INTERFACE_NAME).build();
766         Future<RpcResult<GetEgressActionsForInterfaceOutput>> egressActionsForInterfaceOutput =
767             odlInterfaceRpcService.getEgressActionsForInterface(egressActionsForInterfaceInput);
768         assertEqualBeans(EgressActionsForInterfaceOutput.newEgressActionsForInterfaceOutput(),
769             egressActionsForInterfaceOutput.get().getResult());
770
771         //4. Test egress instructions fetching for interface
772         GetEgressInstructionsForInterfaceInput egressInstructionsForInterfaceInput = new
773             GetEgressInstructionsForInterfaceInputBuilder().setIntfName(INTERFACE_NAME).build();
774         Future<RpcResult<GetEgressInstructionsForInterfaceOutput>> egressInstructionsForInterfaceOutput =
775             odlInterfaceRpcService.getEgressInstructionsForInterface(egressInstructionsForInterfaceInput);
776         assertEqualBeans(EgressInstructionsForInterfaceOutput.newEgressInstructionsForInterfaceOutput(),
777             egressInstructionsForInterfaceOutput.get().getResult());
778
779
780         //5. Test interface fetching from if-index
781         /* FIXME can be tested only once ResourceBatchingManager becomes testable
782         GetInterfaceFromIfIndexInput interfaceFromIfIndexInput = new GetInterfaceFromIfIndexInputBuilder()
783                 .setIfIndex(1).build();
784         Future<RpcResult<GetInterfaceFromIfIndexOutput>> interfaceFromIfIndexOutput = odlInterfaceRpcService
785             .getInterfaceFromIfIndex(interfaceFromIfIndexInput);
786         assertEqualBeans(InterfaceFromIfIndexOutput.newInterfaceFromIfIndexOutput(),
787                 interfaceFromIfIndexOutput.get().getResult());*/
788
789         //6. Test interface type fetching from interface-name
790         GetInterfaceTypeInput interfaceTypeInput = new GetInterfaceTypeInputBuilder().setIntfName(INTERFACE_NAME)
791             .build();
792         Future<RpcResult<GetInterfaceTypeOutput>> interfaceTypeOutput =
793                 odlInterfaceRpcService.getInterfaceType(interfaceTypeInput);
794         assertEqualBeans(InterfaceTypeOutput.newInterfaceTypeOutput(), interfaceTypeOutput.get().getResult());
795
796         //7. Test get nodeconnector-id from interface-name
797         GetNodeconnectorIdFromInterfaceInput nodeconnectorIdFromInterfaceInput = new
798             GetNodeconnectorIdFromInterfaceInputBuilder().setIntfName(INTERFACE_NAME).build();
799         Future<RpcResult<GetNodeconnectorIdFromInterfaceOutput>> nodeconnectorIdFromInterfaceOutput =
800             odlInterfaceRpcService.getNodeconnectorIdFromInterface(nodeconnectorIdFromInterfaceInput);
801         assertEqualBeans(NodeconnectorIdFromInterfaceOutput.newNodeconnectorIdFromInterfaceOutput(),
802             nodeconnectorIdFromInterfaceOutput.get().getResult());
803
804         //8. Test get port details from interface-name
805         GetPortFromInterfaceInput portFromInterfaceInput =
806                 new GetPortFromInterfaceInputBuilder().setIntfName(INTERFACE_NAME).build();
807         Future<RpcResult<GetPortFromInterfaceOutput>> portFromInterfaceOutput = odlInterfaceRpcService
808             .getPortFromInterface(portFromInterfaceInput);
809         assertEqualBeans(PortFromInterfaceOutput.newPortFromInterfaceOutput(),
810                 portFromInterfaceOutput.get().getResult());
811     }
812
813     private void checkTunnelRpcs() throws Exception {
814         //1. Test endpoint ip fetching for dpn-id
815         GetEndpointIpForDpnInput endpointIpForDpnInput = new GetEndpointIpForDpnInputBuilder().setDpid(DPN_ID_2)
816             .build();
817         Future<RpcResult<GetEndpointIpForDpnOutput>> endpointIpForDpnOutput = odlInterfaceRpcService
818                 .getEndpointIpForDpn(endpointIpForDpnInput);
819         assertEqualBeans(EndPointIpFromDpn.newEndPointIpFromDpn(), endpointIpForDpnOutput.get().getResult());
820
821
822         //2. fetch tunnel type from interface-name
823         GetTunnelTypeInput tunnelTypeInput = new GetTunnelTypeInputBuilder().setIntfName(TUNNEL_INTERFACE_NAME).build();
824         Future<RpcResult<GetTunnelTypeOutput>> tunnelTypeOutput = odlInterfaceRpcService.getTunnelType(tunnelTypeInput);
825         assertEqualBeans(TunnelTypeOutput.newTunnelTypeOutput(), tunnelTypeOutput.get().getResult());
826     }
827
828     private void checkTunnelApis() throws  Exception {
829
830         // 1. fetch get all ports on bridge
831         assertEqualBeans(ExpectedTerminationPoint.newTerminationPointList(),
832             interfaceManager.getPortsOnBridge(DPN_ID_2));
833
834         // 2. fetch get all tunnel ports on bridge
835         assertEqualBeans(ExpectedTerminationPoint.newTerminationPointList(),
836             interfaceManager.getTunnelPortsOnBridge(DPN_ID_2));
837
838         // 3. fetch tunnel end point ip for DPN
839         assertEqualBeans("2.2.2.2", interfaceManager.getEndpointIpForDpn(DPN_ID_2));
840
841         // 4. get list of vxlan interfaces
842         assertEqualBeans(1, interfaceManager.getVxlanInterfaces().size());
843     }
844
845     public void testVlanMemberInterface() throws Exception {
846         // Test VlanMember interface creation
847         InterfaceManagerTestUtil.putVlanInterfaceConfig(dataBroker, TRUNK_INTERFACE_NAME, INTERFACE_NAME,
848                 IfL2vlan.L2vlanMode.TrunkMember);
849         InterfaceManagerTestUtil.waitTillOperationCompletes("create vlan member interface",
850                 coordinatorEventsWaiter, 7, asyncEventsWaiter);
851
852         // 3. Then
853         // a) check expected interface-child entry mapping in odl-interface-meta/config/interface-child-info was created
854         InstanceIdentifier<InterfaceChildEntry> interfaceChildEntryInstanceIdentifier = InterfaceMetaUtils
855             .getInterfaceChildEntryIdentifier(new InterfaceParentEntryKey(INTERFACE_NAME),
856                 new InterfaceChildEntryKey(TRUNK_INTERFACE_NAME));
857         assertEqualBeans(ExpectedInterfaceChildEntry.interfaceChildEntry(TRUNK_INTERFACE_NAME),
858                 dataBroker.newReadOnlyTransaction().read(CONFIGURATION, interfaceChildEntryInstanceIdentifier)
859                         .get());
860
861         // Then
862         // a) check if operational/ietf-interfaces-state is populated for the vlan interface
863         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
864             .interfaces.state.Interface ifaceState =
865             dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
866                 IfmUtil.buildStateInterfaceId(TRUNK_INTERFACE_NAME)).get().get();
867         assertEqualBeans(ExpectedInterfaceState.newInterfaceState(ifaceState.getIfIndex(), TRUNK_INTERFACE_NAME,
868                 Interface.OperStatus.Up, L2vlan.class, DPN_ID_1.toString(),
869                 ifaceState.getStatistics().getDiscontinuityTime()), ifaceState);
870
871         // FIXME can assert this only once ResourceBatchingManager becomes testable
872         // b) check if lport-tag to interface mapping is created
873         /*InstanceIdentifier<IfIndexInterface> ifIndexInterfaceInstanceIdentifier = InstanceIdentifier.builder(
874             IfIndexesInterfaceMap.class).child(
875             IfIndexInterface.class, new IfIndexInterfaceKey(ifaceState.getIfIndex())).build();
876         Assert.assertEquals(TRUNK_INTERFACE_NAME, dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
877             ifIndexInterfaceInstanceIdentifier).get().getInterfaceName());*/
878
879         //Update test
880         // i) vlan member interface admin-state updated
881         InterfaceManagerTestUtil.updateInterfaceAdminState(dataBroker, TRUNK_INTERFACE_NAME, false);
882
883         InterfaceManagerTestUtil.waitTillOperationCompletes("update vlan member interface admin state",
884                 coordinatorEventsWaiter, 2, asyncEventsWaiter);
885
886         //Then
887         // a) check if operational/ietf-interfaces-state is updated for vlan interface
888         ifaceState = dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
889             IfmUtil.buildStateInterfaceId(TRUNK_INTERFACE_NAME)).get().get();
890         assertEqualBeans(ExpectedInterfaceState.newInterfaceState(ifaceState.getIfIndex(), TRUNK_INTERFACE_NAME,
891             Interface.OperStatus.Down, L2vlan.class, DPN_ID_1.toString(),
892                 ifaceState.getStatistics().getDiscontinuityTime()), ifaceState);
893
894         InterfaceManagerTestUtil.deleteInterfaceConfig(dataBroker, TRUNK_INTERFACE_NAME);
895         InterfaceManagerTestUtil.waitTillOperationCompletes("delete vlan member interface",
896                 coordinatorEventsWaiter, 7, asyncEventsWaiter);
897         // 1. Then
898         // a)
899         Assert.assertEquals(Optional.empty(), dataBroker.newReadOnlyTransaction()
900             .read(CONFIGURATION, interfaceChildEntryInstanceIdentifier).get());
901
902         // b) check if operational/ietf-interfaces-state is deleted for the vlan interface
903         Assert.assertEquals(Optional.empty(), dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
904             IfmUtil.buildStateInterfaceId(TRUNK_INTERFACE_NAME)).get());
905
906         // FIXME can assert this only once ResourceBatchingManager becomes testable
907         // c) check if lport-tag to interface mapping is deleted
908         /*Assert.assertEquals(Optional.empty(), dataBroker.newReadOnlyTransaction().read(OPERATIONAL,
909             ifIndexInterfaceInstanceIdentifier).get());*/
910     }
911
912     @Ignore
913     @Test
914     public void testDpnToInterfaceList() throws  Exception {
915         //Write into DpnToInterfaceList
916         createDpnToInterface(DPN_ID_1, "23701c04-7e58-4c65-9425-78a80d49a218", L2vlan.class);
917
918         //Test interface list fetching from dpnId
919         GetDpnInterfaceListInput dpnInterfaceListInput = new GetDpnInterfaceListInputBuilder()
920                 .setDpid(DPN_ID_1).build();
921         Future<RpcResult<GetDpnInterfaceListOutput>> dpnInterfaceListOutput = odlInterfaceRpcService
922                 .getDpnInterfaceList(dpnInterfaceListInput);
923
924         List<Interfaces> actualDpnInterfaceList = dpnInterfaceListOutput.get().getResult().getInterfaces();
925         assertEqualBeans(ExpectedInterfaceListFromDpn.checkDpnToInterfaceList(), actualDpnInterfaceList.get(0));
926     }
927
928     private void createDpnToInterface(Uint64 dpId, String infName,
929                                       Class<? extends InterfaceType> interfaceType) throws  Exception {
930         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
931         DpnToInterfaceKey dpnToInterfaceKey = new DpnToInterfaceKey(dpId);
932         InterfaceNameEntryKey interfaceNameEntryKey = new InterfaceNameEntryKey(infName);
933         InstanceIdentifier<InterfaceNameEntry> intfid = InstanceIdentifier.builder(DpnToInterfaceList.class)
934                 .child(DpnToInterface.class, dpnToInterfaceKey)
935                 .child(InterfaceNameEntry.class, interfaceNameEntryKey)
936                 .build();
937         InterfaceNameEntryBuilder entryBuilder =
938                 new InterfaceNameEntryBuilder().withKey(interfaceNameEntryKey).setInterfaceName(infName);
939         if (interfaceType != null) {
940             entryBuilder.setInterfaceType(interfaceType);
941         }
942         tx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL, intfid, entryBuilder.build());
943         tx.commit().get();
944     }
945 }