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