2 * Copyright (c) 2014, 2015 Cisco Systems, Inc. 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.controller.cluster.datastore;
11 import akka.actor.ActorRef;
12 import akka.actor.Props;
13 import akka.pattern.AskTimeoutException;
14 import akka.testkit.TestActorRef;
15 import java.util.Collections;
16 import java.util.concurrent.TimeUnit;
17 import org.junit.Test;
18 import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
19 import org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard.ShardStats;
20 import org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeSerializer;
21 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
22 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
23 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
24 import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
26 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
27 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
28 import scala.concurrent.Await;
29 import scala.concurrent.Future;
30 import scala.concurrent.duration.Duration;
33 * Covers negative test cases
35 * @author Basheeruddin Ahmed <syedbahm@cisco.com>
37 public class ShardTransactionFailureTest extends AbstractActorTest {
38 private static final SchemaContext testSchemaContext =
39 TestModel.createTestContext();
40 private static final TransactionType RO = TransactionType.READ_ONLY;
41 private static final TransactionType RW = TransactionType.READ_WRITE;
42 private static final TransactionType WO = TransactionType.WRITE_ONLY;
44 private static final ShardDataTree store = new ShardDataTree(testSchemaContext);
46 private static final ShardIdentifier SHARD_IDENTIFIER =
47 ShardIdentifier.builder().memberName("member-1")
48 .shardName("inventory").type("operational").build();
50 private final DatastoreContext datastoreContext = DatastoreContext.newBuilder().build();
52 private final ShardStats shardStats = new ShardStats(SHARD_IDENTIFIER.toString(), "DataStore");
54 private ActorRef createShard(){
55 return getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.<String, String>emptyMap(), datastoreContext,
56 TestModel.createTestContext()));
59 @Test(expected = ReadFailedException.class)
60 public void testNegativeReadWithReadOnlyTransactionClosed()
63 final ActorRef shard = createShard();
64 final Props props = ShardTransaction.props(RO, store.newReadOnlyTransaction("test-txn", null), shard,
65 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
67 final TestActorRef<ShardTransaction> subject = TestActorRef
68 .create(getSystem(), props,
69 "testNegativeReadWithReadOnlyTransactionClosed");
71 ShardTransactionMessages.ReadData readData =
72 ShardTransactionMessages.ReadData.newBuilder()
73 .setInstanceIdentifierPathArguments(
74 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
77 Future<Object> future =
78 akka.pattern.Patterns.ask(subject, readData, 3000);
79 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
81 subject.underlyingActor().getDOMStoreTransaction().abort();
83 future = akka.pattern.Patterns.ask(subject, readData, 3000);
84 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
88 @Test(expected = ReadFailedException.class)
89 public void testNegativeReadWithReadWriteTransactionClosed()
92 final ActorRef shard = createShard();
93 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
94 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
96 final TestActorRef<ShardTransaction> subject = TestActorRef
97 .create(getSystem(), props,
98 "testNegativeReadWithReadWriteTransactionClosed");
100 ShardTransactionMessages.ReadData readData =
101 ShardTransactionMessages.ReadData.newBuilder()
102 .setInstanceIdentifierPathArguments(
103 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
107 Future<Object> future =
108 akka.pattern.Patterns.ask(subject, readData, 3000);
109 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
111 subject.underlyingActor().getDOMStoreTransaction().abort();
113 future = akka.pattern.Patterns.ask(subject, readData, 3000);
114 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
117 @Test(expected = ReadFailedException.class)
118 public void testNegativeExistsWithReadWriteTransactionClosed()
121 final ActorRef shard = createShard();
122 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
123 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
125 final TestActorRef<ShardTransaction> subject = TestActorRef
126 .create(getSystem(), props,
127 "testNegativeExistsWithReadWriteTransactionClosed");
129 ShardTransactionMessages.DataExists dataExists =
130 ShardTransactionMessages.DataExists.newBuilder()
131 .setInstanceIdentifierPathArguments(
132 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
136 Future<Object> future =
137 akka.pattern.Patterns.ask(subject, dataExists, 3000);
138 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
140 subject.underlyingActor().getDOMStoreTransaction().abort();
142 future = akka.pattern.Patterns.ask(subject, dataExists, 3000);
143 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
146 @Test(expected = AskTimeoutException.class)
147 public void testNegativeWriteWithTransactionReady() throws Exception {
150 final ActorRef shard = createShard();
151 final Props props = ShardTransaction.props(WO, store.newReadWriteTransaction("test-txn", null), shard,
152 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
154 final TestActorRef<ShardTransaction> subject = TestActorRef
155 .create(getSystem(), props,
156 "testNegativeWriteWithTransactionReady");
158 ShardTransactionMessages.ReadyTransaction readyTransaction =
159 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
161 Future<Object> future =
162 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
163 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
165 ShardTransactionMessages.WriteData writeData =
166 ShardTransactionMessages.WriteData.newBuilder()
167 .setInstanceIdentifierPathArguments(
168 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
169 .build()).setNormalizedNode(
170 buildNormalizedNode()
174 future = akka.pattern.Patterns.ask(subject, writeData, 3000);
175 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
178 @Test(expected = AskTimeoutException.class)
179 public void testNegativeReadWriteWithTransactionReady() throws Exception {
182 final ActorRef shard = createShard();
183 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
184 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
186 final TestActorRef<ShardTransaction> subject = TestActorRef
187 .create(getSystem(), props,
188 "testNegativeReadWriteWithTransactionReady");
190 ShardTransactionMessages.ReadyTransaction readyTransaction =
191 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
193 Future<Object> future =
194 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
195 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
197 ShardTransactionMessages.WriteData writeData =
198 ShardTransactionMessages.WriteData.newBuilder()
199 .setInstanceIdentifierPathArguments(
200 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
203 .setNormalizedNode(buildNormalizedNode())
206 future = akka.pattern.Patterns.ask(subject, writeData, 3000);
207 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
210 private NormalizedNodeMessages.Node buildNormalizedNode() {
211 return NormalizedNodeSerializer
212 .serialize(Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME)).build());
215 @Test(expected = AskTimeoutException.class)
216 public void testNegativeMergeTransactionReady() throws Exception {
219 final ActorRef shard = createShard();
220 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
221 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
223 final TestActorRef<ShardTransaction> subject = TestActorRef
224 .create(getSystem(), props, "testNegativeMergeTransactionReady");
226 ShardTransactionMessages.ReadyTransaction readyTransaction =
227 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
229 Future<Object> future =
230 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
231 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
233 ShardTransactionMessages.MergeData mergeData =
234 ShardTransactionMessages.MergeData.newBuilder()
235 .setInstanceIdentifierPathArguments(
236 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
237 .build()).setNormalizedNode(
238 buildNormalizedNode()
242 future = akka.pattern.Patterns.ask(subject, mergeData, 3000);
243 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
247 @Test(expected = AskTimeoutException.class)
248 public void testNegativeDeleteDataWhenTransactionReady() throws Exception {
251 final ActorRef shard = createShard();
252 final Props props = ShardTransaction.props(RW, store.newReadWriteTransaction("test-txn", null), shard,
253 datastoreContext, shardStats, "txn", DataStoreVersions.CURRENT_VERSION);
255 final TestActorRef<ShardTransaction> subject = TestActorRef
256 .create(getSystem(), props,
257 "testNegativeDeleteDataWhenTransactionReady");
259 ShardTransactionMessages.ReadyTransaction readyTransaction =
260 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
262 Future<Object> future =
263 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
264 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
266 ShardTransactionMessages.DeleteData deleteData =
267 ShardTransactionMessages.DeleteData.newBuilder()
268 .setInstanceIdentifierPathArguments(
269 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
272 future = akka.pattern.Patterns.ask(subject, deleteData, 3000);
273 Await.result(future, Duration.create(3, TimeUnit.SECONDS));