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.identifiers.ShardIdentifier;
21 import org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard.ShardStats;
22 import org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeSerializer;
23 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
24 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
25 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
26 import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
28 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
29 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
30 import scala.concurrent.Await;
31 import scala.concurrent.Future;
32 import scala.concurrent.duration.Duration;
35 * Covers negative test cases
37 * @author Basheeruddin Ahmed <syedbahm@cisco.com>
39 public class ShardTransactionFailureTest extends AbstractActorTest {
40 private static final SchemaContext testSchemaContext =
41 TestModel.createTestContext();
42 private static final TransactionType RO = TransactionType.READ_ONLY;
43 private static final TransactionType RW = TransactionType.READ_WRITE;
44 private static final TransactionType WO = TransactionType.WRITE_ONLY;
46 private static final ShardDataTree store = new ShardDataTree(testSchemaContext);
48 private static final ShardIdentifier SHARD_IDENTIFIER =
49 ShardIdentifier.builder().memberName("member-1")
50 .shardName("inventory").type("operational").build();
52 private final DatastoreContext datastoreContext = DatastoreContext.newBuilder().build();
54 private final ShardStats shardStats = new ShardStats(SHARD_IDENTIFIER.toString(), "DataStore");
56 private ActorRef createShard(){
57 return getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.<String, String>emptyMap(), datastoreContext,
58 TestModel.createTestContext()));
61 @Test(expected = ReadFailedException.class)
62 public void testNegativeReadWithReadOnlyTransactionClosed()
65 final ActorRef shard = createShard();
66 final Props props = ShardTransaction.props(RO, store.newReadOnlyTransaction("test-txn", null), shard,
67 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
69 final TestActorRef<ShardTransaction> subject = TestActorRef
70 .create(getSystem(), props,
71 "testNegativeReadWithReadOnlyTransactionClosed");
73 ShardTransactionMessages.ReadData readData =
74 ShardTransactionMessages.ReadData.newBuilder()
75 .setInstanceIdentifierPathArguments(
76 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
79 Future<Object> future =
80 akka.pattern.Patterns.ask(subject, readData, 3000);
81 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
83 subject.underlyingActor().getDOMStoreTransaction().abort();
85 future = akka.pattern.Patterns.ask(subject, readData, 3000);
86 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
90 @Test(expected = ReadFailedException.class)
91 public void testNegativeReadWithReadWriteTransactionClosed()
94 final ActorRef shard = createShard();
95 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
96 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
98 final TestActorRef<ShardTransaction> subject = TestActorRef
99 .create(getSystem(), props,
100 "testNegativeReadWithReadWriteTransactionClosed");
102 ShardTransactionMessages.ReadData readData =
103 ShardTransactionMessages.ReadData.newBuilder()
104 .setInstanceIdentifierPathArguments(
105 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
109 Future<Object> future =
110 akka.pattern.Patterns.ask(subject, readData, 3000);
111 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
113 subject.underlyingActor().getDOMStoreTransaction().abort();
115 future = akka.pattern.Patterns.ask(subject, readData, 3000);
116 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
119 @Test(expected = ReadFailedException.class)
120 public void testNegativeExistsWithReadWriteTransactionClosed()
123 final ActorRef shard = createShard();
124 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
125 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
127 final TestActorRef<ShardTransaction> subject = TestActorRef
128 .create(getSystem(), props,
129 "testNegativeExistsWithReadWriteTransactionClosed");
131 ShardTransactionMessages.DataExists dataExists =
132 ShardTransactionMessages.DataExists.newBuilder()
133 .setInstanceIdentifierPathArguments(
134 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
138 Future<Object> future =
139 akka.pattern.Patterns.ask(subject, dataExists, 3000);
140 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
142 subject.underlyingActor().getDOMStoreTransaction().abort();
144 future = akka.pattern.Patterns.ask(subject, dataExists, 3000);
145 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
148 @Test(expected = AskTimeoutException.class)
149 public void testNegativeWriteWithTransactionReady() throws Exception {
152 final ActorRef shard = createShard();
153 final Props props = ShardTransaction.props(WO, store.newReadWriteTransaction("test-txn", null), shard,
154 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
156 final TestActorRef<ShardTransaction> subject = TestActorRef
157 .create(getSystem(), props,
158 "testNegativeWriteWithTransactionReady");
160 ShardTransactionMessages.ReadyTransaction readyTransaction =
161 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
163 Future<Object> future =
164 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
165 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
167 ShardTransactionMessages.WriteData writeData =
168 ShardTransactionMessages.WriteData.newBuilder()
169 .setInstanceIdentifierPathArguments(
170 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
171 .build()).setNormalizedNode(
172 buildNormalizedNode()
176 future = akka.pattern.Patterns.ask(subject, writeData, 3000);
177 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
180 @Test(expected = AskTimeoutException.class)
181 public void testNegativeReadWriteWithTransactionReady() throws Exception {
184 final ActorRef shard = createShard();
185 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
186 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
188 final TestActorRef<ShardTransaction> subject = TestActorRef
189 .create(getSystem(), props,
190 "testNegativeReadWriteWithTransactionReady");
192 ShardTransactionMessages.ReadyTransaction readyTransaction =
193 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
195 Future<Object> future =
196 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
197 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
199 ShardTransactionMessages.WriteData writeData =
200 ShardTransactionMessages.WriteData.newBuilder()
201 .setInstanceIdentifierPathArguments(
202 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
205 .setNormalizedNode(buildNormalizedNode())
208 future = akka.pattern.Patterns.ask(subject, writeData, 3000);
209 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
212 private NormalizedNodeMessages.Node buildNormalizedNode() {
213 return NormalizedNodeSerializer
214 .serialize(Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME)).build());
217 @Test(expected = AskTimeoutException.class)
218 public void testNegativeMergeTransactionReady() throws Exception {
221 final ActorRef shard = createShard();
222 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
223 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
225 final TestActorRef<ShardTransaction> subject = TestActorRef
226 .create(getSystem(), props, "testNegativeMergeTransactionReady");
228 ShardTransactionMessages.ReadyTransaction readyTransaction =
229 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
231 Future<Object> future =
232 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
233 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
235 ShardTransactionMessages.MergeData mergeData =
236 ShardTransactionMessages.MergeData.newBuilder()
237 .setInstanceIdentifierPathArguments(
238 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
239 .build()).setNormalizedNode(
240 buildNormalizedNode()
244 future = akka.pattern.Patterns.ask(subject, mergeData, 3000);
245 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
249 @Test(expected = AskTimeoutException.class)
250 public void testNegativeDeleteDataWhenTransactionReady() throws Exception {
253 final ActorRef shard = createShard();
254 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
255 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
257 final TestActorRef<ShardTransaction> subject = TestActorRef
258 .create(getSystem(), props,
259 "testNegativeDeleteDataWhenTransactionReady");
261 ShardTransactionMessages.ReadyTransaction readyTransaction =
262 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
264 Future<Object> future =
265 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
266 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
268 ShardTransactionMessages.DeleteData deleteData =
269 ShardTransactionMessages.DeleteData.newBuilder()
270 .setInstanceIdentifierPathArguments(
271 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
274 future = akka.pattern.Patterns.ask(subject, deleteData, 3000);
275 Await.result(future, Duration.create(3, TimeUnit.SECONDS));