Remove DocumentedException.ErrorSeverity
[netconf.git] / netconf / netconf-topology-singleton / src / test / java / org / opendaylight / netconf / topology / singleton / impl / netconf / ProxyNetconfServiceTest.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.netconf.topology.singleton.impl.netconf;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
14
15 import akka.actor.ActorSystem;
16 import akka.actor.Status;
17 import akka.dispatch.Futures;
18 import akka.testkit.TestProbe;
19 import akka.testkit.javadsl.TestKit;
20 import akka.util.Timeout;
21 import com.google.common.util.concurrent.ListenableFuture;
22 import java.net.InetSocketAddress;
23 import java.util.Collections;
24 import java.util.Optional;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.TimeUnit;
27 import java.util.concurrent.TimeoutException;
28 import org.junit.AfterClass;
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
32 import org.opendaylight.mdsal.common.api.ReadFailedException;
33 import org.opendaylight.netconf.api.DocumentedException;
34 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
35 import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
36 import org.opendaylight.netconf.topology.singleton.messages.netconf.CommitRequest;
37 import org.opendaylight.netconf.topology.singleton.messages.netconf.CreateEditConfigRequest;
38 import org.opendaylight.netconf.topology.singleton.messages.netconf.DeleteEditConfigRequest;
39 import org.opendaylight.netconf.topology.singleton.messages.netconf.DiscardChangesRequest;
40 import org.opendaylight.netconf.topology.singleton.messages.netconf.GetConfigRequest;
41 import org.opendaylight.netconf.topology.singleton.messages.netconf.GetRequest;
42 import org.opendaylight.netconf.topology.singleton.messages.netconf.LockRequest;
43 import org.opendaylight.netconf.topology.singleton.messages.netconf.MergeEditConfigRequest;
44 import org.opendaylight.netconf.topology.singleton.messages.netconf.RemoveEditConfigRequest;
45 import org.opendaylight.netconf.topology.singleton.messages.netconf.ReplaceEditConfigRequest;
46 import org.opendaylight.netconf.topology.singleton.messages.netconf.UnlockRequest;
47 import org.opendaylight.netconf.topology.singleton.messages.rpc.InvokeRpcMessageReply;
48 import org.opendaylight.netconf.topology.singleton.messages.transactions.EmptyReadResponse;
49 import org.opendaylight.yangtools.yang.common.ErrorSeverity;
50 import org.opendaylight.yangtools.yang.common.QName;
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.api.schema.NormalizedNode;
54 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
55
56 public class ProxyNetconfServiceTest {
57     private static final RemoteDeviceId DEVICE_ID =
58         new RemoteDeviceId("dev1", InetSocketAddress.createUnresolved("localhost", 17830));
59     private static final YangInstanceIdentifier PATH = YangInstanceIdentifier.empty();
60     private static final LogicalDatastoreType STORE = LogicalDatastoreType.CONFIGURATION;
61
62     private static ActorSystem system = ActorSystem.apply();
63     private TestProbe masterActor;
64     private ContainerNode node;
65
66     @Before
67     public void setUp() {
68         masterActor = new TestProbe(system);
69         node = Builders.containerBuilder()
70             .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create("", "cont")))
71             .build();
72     }
73
74     @AfterClass
75     public static void staticTearDown() {
76         TestKit.shutdownActorSystem(system, true);
77     }
78
79     private ProxyNetconfService newSuccessfulProxyNetconfService() {
80         return new ProxyNetconfService(DEVICE_ID, Futures.successful(masterActor.ref()),
81             system.dispatcher(), Timeout.apply(5, TimeUnit.SECONDS));
82     }
83
84     private ProxyNetconfService newSuccessfulProxyNetconfService(final Timeout timeout) {
85         return new ProxyNetconfService(DEVICE_ID, Futures.successful(masterActor.ref()),
86             system.dispatcher(), timeout);
87     }
88
89     @Test
90     public void testLock() {
91         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
92         netconf.lock();
93         masterActor.expectMsgClass(LockRequest.class);
94     }
95
96     @Test
97     public void testUnlock() {
98         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
99         netconf.unlock();
100         masterActor.expectMsgClass(UnlockRequest.class);
101     }
102
103     @Test
104     public void testDiscardChanges() {
105         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
106         netconf.discardChanges();
107         masterActor.expectMsgClass(DiscardChangesRequest.class);
108     }
109
110     @Test
111     public void testGet() throws Exception {
112         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
113         final ListenableFuture<Optional<NormalizedNode>> get = netconf.get(PATH);
114         final GetRequest getRequest = masterActor.expectMsgClass(GetRequest.class);
115         assertEquals(PATH, getRequest.getPath());
116
117         masterActor.reply(new NormalizedNodeMessage(PATH, node));
118         final Optional<NormalizedNode> result = get.get(5, TimeUnit.SECONDS);
119         assertTrue(result.isPresent());
120         assertEquals(node, result.get());
121     }
122
123     @Test
124     public void testGetFailure() throws InterruptedException, TimeoutException {
125         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
126
127         final ListenableFuture<Optional<NormalizedNode>> get = netconf.get(PATH);
128         masterActor.expectMsgClass(GetRequest.class);
129         final RuntimeException mockEx = new RuntimeException("fail");
130         masterActor.reply(new Status.Failure(mockEx));
131
132         try {
133             get.get(5, TimeUnit.SECONDS);
134             fail("Exception should be thrown");
135         } catch (final ExecutionException e) {
136             Throwable cause = e.getCause();
137             assertTrue("Unexpected cause " + cause, cause instanceof ReadFailedException);
138             assertEquals(mockEx, cause.getCause());
139         }
140     }
141
142     @Test
143     public void testGetEmpty() throws Exception {
144         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
145         final ListenableFuture<Optional<NormalizedNode>> get = netconf.get(PATH);
146         masterActor.expectMsgClass(GetRequest.class);
147         masterActor.reply(new EmptyReadResponse());
148         final Optional<NormalizedNode> result = get.get(5, TimeUnit.SECONDS);
149         assertFalse(result.isPresent());
150     }
151
152     @Test
153     public void testGetConfig() throws Exception {
154         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
155         final ListenableFuture<Optional<NormalizedNode>> getConfig = netconf.getConfig(PATH);
156         final GetConfigRequest getRequest = masterActor.expectMsgClass(GetConfigRequest.class);
157         assertEquals(PATH, getRequest.getPath());
158
159         masterActor.reply(new NormalizedNodeMessage(PATH, node));
160         final Optional<NormalizedNode> result = getConfig.get(5, TimeUnit.SECONDS);
161         assertTrue(result.isPresent());
162         assertEquals(node, result.get());
163     }
164
165     @Test
166     public void testGetConfigFailure() throws InterruptedException, TimeoutException {
167         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
168
169         final ListenableFuture<Optional<NormalizedNode>> getConfig = netconf.getConfig(PATH);
170         masterActor.expectMsgClass(GetConfigRequest.class);
171         final RuntimeException mockEx = new RuntimeException("fail");
172         masterActor.reply(new Status.Failure(mockEx));
173
174         try {
175             getConfig.get(5, TimeUnit.SECONDS);
176             fail("Exception should be thrown");
177         } catch (final ExecutionException e) {
178             Throwable cause = e.getCause();
179             assertTrue("Unexpected cause " + cause, cause instanceof ReadFailedException);
180             assertEquals(mockEx, cause.getCause());
181         }
182     }
183
184     @Test
185     public void testGetConfigEmpty() throws Exception {
186         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
187         final ListenableFuture<Optional<NormalizedNode>> getConfig = netconf.getConfig(PATH);
188         masterActor.expectMsgClass(GetConfigRequest.class);
189         masterActor.reply(new EmptyReadResponse());
190         final Optional<NormalizedNode> result = getConfig.get(5, TimeUnit.SECONDS);
191         assertFalse(result.isPresent());
192     }
193
194     @Test
195     public void testMerge() {
196         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
197         netconf.merge(STORE, PATH, node, Optional.empty());
198         final MergeEditConfigRequest mergeRequest = masterActor.expectMsgClass(MergeEditConfigRequest.class);
199         assertEquals(STORE, mergeRequest.getStore());
200         assertEquals(PATH, mergeRequest.getNormalizedNodeMessage().getIdentifier());
201         assertEquals(node, mergeRequest.getNormalizedNodeMessage().getNode());
202     }
203
204     @Test
205     public void testReplace() {
206         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
207         netconf.replace(STORE, PATH, node, Optional.empty());
208         final ReplaceEditConfigRequest replaceRequest = masterActor.expectMsgClass(ReplaceEditConfigRequest.class);
209         assertEquals(STORE, replaceRequest.getStore());
210         assertEquals(PATH, replaceRequest.getNormalizedNodeMessage().getIdentifier());
211         assertEquals(node, replaceRequest.getNormalizedNodeMessage().getNode());
212     }
213
214     @Test
215     public void testCreate() {
216         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
217         netconf.create(STORE, PATH, node, Optional.empty());
218         final CreateEditConfigRequest createRequest = masterActor.expectMsgClass(CreateEditConfigRequest.class);
219         assertEquals(STORE, createRequest.getStore());
220         assertEquals(PATH, createRequest.getNormalizedNodeMessage().getIdentifier());
221         assertEquals(node, createRequest.getNormalizedNodeMessage().getNode());
222     }
223
224     @Test
225     public void testDelete() {
226         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
227         netconf.delete(STORE, PATH);
228         final DeleteEditConfigRequest deleteRequest = masterActor.expectMsgClass(DeleteEditConfigRequest.class);
229         assertEquals(STORE, deleteRequest.getStore());
230         assertEquals(PATH, deleteRequest.getPath());
231     }
232
233     @Test
234     public void testRemove() {
235         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
236         netconf.remove(STORE, PATH);
237         final RemoveEditConfigRequest removeRequest = masterActor.expectMsgClass(RemoveEditConfigRequest.class);
238         assertEquals(STORE, removeRequest.getStore());
239         assertEquals(PATH, removeRequest.getPath());
240     }
241
242     @Test
243     public void testCommit() throws InterruptedException, ExecutionException, TimeoutException {
244         ProxyNetconfService netconf = newSuccessfulProxyNetconfService();
245         commit(netconf);
246     }
247
248     @Test
249     public void testFutureOperationsWithMasterDown() throws InterruptedException, TimeoutException {
250         ProxyNetconfService netconf = newSuccessfulProxyNetconfService(
251             Timeout.apply(500, TimeUnit.MILLISECONDS));
252
253         ListenableFuture<?> future = netconf.get(PATH);
254         masterActor.expectMsgClass(GetRequest.class);
255
256         // master doesn't reply
257         try {
258             future.get(5, TimeUnit.SECONDS);
259             fail("Exception should be thrown");
260         } catch (final ExecutionException e) {
261             Throwable cause = e.getCause();
262             assertTrue("Unexpected cause " + cause, cause instanceof ReadFailedException);
263             verifyDocumentedException(cause.getCause());
264         }
265
266         future = netconf.getConfig(PATH);
267         masterActor.expectMsgClass(GetConfigRequest.class);
268
269         // master doesn't reply
270         try {
271             future.get(5, TimeUnit.SECONDS);
272             fail("Exception should be thrown");
273         } catch (final ExecutionException e) {
274             Throwable cause = e.getCause();
275             assertTrue("Unexpected cause " + cause, cause instanceof ReadFailedException);
276             verifyDocumentedException(cause.getCause());
277         }
278
279         future = netconf.commit();
280         masterActor.expectMsgClass(CommitRequest.class);
281
282         // master doesn't reply
283         try {
284             future.get(5, TimeUnit.SECONDS);
285             fail("Exception should be thrown");
286         } catch (final ExecutionException e) {
287             Throwable cause = e.getCause();
288             assertTrue("Unexpected cause " + cause, cause instanceof NetconfServiceFailedException);
289             verifyDocumentedException(cause.getCause());
290         }
291     }
292
293     private void commit(final ProxyNetconfService netconf)
294         throws InterruptedException, ExecutionException, TimeoutException {
295         final ListenableFuture<?> submit = netconf.commit();
296         masterActor.expectMsgClass(CommitRequest.class);
297         masterActor.reply(new InvokeRpcMessageReply(null, Collections.emptyList()));
298         submit.get(5, TimeUnit.SECONDS);
299     }
300
301     private static void verifyDocumentedException(final Throwable cause) {
302         assertTrue("Unexpected cause " + cause, cause instanceof DocumentedException);
303         final DocumentedException de = (DocumentedException) cause;
304         assertEquals(ErrorSeverity.WARNING, de.getErrorSeverity());
305         assertEquals(DocumentedException.ErrorTag.OPERATION_FAILED, de.getErrorTag());
306         assertEquals(DocumentedException.ErrorType.APPLICATION, de.getErrorType());
307     }
308 }