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.testkit.TestActorRef;
17 import com.google.common.util.concurrent.ListeningExecutorService;
18 import com.google.common.util.concurrent.MoreExecutors;
20 import org.junit.BeforeClass;
21 import org.junit.Test;
22 import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
23 import org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard.ShardStats;
24 import org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeSerializer;
25 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
26 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
27 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
28 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
29 import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
31 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
32 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
34 import scala.concurrent.Await;
35 import scala.concurrent.Future;
36 import scala.concurrent.duration.Duration;
38 import java.util.Collections;
39 import java.util.concurrent.TimeUnit;
42 * Covers negative test cases
44 * @author Basheeruddin Ahmed <syedbahm@cisco.com>
46 public class ShardTransactionFailureTest extends AbstractActorTest {
47 private static ListeningExecutorService storeExecutor =
48 MoreExecutors.listeningDecorator(MoreExecutors.sameThreadExecutor());
50 private static final InMemoryDOMDataStore store =
51 new InMemoryDOMDataStore("OPER", storeExecutor,
52 MoreExecutors.sameThreadExecutor());
54 private static final SchemaContext testSchemaContext =
55 TestModel.createTestContext();
57 private static final ShardIdentifier SHARD_IDENTIFIER =
58 ShardIdentifier.builder().memberName("member-1")
59 .shardName("inventory").type("operational").build();
61 private final DatastoreContext datastoreContext = new DatastoreContext();
63 private final ShardStats shardStats = new ShardStats(SHARD_IDENTIFIER.toString(), "DataStore");
66 public static void staticSetup() {
67 store.onGlobalContextUpdated(testSchemaContext);
70 private ActorRef createShard(){
71 return getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP, new DatastoreContext(), TestModel.createTestContext()));
74 @Test(expected = ReadFailedException.class)
75 public void testNegativeReadWithReadOnlyTransactionClosed()
78 final ActorRef shard = createShard();
79 final Props props = ShardTransaction.props(store.newReadOnlyTransaction(), shard,
80 testSchemaContext, datastoreContext, shardStats);
82 final TestActorRef<ShardTransaction> subject = TestActorRef
83 .create(getSystem(), props,
84 "testNegativeReadWithReadOnlyTransactionClosed");
86 ShardTransactionMessages.ReadData readData =
87 ShardTransactionMessages.ReadData.newBuilder()
88 .setInstanceIdentifierPathArguments(
89 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
92 Future<Object> future =
93 akka.pattern.Patterns.ask(subject, readData, 3000);
94 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
96 subject.underlyingActor().getDOMStoreTransaction().close();
98 future = akka.pattern.Patterns.ask(subject, readData, 3000);
99 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
103 @Test(expected = ReadFailedException.class)
104 public void testNegativeReadWithReadWriteTransactionClosed()
107 final ActorRef shard = createShard();
108 final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
109 testSchemaContext, datastoreContext, shardStats);
111 final TestActorRef<ShardTransaction> subject = TestActorRef
112 .create(getSystem(), props,
113 "testNegativeReadWithReadWriteTransactionClosed");
115 ShardTransactionMessages.ReadData readData =
116 ShardTransactionMessages.ReadData.newBuilder()
117 .setInstanceIdentifierPathArguments(
118 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
122 Future<Object> future =
123 akka.pattern.Patterns.ask(subject, readData, 3000);
124 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
126 subject.underlyingActor().getDOMStoreTransaction().close();
128 future = akka.pattern.Patterns.ask(subject, readData, 3000);
129 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
132 @Test(expected = ReadFailedException.class)
133 public void testNegativeExistsWithReadWriteTransactionClosed()
136 final ActorRef shard = createShard();
137 final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
138 testSchemaContext, datastoreContext, shardStats);
140 final TestActorRef<ShardTransaction> subject = TestActorRef
141 .create(getSystem(), props,
142 "testNegativeExistsWithReadWriteTransactionClosed");
144 ShardTransactionMessages.DataExists dataExists =
145 ShardTransactionMessages.DataExists.newBuilder()
146 .setInstanceIdentifierPathArguments(
147 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
151 Future<Object> future =
152 akka.pattern.Patterns.ask(subject, dataExists, 3000);
153 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
155 subject.underlyingActor().getDOMStoreTransaction().close();
157 future = akka.pattern.Patterns.ask(subject, dataExists, 3000);
158 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
161 @Test(expected = IllegalStateException.class)
162 public void testNegativeWriteWithTransactionReady() throws Exception {
165 final ActorRef shard = createShard();
166 final Props props = ShardTransaction.props(store.newWriteOnlyTransaction(), shard,
167 testSchemaContext, datastoreContext, shardStats);
169 final TestActorRef<ShardTransaction> subject = TestActorRef
170 .create(getSystem(), props,
171 "testNegativeWriteWithTransactionReady");
173 ShardTransactionMessages.ReadyTransaction readyTransaction =
174 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
176 Future<Object> future =
177 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
178 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
180 ShardTransactionMessages.WriteData writeData =
181 ShardTransactionMessages.WriteData.newBuilder()
182 .setInstanceIdentifierPathArguments(
183 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
184 .build()).setNormalizedNode(
185 buildNormalizedNode()
189 future = akka.pattern.Patterns.ask(subject, writeData, 3000);
190 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
193 @Test(expected = IllegalStateException.class)
194 public void testNegativeReadWriteWithTransactionReady() throws Exception {
197 final ActorRef shard = createShard();
198 final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
199 testSchemaContext, datastoreContext, shardStats);
201 final TestActorRef<ShardTransaction> subject = TestActorRef
202 .create(getSystem(), props,
203 "testNegativeReadWriteWithTransactionReady");
205 ShardTransactionMessages.ReadyTransaction readyTransaction =
206 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
208 Future<Object> future =
209 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
210 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
212 ShardTransactionMessages.WriteData writeData =
213 ShardTransactionMessages.WriteData.newBuilder()
214 .setInstanceIdentifierPathArguments(
215 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
218 .setNormalizedNode(buildNormalizedNode())
221 future = akka.pattern.Patterns.ask(subject, writeData, 3000);
222 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
225 private NormalizedNodeMessages.Node buildNormalizedNode() {
226 return NormalizedNodeSerializer
227 .serialize(Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME)).build());
230 @Test(expected = IllegalStateException.class)
231 public void testNegativeMergeTransactionReady() throws Exception {
234 final ActorRef shard = createShard();
235 final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
236 testSchemaContext, datastoreContext, shardStats);
238 final TestActorRef<ShardTransaction> subject = TestActorRef
239 .create(getSystem(), props, "testNegativeMergeTransactionReady");
241 ShardTransactionMessages.ReadyTransaction readyTransaction =
242 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
244 Future<Object> future =
245 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
246 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
248 ShardTransactionMessages.MergeData mergeData =
249 ShardTransactionMessages.MergeData.newBuilder()
250 .setInstanceIdentifierPathArguments(
251 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
252 .build()).setNormalizedNode(
253 buildNormalizedNode()
257 future = akka.pattern.Patterns.ask(subject, mergeData, 3000);
258 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
262 @Test(expected = IllegalStateException.class)
263 public void testNegativeDeleteDataWhenTransactionReady() throws Exception {
266 final ActorRef shard = createShard();
267 final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
268 testSchemaContext, datastoreContext, shardStats);
270 final TestActorRef<ShardTransaction> subject = TestActorRef
271 .create(getSystem(), props,
272 "testNegativeDeleteDataWhenTransactionReady");
274 ShardTransactionMessages.ReadyTransaction readyTransaction =
275 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
277 Future<Object> future =
278 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
279 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
281 ShardTransactionMessages.DeleteData deleteData =
282 ShardTransactionMessages.DeleteData.newBuilder()
283 .setInstanceIdentifierPathArguments(
284 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
287 future = akka.pattern.Patterns.ask(subject, deleteData, 3000);
288 Await.result(future, Duration.create(3, TimeUnit.SECONDS));