BUG-650: remove executor abstraction
[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 com.google.common.util.concurrent.MoreExecutors;
18 import java.util.Collections;
19 import java.util.concurrent.TimeUnit;
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.messages.CreateTransaction;
25 import org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeSerializer;
26 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
27 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
28 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
29 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
30 import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
32 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
33 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
34 import scala.concurrent.Await;
35 import scala.concurrent.Future;
36 import scala.concurrent.duration.Duration;
37
38 /**
39  * Covers negative test cases
40  *
41  * @author Basheeruddin Ahmed <syedbahm@cisco.com>
42  */
43 public class ShardTransactionFailureTest extends AbstractActorTest {
44     private static final InMemoryDOMDataStore store =
45         new InMemoryDOMDataStore("OPER", MoreExecutors.sameThreadExecutor());
46
47     private static final SchemaContext testSchemaContext =
48         TestModel.createTestContext();
49
50     private static final ShardIdentifier SHARD_IDENTIFIER =
51         ShardIdentifier.builder().memberName("member-1")
52             .shardName("inventory").type("operational").build();
53
54     private final DatastoreContext datastoreContext = DatastoreContext.newBuilder().build();
55
56     private final ShardStats shardStats = new ShardStats(SHARD_IDENTIFIER.toString(), "DataStore");
57
58     @BeforeClass
59     public static void staticSetup() {
60         store.onGlobalContextUpdated(testSchemaContext);
61     }
62
63     private ActorRef createShard(){
64         return getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.<ShardIdentifier, String>emptyMap(), datastoreContext,
65                 TestModel.createTestContext()));
66     }
67
68     @Test(expected = ReadFailedException.class)
69     public void testNegativeReadWithReadOnlyTransactionClosed()
70         throws Throwable {
71
72         final ActorRef shard = createShard();
73         final Props props = ShardTransaction.props(store.newReadOnlyTransaction(), shard,
74                 testSchemaContext, datastoreContext, shardStats, "txn",
75                 CreateTransaction.CURRENT_VERSION);
76
77         final TestActorRef<ShardTransaction> subject = TestActorRef
78             .create(getSystem(), props,
79                 "testNegativeReadWithReadOnlyTransactionClosed");
80
81         ShardTransactionMessages.ReadData readData =
82             ShardTransactionMessages.ReadData.newBuilder()
83                 .setInstanceIdentifierPathArguments(
84                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
85                         .build()
86                 ).build();
87         Future<Object> future =
88             akka.pattern.Patterns.ask(subject, readData, 3000);
89         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
90
91         subject.underlyingActor().getDOMStoreTransaction().close();
92
93         future = akka.pattern.Patterns.ask(subject, readData, 3000);
94         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
95     }
96
97
98     @Test(expected = ReadFailedException.class)
99     public void testNegativeReadWithReadWriteTransactionClosed()
100         throws Throwable {
101
102         final ActorRef shard = createShard();
103         final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
104                 testSchemaContext, datastoreContext, shardStats, "txn",
105                 CreateTransaction.CURRENT_VERSION);
106
107         final TestActorRef<ShardTransaction> subject = TestActorRef
108             .create(getSystem(), props,
109                 "testNegativeReadWithReadWriteTransactionClosed");
110
111         ShardTransactionMessages.ReadData readData =
112             ShardTransactionMessages.ReadData.newBuilder()
113                 .setInstanceIdentifierPathArguments(
114                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
115                         .build()
116                 ).build();
117
118         Future<Object> future =
119             akka.pattern.Patterns.ask(subject, readData, 3000);
120         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
121
122         subject.underlyingActor().getDOMStoreTransaction().close();
123
124         future = akka.pattern.Patterns.ask(subject, readData, 3000);
125         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
126     }
127
128     @Test(expected = ReadFailedException.class)
129     public void testNegativeExistsWithReadWriteTransactionClosed()
130         throws Throwable {
131
132         final ActorRef shard = createShard();
133         final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
134                 testSchemaContext, datastoreContext, shardStats, "txn",
135                 CreateTransaction.CURRENT_VERSION);
136
137         final TestActorRef<ShardTransaction> subject = TestActorRef
138             .create(getSystem(), props,
139                 "testNegativeExistsWithReadWriteTransactionClosed");
140
141         ShardTransactionMessages.DataExists dataExists =
142             ShardTransactionMessages.DataExists.newBuilder()
143                 .setInstanceIdentifierPathArguments(
144                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
145                         .build()
146                 ).build();
147
148         Future<Object> future =
149             akka.pattern.Patterns.ask(subject, dataExists, 3000);
150         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
151
152         subject.underlyingActor().getDOMStoreTransaction().close();
153
154         future = akka.pattern.Patterns.ask(subject, dataExists, 3000);
155         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
156     }
157
158     @Test(expected = AskTimeoutException.class)
159     public void testNegativeWriteWithTransactionReady() throws Exception {
160
161
162         final ActorRef shard = createShard();
163         final Props props = ShardTransaction.props(store.newWriteOnlyTransaction(), shard,
164                 testSchemaContext, datastoreContext, shardStats, "txn",
165                 CreateTransaction.CURRENT_VERSION);
166
167         final TestActorRef<ShardTransaction> subject = TestActorRef
168             .create(getSystem(), props,
169                 "testNegativeWriteWithTransactionReady");
170
171         ShardTransactionMessages.ReadyTransaction readyTransaction =
172             ShardTransactionMessages.ReadyTransaction.newBuilder().build();
173
174         Future<Object> future =
175             akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
176         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
177
178         ShardTransactionMessages.WriteData writeData =
179             ShardTransactionMessages.WriteData.newBuilder()
180                 .setInstanceIdentifierPathArguments(
181                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
182                         .build()).setNormalizedNode(
183                 buildNormalizedNode()
184
185             ).build();
186
187         future = akka.pattern.Patterns.ask(subject, writeData, 3000);
188         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
189     }
190
191     @Test(expected = AskTimeoutException.class)
192     public void testNegativeReadWriteWithTransactionReady() throws Exception {
193
194
195         final ActorRef shard = createShard();
196         final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
197                 testSchemaContext, datastoreContext, shardStats, "txn",
198                 CreateTransaction.CURRENT_VERSION);
199
200         final TestActorRef<ShardTransaction> subject = TestActorRef
201             .create(getSystem(), props,
202                 "testNegativeReadWriteWithTransactionReady");
203
204         ShardTransactionMessages.ReadyTransaction readyTransaction =
205             ShardTransactionMessages.ReadyTransaction.newBuilder().build();
206
207         Future<Object> future =
208             akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
209         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
210
211         ShardTransactionMessages.WriteData writeData =
212             ShardTransactionMessages.WriteData.newBuilder()
213                 .setInstanceIdentifierPathArguments(
214                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
215                         .build()
216                 )
217                 .setNormalizedNode(buildNormalizedNode())
218                 .build();
219
220         future = akka.pattern.Patterns.ask(subject, writeData, 3000);
221         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
222     }
223
224     private NormalizedNodeMessages.Node buildNormalizedNode() {
225         return NormalizedNodeSerializer
226             .serialize(Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME)).build());
227     }
228
229     @Test(expected = AskTimeoutException.class)
230     public void testNegativeMergeTransactionReady() throws Exception {
231
232
233         final ActorRef shard = createShard();
234         final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
235                 testSchemaContext, datastoreContext, shardStats, "txn",
236                 CreateTransaction.CURRENT_VERSION);
237
238         final TestActorRef<ShardTransaction> subject = TestActorRef
239             .create(getSystem(), props, "testNegativeMergeTransactionReady");
240
241         ShardTransactionMessages.ReadyTransaction readyTransaction =
242             ShardTransactionMessages.ReadyTransaction.newBuilder().build();
243
244         Future<Object> future =
245             akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
246         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
247
248         ShardTransactionMessages.MergeData mergeData =
249             ShardTransactionMessages.MergeData.newBuilder()
250                 .setInstanceIdentifierPathArguments(
251                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
252                         .build()).setNormalizedNode(
253                 buildNormalizedNode()
254
255             ).build();
256
257         future = akka.pattern.Patterns.ask(subject, mergeData, 3000);
258         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
259     }
260
261
262     @Test(expected = AskTimeoutException.class)
263     public void testNegativeDeleteDataWhenTransactionReady() throws Exception {
264
265
266         final ActorRef shard = createShard();
267         final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard,
268                 testSchemaContext, datastoreContext, shardStats, "txn",
269                 CreateTransaction.CURRENT_VERSION);
270
271         final TestActorRef<ShardTransaction> subject = TestActorRef
272             .create(getSystem(), props,
273                 "testNegativeDeleteDataWhenTransactionReady");
274
275         ShardTransactionMessages.ReadyTransaction readyTransaction =
276             ShardTransactionMessages.ReadyTransaction.newBuilder().build();
277
278         Future<Object> future =
279             akka.pattern.Patterns.ask(subject, readyTransaction, 3000);
280         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
281
282         ShardTransactionMessages.DeleteData deleteData =
283             ShardTransactionMessages.DeleteData.newBuilder()
284                 .setInstanceIdentifierPathArguments(
285                     NormalizedNodeMessages.InstanceIdentifier.newBuilder()
286                         .build()).build();
287
288         future = akka.pattern.Patterns.ask(subject, deleteData, 3000);
289         Await.result(future, Duration.create(3, TimeUnit.SECONDS));
290     }
291 }