2661fcfa238a76500159cd35da1394a61cc37e1f
[groupbasedpolicy.git] / ip-sgt-distribution-service / src / test / java / org / opendaylight / groupbasedpolicy / ip / sgt / distribution / service / impl / IpSgtDistributionServiceImplTest.java
1 /*
2  * Copyright (c) 2016 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.ip.sgt.distribution.service.impl;
10
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
13 import static org.mockito.Matchers.any;
14 import static org.mockito.Matchers.eq;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.verify;
17 import static org.mockito.Mockito.when;
18
19 import com.google.common.util.concurrent.Futures;
20 import java.util.Collections;
21 import java.util.concurrent.Future;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.mockito.ArgumentMatcher;
26 import org.mockito.Matchers;
27 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
28 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
31 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
32 import org.opendaylight.sxp.util.time.TimeConv;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ip.sgt.distribution.rev160715.RemoveIpSgtBindingFromPeerInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ip.sgt.distribution.rev160715.RemoveIpSgtBindingFromPeerInputBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ip.sgt.distribution.rev160715.SendIpSgtBindingToPeerInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ip.sgt.distribution.rev160715.SendIpSgtBindingToPeerInputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ip.sgt.distribution.rev160715.rpc.fields.BindingBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ip.sgt.distribution.rev160715.rpc.fields.binding.PeerNodeBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.controller.rev141002.AddNodeInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.controller.rev141002.AddNodeInputBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.controller.rev141002.AddNodeOutput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.controller.rev141002.AddNodeOutputBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.controller.rev141002.SxpControllerService;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBindingBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBindingKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.peer.sequence.fields.PeerSequence;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.peer.sequence.fields.PeerSequenceBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentity;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.SxpDomains;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomain;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomainKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.sxp.databases.fields.MasterDatabase;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.protocol.rev141002.NodeId;
61 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
62 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
63 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
64 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
65 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
67 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
68 import org.opendaylight.yangtools.yang.common.RpcResult;
69 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
70 import org.powermock.api.mockito.PowerMockito;
71 import org.powermock.core.classloader.annotations.PrepareForTest;
72 import org.powermock.modules.junit4.PowerMockRunner;
73
74 @RunWith(PowerMockRunner.class)
75 @PrepareForTest(IpSgtDistributionServiceImpl.class)
76 public class IpSgtDistributionServiceImplTest {
77
78     private static final PeerSequence EMPTY_PEER_SEQUENCE = new PeerSequenceBuilder().build();
79     private static final DateAndTime DUMMY_DT = TimeConv.toDt(123456L);
80     private final IpAddress ADDR = new IpAddress(new Ipv4Address("10.0.0.1"));
81     private final IpPrefix BINDING_ADDR = new IpPrefix(new Ipv4Prefix("192.168.50.1/32"));
82     private final Sgt BINDING_SGT = new Sgt(1010);
83     private final String NODE_ID = "node1";
84     private final String TOPOLOGY_ID = "test-topology";
85     private final String DOMAIN_ID = TOPOLOGY_ID + "/" + NODE_ID;
86     private final InstanceIdentifier<Node> PEER_IID = InstanceIdentifier.builder(NetworkTopology.class)
87         .child(Topology.class, new TopologyKey(new TopologyId("test-topology")))
88         .child(Node.class, new NodeKey(
89                 new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId(NODE_ID)))
90         .build();
91     private final InstanceIdentifier<Node> SXP_NODE_IID = InstanceIdentifier.builder(NetworkTopology.class)
92         .child(Topology.class, new TopologyKey(new TopologyId("sxp")))
93         .child(Node.class,
94                 new NodeKey(
95                         new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId(
96                                 ADDR.getIpv4Address().getValue())))
97         .build();
98     private DataBroker dataBroker;
99     private IpSgtDistributionServiceImpl impl;
100     private SxpCapableNodeListener nodeListener;
101
102     @Before
103     public void init() throws Exception {
104         SxpControllerService sxpService = mock(SxpControllerService.class);
105         when(sxpService.addNode(any())).thenReturn(Futures.immediateFuture(
106                 RpcResultBuilder.<AddNodeOutput>success(new AddNodeOutputBuilder().setResult(true).build()).build()));
107         nodeListener = PowerMockito.mock(SxpCapableNodeListener.class);
108         PowerMockito.whenNew(SxpCapableNodeListener.class).withAnyArguments().thenReturn(nodeListener);
109         dataBroker = mock(DataBroker.class);
110         impl = new IpSgtDistributionServiceImpl(dataBroker, sxpService, ADDR);
111     }
112
113     @Test
114     public void testInit() throws Exception {
115         RpcProviderRegistry rpcProvider = mock(RpcProviderRegistry.class);
116         SxpControllerService sxpService = mock(SxpControllerService.class);
117         when(rpcProvider.getRpcService(SxpControllerService.class)).thenReturn(sxpService);
118         when(sxpService.addNode(any())).thenReturn(Futures.immediateFuture(
119                 RpcResultBuilder.<AddNodeOutput>success(new AddNodeOutputBuilder().setResult(true).build()).build()));
120         SxpCapableNodeListener nodeListener = PowerMockito.mock(SxpCapableNodeListener.class);
121         PowerMockito.whenNew(SxpCapableNodeListener.class).withAnyArguments().thenReturn(nodeListener);
122         impl = new IpSgtDistributionServiceImpl(dataBroker, sxpService, ADDR);
123         AddNodeInput addNodeInput = new AddNodeInputBuilder().setNodeId(new NodeId(ADDR.getIpv4Address().getValue()))
124             .setSourceIp(ADDR)
125             .setDescription(IpSgtDistributionServiceImpl.SXP_NODE_DESCRIPTION)
126             .build();
127         verify(sxpService).addNode(eq(addNodeInput));
128         PowerMockito.verifyNew(SxpCapableNodeListener.class);
129     }
130
131     @Test
132     public void testSendIpSgtBindingToPeer_successfullWrite() throws Exception {
133         SendIpSgtBindingToPeerInput input =
134                 new SendIpSgtBindingToPeerInputBuilder()
135                     .setBinding(
136                             Collections
137                                 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
138                                     .setSgt(BINDING_SGT)
139                                     .setPeerNode(Collections
140                                         .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).build()))
141                                     .build()))
142                     .build();
143         WriteTransaction wtx = mock(WriteTransaction.class);
144         when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
145         when(wtx.submit()).thenReturn(Futures.immediateCheckedFuture(null));
146         when(nodeListener.getDomainIdForPeer(PEER_IID)).thenReturn(DOMAIN_ID);
147         Future<RpcResult<Void>> response = impl.sendIpSgtBindingToPeer(input);
148         final MasterDatabaseBinding expectedMasterDBBinding = new MasterDatabaseBindingBuilder().setIpPrefix(BINDING_ADDR)
149                 .setSecurityGroupTag(BINDING_SGT)
150                 .setPeerSequence(EMPTY_PEER_SEQUENCE)
151                 .setTimestamp(DUMMY_DT)
152                 .build();
153         verify(wtx).put(eq(LogicalDatastoreType.CONFIGURATION),
154                 eq(InstanceIdentifier.builder(SXP_NODE_IID)
155                         .augmentation(SxpNodeIdentity.class)
156                         .child(SxpDomains.class)
157                         .child(SxpDomain.class, new SxpDomainKey(DOMAIN_ID))
158                         .child(MasterDatabase.class)
159                         .child(MasterDatabaseBinding.class, new MasterDatabaseBindingKey(BINDING_ADDR))
160                         .build()),
161                 Matchers.argThat(createMasterBDBindingMatcher(expectedMasterDBBinding)));
162         assertTrue(response.get().isSuccessful());
163     }
164
165     private static ArgumentMatcher<MasterDatabaseBinding> createMasterBDBindingMatcher(final MasterDatabaseBinding expectedMasterDBBinding) {
166         return new ArgumentMatcher<MasterDatabaseBinding>() {
167             @Override
168             public boolean matches(final Object o) {
169                 boolean verdict = false;
170                 if (o instanceof MasterDatabaseBinding) {
171                     final MasterDatabaseBinding otherMasterDBBinding =
172                             new MasterDatabaseBindingBuilder((MasterDatabaseBinding) o).setTimestamp(DUMMY_DT).build();
173                     verdict = expectedMasterDBBinding.equals(otherMasterDBBinding);
174                 }
175                 return verdict;
176             }
177         };
178     }
179
180     @Test
181     public void testSendIpSgtBindingToPeer_failedWrite() throws Exception {
182         SendIpSgtBindingToPeerInput input =
183                 new SendIpSgtBindingToPeerInputBuilder()
184                     .setBinding(
185                             Collections
186                                 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
187                                     .setSgt(BINDING_SGT)
188                                     .setPeerNode(Collections
189                                         .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).build()))
190                                     .build()))
191                     .build();
192         WriteTransaction wtx = mock(WriteTransaction.class);
193         when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
194         when(wtx.submit()).thenReturn(Futures.immediateFailedCheckedFuture(new TransactionCommitFailedException("")));
195         when(nodeListener.getDomainIdForPeer(PEER_IID)).thenReturn(DOMAIN_ID);
196         Future<RpcResult<Void>> response = impl.sendIpSgtBindingToPeer(input);
197         assertFalse(response.get().isSuccessful());
198     }
199
200     @Test
201     public void testSendIpSgtBindingToPeer_noSxpCapableNode() throws Exception {
202         SendIpSgtBindingToPeerInput input =
203                 new SendIpSgtBindingToPeerInputBuilder()
204                     .setBinding(
205                             Collections
206                                 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
207                                     .setSgt(BINDING_SGT)
208                                     .setPeerNode(Collections
209                                         .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).build()))
210                                     .build()))
211                     .build();
212         when(nodeListener.getDomainIdForPeer(PEER_IID)).thenReturn(null);
213         Future<RpcResult<Void>> response = impl.sendIpSgtBindingToPeer(input);
214         assertFalse(response.get().isSuccessful());
215     }
216
217     @Test
218     public void testRemoveIpSgtBindingFromPeer_successfullWrite() throws Exception {
219         RemoveIpSgtBindingFromPeerInput input =
220                 new RemoveIpSgtBindingFromPeerInputBuilder()
221                     .setBinding(
222                             Collections
223                                 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
224                                     .setSgt(BINDING_SGT)
225                                     .setPeerNode(Collections
226                                         .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).build()))
227                                     .build()))
228                     .build();
229         WriteTransaction wtx = mock(WriteTransaction.class);
230         when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
231         when(wtx.submit()).thenReturn(Futures.immediateCheckedFuture(null));
232         when(nodeListener.getDomainIdForPeer(PEER_IID)).thenReturn(DOMAIN_ID);
233         Future<RpcResult<Void>> response = impl.removeIpSgtBindingFromPeer(input);
234         new MasterDatabaseBindingBuilder().setIpPrefix(BINDING_ADDR).setSecurityGroupTag(BINDING_SGT).build();
235         verify(wtx).delete(eq(LogicalDatastoreType.CONFIGURATION),
236                 eq(InstanceIdentifier.builder(SXP_NODE_IID)
237                     .augmentation(SxpNodeIdentity.class)
238                     .child(SxpDomains.class)
239                     .child(SxpDomain.class, new SxpDomainKey(DOMAIN_ID))
240                     .child(MasterDatabase.class)
241                     .child(MasterDatabaseBinding.class, new MasterDatabaseBindingKey(BINDING_ADDR))
242                     .build()));
243         assertTrue(response.get().isSuccessful());
244     }
245
246     @Test
247     public void testRemoveIpSgtBindingFromPeer_failedWrite() throws Exception {
248         RemoveIpSgtBindingFromPeerInput input =
249                 new RemoveIpSgtBindingFromPeerInputBuilder()
250                     .setBinding(
251                             Collections
252                                 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
253                                     .setSgt(BINDING_SGT)
254                                     .setPeerNode(Collections
255                                         .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).build()))
256                                     .build()))
257                     .build();
258         WriteTransaction wtx = mock(WriteTransaction.class);
259         when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
260         when(wtx.submit()).thenReturn(Futures.immediateFailedCheckedFuture(new TransactionCommitFailedException("")));
261         when(nodeListener.getDomainIdForPeer(PEER_IID)).thenReturn(DOMAIN_ID);
262         Future<RpcResult<Void>> response = impl.removeIpSgtBindingFromPeer(input);
263         assertFalse(response.get().isSuccessful());
264     }
265
266     @Test
267     public void testRemoveIpSgtBindingFromPeer_noSxpCapableNode() throws Exception {
268         RemoveIpSgtBindingFromPeerInput input =
269                 new RemoveIpSgtBindingFromPeerInputBuilder()
270                     .setBinding(
271                             Collections
272                                 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
273                                     .setSgt(BINDING_SGT)
274                                     .setPeerNode(Collections
275                                         .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).build()))
276                                     .build()))
277                     .build();
278         when(nodeListener.getDomainIdForPeer(PEER_IID)).thenReturn(null);
279         Future<RpcResult<Void>> response = impl.removeIpSgtBindingFromPeer(input);
280         assertFalse(response.get().isSuccessful());
281     }
282 }