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 @Test(expected = ReadFailedException.class)
71 public void testNegativeReadWithReadOnlyTransactionClosed()
74 final ActorRef shard =
75 getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP, new DatastoreContext()));
76 final Props props = ShardTransaction.props(store.newReadOnlyTransaction(), shard,
77 testSchemaContext, datastoreContext, shardStats);
79 final TestActorRef<ShardTransaction> subject = TestActorRef
80 .create(getSystem(), props,
81 "testNegativeReadWithReadOnlyTransactionClosed");
83 ShardTransactionMessages.ReadData readData =
84 ShardTransactionMessages.ReadData.newBuilder()
85 .setInstanceIdentifierPathArguments(
86 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
89 Future<Object> future =
90 akka.pattern.Patterns.ask(subject, readData, 3000);
91 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
93 subject.underlyingActor().getDOMStoreTransaction().close();
95 future = akka.pattern.Patterns.ask(subject, readData, 3000);
96 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
100 @Test(expected = ReadFailedException.class)
101 public void testNegativeReadWithReadWriteTransactionClosed()
104 final ActorRef shard =
105 getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP, new DatastoreContext()));
106 final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
107 testSchemaContext, datastoreContext, shardStats);
109 final TestActorRef<ShardTransaction> subject = TestActorRef
110 .create(getSystem(), props,
111 "testNegativeReadWithReadWriteTransactionClosed");
113 ShardTransactionMessages.ReadData readData =
114 ShardTransactionMessages.ReadData.newBuilder()
115 .setInstanceIdentifierPathArguments(
116 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
120 Future<Object> future =
121 akka.pattern.Patterns.ask(subject, readData, 3000);
122 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
124 subject.underlyingActor().getDOMStoreTransaction().close();
126 future = akka.pattern.Patterns.ask(subject, readData, 3000);
127 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
130 @Test(expected = ReadFailedException.class)
131 public void testNegativeExistsWithReadWriteTransactionClosed()
134 final ActorRef shard =
135 getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP, new DatastoreContext()));
136 final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
137 testSchemaContext, datastoreContext, shardStats);
139 final TestActorRef<ShardTransaction> subject = TestActorRef
140 .create(getSystem(), props,
141 "testNegativeExistsWithReadWriteTransactionClosed");
143 ShardTransactionMessages.DataExists dataExists =
144 ShardTransactionMessages.DataExists.newBuilder()
145 .setInstanceIdentifierPathArguments(
146 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
150 Future<Object> future =
151 akka.pattern.Patterns.ask(subject, dataExists, 3000);
152 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
154 subject.underlyingActor().getDOMStoreTransaction().close();
156 future = akka.pattern.Patterns.ask(subject, dataExists, 3000);
157 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
160 @Test(expected = IllegalStateException.class)
161 public void testNegativeWriteWithTransactionReady() throws Exception {
164 final ActorRef shard =
165 getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP, new DatastoreContext()));
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 =
198 getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP, new DatastoreContext()));
199 final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
200 testSchemaContext, datastoreContext, shardStats);
202 final TestActorRef<ShardTransaction> subject = TestActorRef
203 .create(getSystem(), props,
204 "testNegativeReadWriteWithTransactionReady");
206 ShardTransactionMessages.ReadyTransaction readyTransaction =
207 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
209 Future<Object> future =
210 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
211 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
213 ShardTransactionMessages.WriteData writeData =
214 ShardTransactionMessages.WriteData.newBuilder()
215 .setInstanceIdentifierPathArguments(
216 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
219 .setNormalizedNode(buildNormalizedNode())
222 future = akka.pattern.Patterns.ask(subject, writeData, 3000);
223 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
226 private NormalizedNodeMessages.Node buildNormalizedNode() {
227 return NormalizedNodeSerializer
228 .serialize(Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME)).build());
231 @Test(expected = IllegalStateException.class)
232 public void testNegativeMergeTransactionReady() throws Exception {
235 final ActorRef shard =
236 getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP, new DatastoreContext()));
237 final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
238 testSchemaContext, datastoreContext, shardStats);
240 final TestActorRef<ShardTransaction> subject = TestActorRef
241 .create(getSystem(), props, "testNegativeMergeTransactionReady");
243 ShardTransactionMessages.ReadyTransaction readyTransaction =
244 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
246 Future<Object> future =
247 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
248 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
250 ShardTransactionMessages.MergeData mergeData =
251 ShardTransactionMessages.MergeData.newBuilder()
252 .setInstanceIdentifierPathArguments(
253 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
254 .build()).setNormalizedNode(
255 buildNormalizedNode()
259 future = akka.pattern.Patterns.ask(subject, mergeData, 3000);
260 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
264 @Test(expected = IllegalStateException.class)
265 public void testNegativeDeleteDataWhenTransactionReady() throws Exception {
268 final ActorRef shard =
269 getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP, new DatastoreContext()));
270 final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
271 testSchemaContext, datastoreContext, shardStats);
273 final TestActorRef<ShardTransaction> subject = TestActorRef
274 .create(getSystem(), props,
275 "testNegativeDeleteDataWhenTransactionReady");
277 ShardTransactionMessages.ReadyTransaction readyTransaction =
278 ShardTransactionMessages.ReadyTransaction.newBuilder().build();
280 Future<Object> future =
281 akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
282 Await.result(future, Duration.create(3, TimeUnit.SECONDS));
284 ShardTransactionMessages.DeleteData deleteData =
285 ShardTransactionMessages.DeleteData.newBuilder()
286 .setInstanceIdentifierPathArguments(
287 NormalizedNodeMessages.InstanceIdentifier.newBuilder()
290 future = akka.pattern.Patterns.ask(subject, deleteData, 3000);
291 Await.result(future, Duration.create(3, TimeUnit.SECONDS));