2 * Copyright (c) 2019 Lumina Networks, 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
8 package org.opendaylight.bgpcep.pcep.topology.provider;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.Mockito.doNothing;
14 import static org.mockito.Mockito.doReturn;
16 import java.util.List;
18 import org.junit.After;
19 import org.junit.Before;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22 import org.mockito.Mock;
23 import org.mockito.junit.MockitoJUnitRunner;
24 import org.opendaylight.mdsal.binding.api.RpcProviderService;
25 import org.opendaylight.mdsal.binding.api.WriteTransaction;
26 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractConcurrentDataBrokerTest;
27 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.PcepEntityIdRpcAugBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.PcepEntityIdStatsAugBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulCapabilitiesRpcAugBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulCapabilitiesStatsAugBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulMessagesRpcAug;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulMessagesRpcAugBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulMessagesStatsAug;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulMessagesStatsAugBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.error.messages.grouping.ErrorMessages;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.error.messages.grouping.ErrorMessagesBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPref;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPrefBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.Messages;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.MessagesBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerCapabilities;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerCapabilitiesBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerPrefBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.grouping.PcepSessionState;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.grouping.PcepSessionStateBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.reply.time.grouping.ReplyTime;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.reply.time.grouping.ReplyTimeBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321.GetStatsInput;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321.GetStatsInputBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321.GetStatsOutput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321.GetStatsOutputBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.stats.rev181109.PcepTopologyNodeStatsAugBuilder;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
59 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
60 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
61 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
62 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
63 import org.opendaylight.yangtools.concepts.Registration;
64 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
65 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
66 import org.opendaylight.yangtools.yang.common.RpcResult;
67 import org.opendaylight.yangtools.yang.common.Uint16;
68 import org.opendaylight.yangtools.yang.common.Uint32;
69 import org.opendaylight.yangtools.yang.common.Uint8;
71 @RunWith(MockitoJUnitRunner.StrictStubs.class)
72 public class TopologyStatsRpcTest extends AbstractConcurrentDataBrokerTest {
73 private static final String TOPOLOGY_ID1 = "pcep-topology-1";
74 private static final String TOPOLOGY_ID2 = "pcep-topology-2";
75 private static final String NONEXISTENT_TOPOLOGY = "nonexistent-topology";
76 private static final String NONPCEP_TOPOLOGY = "nonpcep-topology";
77 private static final String NODE_ID1 = "pcc://1.1.1.1";
78 private static final String NODE_ID2 = "pcc://2.2.2.2";
79 private static final String NODE_ID3 = "pcc://3.3.3.3";
80 private static final String NONEXISTENT_NODE = "pcc://4.4.4.4";
81 private static final String NONPCEP_NODE = "nonpcep-node";
84 private RpcProviderService rpcProviderService;
86 private Registration rpcReg;
88 TopologyStatsRpc rpcService;
91 public void setUp() throws Exception {
92 doReturn(rpcReg).when(rpcProviderService).registerRpcImplementation(any());
93 doNothing().when(rpcReg).close();
94 rpcService = new TopologyStatsRpc(getDataBroker(), rpcProviderService);
96 // PCEP topology with one PCC node
97 final Topology t1 = createTopology(TOPOLOGY_ID1, BindingMap.of(createPcepNode(NODE_ID1)));
99 // PCEP topology with two PCC node
101 createTopology(TOPOLOGY_ID2, BindingMap.of(createPcepNode(NODE_ID2), createPcepNode(NODE_ID3)));
103 // Non-PCEP topology with one non-PCC node
104 final Topology t3 = createTopology(NONPCEP_TOPOLOGY,
105 BindingMap.of(new NodeBuilder().setNodeId(new NodeId(NONPCEP_NODE)).build()));
107 final WriteTransaction wtx = getDataBroker().newWriteOnlyTransaction();
108 final NetworkTopologyBuilder ntb = new NetworkTopologyBuilder();
109 ntb.setTopology(BindingMap.of(t1, t2, t3));
110 wtx.put(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(NetworkTopology.class).build(),
115 private static Topology createTopology(final String topologyId, final Map<NodeKey, Node> nodes) {
116 return new TopologyBuilder().setTopologyId(new TopologyId(topologyId)).setNode(nodes).build();
119 private static Node createPcepNode(final String nodeId) {
120 return new NodeBuilder()
121 .setNodeId(new NodeId(nodeId))
122 .addAugmentation(new PcepTopologyNodeStatsAugBuilder()
123 .setPcepSessionState(createTopologySessionState())
128 private static PcepSessionState createTopologySessionState() {
129 final ReplyTime replyTime = new ReplyTimeBuilder()
130 .setAverageTime(Uint32.ONE)
131 .setMaxTime(Uint32.valueOf(3))
132 .setMinTime(Uint32.TWO)
135 final ErrorMessages errorMsg = new ErrorMessagesBuilder()
136 .setReceivedErrorMsgCount(Uint32.ONE)
137 .setSentErrorMsgCount(Uint32.valueOf(2))
140 final StatefulMessagesStatsAug statefulMsg = new StatefulMessagesStatsAugBuilder()
141 .setLastReceivedRptMsgTimestamp(Uint32.valueOf(1553183614L))
142 .setSentUpdMsgCount(Uint32.ONE)
143 .setReceivedRptMsgCount(Uint32.TWO)
144 .setSentInitMsgCount(Uint32.valueOf(3))
147 final Messages messages = new MessagesBuilder()
148 .setLastSentMsgTimestamp(Uint32.valueOf(1553183734L))
149 .setUnknownMsgReceived(Uint16.ONE)
150 .setSentMsgCount(Uint32.valueOf(5))
151 .setReceivedMsgCount(Uint32.valueOf(4))
152 .setReplyTime(replyTime)
153 .setErrorMessages(errorMsg)
154 .addAugmentation(statefulMsg).build();
156 final PeerCapabilities capabilities = new PeerCapabilitiesBuilder()
157 .addAugmentation(new StatefulCapabilitiesStatsAugBuilder()
159 .setInstantiation(true)
164 final LocalPref localPref = new LocalPrefBuilder()
165 .setKeepalive(Uint8.valueOf(30))
166 .setDeadtimer(Uint8.valueOf(120))
167 .setIpAddress("127.0.0.1")
168 .setSessionId(Uint16.ZERO)
169 .addAugmentation(new PcepEntityIdStatsAugBuilder()
170 .setSpeakerEntityIdValue(new byte[] {0x01, 0x02, 0x03, 0x04})
174 return new PcepSessionStateBuilder().setSynchronized(true).setSessionDuration("0:00:05:18")
175 .setDelegatedLspsCount(Uint16.ONE).setLocalPref(localPref)
176 .setPeerPref(new PeerPrefBuilder(localPref).build())
177 .setPeerCapabilities(capabilities).setMessages(messages).build();
180 private static PcepSessionState createRpcSessionState() {
181 final ReplyTime replyTime = new ReplyTimeBuilder()
182 .setAverageTime(Uint32.ONE)
183 .setMaxTime(Uint32.valueOf(3))
184 .setMinTime(Uint32.TWO)
187 final ErrorMessages errorMsg = new ErrorMessagesBuilder()
188 .setReceivedErrorMsgCount(Uint32.ONE).setSentErrorMsgCount(Uint32.TWO).build();
190 final StatefulMessagesRpcAug statefulMsg = new StatefulMessagesRpcAugBuilder()
191 .setLastReceivedRptMsgTimestamp(Uint32.valueOf(1553183614L))
192 .setSentUpdMsgCount(Uint32.ONE)
193 .setReceivedRptMsgCount(Uint32.TWO)
194 .setSentInitMsgCount(Uint32.valueOf(3))
197 final Messages messages = new MessagesBuilder()
198 .setLastSentMsgTimestamp(Uint32.valueOf(1553183734L))
199 .setUnknownMsgReceived(Uint16.ONE)
200 .setSentMsgCount(Uint32.valueOf(5))
201 .setReceivedMsgCount(Uint32.valueOf(4))
202 .setReplyTime(replyTime)
203 .setErrorMessages(errorMsg)
204 .addAugmentation(statefulMsg).build();
206 final PeerCapabilities capabilities = new PeerCapabilitiesBuilder()
207 .addAugmentation(new StatefulCapabilitiesRpcAugBuilder()
208 .setStateful(true).setInstantiation(true).setActive(true).build())
211 final LocalPref localPref = new LocalPrefBuilder()
212 .setKeepalive(Uint8.valueOf(30))
213 .setDeadtimer(Uint8.valueOf(120))
214 .setIpAddress("127.0.0.1")
215 .setSessionId(Uint16.ZERO)
216 .addAugmentation(new PcepEntityIdRpcAugBuilder()
217 .setSpeakerEntityIdValue(new byte[] {0x01, 0x02, 0x03, 0x04})
221 return new PcepSessionStateBuilder().setSynchronized(true).setSessionDuration("0:00:05:18")
222 .setDelegatedLspsCount(Uint16.ONE).setLocalPref(localPref)
223 .setPeerPref(new PeerPrefBuilder(localPref).build())
224 .setPeerCapabilities(capabilities).setMessages(messages)
229 public void testGetStatsNoMatch() throws Exception {
233 // Non-existing topology
234 in = createGetStatsInput(NONEXISTENT_TOPOLOGY, null);
235 out = createGetStatsOutput(NONEXISTENT_TOPOLOGY, List.of(), null);
236 performTest(in, out);
239 in = createGetStatsInput(TOPOLOGY_ID1, List.of(NONEXISTENT_NODE));
240 out = createGetStatsOutput(TOPOLOGY_ID1, List.of(NONEXISTENT_NODE), null);
241 performTest(in, out);
244 in = createGetStatsInput(NONPCEP_TOPOLOGY, List.of(NONPCEP_NODE));
245 out = createGetStatsOutput(NONPCEP_TOPOLOGY, List.of(NONPCEP_NODE), null);
246 performTest(in, out);
250 public void testGetStatsPartialMatch() throws Exception {
254 // Match one PCEP topology
255 in = createGetStatsInput(TOPOLOGY_ID1, null);
256 out = createGetStatsOutput(TOPOLOGY_ID1, List.of(NODE_ID1), createRpcSessionState());
257 performTest(in, out);
259 // Match one PCEP node in one topology
260 in = createGetStatsInput(TOPOLOGY_ID2, List.of(NODE_ID3));
261 out = createGetStatsOutput(TOPOLOGY_ID2, List.of(NODE_ID3), createRpcSessionState());
262 performTest(in, out);
264 // Match two PCEP nodes in one topology
265 in = createGetStatsInput(TOPOLOGY_ID2, List.of(NODE_ID2, NODE_ID3));
266 out = createGetStatsOutput(TOPOLOGY_ID2, List.of(NODE_ID2, NODE_ID3), createRpcSessionState());
267 performCountTest(in, out);
271 public void testGetStatsAllMatch() throws Exception {
274 final var ot1 = createGetStatsOutput(TOPOLOGY_ID1, List.of(NODE_ID1), createRpcSessionState())
275 .getTopology().values() .iterator().next();
276 final var ot2 = createGetStatsOutput(TOPOLOGY_ID2, List.of(NODE_ID2, NODE_ID3), createRpcSessionState())
277 .getTopology().values().iterator().next();
278 final GetStatsOutput out = new GetStatsOutputBuilder().setTopology(BindingMap.of(ot1, ot2)).build();
280 // Implicitly match all PCEP topologies and nodes
281 in = createGetStatsInput(null, null);
282 performCountTest(in, out);
284 // Explicitly match all PCEP topologies and nodes
285 final var it1 = createGetStatsInput(TOPOLOGY_ID1, List.of(NODE_ID1)).getTopology().values()
287 final var it2 = createGetStatsInput(TOPOLOGY_ID2, List.of(NODE_ID2, NODE_ID3)).getTopology().values()
289 in = new GetStatsInputBuilder().setTopology(BindingMap.of(it1, it2)).build();
290 performCountTest(in, out);
293 private void performTest(final GetStatsInput in, final GetStatsOutput out) throws Exception {
294 final RpcResult<GetStatsOutput> result = rpcService.getStats(in).get();
295 assertEquals(out, result.getResult());
296 assertTrue(result.isSuccessful());
297 assertTrue(result.getErrors().isEmpty());
301 * When topology and/or node list is expected to contain more than one item,
302 * direct comparison will fail due to potential list ordering differences. So
303 * just compare the number of nodes
305 private void performCountTest(final GetStatsInput in, final GetStatsOutput out) throws Exception {
306 final RpcResult<GetStatsOutput> result = rpcService.getStats(in).get();
307 assertEquals(result.getResult().getTopology().size(), out.getTopology().size());
308 assertTrue(result.isSuccessful());
309 assertEquals(result.getResult().nonnullTopology().values().stream()
310 .flatMap(t -> t.nonnullNode().values().stream()).count(),
311 out.nonnullTopology().values().stream().flatMap(t -> t.nonnullNode().values().stream()).count());
312 assertTrue(result.isSuccessful());
313 assertTrue(result.getErrors().isEmpty());
316 private static GetStatsInput createGetStatsInput(final String topologyId, final List<String> nodeIds) {
318 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321
319 .get.stats.input.topology.NodeKey,
320 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321
321 .get.stats.input.topology.Node> nodes;
322 if (nodeIds != null) {
323 nodes = nodeIds.stream()
324 .map(nodeId -> new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology
325 .stats.rpc.rev190321.get.stats.input.topology.NodeBuilder()
326 .setNodeId(new NodeId(nodeId))
328 .collect(BindingMap.toOrderedMap());
332 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321.get
333 .stats.input.Topology topology;
334 if (topologyId != null) {
335 topology = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc
336 .rev190321.get.stats.input.TopologyBuilder()
337 .setTopologyId(new TopologyId(topologyId))
343 return new GetStatsInputBuilder().setTopology(topology != null ? BindingMap.of(topology) : null).build();
346 private static GetStatsOutput createGetStatsOutput(final String topologyId, final List<String> nodeIds,
347 final PcepSessionState state) {
349 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321
350 .get.stats.output.topology.NodeKey,
351 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321
352 .get.stats.output.topology.Node> nodes;
353 if (nodeIds != null) {
354 nodes = nodeIds.stream()
355 .map(nodeId -> new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology
356 .stats.rpc.rev190321.get.stats.output.topology.NodeBuilder()
357 .setNodeId(new NodeId(nodeId))
358 .setPcepSessionState(state)
360 .collect(BindingMap.toOrderedMap());
364 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321.get
365 .stats.output.Topology topology;
366 if (topologyId != null) {
367 topology = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc
368 .rev190321.get.stats.output.TopologyBuilder()
369 .setTopologyId(new TopologyId(topologyId))
375 return new GetStatsOutputBuilder().setTopology(topology != null ? BindingMap.of(topology) : null).build();
379 public void tearDown() {