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.client.mdsal;
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.mockito.ArgumentMatchers.any;
17 import static org.mockito.ArgumentMatchers.eq;
18 import static org.mockito.Mockito.doReturn;
19 import static org.mockito.Mockito.mock;
20 import static org.mockito.Mockito.when;
22 import com.google.common.util.concurrent.Futures;
23 import com.google.common.util.concurrent.ListenableFuture;
24 import java.net.InetSocketAddress;
26 import java.util.concurrent.ExecutionException;
27 import java.util.concurrent.Executors;
28 import java.util.concurrent.TimeUnit;
29 import org.junit.Before;
30 import org.junit.Ignore;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.mockito.Mock;
34 import org.mockito.junit.MockitoJUnitRunner;
35 import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
36 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
37 import org.opendaylight.mdsal.dom.api.DOMRpcService;
38 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
39 import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
40 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
41 import org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.Get;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
45 import org.opendaylight.yangtools.util.xml.UntrustedXML;
46 import org.opendaylight.yangtools.yang.common.ErrorTag;
47 import org.opendaylight.yangtools.yang.common.ErrorType;
48 import org.opendaylight.yangtools.yang.common.QName;
49 import org.opendaylight.yangtools.yang.common.RpcError;
50 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
51 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
52 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
53 import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
54 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
55 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizationResultHolder;
56 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
57 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
58 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
62 @RunWith(MockitoJUnitRunner.StrictStubs.class)
63 public class NetconfStateSchemasTest extends AbstractBaseSchemasTest {
64 private static final Logger LOG = LoggerFactory.getLogger(NetconfStateSchemasTest.class);
65 private static final NetconfSessionPreferences CAPS = NetconfSessionPreferences.fromStrings(Set.of(
66 "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04"));
68 private final RemoteDeviceId deviceId = new RemoteDeviceId("device", new InetSocketAddress(99));
69 private final int numberOfSchemas = 73;
70 private final int numberOfLegalSchemas = numberOfSchemas - 3;
72 private ContainerNode compositeNodeSchemas;
75 private DOMRpcService rpc;
77 private EffectiveModelContext modelContext;
80 public void setUp() throws Exception {
81 modelContext = BASE_SCHEMAS.baseSchemaForCapabilities(CAPS).modelContext();
83 final var resultHolder = new NormalizationResultHolder();
84 final var writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
85 final var xmlParser = XmlParserStream.create(writer,
86 SchemaInferenceStack.ofDataTreePath(modelContext, NetconfState.QNAME, Schemas.QNAME).toInference(), false);
88 xmlParser.parse(UntrustedXML.createXMLStreamReader(getClass().getResourceAsStream(
89 "/netconf-state.schemas.payload.xml")));
90 compositeNodeSchemas = (ContainerNode) resultHolder.getResult().data();
94 public void testCreate() throws Exception {
95 final var schemas = NetconfStateSchemas.create(deviceId, compositeNodeSchemas);
97 final var availableYangSchemasQNames = schemas.getAvailableYangSchemasQNames();
98 assertEquals(numberOfLegalSchemas, availableYangSchemasQNames.size());
100 assertThat(availableYangSchemasQNames,
101 hasItem(QName.create("urn:TBD:params:xml:ns:yang:network-topology", "2013-07-12", "network-topology")));
106 public void testCreate2() throws Exception {
107 final ContainerNode netconfState = ImmutableNodes.newContainerBuilder()
108 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NetconfState.QNAME))
109 .withChild(compositeNodeSchemas)
111 final ContainerNode data = ImmutableNodes.newContainerBuilder()
112 .withNodeIdentifier(NetconfMessageTransformUtil.NETCONF_DATA_NODEID)
113 .withChild(netconfState)
115 final ContainerNode rpcReply = ImmutableNodes.newContainerBuilder()
116 .withNodeIdentifier(new YangInstanceIdentifier
117 .NodeIdentifier(NetconfMessageTransformUtil.NETCONF_RPC_REPLY_QNAME))
120 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult(rpcReply))).when(rpc).invokeRpc(eq(Get.QNAME), any());
121 final NetconfStateSchemas stateSchemas = NetconfStateSchemas.create(rpc, CAPS, deviceId, modelContext);
122 final Set<QName> availableYangSchemasQNames = stateSchemas.getAvailableYangSchemasQNames();
123 assertEquals(numberOfLegalSchemas, availableYangSchemasQNames.size());
125 assertThat(availableYangSchemasQNames,
126 hasItem(QName.create("urn:TBD:params:xml:ns:yang:network-topology", "2013-07-12", "network-topology")));
130 public void testCreateMonitoringNotSupported() throws Exception {
131 final var caps = NetconfSessionPreferences.fromStrings(Set.of());
132 final var stateSchemas = NetconfStateSchemas.create(rpc, caps, deviceId, modelContext);
133 assertEquals(Set.of(), stateSchemas.getAvailableYangSchemasQNames());
137 public void testCreateFail() throws Exception {
138 when(rpc.invokeRpc(eq(Get.QNAME), any())).thenReturn(
139 Futures.immediateFailedFuture(new DOMRpcImplementationNotAvailableException("not available")));
140 final var stateSchemas = NetconfStateSchemas.create(rpc, CAPS, deviceId, modelContext);
141 assertEquals(Set.of(), stateSchemas.getAvailableYangSchemasQNames());
145 public void testCreateRpcError() throws Exception {
146 final RpcError rpcError = RpcResultBuilder.newError(ErrorType.RPC, new ErrorTag("fail"), "fail");
147 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult(rpcError))).when(rpc)
148 .invokeRpc(eq(Get.QNAME), any());
149 final var stateSchemas = NetconfStateSchemas.create(rpc, CAPS, deviceId, modelContext);
150 assertEquals(Set.of(), stateSchemas.getAvailableYangSchemasQNames());
154 public void testCreateInterrupted() {
155 //NetconfStateSchemas.create calls Thread.currentThread().interrupt(), so it must run in its own thread
156 final var testFuture = Executors.newSingleThreadExecutor().submit(() -> {
157 final ListenableFuture<DOMRpcResult> interruptedFuture = mock(ListenableFuture.class);
159 when(interruptedFuture.get()).thenThrow(new InterruptedException("interrupted"));
160 doReturn(interruptedFuture).when(rpc).invokeRpc(eq(Get.QNAME), any());
161 NetconfStateSchemas.create(rpc, CAPS, deviceId, modelContext);
162 } catch (final InterruptedException | ExecutionException e) {
163 LOG.info("Operation failed.", e);
167 assertThat(assertThrows(ExecutionException.class, () -> testFuture.get(3, TimeUnit.SECONDS)).getCause(),
168 instanceOf(RuntimeException.class));
172 public void testRemoteYangSchemaEquals() throws Exception {
173 final NetconfStateSchemas.RemoteYangSchema schema1 =
174 new NetconfStateSchemas.RemoteYangSchema(NetconfState.QNAME);
175 final NetconfStateSchemas.RemoteYangSchema schema2 =
176 new NetconfStateSchemas.RemoteYangSchema(NetconfState.QNAME);
177 final NetconfStateSchemas.RemoteYangSchema schema3 =
178 new NetconfStateSchemas.RemoteYangSchema(Schemas.QNAME);
179 assertEquals(schema1, schema2);
180 assertEquals(schema2, schema1);
181 assertNotEquals(schema1, schema3);
182 assertNotEquals(schema2, schema3);