54b887cbb8319c7fe5f14a3ac4c36867bcc61db6
[netconf.git] / netconf / netconf-topology-singleton / src / test / java / org / opendaylight / netconf / topology / singleton / impl / tx / ProxyReadWriteTransactionTest.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies 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
9 package org.opendaylight.netconf.topology.singleton.impl.tx;
10
11 import akka.actor.ActorSystem;
12 import akka.testkit.JavaTestKit;
13 import akka.testkit.TestProbe;
14 import akka.util.Timeout;
15 import com.google.common.base.Optional;
16 import com.google.common.util.concurrent.CheckedFuture;
17 import java.net.InetSocketAddress;
18 import java.util.concurrent.Executors;
19 import java.util.concurrent.Future;
20 import java.util.concurrent.TimeUnit;
21 import org.junit.After;
22 import org.junit.Assert;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
27 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
28 import org.opendaylight.netconf.api.DocumentedException;
29 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
30 import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
31 import org.opendaylight.netconf.topology.singleton.messages.transactions.CancelRequest;
32 import org.opendaylight.netconf.topology.singleton.messages.transactions.DeleteRequest;
33 import org.opendaylight.netconf.topology.singleton.messages.transactions.EmptyReadResponse;
34 import org.opendaylight.netconf.topology.singleton.messages.transactions.ExistsRequest;
35 import org.opendaylight.netconf.topology.singleton.messages.transactions.MergeRequest;
36 import org.opendaylight.netconf.topology.singleton.messages.transactions.PutRequest;
37 import org.opendaylight.netconf.topology.singleton.messages.transactions.ReadRequest;
38 import org.opendaylight.netconf.topology.singleton.messages.transactions.SubmitReply;
39 import org.opendaylight.netconf.topology.singleton.messages.transactions.SubmitRequest;
40 import org.opendaylight.yangtools.yang.common.QName;
41 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
42 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
43 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
44 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
45
46 public class ProxyReadWriteTransactionTest {
47     private static final YangInstanceIdentifier PATH = YangInstanceIdentifier.EMPTY;
48     private static final LogicalDatastoreType STORE = LogicalDatastoreType.CONFIGURATION;
49
50     private ActorSystem system;
51     private TestProbe masterActor;
52     private ContainerNode node;
53     private ProxyReadWriteTransaction tx;
54
55     @Before
56     public void setUp() throws Exception {
57         system = ActorSystem.apply();
58         masterActor = new TestProbe(system);
59         final RemoteDeviceId id = new RemoteDeviceId("dev1", InetSocketAddress.createUnresolved("localhost", 17830));
60         node = Builders.containerBuilder()
61                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create("", "cont")))
62                 .build();
63         tx = new ProxyReadWriteTransaction(masterActor.ref(), id, system, Timeout.apply(5, TimeUnit.SECONDS));
64     }
65
66     @After
67     public void tearDown() throws Exception {
68         JavaTestKit.shutdownActorSystem(system, null, true);
69     }
70
71     @Test
72     public void testCancel() throws Exception {
73         final Future<Boolean> submit = Executors.newSingleThreadExecutor().submit(() -> tx.cancel());
74         masterActor.expectMsgClass(CancelRequest.class);
75         masterActor.reply(true);
76         Assert.assertTrue(submit.get());
77     }
78
79     @Test
80     public void testCancelSubmitted() throws Exception {
81         final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = tx.submit();
82         masterActor.expectMsgClass(SubmitRequest.class);
83         masterActor.reply(new SubmitReply());
84         submitFuture.checkedGet();
85         final Future<Boolean> submit = Executors.newSingleThreadExecutor().submit(() -> tx.cancel());
86         masterActor.expectNoMsg();
87         Assert.assertFalse(submit.get());
88     }
89
90     @Test
91     public void testSubmit() throws Exception {
92         final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = tx.submit();
93         masterActor.expectMsgClass(SubmitRequest.class);
94         masterActor.reply(new SubmitReply());
95         submitFuture.checkedGet();
96     }
97
98     @Test
99     public void testDoubleSubmit() throws Exception {
100         final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = tx.submit();
101         masterActor.expectMsgClass(SubmitRequest.class);
102         masterActor.reply(new SubmitReply());
103         submitFuture.checkedGet();
104         try {
105             tx.submit().checkedGet();
106             Assert.fail("Should throw IllegalStateException");
107         } catch (final IllegalStateException e) {
108             masterActor.expectNoMsg();
109         }
110     }
111
112     @Test
113     public void testDelete() throws Exception {
114         tx.delete(STORE, PATH);
115         masterActor.expectMsgClass(DeleteRequest.class);
116     }
117
118     @Test
119     public void testDeleteClosed() throws Exception {
120         submit();
121         try {
122             tx.delete(STORE, PATH);
123             Assert.fail("Should throw IllegalStateException");
124         } catch (final IllegalStateException e) {
125             masterActor.expectNoMsg();
126         }
127     }
128
129     @Test
130     public void testPut() throws Exception {
131         tx.put(STORE, PATH, node);
132         masterActor.expectMsgClass(PutRequest.class);
133     }
134
135     @Test
136     public void testPutClosed() throws Exception {
137         submit();
138         try {
139             tx.put(STORE, PATH, node);
140             Assert.fail("Should throw IllegalStateException");
141         } catch (final IllegalStateException e) {
142             masterActor.expectNoMsg();
143         }
144     }
145
146     @Test
147     public void testMerge() throws Exception {
148         tx.merge(STORE, PATH, node);
149         masterActor.expectMsgClass(MergeRequest.class);
150     }
151
152     @Test
153     public void testMergeClosed() throws Exception {
154         submit();
155         try {
156             tx.merge(STORE, PATH, node);
157             Assert.fail("Should throw IllegalStateException");
158         } catch (final IllegalStateException e) {
159             masterActor.expectNoMsg();
160         }
161     }
162
163     @Test
164     public void testGetIdentifier() throws Exception {
165         Assert.assertEquals(tx, tx.getIdentifier());
166     }
167
168     private void submit() throws TransactionCommitFailedException {
169         final CheckedFuture<Void, TransactionCommitFailedException> submit = tx.submit();
170         masterActor.expectMsgClass(SubmitRequest.class);
171         masterActor.reply(new SubmitReply());
172         submit.checkedGet();
173     }
174
175     @Test
176     public void testRead() throws Exception {
177         final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read = tx.read(STORE, PATH);
178         masterActor.expectMsgClass(ReadRequest.class);
179         masterActor.reply(new NormalizedNodeMessage(PATH, node));
180         final Optional<NormalizedNode<?, ?>> result = read.checkedGet();
181         Assert.assertTrue(result.isPresent());
182         Assert.assertEquals(node, result.get());
183     }
184
185     @Test
186     public void testReadEmpty() throws Exception {
187         final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read = tx.read(STORE, PATH);
188         masterActor.expectMsgClass(ReadRequest.class);
189         masterActor.reply(new EmptyReadResponse());
190         final Optional<NormalizedNode<?, ?>> result = read.checkedGet();
191         Assert.assertFalse(result.isPresent());
192     }
193
194     @Test(expected = ReadFailedException.class)
195     public void testReadFail() throws Exception {
196         final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read = tx.read(STORE, PATH);
197         masterActor.expectMsgClass(ReadRequest.class);
198         masterActor.reply(new RuntimeException("fail"));
199         read.checkedGet();
200     }
201
202     @Test
203     public void testExists() throws Exception {
204         final CheckedFuture<Boolean, ReadFailedException> read = tx.exists(STORE, PATH);
205         masterActor.expectMsgClass(ExistsRequest.class);
206         masterActor.reply(true);
207         final Boolean result = read.checkedGet();
208         Assert.assertTrue(result);
209     }
210
211     @Test(expected = ReadFailedException.class)
212     public void testExistsFail() throws Exception {
213         final CheckedFuture<Boolean, ReadFailedException> read = tx.exists(STORE, PATH);
214         masterActor.expectMsgClass(ExistsRequest.class);
215         masterActor.reply(new RuntimeException("fail"));
216         read.checkedGet();
217     }
218
219     @Test
220     public void testMasterDownRead() throws Exception {
221         final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read = tx.read(STORE, PATH);
222         masterActor.expectMsgClass(ReadRequest.class);
223         //master doesn't reply
224         try {
225             read.checkedGet();
226             Assert.fail("Exception should be thrown");
227         } catch (final ReadFailedException e) {
228             final Throwable cause = e.getCause();
229             Assert.assertTrue(cause instanceof DocumentedException);
230             final DocumentedException de = (DocumentedException) cause;
231             Assert.assertEquals(DocumentedException.ErrorSeverity.WARNING, de.getErrorSeverity());
232             Assert.assertEquals(DocumentedException.ErrorTag.OPERATION_FAILED, de.getErrorTag());
233             Assert.assertEquals(DocumentedException.ErrorType.APPLICATION, de.getErrorType());
234         }
235     }
236 }