6ef22a0f80a9cd805bfe014ddb6b451d0f98faf3
[groupbasedpolicy.git] / renderers / ofoverlay / src / test / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / flow / GroupTableTest.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, 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
9 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
10
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;
21
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;
27
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;
68
69 import com.google.common.base.Optional;
70 import com.google.common.util.concurrent.CheckedFuture;
71
72 public class GroupTableTest {
73
74     private GroupTable groupTable;
75
76     private OfContext ofContext;
77     private DataBroker dataBroker;
78     private ReadOnlyTransaction readOnlyTransaction;
79     private CheckedFuture<Optional<Node>, ReadFailedException> checkedFutureRead;
80     private Optional<Node> optional;
81     private Node node;
82     private FlowCapableNode flowCapableNode;
83     private Group group;
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;
98     private EgKey egKey;
99     private OfOverlayContext ofc;
100     private NodeConnectorId nodeConnectorId;
101
102     @SuppressWarnings("unchecked")
103     @Before
104     public void initialisation() throws Exception {
105         ofContext = mock(OfContext.class);
106         groupTable = spy(new GroupTable(ofContext));
107
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(
114                 checkedFutureRead);
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);
120
121         writeTransaction = mock(WriteTransaction.class);
122         when(dataBroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
123         checkedFutureWrite = mock(CheckedFuture.class);
124         when(writeTransaction.submit()).thenReturn(checkedFutureWrite);
125
126         flowCapableNode = mock(FlowCapableNode.class);
127         when(node.getAugmentation(FlowCapableNode.class)).thenReturn(flowCapableNode);
128
129         group = mock(Group.class);
130         List<Group> groups = Arrays.asList(group);
131         when(flowCapableNode.getGroup()).thenReturn(groups);
132
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);
139
140         bucketOther = mock(Bucket.class);
141         when(bucketOther.getAction()).thenReturn(Arrays.asList(mock(Action.class)));
142
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);
149
150         nodeId = mock(NodeId.class);
151         policyInfo = mock(PolicyInfo.class);
152         flowMap = mock(FlowMap.class);
153
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);
170     }
171
172     @SuppressWarnings("unchecked")
173     @Test
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),
177                 any(HashMap.class));
178
179         groupTable.update(nodeId, policyInfo, flowMap);
180         verify(checkedFutureWrite).get();
181     }
182
183     @Test
184     public void updateTestIsPresentFalse() throws Exception {
185         when(optional.isPresent()).thenReturn(false);
186
187         groupTable.update(nodeId, policyInfo, flowMap);
188         verify(checkedFutureWrite, never()).get();
189     }
190
191     @Test
192     public void updateTestIsFcnNull() throws Exception {
193         when(node.getAugmentation(FlowCapableNode.class)).thenReturn(null);
194
195         groupTable.update(nodeId, policyInfo, flowMap);
196         verify(checkedFutureWrite, never()).get();
197     }
198
199     @SuppressWarnings("unchecked")
200     @Test
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),
204                 any(HashMap.class));
205         when(flowCapableNode.getGroup()).thenReturn(null);
206
207         groupTable.update(nodeId, policyInfo, flowMap);
208         verify(checkedFutureWrite).get();
209     }
210
211     @Test
212     public void syncGroupToStoreTestVisitedFalse() {
213         groupCtx.visited = false;
214         boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
215         Assert.assertTrue(result);
216     }
217
218     @Test
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);
224     }
225
226     @Test
227     public void syncGroupToStoreTestBNullBucketVisitedFalse() {
228         groupCtx.visited = true;
229         bucketCtx.visited = false;
230         bucketCtx.newb = bucket;
231
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));
236     }
237
238     @SuppressWarnings("unchecked")
239     @Test
240     public void syncGroupToStoreTestBNullBucketVisitedTrue() {
241         groupCtx.visited = true;
242         bucketCtx.visited = true;
243         bucketCtx.newb = bucket;
244
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());
250     }
251
252     @Test
253     public void syncGroupToStoreTestBucketVisitedFalse() {
254         groupCtx.visited = true;
255         bucketCtx.visited = false;
256         bucketCtx.newb = bucket;
257         bucketCtx.b = bucketOther;
258
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));
263     }
264
265     @SuppressWarnings("unchecked")
266     @Test
267     public void syncGroupToStoreTestBucketVisitedTrueActionsEqualFalse() {
268         groupCtx.visited = true;
269         bucketCtx.visited = true;
270         bucketCtx.newb = bucket;
271         bucketCtx.b = bucketOther;
272
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());
278     }
279
280     @Test
281     public void syncGroupToStoreTestBucketVisitedTrueActionsEqualTrue() {
282         groupCtx.visited = true;
283         bucketCtx.visited = true;
284         bucketCtx.newb = bucket;
285         bucketCtx.b = bucket;
286
287         boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
288         Assert.assertFalse(result);
289         verify(bucket).getBucketId();
290         verifyNoMoreInteractions(writeTransaction);
291     }
292
293     @Test
294     public void syncTestNodeEqualsTrue() throws Exception {
295         groupMap = new HashMap<>();
296
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");
300
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);
308     }
309
310     @Test
311     public void syncTestNodeEqualsTruePortNumberException() throws Exception {
312         groupMap = new HashMap<>();
313
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");
317
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());
322     }
323
324     @Test
325     public void syncTestNodeEqualsTrueLocalEpExternal() throws Exception {
326         groupMap = new HashMap<>();
327
328         when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeId)));
329         when(ofc.getLocationType()).thenReturn(LocationType.External);
330
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());
335     }
336
337     @Test
338     public void syncTestNodeEqualsFalse() throws Exception {
339         groupMap = new HashMap<>();
340
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");
353
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");
357
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());
362         BucketCtx result;
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);
369     }
370
371     @Test
372     public void syncTestNodeEqualsFalseIpv4Null() throws Exception {
373         groupMap = new HashMap<>();
374
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);
386
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");
390
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);
398     }
399
400     @Test
401     public void syncTestNodeEqualsFalseTunDstNull() throws Exception {
402         groupMap = new HashMap<>();
403
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);
411
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");
415
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);
423     }
424
425     @Test
426     public void syncTestNodeEqualsFalseTunPortNull() throws Exception {
427         groupMap = new HashMap<>();
428
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);
436
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");
440
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);
448     }
449 }