2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
11 import static org.mockito.Matchers.any;
12 import static org.mockito.Matchers.anyBoolean;
13 import static org.mockito.Mockito.doNothing;
14 import static org.mockito.Mockito.doReturn;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.never;
17 import static org.mockito.Mockito.spy;
18 import static org.mockito.Mockito.verify;
19 import static org.mockito.Mockito.verifyNoMoreInteractions;
20 import static org.mockito.Mockito.when;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.List;
28 import org.junit.Assert;
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
32 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
33 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
34 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
35 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
36 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
37 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointManager;
38 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
39 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
40 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.GroupTable.BucketCtx;
41 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.GroupTable.GroupCtx;
42 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
43 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
44 import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
45 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
46 import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
67 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
69 import com.google.common.base.Optional;
70 import com.google.common.util.concurrent.CheckedFuture;
72 public class GroupTableTest {
74 private GroupTable groupTable;
76 private OfContext ofContext;
77 private DataBroker dataBroker;
78 private ReadOnlyTransaction readOnlyTransaction;
79 private CheckedFuture<Optional<Node>, ReadFailedException> checkedFutureRead;
80 private Optional<Node> optional;
82 private FlowCapableNode flowCapableNode;
84 private Buckets buckets;
85 private Bucket bucket;
86 private WriteTransaction writeTransaction;
87 private CheckedFuture<Void, TransactionCommitFailedException> checkedFutureWrite;
88 private NodeId nodeId;
89 private PolicyInfo policyInfo;
90 private FlowMap flowMap;
91 private GroupId groupId;
92 private GroupCtx groupCtx;
93 private HashMap<GroupId, GroupCtx> groupMap;
94 private Bucket bucketOther;
95 private BucketCtx bucketCtx;
96 private EndpointManager endpointManager;
97 private Endpoint localEp;
99 private OfOverlayContext ofc;
100 private NodeConnectorId nodeConnectorId;
102 @SuppressWarnings("unchecked")
104 public void initialisation() throws Exception {
105 ofContext = mock(OfContext.class);
106 groupTable = spy(new GroupTable(ofContext));
108 dataBroker = mock(DataBroker.class);
109 when(ofContext.getDataBroker()).thenReturn(dataBroker);
110 readOnlyTransaction = mock(ReadOnlyTransaction.class);
111 when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
112 checkedFutureRead = mock(CheckedFuture.class);
113 when(readOnlyTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(
115 optional = mock(Optional.class);
116 when(checkedFutureRead.get()).thenReturn(optional);
117 node = mock(Node.class);
118 when(optional.isPresent()).thenReturn(true);
119 when(optional.get()).thenReturn(node);
121 writeTransaction = mock(WriteTransaction.class);
122 when(dataBroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
123 checkedFutureWrite = mock(CheckedFuture.class);
124 when(writeTransaction.submit()).thenReturn(checkedFutureWrite);
126 flowCapableNode = mock(FlowCapableNode.class);
127 when(node.getAugmentation(FlowCapableNode.class)).thenReturn(flowCapableNode);
129 group = mock(Group.class);
130 List<Group> groups = Arrays.asList(group);
131 when(flowCapableNode.getGroup()).thenReturn(groups);
133 buckets = mock(Buckets.class);
134 when(group.getBuckets()).thenReturn(buckets);
135 bucket = mock(Bucket.class);
136 when(bucket.getAction()).thenReturn(Arrays.asList(mock(Action.class)));
137 List<Bucket> bucketList = Arrays.asList(bucket);
138 when(buckets.getBucket()).thenReturn(bucketList);
140 bucketOther = mock(Bucket.class);
141 when(bucketOther.getAction()).thenReturn(Arrays.asList(mock(Action.class)));
143 groupId = mock(GroupId.class);
144 groupCtx = new GroupCtx(groupId);
145 groupMap = new HashMap<>();
146 groupMap.put(groupId, groupCtx);
147 bucketCtx = mock(BucketCtx.class);
148 groupCtx.bucketMap.put(mock(BucketId.class), bucketCtx);
150 nodeId = mock(NodeId.class);
151 policyInfo = mock(PolicyInfo.class);
152 flowMap = mock(FlowMap.class);
154 endpointManager = mock(EndpointManager.class);
155 when(ofContext.getEndpointManager()).thenReturn(endpointManager);
156 localEp = mock(Endpoint.class);
157 when(endpointManager.getEndpointsForNode(nodeId)).thenReturn(Arrays.asList(localEp));
158 PolicyResolver policyResolver = mock(PolicyResolver.class);
159 when(ofContext.getPolicyResolver()).thenReturn(policyResolver);
160 IndexedTenant indexedTenant = mock(IndexedTenant.class);
161 when(policyResolver.getTenant(any(TenantId.class))).thenReturn(indexedTenant);
162 EndpointGroup epg = mock(EndpointGroup.class);
163 when(indexedTenant.getEndpointGroup(any(EndpointGroupId.class))).thenReturn(epg);
164 egKey = mock(EgKey.class);
165 when(endpointManager.getGroupsForNode(any(NodeId.class))).thenReturn(new HashSet<EgKey>(Arrays.asList(egKey)));
166 ofc = mock(OfOverlayContext.class);
167 when(localEp.getAugmentation(OfOverlayContext.class)).thenReturn(ofc);
168 nodeConnectorId = mock(NodeConnectorId.class);
169 when(ofc.getNodeConnectorId()).thenReturn(nodeConnectorId);
172 @SuppressWarnings("unchecked")
174 public void updateTest() throws Exception {
175 doNothing().when(groupTable).sync(any(NodeId.class), any(PolicyInfo.class), any(HashMap.class));
176 doReturn(true).when(groupTable).syncGroupToStore(any(WriteTransaction.class), any(NodeId.class),
179 groupTable.update(nodeId, policyInfo, flowMap);
180 verify(checkedFutureWrite).get();
184 public void updateTestIsPresentFalse() throws Exception {
185 when(optional.isPresent()).thenReturn(false);
187 groupTable.update(nodeId, policyInfo, flowMap);
188 verify(checkedFutureWrite, never()).get();
192 public void updateTestIsFcnNull() throws Exception {
193 when(node.getAugmentation(FlowCapableNode.class)).thenReturn(null);
195 groupTable.update(nodeId, policyInfo, flowMap);
196 verify(checkedFutureWrite, never()).get();
199 @SuppressWarnings("unchecked")
201 public void updateTestIsFcnGroupNull() throws Exception {
202 doNothing().when(groupTable).sync(any(NodeId.class), any(PolicyInfo.class), any(HashMap.class));
203 doReturn(true).when(groupTable).syncGroupToStore(any(WriteTransaction.class), any(NodeId.class),
205 when(flowCapableNode.getGroup()).thenReturn(null);
207 groupTable.update(nodeId, policyInfo, flowMap);
208 verify(checkedFutureWrite).get();
212 public void syncGroupToStoreTestVisitedFalse() {
213 groupCtx.visited = false;
214 boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
215 Assert.assertTrue(result);
219 public void syncGroupToStoreTestBucketMapEmpty() {
220 groupCtx.visited = true;
221 groupCtx.bucketMap = Collections.emptyMap();
222 boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
223 Assert.assertFalse(result);
227 public void syncGroupToStoreTestBNullBucketVisitedFalse() {
228 groupCtx.visited = true;
229 bucketCtx.visited = false;
230 bucketCtx.newb = bucket;
232 boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
233 Assert.assertTrue(result);
234 verify(bucket).getBucketId();
235 verify(writeTransaction).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
238 @SuppressWarnings("unchecked")
240 public void syncGroupToStoreTestBNullBucketVisitedTrue() {
241 groupCtx.visited = true;
242 bucketCtx.visited = true;
243 bucketCtx.newb = bucket;
245 boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
246 Assert.assertTrue(result);
247 verify(bucket).getBucketId();
248 verify(writeTransaction).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class),
249 any(Group.class), anyBoolean());
253 public void syncGroupToStoreTestBucketVisitedFalse() {
254 groupCtx.visited = true;
255 bucketCtx.visited = false;
256 bucketCtx.newb = bucket;
257 bucketCtx.b = bucketOther;
259 boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
260 Assert.assertTrue(result);
261 verify(bucketOther).getBucketId();
262 verify(writeTransaction).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
265 @SuppressWarnings("unchecked")
267 public void syncGroupToStoreTestBucketVisitedTrueActionsEqualFalse() {
268 groupCtx.visited = true;
269 bucketCtx.visited = true;
270 bucketCtx.newb = bucket;
271 bucketCtx.b = bucketOther;
273 boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
274 Assert.assertTrue(result);
275 verify(bucketOther).getBucketId();
276 verify(writeTransaction).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class),
277 any(Group.class), anyBoolean());
281 public void syncGroupToStoreTestBucketVisitedTrueActionsEqualTrue() {
282 groupCtx.visited = true;
283 bucketCtx.visited = true;
284 bucketCtx.newb = bucket;
285 bucketCtx.b = bucket;
287 boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
288 Assert.assertFalse(result);
289 verify(bucket).getBucketId();
290 verifyNoMoreInteractions(writeTransaction);
294 public void syncTestNodeEqualsTrue() throws Exception {
295 groupMap = new HashMap<>();
297 when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeId)));
298 when(ofc.getLocationType()).thenReturn(LocationType.Internal);
299 when(nodeConnectorId.getValue()).thenReturn("value:5");
301 groupTable.sync(nodeId, policyInfo, groupMap);
302 Assert.assertEquals(1, groupMap.size());
303 GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
304 Assert.assertEquals(1, resultGroup.bucketMap.size());
305 BucketCtx result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[0];
306 Assert.assertTrue(result.visited);
307 Assert.assertNotNull(result.newb);
311 public void syncTestNodeEqualsTruePortNumberException() throws Exception {
312 groupMap = new HashMap<>();
314 when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeId)));
315 when(ofc.getLocationType()).thenReturn(LocationType.Internal);
316 when(nodeConnectorId.getValue()).thenReturn("value");
318 groupTable.sync(nodeId, policyInfo, groupMap);
319 Assert.assertEquals(1, groupMap.size());
320 GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
321 Assert.assertTrue(resultGroup.bucketMap.isEmpty());
325 public void syncTestNodeEqualsTrueLocalEpExternal() throws Exception {
326 groupMap = new HashMap<>();
328 when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeId)));
329 when(ofc.getLocationType()).thenReturn(LocationType.External);
331 groupTable.sync(nodeId, policyInfo, groupMap);
332 Assert.assertEquals(1, groupMap.size());
333 GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
334 Assert.assertTrue(resultGroup.bucketMap.isEmpty());
338 public void syncTestNodeEqualsFalse() throws Exception {
339 groupMap = new HashMap<>();
341 NodeId nodeIdOther = mock(NodeId.class);
342 when(nodeIdOther.getValue()).thenReturn("5");
343 SwitchManager switchManager = mock(SwitchManager.class);
344 when(ofContext.getSwitchManager()).thenReturn(switchManager);
345 IpAddress tunDst = mock(IpAddress.class);
346 when(switchManager.getTunnelIP(nodeIdOther, TunnelTypeVxlan.class)).thenReturn(tunDst);
347 NodeConnectorId tunPort = mock(NodeConnectorId.class);
348 when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class)).thenReturn(tunPort);
349 Ipv4Address ipv4Address = mock(Ipv4Address.class);
350 when(tunDst.getIpv4Address()).thenReturn(ipv4Address);
351 when(ipv4Address.getValue()).thenReturn("127.0.0.1");
352 when(tunPort.getValue()).thenReturn("127.0.0.1");
354 when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeIdOther)));
355 when(ofc.getLocationType()).thenReturn(LocationType.Internal);
356 when(nodeConnectorId.getValue()).thenReturn("value:5");
358 groupTable.sync(nodeId, policyInfo, groupMap);
359 Assert.assertEquals(1, groupMap.size());
360 GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
361 Assert.assertEquals(2, resultGroup.bucketMap.size());
363 result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[0];
364 Assert.assertTrue(result.visited);
365 Assert.assertNotNull(result.newb);
366 result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[1];
367 Assert.assertTrue(result.visited);
368 Assert.assertNotNull(result.newb);
372 public void syncTestNodeEqualsFalseIpv4Null() throws Exception {
373 groupMap = new HashMap<>();
375 NodeId nodeIdOther = mock(NodeId.class);
376 when(nodeIdOther.getValue()).thenReturn("5");
377 SwitchManager switchManager = mock(SwitchManager.class);
378 when(ofContext.getSwitchManager()).thenReturn(switchManager);
379 IpAddress tunDst = mock(IpAddress.class);
380 when(switchManager.getTunnelIP(nodeIdOther, TunnelTypeVxlan.class)).thenReturn(tunDst);
381 NodeConnectorId tunPort = mock(NodeConnectorId.class);
382 when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class)).thenReturn(tunPort);
383 when(tunDst.getIpv4Address()).thenReturn(null);
384 Ipv6Address ipv6Address = mock(Ipv6Address.class);
385 when(tunDst.getIpv6Address()).thenReturn(ipv6Address);
387 when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeIdOther)));
388 when(ofc.getLocationType()).thenReturn(LocationType.Internal);
389 when(nodeConnectorId.getValue()).thenReturn("value:5");
391 groupTable.sync(nodeId, policyInfo, groupMap);
392 Assert.assertEquals(1, groupMap.size());
393 GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
394 Assert.assertEquals(1, resultGroup.bucketMap.size());
395 BucketCtx result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[0];
396 Assert.assertTrue(result.visited);
397 Assert.assertNotNull(result.newb);
401 public void syncTestNodeEqualsFalseTunDstNull() throws Exception {
402 groupMap = new HashMap<>();
404 NodeId nodeIdOther = mock(NodeId.class);
405 when(nodeIdOther.getValue()).thenReturn("5");
406 SwitchManager switchManager = mock(SwitchManager.class);
407 when(ofContext.getSwitchManager()).thenReturn(switchManager);
408 when(switchManager.getTunnelIP(nodeIdOther, TunnelTypeVxlan.class)).thenReturn(null);
409 NodeConnectorId tunPort = mock(NodeConnectorId.class);
410 when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class)).thenReturn(tunPort);
412 when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeIdOther)));
413 when(ofc.getLocationType()).thenReturn(LocationType.Internal);
414 when(nodeConnectorId.getValue()).thenReturn("value:5");
416 groupTable.sync(nodeId, policyInfo, groupMap);
417 Assert.assertEquals(1, groupMap.size());
418 GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
419 Assert.assertEquals(1, resultGroup.bucketMap.size());
420 BucketCtx result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[0];
421 Assert.assertTrue(result.visited);
422 Assert.assertNotNull(result.newb);
426 public void syncTestNodeEqualsFalseTunPortNull() throws Exception {
427 groupMap = new HashMap<>();
429 NodeId nodeIdOther = mock(NodeId.class);
430 when(nodeIdOther.getValue()).thenReturn("5");
431 SwitchManager switchManager = mock(SwitchManager.class);
432 when(ofContext.getSwitchManager()).thenReturn(switchManager);
433 IpAddress tunDst = mock(IpAddress.class);
434 when(switchManager.getTunnelIP(nodeIdOther, TunnelTypeVxlan.class)).thenReturn(tunDst);
435 when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class)).thenReturn(null);
437 when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeIdOther)));
438 when(ofc.getLocationType()).thenReturn(LocationType.Internal);
439 when(nodeConnectorId.getValue()).thenReturn("value:5");
441 groupTable.sync(nodeId, policyInfo, groupMap);
442 Assert.assertEquals(1, groupMap.size());
443 GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
444 Assert.assertEquals(1, resultGroup.bucketMap.size());
445 BucketCtx result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[0];
446 Assert.assertTrue(result.visited);
447 Assert.assertNotNull(result.newb);