CDS: use internal DataTree instance
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / ShardTransactionFailureTest.java
1 /*
2  *
3  *  Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
4  *
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
8  *
9  */
10
11 package org.opendaylight.controller.cluster.datastore;
12
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;
34
35 /**
36  * Covers negative test cases
37  *
38  * @author Basheeruddin Ahmed <syedbahm@cisco.com>
39  */
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;
46
47     private static final ShardDataTree store = new ShardDataTree(testSchemaContext);
48
49     private static final ShardIdentifier SHARD_IDENTIFIER =
50         ShardIdentifier.builder().memberName("member-1")
51             .shardName("inventory").type("operational").build();
52
53     private final DatastoreContext datastoreContext = DatastoreContext.newBuilder().build();
54
55     private final ShardStats shardStats = new ShardStats(SHARD_IDENTIFIER.toString(), "DataStore");
56
57     private ActorRef createShard(){
58         return getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.<String, String>emptyMap(), datastoreContext,
59                 TestModel.createTestContext()));
60     }
61
62     @Test(expected = ReadFailedException.class)
63     public void testNegativeReadWithReadOnlyTransactionClosed()
64         throws Throwable {
65
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);
69
70         final TestActorRef<ShardTransaction> subject = TestActorRef
71             .create(getSystem(), props,
72                 "testNegativeReadWithReadOnlyTransactionClosed");
73
74         ShardTransactionMessages.ReadData readData =
75             ShardTransactionMessages.ReadData.newBuilder()
76                 .setInstanceIdentifierPathArguments(
77                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
78                         .build()
79                 ).build();
80         Future<Object> future =
81             akka.pattern.Patterns.ask(subject, readData, 3000);
82         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
83
84         subject.underlyingActor().getDOMStoreTransaction().abort();
85
86         future = akka.pattern.Patterns.ask(subject, readData, 3000);
87         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
88     }
89
90
91     @Test(expected = ReadFailedException.class)
92     public void testNegativeReadWithReadWriteTransactionClosed()
93         throws Throwable {
94
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);
98
99         final TestActorRef<ShardTransaction> subject = TestActorRef
100             .create(getSystem(), props,
101                 "testNegativeReadWithReadWriteTransactionClosed");
102
103         ShardTransactionMessages.ReadData readData =
104             ShardTransactionMessages.ReadData.newBuilder()
105                 .setInstanceIdentifierPathArguments(
106                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
107                         .build()
108                 ).build();
109
110         Future<Object> future =
111             akka.pattern.Patterns.ask(subject, readData, 3000);
112         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
113
114         subject.underlyingActor().getDOMStoreTransaction().abort();
115
116         future = akka.pattern.Patterns.ask(subject, readData, 3000);
117         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
118     }
119
120     @Test(expected = ReadFailedException.class)
121     public void testNegativeExistsWithReadWriteTransactionClosed()
122         throws Throwable {
123
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);
127
128         final TestActorRef<ShardTransaction> subject = TestActorRef
129             .create(getSystem(), props,
130                 "testNegativeExistsWithReadWriteTransactionClosed");
131
132         ShardTransactionMessages.DataExists dataExists =
133             ShardTransactionMessages.DataExists.newBuilder()
134                 .setInstanceIdentifierPathArguments(
135                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
136                         .build()
137                 ).build();
138
139         Future<Object> future =
140             akka.pattern.Patterns.ask(subject, dataExists, 3000);
141         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
142
143         subject.underlyingActor().getDOMStoreTransaction().abort();
144
145         future = akka.pattern.Patterns.ask(subject, dataExists, 3000);
146         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
147     }
148
149     @Test(expected = AskTimeoutException.class)
150     public void testNegativeWriteWithTransactionReady() throws Exception {
151
152
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);
156
157         final TestActorRef<ShardTransaction> subject = TestActorRef
158             .create(getSystem(), props,
159                 "testNegativeWriteWithTransactionReady");
160
161         ShardTransactionMessages.ReadyTransaction readyTransaction =
162             ShardTransactionMessages.ReadyTransaction.newBuilder().build();
163
164         Future<Object> future =
165             akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
166         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
167
168         ShardTransactionMessages.WriteData writeData =
169             ShardTransactionMessages.WriteData.newBuilder()
170                 .setInstanceIdentifierPathArguments(
171                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
172                         .build()).setNormalizedNode(
173                 buildNormalizedNode()
174
175             ).build();
176
177         future = akka.pattern.Patterns.ask(subject, writeData, 3000);
178         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
179     }
180
181     @Test(expected = AskTimeoutException.class)
182     public void testNegativeReadWriteWithTransactionReady() throws Exception {
183
184
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);
188
189         final TestActorRef<ShardTransaction> subject = TestActorRef
190             .create(getSystem(), props,
191                 "testNegativeReadWriteWithTransactionReady");
192
193         ShardTransactionMessages.ReadyTransaction readyTransaction =
194             ShardTransactionMessages.ReadyTransaction.newBuilder().build();
195
196         Future<Object> future =
197             akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
198         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
199
200         ShardTransactionMessages.WriteData writeData =
201             ShardTransactionMessages.WriteData.newBuilder()
202                 .setInstanceIdentifierPathArguments(
203                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
204                         .build()
205                 )
206                 .setNormalizedNode(buildNormalizedNode())
207                 .build();
208
209         future = akka.pattern.Patterns.ask(subject, writeData, 3000);
210         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
211     }
212
213     private NormalizedNodeMessages.Node buildNormalizedNode() {
214         return NormalizedNodeSerializer
215             .serialize(Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME)).build());
216     }
217
218     @Test(expected = AskTimeoutException.class)
219     public void testNegativeMergeTransactionReady() throws Exception {
220
221
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);
225
226         final TestActorRef<ShardTransaction> subject = TestActorRef
227             .create(getSystem(), props, "testNegativeMergeTransactionReady");
228
229         ShardTransactionMessages.ReadyTransaction readyTransaction =
230             ShardTransactionMessages.ReadyTransaction.newBuilder().build();
231
232         Future<Object> future =
233             akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
234         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
235
236         ShardTransactionMessages.MergeData mergeData =
237             ShardTransactionMessages.MergeData.newBuilder()
238                 .setInstanceIdentifierPathArguments(
239                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
240                         .build()).setNormalizedNode(
241                 buildNormalizedNode()
242
243             ).build();
244
245         future = akka.pattern.Patterns.ask(subject, mergeData, 3000);
246         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
247     }
248
249
250     @Test(expected = AskTimeoutException.class)
251     public void testNegativeDeleteDataWhenTransactionReady() throws Exception {
252
253
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);
257
258         final TestActorRef<ShardTransaction> subject = TestActorRef
259             .create(getSystem(), props,
260                 "testNegativeDeleteDataWhenTransactionReady");
261
262         ShardTransactionMessages.ReadyTransaction readyTransaction =
263             ShardTransactionMessages.ReadyTransaction.newBuilder().build();
264
265         Future<Object> future =
266             akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
267         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
268
269         ShardTransactionMessages.DeleteData deleteData =
270             ShardTransactionMessages.DeleteData.newBuilder()
271                 .setInstanceIdentifierPathArguments(
272                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
273                         .build()).build();
274
275         future = akka.pattern.Patterns.ask(subject, deleteData, 3000);
276         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
277     }
278 }