2 * Copyright © 2016, 2017 NEC Corporation 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.reconciliation.configuration;
10 import static org.junit.Assert.assertTrue;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.Mockito.doNothing;
13 import static org.mockito.Mockito.mock;
14 import static org.mockito.Mockito.spy;
15 import static org.mockito.Mockito.verify;
16 import static org.mockito.Mockito.when;
18 import com.google.common.util.concurrent.FluentFuture;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.List;
25 import java.util.Optional;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 import org.mockito.Mock;
30 import org.mockito.Mockito;
31 import org.mockito.junit.MockitoJUnitRunner;
32 import org.mockito.stubbing.Answer;
33 import org.opendaylight.mdsal.binding.api.DataBroker;
34 import org.opendaylight.mdsal.binding.api.ReadTransaction;
35 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
36 import org.opendaylight.ovsdb.southbound.InstanceIdentifierCodec;
37 import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
38 import org.opendaylight.ovsdb.southbound.OvsdbConnectionManager;
39 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
40 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
41 import org.opendaylight.ovsdb.southbound.reconciliation.ReconciliationManager;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow10;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryKey;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
56 import org.opendaylight.yangtools.util.concurrent.FluentFutures;
57 import org.opendaylight.yangtools.yang.binding.DataObject;
58 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
59 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
63 @RunWith(MockitoJUnitRunner.class)
64 public class BridgeConfigReconciliationTaskTest {
65 private static final String BR_INT = "br-int";
66 private static final String NODE_ID = "ovsdb://uuid/6ff3d0cf-4102-429d-b41c-f8027a0fd7f4";
67 private BridgeConfigReconciliationTask configurationReconciliationTask;
68 @Mock private OvsdbConnectionManager ovsdbConnectionManager;
69 @Mock private OvsdbConnectionInstance ovsdbConnectionInstance;
70 @Mock private DataBroker db;
71 @Mock private ReconciliationManager reconciliationManager;
72 @Mock private Topology topology;
73 @Mock private InstanceIdentifier<Node> iid;
74 @Mock private SouthboundProvider provider;
77 public void setUp() throws Exception {
78 NodeKey nodeKey = new NodeKey(new NodeId(new Uri(NODE_ID)));
79 List<Node> bridgeNodes = new ArrayList<>();
81 iid = SouthboundMapper.createInstanceIdentifier(nodeKey.getNodeId());
82 when(topology.getNode()).thenReturn(bridgeNodes);
83 SouthboundProvider.setBridgesReconciliationInclusionList(Arrays.asList(BR_INT));
84 Node brIntNode = createBridgeNode(NODE_ID + "/bridge/" + BR_INT);
85 Optional<Node> nodeOptional = Optional.of(brIntNode);
86 FluentFuture<Optional<Node>> readNodeFuture =
87 FluentFutures.immediateFluentFuture(nodeOptional);
88 when(reconciliationManager.getDb()).thenReturn(db);
89 ReadTransaction tx = mock(ReadTransaction.class);
90 Mockito.when(db.newReadOnlyTransaction()).thenReturn(tx);
91 Mockito.when(tx.read(any(LogicalDatastoreType.class),any(InstanceIdentifier.class)))
92 .thenReturn(readNodeFuture);
93 bridgeNodes.add(brIntNode);
95 configurationReconciliationTask =
96 new BridgeConfigReconciliationTask(reconciliationManager, ovsdbConnectionManager, iid,
97 ovsdbConnectionInstance, mock(InstanceIdentifierCodec.class));
101 public void testReconcileConfiguration() throws Exception {
102 BridgeConfigReconciliationTask underTest = spy(configurationReconciliationTask);
103 doNothing().when(underTest).reconcileBridgeConfigurations(any(Map.class));
104 assertTrue(underTest.reconcileConfiguration(ovsdbConnectionManager));
105 Map<InstanceIdentifier<?>, DataObject> changes = new HashMap<>();
106 for (Node bridgeNode : topology.getNode()) {
107 changes.putAll(createExpectedConfigurationChanges(bridgeNode));
109 verify(underTest).reconcileBridgeConfigurations(changes);
112 private Node createBridgeNode(final String bridgeName) {
113 Node bridgeNode = mock(Node.class);
114 String nodeString = bridgeName;
115 when(bridgeNode.getNodeId()).thenReturn(new NodeId(new Uri(nodeString)));
116 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = mock(OvsdbBridgeAugmentation.class);
117 OvsdbNodeRef ovsdbNodeRef = mock(OvsdbNodeRef.class);
119 when((InstanceIdentifier<Node>)ovsdbNodeRef.getValue()).thenReturn(iid);
120 OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(bridgeName);
121 when(bridgeNode.augmentation(OvsdbBridgeAugmentation.class)).thenReturn(ovsdbBridgeAugmentation);
122 ProtocolEntry protocolEntry = mock(ProtocolEntry.class);
123 ProtocolEntryKey protocolEntryKey = mock(ProtocolEntryKey.class);
124 Mockito.when(protocolEntry.getProtocol()).thenAnswer(
125 (Answer<Class<? extends OvsdbBridgeProtocolBase>>) invocation -> OvsdbBridgeProtocolOpenflow10.class);
126 when(protocolEntry.key()).thenReturn(protocolEntryKey);
127 when(ovsdbBridgeAugmentation.getProtocolEntry()).thenReturn(Collections.singletonList(protocolEntry));
129 ControllerEntry controllerEntry = mock(ControllerEntry.class);
130 ControllerEntryKey controllerEntryKey = mock(ControllerEntryKey.class);
131 when(controllerEntry.key()).thenReturn(controllerEntryKey);
132 when(ovsdbBridgeAugmentation.getControllerEntry()).thenReturn(Collections.singletonList(controllerEntry));
134 when(ovsdbBridgeAugmentation.getManagedBy()).thenReturn(ovsdbNodeRef);
139 private Map<InstanceIdentifier<?>, DataObject> createExpectedConfigurationChanges(final Node bridgeNode) {
140 OvsdbBridgeAugmentation ovsdbBridge = bridgeNode.augmentation(OvsdbBridgeAugmentation.class);
142 Map<InstanceIdentifier<?>, DataObject> changes = new HashMap<>();
143 final InstanceIdentifier<Node> bridgeNodeIid =
144 SouthboundMapper.createInstanceIdentifier(bridgeNode.getNodeId());
145 final InstanceIdentifier<OvsdbBridgeAugmentation> ovsdbBridgeIid =
146 bridgeNodeIid.builder().augmentation(OvsdbBridgeAugmentation.class).build();
147 changes.put(bridgeNodeIid, bridgeNode);
148 changes.put(ovsdbBridgeIid, ovsdbBridge);
149 for (ProtocolEntry protocolEntry : ovsdbBridge.getProtocolEntry()) {
150 KeyedInstanceIdentifier<ProtocolEntry, ProtocolEntryKey> protocolIid =
151 ovsdbBridgeIid.child(ProtocolEntry.class, protocolEntry.key());
152 changes.put(protocolIid, protocolEntry);
154 for (ControllerEntry controller : ovsdbBridge.getControllerEntry()) {
155 KeyedInstanceIdentifier<ControllerEntry, ControllerEntryKey> controllerIid =
156 ovsdbBridgeIid.child(ControllerEntry.class, controller.key());
157 changes.put(controllerIid, controller);