2 * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.topology.singleton.impl.tx;
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;
46 public class ProxyReadWriteTransactionTest {
47 private static final YangInstanceIdentifier PATH = YangInstanceIdentifier.EMPTY;
48 private static final LogicalDatastoreType STORE = LogicalDatastoreType.CONFIGURATION;
50 private ActorSystem system;
51 private TestProbe masterActor;
52 private ContainerNode node;
53 private ProxyReadWriteTransaction tx;
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")))
63 tx = new ProxyReadWriteTransaction(masterActor.ref(), id, system, Timeout.apply(5, TimeUnit.SECONDS));
67 public void tearDown() throws Exception {
68 JavaTestKit.shutdownActorSystem(system, null, true);
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());
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());
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();
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();
105 tx.submit().checkedGet();
106 Assert.fail("Should throw IllegalStateException");
107 } catch (final IllegalStateException e) {
108 masterActor.expectNoMsg();
113 public void testDelete() throws Exception {
114 tx.delete(STORE, PATH);
115 masterActor.expectMsgClass(DeleteRequest.class);
119 public void testDeleteClosed() throws Exception {
122 tx.delete(STORE, PATH);
123 Assert.fail("Should throw IllegalStateException");
124 } catch (final IllegalStateException e) {
125 masterActor.expectNoMsg();
130 public void testPut() throws Exception {
131 tx.put(STORE, PATH, node);
132 masterActor.expectMsgClass(PutRequest.class);
136 public void testPutClosed() throws Exception {
139 tx.put(STORE, PATH, node);
140 Assert.fail("Should throw IllegalStateException");
141 } catch (final IllegalStateException e) {
142 masterActor.expectNoMsg();
147 public void testMerge() throws Exception {
148 tx.merge(STORE, PATH, node);
149 masterActor.expectMsgClass(MergeRequest.class);
153 public void testMergeClosed() throws Exception {
156 tx.merge(STORE, PATH, node);
157 Assert.fail("Should throw IllegalStateException");
158 } catch (final IllegalStateException e) {
159 masterActor.expectNoMsg();
164 public void testGetIdentifier() throws Exception {
165 Assert.assertEquals(tx, tx.getIdentifier());
168 private void submit() throws TransactionCommitFailedException {
169 final CheckedFuture<Void, TransactionCommitFailedException> submit = tx.submit();
170 masterActor.expectMsgClass(SubmitRequest.class);
171 masterActor.reply(new SubmitReply());
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());
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());
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"));
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);
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"));
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
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());