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.netconf.sal.connect.netconf.sal;
11 import static org.junit.Assert.assertEquals;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.ArgumentMatchers.eq;
14 import static org.mockito.ArgumentMatchers.isNull;
15 import static org.mockito.Mockito.doNothing;
16 import static org.mockito.Mockito.doReturn;
17 import static org.mockito.Mockito.mock;
18 import static org.mockito.Mockito.times;
19 import static org.mockito.Mockito.verify;
21 import java.net.InetSocketAddress;
22 import java.util.List;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.junit.runner.RunWith;
26 import org.mockito.ArgumentCaptor;
27 import org.mockito.Captor;
28 import org.mockito.Mock;
29 import org.mockito.junit.MockitoJUnitRunner;
30 import org.opendaylight.mdsal.binding.api.DataBroker;
31 import org.opendaylight.mdsal.binding.api.TransactionChain;
32 import org.opendaylight.mdsal.binding.api.WriteTransaction;
33 import org.opendaylight.mdsal.common.api.CommitInfo;
34 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
35 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
36 import org.opendaylight.mdsal.dom.api.DOMNotification;
37 import org.opendaylight.mdsal.dom.api.DOMRpcService;
38 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
39 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
40 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
41 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
44 import org.opendaylight.yangtools.rfc8528.data.util.EmptyMountPointContext;
45 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
47 @RunWith(MockitoJUnitRunner.StrictStubs.class)
48 public class NetconfDeviceSalFacadeTest {
49 private final RemoteDeviceId remoteDeviceId = new RemoteDeviceId("test", new InetSocketAddress("127.0.0.1", 8000));
52 private NetconfDeviceSalProvider.MountInstance mountInstance;
54 private NetconfDeviceSalProvider salProvider;
56 private DataBroker dataBroker;
58 private TransactionChain txChain;
60 private WriteTransaction tx;
62 private ArgumentCaptor<NetconfNode> nodeCaptor;
64 private NetconfDeviceSalFacade deviceFacade;
67 public void setUp() throws Exception {
68 doReturn(txChain).when(dataBroker).createMergingTransactionChain(any());
69 doReturn(tx).when(txChain).newWriteOnlyTransaction();
70 doNothing().when(tx).mergeParentStructurePut(eq(LogicalDatastoreType.OPERATIONAL),
71 eq(remoteDeviceId.getTopologyBindingPath().augmentation(NetconfNode.class)), nodeCaptor.capture());
72 doReturn(CommitInfo.emptyFluentFuture()).when(tx).commit();
74 final NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(dataBroker, remoteDeviceId);
76 deviceFacade = new NetconfDeviceSalFacade(remoteDeviceId, salProvider, dataBroker, "mockTopo");
78 doReturn(adapter).when(salProvider).getTopologyDatastoreAdapter();
80 doReturn(mountInstance).when(salProvider).getMountInstance();
81 doNothing().when(mountInstance).onTopologyDeviceDisconnected();
85 public void testOnDeviceDisconnected() {
86 deviceFacade.onDeviceDisconnected();
88 verifyConnectionStatusUpdate(ConnectionStatus.Connecting);
89 verify(mountInstance, times(1)).onTopologyDeviceDisconnected();
93 public void testOnDeviceFailed() {
94 final Throwable throwable = new Throwable();
95 deviceFacade.onDeviceFailed(throwable);
97 verifyConnectionStatusUpdate(ConnectionStatus.UnableToConnect);
98 verify(mountInstance, times(1)).onTopologyDeviceDisconnected();
102 public void testOnDeviceClose() throws Exception {
103 deviceFacade.close();
104 verify(salProvider).close();
108 public void testOnDeviceConnected() {
109 final EffectiveModelContext schemaContext = mock(EffectiveModelContext.class);
111 final var netconfSessionPreferences = NetconfSessionPreferences.fromStrings(
112 List.of(NetconfMessageTransformUtil.NETCONF_CANDIDATE_URI.toString()));
114 final DOMRpcService deviceRpc = mock(DOMRpcService.class);
115 deviceFacade.onDeviceConnected(new EmptyMountPointContext(schemaContext), netconfSessionPreferences, deviceRpc,
117 verifyConnectionStatusUpdate(ConnectionStatus.Connected);
118 verify(mountInstance, times(1)).onTopologyDeviceConnected(eq(schemaContext),
119 any(DOMDataBroker.class), any(NetconfDataTreeService.class), eq(deviceRpc),
120 any(NetconfDeviceNotificationService.class), isNull());
124 public void testOnDeviceNotification() throws Exception {
125 final DOMNotification domNotification = mock(DOMNotification.class);
126 deviceFacade.onNotification(domNotification);
127 verify(mountInstance).publish(domNotification);
130 private void verifyConnectionStatusUpdate(final ConnectionStatus expectedStatus) {
131 verify(tx).mergeParentStructurePut(eq(LogicalDatastoreType.OPERATIONAL),
132 eq(remoteDeviceId.getTopologyBindingPath().augmentation(NetconfNode.class)), any());
133 assertEquals(expectedStatus, nodeCaptor.getValue().getConnectionStatus());