2 * Copyright (c) 2014 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.bgpcep.pcep.topology.provider;
11 import static org.junit.Assert.assertFalse;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Mockito.doAnswer;
14 import static org.mockito.Mockito.doNothing;
15 import static org.mockito.Mockito.doReturn;
16 import static org.mockito.Mockito.mock;
17 import static org.opendaylight.protocol.util.CheckUtil.checkEquals;
19 import com.google.common.util.concurrent.ListenableFuture;
20 import io.netty.channel.Channel;
21 import io.netty.channel.ChannelFuture;
22 import io.netty.channel.ChannelHandler;
23 import io.netty.channel.ChannelPipeline;
24 import io.netty.channel.EventLoop;
25 import io.netty.util.concurrent.Promise;
26 import java.lang.reflect.ParameterizedType;
27 import java.net.InetSocketAddress;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.concurrent.TimeUnit;
32 import org.junit.After;
33 import org.junit.Before;
34 import org.mockito.Mock;
35 import org.mockito.Mockito;
36 import org.mockito.MockitoAnnotations;
37 import org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyConfiguration;
38 import org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyProviderDependencies;
39 import org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry;
40 import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
41 import org.opendaylight.protocol.pcep.PCEPSessionListener;
42 import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiator;
43 import org.opendaylight.protocol.pcep.impl.PCEPSessionImpl;
44 import org.opendaylight.protocol.util.InetSocketAddressUtil;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.config.rev171025.pcep.config.SessionConfig;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.EroBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.Subobject;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.SubobjectBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Open;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCase;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCaseBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefixBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.NetworkTopologyPcepService;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.Node1;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.pcep.client.attributes.PathComputationClient;
63 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
64 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
65 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
67 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
68 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
69 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
70 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
71 import org.opendaylight.yangtools.yang.binding.Notification;
73 public abstract class AbstractPCEPSessionTest<T extends TopologySessionListenerFactory>
74 extends AbstractConcurrentDataBrokerTest {
76 static final short DEAD_TIMER = 30;
77 static final short KEEP_ALIVE = 10;
78 static final short RPC_TIMEOUT = 4;
79 private static final TopologyId TEST_TOPOLOGY_ID = new TopologyId("testtopo");
80 static final InstanceIdentifier<Topology> TOPO_IID = InstanceIdentifier.builder(NetworkTopology.class)
81 .child(Topology.class, new TopologyKey(TEST_TOPOLOGY_ID)).build();
82 private static final String IPV4_MASK = "/32";
83 final String testAddress = InetSocketAddressUtil.getRandomLoopbackIpAddress();
84 final NodeId nodeId = new NodeId("pcc://" + this.testAddress);
85 protected final InstanceIdentifier<PathComputationClient> pathComputationClientIId = TOPO_IID.builder()
86 .child(Node.class, new NodeKey(this.nodeId)).augmentation(Node1.class).child(PathComputationClient.class
88 final String eroIpPrefix = this.testAddress + IPV4_MASK;
89 final String newDestinationAddress = InetSocketAddressUtil.getRandomLoopbackIpAddress();
90 final String dstIpPrefix = this.newDestinationAddress + IPV4_MASK;
91 private final Open localPrefs = new OpenBuilder().setDeadTimer((short) 30).setKeepalive((short) 10)
92 .setSessionId((short) 0).build();
93 private final Open remotePrefs = this.localPrefs;
94 List<Notification> receivedMsgs;
95 ServerSessionManager manager;
96 NetworkTopologyPcepService topologyRpcs;
98 private EventLoop eventLoop;
100 private Channel clientListener;
102 private ChannelPipeline pipeline;
104 private ChannelFuture channelFuture;
106 private TopologySessionStatsRegistry statsRegistry;
108 private PCEPTopologyProviderDependencies topologyDependencies;
110 private SessionConfig sessionConfig;
112 private Topology topology;
114 private Promise<PCEPSessionImpl> promise;
115 private DefaultPCEPSessionNegotiator neg;
118 public void setUp() throws Exception {
119 MockitoAnnotations.initMocks(this);
120 this.receivedMsgs = new ArrayList<>();
121 doAnswer(invocation -> {
122 final Object[] args = invocation.getArguments();
123 AbstractPCEPSessionTest.this.receivedMsgs.add((Notification) args[0]);
124 return this.channelFuture;
125 }).when(this.clientListener).writeAndFlush(any(Notification.class));
126 doReturn(null).when(this.channelFuture).addListener(Mockito.any());
127 doReturn("TestingChannel").when(this.clientListener).toString();
128 doReturn(this.pipeline).when(this.clientListener).pipeline();
129 doReturn(this.pipeline).when(this.pipeline).replace(any(ChannelHandler.class), any(String.class),
130 any(ChannelHandler.class));
131 doReturn(this.eventLoop).when(this.clientListener).eventLoop();
132 doNothing().when(this.statsRegistry).bind(any(), any());
133 doNothing().when(this.statsRegistry).unbind(any());
134 doReturn(null).when(this.eventLoop).schedule(any(Runnable.class), any(long.class),
135 any(TimeUnit.class));
136 doReturn(true).when(this.clientListener).isActive();
137 final InetSocketAddress ra = new InetSocketAddress(this.testAddress, 4189);
138 doReturn(ra).when(this.clientListener).remoteAddress();
139 final InetSocketAddress la = new InetSocketAddress(this.testAddress, InetSocketAddressUtil.getRandomPort());
140 doReturn(la).when(this.clientListener).localAddress();
142 doReturn(mock(ChannelFuture.class)).when(this.clientListener).close();
144 doReturn(getDataBroker()).when(this.topologyDependencies).getDataBroker();
145 doReturn(this.statsRegistry).when(this.topologyDependencies).getStateRegistry();
147 @SuppressWarnings("unchecked") final T listenerFactory = (T) ((Class) ((ParameterizedType) this.getClass()
148 .getGenericSuperclass()).getActualTypeArguments()[0]).newInstance();
149 doReturn(new IpAddress(new Ipv4Address(this.testAddress))).when(this.sessionConfig).getListenAddress();
150 doReturn(new PortNumber(4189)).when(this.sessionConfig).getListenPort();
151 doReturn(RPC_TIMEOUT).when(this.sessionConfig).getRpcTimeout();
152 doReturn(TEST_TOPOLOGY_ID).when(this.topology).getTopologyId();
153 doReturn(Collections.emptyList()).when(this.topology).getNode();
155 final PCEPTopologyConfiguration configDep = new PCEPTopologyConfiguration(this.sessionConfig, this.topology);
156 this.manager = new ServerSessionManager(this.topologyDependencies, listenerFactory, configDep);
157 startSessionManager();
158 this.neg = new DefaultPCEPSessionNegotiator(this.promise, this.clientListener,
159 this.manager.getSessionListener(), (short) 1, 5, this.localPrefs);
160 this.topologyRpcs = new TopologyRPCs(this.manager);
163 void startSessionManager() throws Exception {
164 final ListenableFuture<Void> future = this.manager.instantiateServiceInstance();
166 checkEquals(() -> assertFalse(this.manager.isClosed.get()));
169 void stopSessionManager() {
170 this.manager.closeServiceInstance();
174 public void tearDown() {
175 stopSessionManager();
178 Ero createEroWithIpPrefixes(final List<String> ipPrefixes) {
179 final List<Subobject> subobjs = new ArrayList<>(ipPrefixes.size());
180 final SubobjectBuilder subobjBuilder = new SubobjectBuilder();
181 for (final String ipPrefix : ipPrefixes) {
182 subobjBuilder.setSubobjectType(new IpPrefixCaseBuilder().setIpPrefix(new IpPrefixBuilder()
183 .setIpPrefix(new IpPrefix(new Ipv4Prefix(ipPrefix))).build()).build());
184 subobjs.add(subobjBuilder.build());
186 return new EroBuilder().setSubobject(subobjs).build();
189 String getLastEroIpPrefix(final Ero ero) {
190 return ((IpPrefixCase) ero.getSubobject().get(ero.getSubobject().size() - 1).getSubobjectType()).getIpPrefix()
191 .getIpPrefix().getIpv4Prefix().getValue();
194 protected Open getLocalPref() {
195 return this.localPrefs;
198 protected Open getRemotePref() {
199 return this.remotePrefs;
202 protected PCEPSessionListener getSessionListener() {
203 return this.manager.getSessionListener();
206 protected final PCEPSessionImpl getPCEPSession(final Open localOpen, final Open remoteOpen) {
207 return this.neg.createSession(this.clientListener, localOpen, remoteOpen);