6323677df08a759ef47044459b903a3d8275d86b
[ovsdb.git] / southbound / southbound-impl / src / test / java / org / opendaylight / ovsdb / southbound / reconciliation / configuration / BridgeConfigReconciliationTaskTest.java
1 /*
2  * Copyright (c) 2016 , NEC Corporation and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.ovsdb.southbound.reconciliation.configuration;
9
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;
14
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;
22 import java.util.Map;
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;
58
59 /**
60  * Created by Vinh Nguyen (vinh.nguyen@hcl.com) on 3/21/16.
61  */
62 @RunWith(PowerMockRunner.class)
63 @PrepareForTest({ BridgeConfigReconciliationTask.class, OvsdbConnectionManager.class, OvsdbConnectionInstance.class,
64         InstanceIdentifier.class, Optional.class })
65 public class BridgeConfigReconciliationTaskTest {
66
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";
70
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;
78
79     @Before
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);
85
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);
91
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);
97
98         when(topology.getNode()).thenReturn(bridgeNodes);
99         NodeKey nodeKey = new NodeKey(new NodeId(new Uri(NODE_ID)));
100         when(ovsdbConnectionInstance.getNodeKey()).thenReturn(nodeKey);
101
102         configurationReconciliationTask = new BridgeConfigReconciliationTask(
103                 reconciliationManager, ovsdbConnectionManager, iid, ovsdbConnectionInstance);
104     }
105
106     @Test
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));
114         }
115         PowerMockito.verifyPrivate(underTest).invoke("reconcileBridgeConfigurations", changes);
116     }
117
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);
122
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;
133             }
134         });
135         when(protocolEntry.getKey()).thenReturn(protocolEntryKey);
136         when(ovsdbBridgeAugmentation.getProtocolEntry()).thenReturn(Arrays.asList(protocolEntry));
137
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));
142
143         when(ovsdbBridgeAugmentation.getManagedBy()).thenReturn(ovsdbNodeRef);
144
145         return bridgeNode;
146     }
147
148     private Map<InstanceIdentifier<?>, DataObject> createExpectedConfigurationChanges(final Node bridgeNode) {
149         OvsdbBridgeAugmentation ovsdbBridge = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
150
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);
162         }
163         for (ControllerEntry controller : ovsdbBridge.getControllerEntry()) {
164             KeyedInstanceIdentifier<ControllerEntry, ControllerEntryKey> controllerIid =
165                     ovsdbBridgeIid.child(ControllerEntry.class, controller.getKey());
166             changes.put(controllerIid, controller);
167         }
168         return changes;
169     }
170 }