3 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
11 package org.opendaylight.controller.cluster.datastore;
13 import akka.actor.ActorRef;
14 import akka.actor.Props;
15 import akka.pattern.AskTimeoutException;
16 import akka.testkit.TestActorRef;
17 import java.util.Collections;
18 import java.util.concurrent.TimeUnit;
19 import org.junit.Test;
20 import org.opendaylight.controller.cluster.datastore.TransactionProxy.TransactionType;
21 import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
22 import org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard.ShardStats;
23 import org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeSerializer;
24 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
25 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
26 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
27 import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
29 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
30 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
31 import scala.concurrent.Await;
32 import scala.concurrent.Future;
33 import scala.concurrent.duration.Duration;
36 * Covers negative test cases
38 * @author Basheeruddin Ahmed <syedbahm@cisco.com>
40 public class ShardTransactionFailureTest extends AbstractActorTest {
41 private static final SchemaContext testSchemaContext =
42 TestModel.createTestContext();
43 private static final TransactionType RO = TransactionType.READ_ONLY;
44 private static final TransactionType RW = TransactionType.READ_WRITE;
45 private static final TransactionType WO = TransactionType.WRITE_ONLY;
47 private static final ShardDataTree store = new ShardDataTree(testSchemaContext);
49 private static final ShardIdentifier SHARD_IDENTIFIER =
50 ShardIdentifier.builder().memberName("member-1")
51 .shardName("inventory").type("operational").build();
53 private final DatastoreContext datastoreContext = DatastoreContext.newBuilder().build();
55 private final ShardStats shardStats = new ShardStats(SHARD_IDENTIFIER.toString(), "DataStore");
57 private ActorRef createShard(){
58 return getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.<String, String>emptyMap(), datastoreContext,
59 TestModel.createTestContext()));
62 @Test(expected = ReadFailedException.class)
63 public void testNegativeReadWithReadOnlyTransactionClosed()
66 final ActorRef shard = createShard();
67 final Props props = ShardTransaction.props(RO, store.newReadOnlyTransaction("test-txn", null), shard,
68 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
70 final TestActorRef<ShardTransaction> subject = TestActorRef
71 .create(getSystem(), props,
72 "testNegativeReadWithReadOnlyTransactionClosed");
74 ShardTransactionMessages.ReadData readData =
75 ShardTransactionMessages.ReadData.newBuilder()
76 .setInstanceIdentifierPathArguments(
77 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
80 Future<Object> future =
81 akka.pattern.Patterns.ask(subject, readData, 3000);
82 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
84 subject.underlyingActor().getDOMStoreTransaction().abort();
86 future = akka.pattern.Patterns.ask(subject, readData, 3000);
87 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
91 @Test(expected = ReadFailedException.class)
92 public void testNegativeReadWithReadWriteTransactionClosed()
95 final ActorRef shard = createShard();
96 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
97 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
99 final TestActorRef<ShardTransaction> subject = TestActorRef
100 .create(getSystem(), props,
101 "testNegativeReadWithReadWriteTransactionClosed");
103 ShardTransactionMessages.ReadData readData =
104 ShardTransactionMessages.ReadData.newBuilder()
105 .setInstanceIdentifierPathArguments(
106 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
110 Future<Object> future =
111 akka.pattern.Patterns.ask(subject, readData, 3000);
112 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
114 subject.underlyingActor().getDOMStoreTransaction().abort();
116 future = akka.pattern.Patterns.ask(subject, readData, 3000);
117 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
120 @Test(expected = ReadFailedException.class)
121 public void testNegativeExistsWithReadWriteTransactionClosed()
124 final ActorRef shard = createShard();
125 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
126 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
128 final TestActorRef<ShardTransaction> subject = TestActorRef
129 .create(getSystem(), props,
130 "testNegativeExistsWithReadWriteTransactionClosed");
132 ShardTransactionMessages.DataExists dataExists =
133 ShardTransactionMessages.DataExists.newBuilder()
134 .setInstanceIdentifierPathArguments(
135 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
139 Future<Object> future =
140 akka.pattern.Patterns.ask(subject, dataExists, 3000);
141 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
143 subject.underlyingActor().getDOMStoreTransaction().abort();
145 future = akka.pattern.Patterns.ask(subject, dataExists, 3000);
146 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
149 @Test(expected = AskTimeoutException.class)
150 public void testNegativeWriteWithTransactionReady() throws Exception {
153 final ActorRef shard = createShard();
154 final Props props = ShardTransaction.props(WO, store.newReadWriteTransaction("test-txn", null), shard,
155 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
157 final TestActorRef<ShardTransaction> subject = TestActorRef
158 .create(getSystem(), props,
159 "testNegativeWriteWithTransactionReady");
161 ShardTransactionMessages.ReadyTransaction readyTransaction =
162 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
164 Future<Object> future =
165 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
166 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
168 ShardTransactionMessages.WriteData writeData =
169 ShardTransactionMessages.WriteData.newBuilder()
170 .setInstanceIdentifierPathArguments(
171 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
172 .build()).setNormalizedNode(
173 buildNormalizedNode()
177 future = akka.pattern.Patterns.ask(subject, writeData, 3000);
178 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
181 @Test(expected = AskTimeoutException.class)
182 public void testNegativeReadWriteWithTransactionReady() throws Exception {
185 final ActorRef shard = createShard();
186 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
187 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
189 final TestActorRef<ShardTransaction> subject = TestActorRef
190 .create(getSystem(), props,
191 "testNegativeReadWriteWithTransactionReady");
193 ShardTransactionMessages.ReadyTransaction readyTransaction =
194 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
196 Future<Object> future =
197 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
198 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
200 ShardTransactionMessages.WriteData writeData =
201 ShardTransactionMessages.WriteData.newBuilder()
202 .setInstanceIdentifierPathArguments(
203 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
206 .setNormalizedNode(buildNormalizedNode())
209 future = akka.pattern.Patterns.ask(subject, writeData, 3000);
210 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
213 private NormalizedNodeMessages.Node buildNormalizedNode() {
214 return NormalizedNodeSerializer
215 .serialize(Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME)).build());
218 @Test(expected = AskTimeoutException.class)
219 public void testNegativeMergeTransactionReady() throws Exception {
222 final ActorRef shard = createShard();
223 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
224 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
226 final TestActorRef<ShardTransaction> subject = TestActorRef
227 .create(getSystem(), props, "testNegativeMergeTransactionReady");
229 ShardTransactionMessages.ReadyTransaction readyTransaction =
230 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
232 Future<Object> future =
233 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
234 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
236 ShardTransactionMessages.MergeData mergeData =
237 ShardTransactionMessages.MergeData.newBuilder()
238 .setInstanceIdentifierPathArguments(
239 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
240 .build()).setNormalizedNode(
241 buildNormalizedNode()
245 future = akka.pattern.Patterns.ask(subject, mergeData, 3000);
246 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
250 @Test(expected = AskTimeoutException.class)
251 public void testNegativeDeleteDataWhenTransactionReady() throws Exception {
254 final ActorRef shard = createShard();
255 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
256 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
258 final TestActorRef<ShardTransaction> subject = TestActorRef
259 .create(getSystem(), props,
260 "testNegativeDeleteDataWhenTransactionReady");
262 ShardTransactionMessages.ReadyTransaction readyTransaction =
263 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
265 Future<Object> future =
266 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
267 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
269 ShardTransactionMessages.DeleteData deleteData =
270 ShardTransactionMessages.DeleteData.newBuilder()
271 .setInstanceIdentifierPathArguments(
272 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
275 future = akka.pattern.Patterns.ask(subject, deleteData, 3000);
276 Await.result(future, Duration.create(3, TimeUnit.SECONDS));