1 package org.opendaylight.controller.cluster.datastore;
3 import akka.actor.ActorRef;
4 import akka.actor.Props;
5 import akka.actor.Terminated;
6 import akka.testkit.JavaTestKit;
7 import akka.testkit.TestActorRef;
8 import com.google.common.util.concurrent.ListeningExecutorService;
9 import com.google.common.util.concurrent.MoreExecutors;
10 import org.junit.Assert;
11 import org.junit.Test;
12 import org.opendaylight.controller.cluster.datastore.messages.CloseTransaction;
13 import org.opendaylight.controller.cluster.datastore.messages.CloseTransactionReply;
14 import org.opendaylight.controller.cluster.datastore.messages.DeleteData;
15 import org.opendaylight.controller.cluster.datastore.messages.DeleteDataReply;
16 import org.opendaylight.controller.cluster.datastore.messages.MergeData;
17 import org.opendaylight.controller.cluster.datastore.messages.MergeDataReply;
18 import org.opendaylight.controller.cluster.datastore.messages.ReadData;
19 import org.opendaylight.controller.cluster.datastore.messages.ReadDataReply;
20 import org.opendaylight.controller.cluster.datastore.messages.ReadyTransaction;
21 import org.opendaylight.controller.cluster.datastore.messages.ReadyTransactionReply;
22 import org.opendaylight.controller.cluster.datastore.messages.WriteData;
23 import org.opendaylight.controller.cluster.datastore.messages.WriteDataReply;
24 import org.opendaylight.controller.cluster.datastore.modification.CompositeModification;
25 import org.opendaylight.controller.cluster.datastore.modification.DeleteModification;
26 import org.opendaylight.controller.cluster.datastore.modification.MergeModification;
27 import org.opendaylight.controller.cluster.datastore.modification.Modification;
28 import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
29 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
30 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
32 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
33 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
35 import java.util.Collections;
37 import static org.junit.Assert.assertEquals;
38 import static org.junit.Assert.assertTrue;
40 public class ShardTransactionTest extends AbstractActorTest {
41 private static ListeningExecutorService storeExecutor =
42 MoreExecutors.listeningDecorator(MoreExecutors.sameThreadExecutor());
44 private static final InMemoryDOMDataStore store =
45 new InMemoryDOMDataStore("OPER", storeExecutor);
47 private static final SchemaContext testSchemaContext = TestModel.createTestContext();
50 store.onGlobalContextUpdated(testSchemaContext);
54 public void testOnReceiveReadData() throws Exception {
55 new JavaTestKit(getSystem()) {{
56 final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
58 ShardTransaction.props(store.newReadOnlyTransaction(), shard, testSchemaContext);
59 final ActorRef subject = getSystem().actorOf(props, "testReadData");
61 new Within(duration("1 seconds")) {
62 protected void run() {
65 new ReadData(YangInstanceIdentifier.builder().build()).toSerializable(),
68 final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
69 // do not put code outside this method, will run afterwards
70 protected String match(Object in) {
71 if (in.getClass().equals(ReadDataReply.SERIALIZABLE_CLASS)) {
72 if (ReadDataReply.fromSerializable(testSchemaContext,YangInstanceIdentifier.builder().build(), in)
73 .getNormalizedNode()!= null) {
81 }.get(); // this extracts the received message
83 assertEquals("match", out);
94 public void testOnReceiveReadDataWhenDataNotFound() throws Exception {
95 new JavaTestKit(getSystem()) {{
96 final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
98 ShardTransaction.props( store.newReadOnlyTransaction(), shard, testSchemaContext);
99 final ActorRef subject = getSystem().actorOf(props, "testReadDataWhenDataNotFound");
101 new Within(duration("1 seconds")) {
102 protected void run() {
105 new ReadData(TestModel.TEST_PATH).toSerializable(),
108 final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
109 // do not put code outside this method, will run afterwards
110 protected String match(Object in) {
111 if (in.getClass().equals(ReadDataReply.SERIALIZABLE_CLASS)) {
112 if (ReadDataReply.fromSerializable(testSchemaContext,TestModel.TEST_PATH, in)
122 }.get(); // this extracts the received message
124 assertEquals("match", out);
134 private void assertModification(final ActorRef subject,
135 final Class<? extends Modification> modificationType) {
136 new JavaTestKit(getSystem()) {{
137 new Within(duration("1 seconds")) {
138 protected void run() {
140 .tell(new ShardTransaction.GetCompositedModification(),
143 final CompositeModification compositeModification =
144 new ExpectMsg<CompositeModification>(duration("1 seconds"), "match hint") {
145 // do not put code outside this method, will run afterwards
146 protected CompositeModification match(Object in) {
147 if (in instanceof ShardTransaction.GetCompositeModificationReply) {
148 return ((ShardTransaction.GetCompositeModificationReply) in)
154 }.get(); // this extracts the received message
157 compositeModification.getModifications().size() == 1);
158 assertEquals(modificationType,
159 compositeModification.getModifications().get(0)
168 public void testOnReceiveWriteData() throws Exception {
169 new JavaTestKit(getSystem()) {{
170 final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
172 ShardTransaction.props(store.newWriteOnlyTransaction(), shard, TestModel.createTestContext());
173 final ActorRef subject =
174 getSystem().actorOf(props, "testWriteData");
176 new Within(duration("1 seconds")) {
177 protected void run() {
179 subject.tell(new WriteData(TestModel.TEST_PATH,
180 ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(),
183 final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
184 // do not put code outside this method, will run afterwards
185 protected String match(Object in) {
186 if (in.getClass().equals(WriteDataReply.SERIALIZABLE_CLASS)) {
192 }.get(); // this extracts the received message
194 assertEquals("match", out);
196 assertModification(subject, WriteModification.class);
206 public void testOnReceiveMergeData() throws Exception {
207 new JavaTestKit(getSystem()) {{
208 final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
210 ShardTransaction.props(store.newReadWriteTransaction(), shard, testSchemaContext);
211 final ActorRef subject =
212 getSystem().actorOf(props, "testMergeData");
214 new Within(duration("1 seconds")) {
215 protected void run() {
217 subject.tell(new MergeData(TestModel.TEST_PATH,
218 ImmutableNodes.containerNode(TestModel.TEST_QNAME), testSchemaContext).toSerializable(),
221 final String out = new ExpectMsg<String>(duration("500 milliseconds"), "match hint") {
222 // do not put code outside this method, will run afterwards
223 protected String match(Object in) {
224 if (in.getClass().equals(MergeDataReply.SERIALIZABLE_CLASS)) {
230 }.get(); // this extracts the received message
232 assertEquals("match", out);
234 assertModification(subject, MergeModification.class);
245 public void testOnReceiveDeleteData() throws Exception {
246 new JavaTestKit(getSystem()) {{
247 final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
249 ShardTransaction.props( store.newWriteOnlyTransaction(), shard, TestModel.createTestContext());
250 final ActorRef subject =
251 getSystem().actorOf(props, "testDeleteData");
253 new Within(duration("1 seconds")) {
254 protected void run() {
256 subject.tell(new DeleteData(TestModel.TEST_PATH).toSerializable(), getRef());
258 final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
259 // do not put code outside this method, will run afterwards
260 protected String match(Object in) {
261 if (in.getClass().equals(DeleteDataReply.SERIALIZABLE_CLASS)) {
267 }.get(); // this extracts the received message
269 assertEquals("match", out);
271 assertModification(subject, DeleteModification.class);
282 public void testOnReceiveReadyTransaction() throws Exception {
283 new JavaTestKit(getSystem()) {{
284 final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
286 ShardTransaction.props( store.newReadWriteTransaction(), shard, TestModel.createTestContext());
287 final ActorRef subject =
288 getSystem().actorOf(props, "testReadyTransaction");
290 new Within(duration("1 seconds")) {
291 protected void run() {
293 subject.tell(new ReadyTransaction().toSerializable(), getRef());
295 final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
296 // do not put code outside this method, will run afterwards
297 protected String match(Object in) {
298 if (in.getClass().equals(ReadyTransactionReply.SERIALIZABLE_CLASS)) {
304 }.get(); // this extracts the received message
306 assertEquals("match", out);
318 public void testOnReceiveCloseTransaction() throws Exception {
319 new JavaTestKit(getSystem()) {{
320 final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
322 ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
323 final ActorRef subject =
324 getSystem().actorOf(props, "testCloseTransaction");
328 new Within(duration("2 seconds")) {
329 protected void run() {
331 subject.tell(new CloseTransaction().toSerializable(), getRef());
333 final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
334 // do not put code outside this method, will run afterwards
335 protected String match(Object in) {
336 if (in.getClass().equals(CloseTransactionReply.SERIALIZABLE_CLASS)) {
342 }.get(); // this extracts the received message
344 assertEquals("match", out);
346 final String termination = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
347 // do not put code outside this method, will run afterwards
348 protected String match(Object in) {
349 if (in instanceof Terminated) {
355 }.get(); // this extracts the received message
369 public void testNegativePerformingWriteOperationOnReadTransaction() throws Exception {
372 final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
374 ShardTransaction.props(store.newReadOnlyTransaction(), shard, TestModel.createTestContext());
375 final TestActorRef subject = TestActorRef.apply(props,getSystem());
377 subject.receive(new DeleteData(TestModel.TEST_PATH).toSerializable(), ActorRef.noSender());
378 Assert.assertFalse(true);
381 } catch (Exception cs) {
382 assertEquals(cs.getClass().getSimpleName(), Exception.class.getSimpleName());
383 assertTrue(cs.getMessage().startsWith("ShardTransaction:handleRecieve received an unknown message"));