2 * Copyright (c) 2014, 2015 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
8 package org.opendaylight.netconf.sal.connect.netconf;
10 import static org.hamcrest.CoreMatchers.hasItem;
11 import static org.hamcrest.CoreMatchers.instanceOf;
12 import static org.hamcrest.MatcherAssert.assertThat;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertNotEquals;
15 import static org.junit.Assert.assertThrows;
16 import static org.junit.Assert.assertTrue;
17 import static org.mockito.ArgumentMatchers.any;
18 import static org.mockito.ArgumentMatchers.eq;
19 import static org.mockito.Mockito.doReturn;
20 import static org.mockito.Mockito.mock;
21 import static org.mockito.Mockito.when;
22 import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_QNAME;
24 import com.google.common.util.concurrent.Futures;
25 import com.google.common.util.concurrent.ListenableFuture;
26 import java.net.InetSocketAddress;
28 import java.util.concurrent.ExecutionException;
29 import java.util.concurrent.Executors;
30 import java.util.concurrent.Future;
31 import java.util.concurrent.TimeUnit;
32 import org.junit.Before;
33 import org.junit.Ignore;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.mockito.Mock;
37 import org.mockito.junit.MockitoJUnitRunner;
38 import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
39 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
40 import org.opendaylight.mdsal.dom.api.DOMRpcService;
41 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
42 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceId;
43 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
44 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
47 import org.opendaylight.yangtools.util.xml.UntrustedXML;
48 import org.opendaylight.yangtools.yang.common.ErrorTag;
49 import org.opendaylight.yangtools.yang.common.ErrorType;
50 import org.opendaylight.yangtools.yang.common.QName;
51 import org.opendaylight.yangtools.yang.common.RpcError;
52 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
53 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
54 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
55 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
56 import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
57 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
58 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
59 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
60 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
61 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
65 @RunWith(MockitoJUnitRunner.StrictStubs.class)
66 public class NetconfStateSchemasTest extends AbstractBaseSchemasTest {
68 private static final Logger LOG = LoggerFactory.getLogger(NetconfStateSchemasTest.class);
70 private static final NetconfSessionPreferences CAPS = NetconfSessionPreferences.fromStrings(Set.of(
71 "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04"));
72 private final RemoteDeviceId deviceId = new RemoteDeviceId("device", new InetSocketAddress(99));
73 private final int numberOfSchemas = 73;
74 private final int numberOfLegalSchemas = numberOfSchemas - 3;
75 private ContainerNode compositeNodeSchemas;
78 private DOMRpcService rpc;
80 private EffectiveModelContext schemaContext;
83 public void setUp() throws Exception {
84 schemaContext = BASE_SCHEMAS.getBaseSchemaWithNotifications().getEffectiveModelContext();
86 final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
87 final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
88 final XmlParserStream xmlParser = XmlParserStream.create(writer,
89 SchemaInferenceStack.ofDataTreePath(schemaContext, NetconfState.QNAME, Schemas.QNAME).toInference(), false);
91 xmlParser.parse(UntrustedXML.createXMLStreamReader(getClass().getResourceAsStream(
92 "/netconf-state.schemas.payload.xml")));
93 compositeNodeSchemas = (ContainerNode) resultHolder.getResult();
97 public void testCreate() throws Exception {
98 final NetconfStateSchemas schemas = NetconfStateSchemas.create(deviceId, compositeNodeSchemas);
100 final Set<QName> availableYangSchemasQNames = schemas.getAvailableYangSchemasQNames();
101 assertEquals(numberOfLegalSchemas, availableYangSchemasQNames.size());
103 assertThat(availableYangSchemasQNames,
104 hasItem(QName.create("urn:TBD:params:xml:ns:yang:network-topology", "2013-07-12", "network-topology")));
109 public void testCreate2() throws Exception {
110 final ContainerNode netconfState = Builders.containerBuilder()
111 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NetconfState.QNAME))
112 .withChild(compositeNodeSchemas)
114 final ContainerNode data = Builders.containerBuilder()
115 .withNodeIdentifier(NetconfMessageTransformUtil.NETCONF_DATA_NODEID)
116 .withChild(netconfState)
118 final ContainerNode rpcReply = Builders.containerBuilder()
119 .withNodeIdentifier(new YangInstanceIdentifier
120 .NodeIdentifier(NetconfMessageTransformUtil.NETCONF_RPC_REPLY_QNAME))
123 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult(rpcReply))).when(rpc)
124 .invokeRpc(eq(NETCONF_GET_QNAME), any());
125 final NetconfStateSchemas stateSchemas = NetconfStateSchemas.create(rpc, CAPS, deviceId, schemaContext);
126 final Set<QName> availableYangSchemasQNames = stateSchemas.getAvailableYangSchemasQNames();
127 assertEquals(numberOfLegalSchemas, availableYangSchemasQNames.size());
129 assertThat(availableYangSchemasQNames,
130 hasItem(QName.create("urn:TBD:params:xml:ns:yang:network-topology", "2013-07-12", "network-topology")));
134 public void testCreateMonitoringNotSupported() throws Exception {
135 final NetconfSessionPreferences caps = NetconfSessionPreferences.fromStrings(Set.of());
136 final NetconfStateSchemas stateSchemas = NetconfStateSchemas.create(rpc, caps, deviceId, schemaContext);
137 final Set<QName> availableYangSchemasQNames = stateSchemas.getAvailableYangSchemasQNames();
138 assertTrue(availableYangSchemasQNames.isEmpty());
142 public void testCreateFail() throws Exception {
143 when(rpc.invokeRpc(eq(NETCONF_GET_QNAME), any())).thenReturn(
144 Futures.immediateFailedFuture(new DOMRpcImplementationNotAvailableException("not available")));
145 final NetconfStateSchemas stateSchemas = NetconfStateSchemas.create(rpc, CAPS, deviceId, schemaContext);
146 final Set<QName> availableYangSchemasQNames = stateSchemas.getAvailableYangSchemasQNames();
147 assertTrue(availableYangSchemasQNames.isEmpty());
151 public void testCreateRpcError() throws Exception {
152 final RpcError rpcError = RpcResultBuilder.newError(ErrorType.RPC, new ErrorTag("fail"), "fail");
153 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult(rpcError))).when(rpc)
154 .invokeRpc(eq(NETCONF_GET_QNAME), any());
155 final NetconfStateSchemas stateSchemas = NetconfStateSchemas.create(rpc, CAPS, deviceId, schemaContext);
156 final Set<QName> availableYangSchemasQNames = stateSchemas.getAvailableYangSchemasQNames();
157 assertTrue(availableYangSchemasQNames.isEmpty());
161 public void testCreateInterrupted() {
162 //NetconfStateSchemas.create calls Thread.currentThread().interrupt(), so it must run in its own thread
163 final Future<?> testFuture = Executors.newSingleThreadExecutor().submit(() -> {
164 final ListenableFuture<DOMRpcResult> interruptedFuture = mock(ListenableFuture.class);
166 when(interruptedFuture.get()).thenThrow(new InterruptedException("interrupted"));
167 doReturn(interruptedFuture).when(rpc).invokeRpc(eq(NETCONF_GET_QNAME), any());
168 NetconfStateSchemas.create(rpc, CAPS, deviceId, schemaContext);
169 } catch (final InterruptedException | ExecutionException e) {
170 LOG.info("Operation failed.", e);
174 assertThat(assertThrows(ExecutionException.class, () -> testFuture.get(3, TimeUnit.SECONDS)).getCause(),
175 instanceOf(RuntimeException.class));
179 public void testRemoteYangSchemaEquals() throws Exception {
180 final NetconfStateSchemas.RemoteYangSchema schema1 =
181 new NetconfStateSchemas.RemoteYangSchema(NetconfState.QNAME);
182 final NetconfStateSchemas.RemoteYangSchema schema2 =
183 new NetconfStateSchemas.RemoteYangSchema(NetconfState.QNAME);
184 final NetconfStateSchemas.RemoteYangSchema schema3 =
185 new NetconfStateSchemas.RemoteYangSchema(Schemas.QNAME);
186 assertEquals(schema1, schema2);
187 assertEquals(schema2, schema1);
188 assertNotEquals(schema1, schema3);
189 assertNotEquals(schema2, schema3);