2 * Copyright (c) 2016 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.ip.sgt.distribution.service.impl;
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;
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;
74 @RunWith(PowerMockRunner.class)
75 @PrepareForTest(IpSgtDistributionServiceImpl.class)
76 public class IpSgtDistributionServiceImplTest {
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)))
91 private final InstanceIdentifier<Node> SXP_NODE_IID = InstanceIdentifier.builder(NetworkTopology.class)
92 .child(Topology.class, new TopologyKey(new TopologyId("sxp")))
95 new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId(
96 ADDR.getIpv4Address().getValue())))
98 private DataBroker dataBroker;
99 private IpSgtDistributionServiceImpl impl;
100 private SxpCapableNodeListener nodeListener;
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);
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()))
125 .setDescription(IpSgtDistributionServiceImpl.SXP_NODE_DESCRIPTION)
127 verify(sxpService).addNode(eq(addNodeInput));
128 PowerMockito.verifyNew(SxpCapableNodeListener.class);
132 public void testSendIpSgtBindingToPeer_successfullWrite() throws Exception {
133 SendIpSgtBindingToPeerInput input =
134 new SendIpSgtBindingToPeerInputBuilder()
137 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
139 .setPeerNode(Collections
140 .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).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)
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))
161 Matchers.argThat(createMasterBDBindingMatcher(expectedMasterDBBinding)));
162 assertTrue(response.get().isSuccessful());
165 private static ArgumentMatcher<MasterDatabaseBinding> createMasterBDBindingMatcher(final MasterDatabaseBinding expectedMasterDBBinding) {
166 return new ArgumentMatcher<MasterDatabaseBinding>() {
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);
181 public void testSendIpSgtBindingToPeer_failedWrite() throws Exception {
182 SendIpSgtBindingToPeerInput input =
183 new SendIpSgtBindingToPeerInputBuilder()
186 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
188 .setPeerNode(Collections
189 .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).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());
201 public void testSendIpSgtBindingToPeer_noSxpCapableNode() throws Exception {
202 SendIpSgtBindingToPeerInput input =
203 new SendIpSgtBindingToPeerInputBuilder()
206 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
208 .setPeerNode(Collections
209 .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).build()))
212 when(nodeListener.getDomainIdForPeer(PEER_IID)).thenReturn(null);
213 Future<RpcResult<Void>> response = impl.sendIpSgtBindingToPeer(input);
214 assertFalse(response.get().isSuccessful());
218 public void testRemoveIpSgtBindingFromPeer_successfullWrite() throws Exception {
219 RemoveIpSgtBindingFromPeerInput input =
220 new RemoveIpSgtBindingFromPeerInputBuilder()
223 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
225 .setPeerNode(Collections
226 .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).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))
243 assertTrue(response.get().isSuccessful());
247 public void testRemoveIpSgtBindingFromPeer_failedWrite() throws Exception {
248 RemoveIpSgtBindingFromPeerInput input =
249 new RemoveIpSgtBindingFromPeerInputBuilder()
252 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
254 .setPeerNode(Collections
255 .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).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());
267 public void testRemoveIpSgtBindingFromPeer_noSxpCapableNode() throws Exception {
268 RemoveIpSgtBindingFromPeerInput input =
269 new RemoveIpSgtBindingFromPeerInputBuilder()
272 .singletonList(new BindingBuilder().setIpPrefix(BINDING_ADDR)
274 .setPeerNode(Collections
275 .singletonList(new PeerNodeBuilder().setNodeIid(PEER_IID).build()))
278 when(nodeListener.getDomainIdForPeer(PEER_IID)).thenReturn(null);
279 Future<RpcResult<Void>> response = impl.removeIpSgtBindingFromPeer(input);
280 assertFalse(response.get().isSuccessful());