2 * Copyright (c) 2016 , 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.assertEquals;
11 import static org.mockito.Matchers.any;
12 import static org.mockito.Mockito.mock;
13 import static org.mockito.Mockito.when;
15 import com.google.common.base.Optional;
16 import com.google.common.util.concurrent.CheckedFuture;
17 import com.google.common.util.concurrent.Futures;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.HashMap;
21 import java.util.List;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.junit.runner.RunWith;
26 import org.mockito.Mock;
27 import org.mockito.Mockito;
28 import org.mockito.invocation.InvocationOnMock;
29 import org.mockito.stubbing.Answer;
30 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
31 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
32 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
33 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
34 import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
35 import org.opendaylight.ovsdb.southbound.OvsdbConnectionManager;
36 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
37 import org.opendaylight.ovsdb.southbound.reconciliation.ReconciliationManager;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow10;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryKey;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
52 import org.opendaylight.yangtools.yang.binding.DataObject;
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
54 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
55 import org.powermock.api.mockito.PowerMockito;
56 import org.powermock.core.classloader.annotations.PrepareForTest;
57 import org.powermock.modules.junit4.PowerMockRunner;
60 * Created by Vinh Nguyen (vinh.nguyen@hcl.com) on 3/21/16.
62 @RunWith(PowerMockRunner.class)
63 @PrepareForTest({ BridgeConfigReconciliationTask.class, OvsdbConnectionManager.class, OvsdbConnectionInstance.class,
64 InstanceIdentifier.class, Optional.class })
65 public class BridgeConfigReconciliationTaskTest {
67 private static final String NODE_ID = "ovsdb://uuid/6ff3d0cf-4102-429d-b41c-f8027a0fd7f4";
68 private static final String BR01 = "br01";
69 private static final String BR02 = "br02";
71 private BridgeConfigReconciliationTask configurationReconciliationTask;
72 @Mock private OvsdbConnectionManager ovsdbConnectionManager;
73 @Mock private OvsdbConnectionInstance ovsdbConnectionInstance;
74 @Mock private DataBroker db;
75 @Mock private ReconciliationManager reconciliationManager;
76 @Mock private Topology topology;
77 @Mock private InstanceIdentifier<Node> iid;
80 public void setUp() throws Exception {
81 List<Node> bridgeNodes = new ArrayList<>();
82 bridgeNodes.add(createBridgeNode(BR01));
83 bridgeNodes.add(createBridgeNode(BR02));
84 when(topology.getNode()).thenReturn(bridgeNodes);
86 Optional<Topology> topologyOptional = mock(Optional.class);
87 when(topologyOptional.isPresent()).thenReturn(true);
88 when(topologyOptional.get()).thenReturn(topology);
89 CheckedFuture<Optional<Topology>, ReadFailedException> readTopologyFuture = Futures
90 .immediateCheckedFuture(topologyOptional);
92 when(reconciliationManager.getDb()).thenReturn(db);
93 ReadOnlyTransaction tx = mock(ReadOnlyTransaction.class);
94 Mockito.when(db.newReadOnlyTransaction()).thenReturn(tx);
95 Mockito.when(tx.read(any(LogicalDatastoreType.class),any(InstanceIdentifier.class)))
96 .thenReturn(readTopologyFuture);
98 when(topology.getNode()).thenReturn(bridgeNodes);
99 NodeKey nodeKey = new NodeKey(new NodeId(new Uri(NODE_ID)));
100 when(ovsdbConnectionInstance.getNodeKey()).thenReturn(nodeKey);
102 configurationReconciliationTask = new BridgeConfigReconciliationTask(
103 reconciliationManager, ovsdbConnectionManager, iid, ovsdbConnectionInstance);
107 public void testReconcileConfiguration() throws Exception {
108 BridgeConfigReconciliationTask underTest = PowerMockito.spy(configurationReconciliationTask);
109 PowerMockito.doNothing().when(underTest, "reconcileBridgeConfigurations", any(Map.class));
110 assertEquals(true, underTest.reconcileConfiguration(ovsdbConnectionManager));
111 Map<InstanceIdentifier<?>, DataObject> changes = new HashMap<>();
112 for (Node bridgeNode : topology.getNode()) {
113 changes.putAll(createExpectedConfigurationChanges(bridgeNode));
115 PowerMockito.verifyPrivate(underTest).invoke("reconcileBridgeConfigurations", changes);
118 private Node createBridgeNode(final String bridgeName) {
119 Node bridgeNode = mock(Node.class);
120 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = mock(OvsdbBridgeAugmentation.class);
121 OvsdbNodeRef ovsdbNodeRef = mock(OvsdbNodeRef.class);
123 when((InstanceIdentifier<Node>)ovsdbNodeRef.getValue()).thenReturn(iid);
124 OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(bridgeName);
125 when(bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class)).thenReturn(ovsdbBridgeAugmentation);
126 when(ovsdbBridgeAugmentation.getBridgeName()).thenReturn(ovsdbBridgeName);
127 ProtocolEntry protocolEntry = mock(ProtocolEntry.class);
128 ProtocolEntryKey protocolEntryKey = mock(ProtocolEntryKey.class);
129 Mockito.when(protocolEntry.getProtocol()).thenAnswer(new Answer<Class<? extends OvsdbBridgeProtocolBase>>() {
130 public Class<? extends OvsdbBridgeProtocolBase> answer(
131 InvocationOnMock invocation) throws Throwable {
132 return OvsdbBridgeProtocolOpenflow10.class;
135 when(protocolEntry.getKey()).thenReturn(protocolEntryKey);
136 when(ovsdbBridgeAugmentation.getProtocolEntry()).thenReturn(Arrays.asList(protocolEntry));
138 ControllerEntry controllerEntry = mock(ControllerEntry.class);
139 ControllerEntryKey controllerEntryKey = mock(ControllerEntryKey.class);
140 when(controllerEntry.getKey()).thenReturn(controllerEntryKey);
141 when(ovsdbBridgeAugmentation.getControllerEntry()).thenReturn(Arrays.asList(controllerEntry));
143 when(ovsdbBridgeAugmentation.getManagedBy()).thenReturn(ovsdbNodeRef);
148 private Map<InstanceIdentifier<?>, DataObject> createExpectedConfigurationChanges(final Node bridgeNode) {
149 OvsdbBridgeAugmentation ovsdbBridge = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
151 Map<InstanceIdentifier<?>, DataObject> changes = new HashMap<>();
152 final InstanceIdentifier<Node> bridgeNodeIid = SouthboundMapper
153 .createInstanceIdentifier(ovsdbConnectionInstance, ovsdbBridge.getBridgeName().getValue());
154 final InstanceIdentifier<OvsdbBridgeAugmentation> ovsdbBridgeIid =
155 bridgeNodeIid.builder().augmentation(OvsdbBridgeAugmentation.class).build();
156 changes.put(bridgeNodeIid, bridgeNode);
157 changes.put(ovsdbBridgeIid, ovsdbBridge);
158 for (ProtocolEntry protocolEntry : ovsdbBridge.getProtocolEntry()) {
159 KeyedInstanceIdentifier<ProtocolEntry, ProtocolEntryKey> protocolIid =
160 ovsdbBridgeIid.child(ProtocolEntry.class, protocolEntry.getKey());
161 changes.put(protocolIid, protocolEntry);
163 for (ControllerEntry controller : ovsdbBridge.getControllerEntry()) {
164 KeyedInstanceIdentifier<ControllerEntry, ControllerEntryKey> controllerIid =
165 ovsdbBridgeIid.child(ControllerEntry.class, controller.getKey());
166 changes.put(controllerIid, controller);