e275bc5f12e9507d923b1757930b4f0d42333085
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / BasicIntegrationTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.cluster.datastore;
10
11 import akka.actor.ActorPath;
12 import akka.actor.ActorRef;
13 import akka.actor.ActorSelection;
14 import akka.actor.Props;
15 import akka.actor.Terminated;
16 import akka.testkit.JavaTestKit;
17 import junit.framework.Assert;
18 import org.junit.Test;
19 import org.opendaylight.controller.cluster.datastore.messages.CommitTransaction;
20 import org.opendaylight.controller.cluster.datastore.messages.CommitTransactionReply;
21 import org.opendaylight.controller.cluster.datastore.messages.CreateTransaction;
22 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionChain;
23 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionChainReply;
24 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionReply;
25 import org.opendaylight.controller.cluster.datastore.messages.PreCommitTransaction;
26 import org.opendaylight.controller.cluster.datastore.messages.PreCommitTransactionReply;
27 import org.opendaylight.controller.cluster.datastore.messages.ReadyTransaction;
28 import org.opendaylight.controller.cluster.datastore.messages.ReadyTransactionReply;
29 import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
30 import org.opendaylight.controller.cluster.datastore.messages.WriteData;
31 import org.opendaylight.controller.cluster.datastore.messages.WriteDataReply;
32 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
33 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
34 import scala.concurrent.Await;
35 import scala.concurrent.Future;
36 import scala.concurrent.duration.FiniteDuration;
37
38 public class BasicIntegrationTest extends AbstractActorTest {
39
40     @Test
41     public void integrationTest() throws Exception{
42         // This test will
43         // - create a Shard
44         // - initiate a transaction
45         // - write something
46         // - read the transaction for commit
47         // - commit the transaction
48
49
50         new JavaTestKit(getSystem()) {{
51             final Props props = Shard.props("config");
52             final ActorRef shard = getSystem().actorOf(props);
53
54             new Within(duration("5 seconds")) {
55                 protected void run() {
56
57                     shard.tell(
58                         new UpdateSchemaContext(TestModel.createTestContext()),
59                         getRef());
60
61                     shard.tell(new CreateTransactionChain(), getRef());
62
63                     final ActorSelection transactionChain =
64                         new ExpectMsg<ActorSelection>("CreateTransactionChainReply") {
65                             protected ActorSelection match(Object in) {
66                                 if (in instanceof CreateTransactionChainReply) {
67                                     ActorPath transactionChainPath =
68                                         ((CreateTransactionChainReply) in)
69                                             .getTransactionChainPath();
70                                     return getSystem()
71                                         .actorSelection(transactionChainPath);
72                                 } else {
73                                     throw noMatch();
74                                 }
75                             }
76                         }.get(); // this extracts the received message
77
78                     Assert.assertNotNull(transactionChain);
79
80                     transactionChain.tell(new CreateTransaction("txn-1"), getRef());
81
82                     final ActorSelection transaction =
83                         new ExpectMsg<ActorSelection>("CreateTransactionReply") {
84                             protected ActorSelection match(Object in) {
85                                 if (CreateTransactionReply.SERIALIZABLE_CLASS.equals(in.getClass())) {
86                                     CreateTransactionReply reply = CreateTransactionReply.fromSerializable(in);
87                                     return getSystem()
88                                         .actorSelection(reply
89                                             .getTransactionPath());
90                                 } else {
91                                     throw noMatch();
92                                 }
93                             }
94                         }.get(); // this extracts the received message
95
96                     Assert.assertNotNull(transaction);
97
98                     // Add a watch on the transaction actor so that we are notified when it dies
99                     final ActorRef transactionActorRef = watchActor(transaction);
100
101                     transaction.tell(new WriteData(TestModel.TEST_PATH,
102                         ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(),
103                         getRef());
104
105                     Boolean writeDone = new ExpectMsg<Boolean>("WriteDataReply") {
106                         protected Boolean match(Object in) {
107                             if (in instanceof WriteDataReply) {
108                                 return true;
109                             } else {
110                                 throw noMatch();
111                             }
112                         }
113                     }.get(); // this extracts the received message
114
115                     Assert.assertTrue(writeDone);
116
117                     transaction.tell(new ReadyTransaction(), getRef());
118
119                     final ActorSelection cohort =
120                         new ExpectMsg<ActorSelection>("ReadyTransactionReply") {
121                             protected ActorSelection match(Object in) {
122                                 if (in instanceof ReadyTransactionReply) {
123                                     ActorPath cohortPath =
124                                         ((ReadyTransactionReply) in)
125                                             .getCohortPath();
126                                     return getSystem()
127                                         .actorSelection(cohortPath);
128                                 } else {
129                                     throw noMatch();
130                                 }
131                             }
132                         }.get(); // this extracts the received message
133
134                     Assert.assertNotNull(cohort);
135
136                     // Add a watch on the transaction actor so that we are notified when it dies
137                     final ActorRef cohorActorRef = watchActor(cohort);
138
139                     cohort.tell(new PreCommitTransaction(), getRef());
140
141                     Boolean preCommitDone =
142                         new ExpectMsg<Boolean>("PreCommitTransactionReply") {
143                             protected Boolean match(Object in) {
144                                 if (in instanceof PreCommitTransactionReply) {
145                                     return true;
146                                 } else {
147                                     throw noMatch();
148                                 }
149                             }
150                         }.get(); // this extracts the received message
151
152                     Assert.assertTrue(preCommitDone);
153
154                     // FIXME : When we commit on the cohort it "kills" the Transaction.
155                     // This in turn kills the child of Transaction as well.
156                     // The order in which we receive the terminated event for both
157                     // these actors is not fixed which may cause this test to fail
158                     cohort.tell(new CommitTransaction(), getRef());
159
160                     final Boolean terminatedCohort =
161                         new ExpectMsg<Boolean>("Terminated Cohort") {
162                             protected Boolean match(Object in) {
163                                 if (in instanceof Terminated) {
164                                     return cohorActorRef.equals(((Terminated) in).actor());
165                                 } else {
166                                     throw noMatch();
167                                 }
168                             }
169                         }.get(); // this extracts the received message
170
171                     Assert.assertTrue(terminatedCohort);
172
173
174                     final Boolean terminatedTransaction =
175                         new ExpectMsg<Boolean>("Terminated Transaction") {
176                             protected Boolean match(Object in) {
177                                 if (in instanceof Terminated) {
178                                     return transactionActorRef.equals(((Terminated) in).actor());
179                                 } else {
180                                     throw noMatch();
181                                 }
182                             }
183                         }.get(); // this extracts the received message
184
185                     Assert.assertTrue(terminatedTransaction);
186
187                     final Boolean commitDone =
188                         new ExpectMsg<Boolean>("CommitTransactionReply") {
189                             protected Boolean match(Object in) {
190                                 if (in instanceof CommitTransactionReply) {
191                                     return true;
192                                 } else {
193                                     throw noMatch();
194                                 }
195                             }
196                         }.get(); // this extracts the received message
197
198                     Assert.assertTrue(commitDone);
199
200                 }
201
202
203             };
204         }
205
206             private ActorRef watchActor(ActorSelection actor) {
207                 Future<ActorRef> future = actor
208                     .resolveOne(FiniteDuration.apply(100, "milliseconds"));
209
210                 try {
211                     ActorRef actorRef = Await.result(future,
212                         FiniteDuration.apply(100, "milliseconds"));
213
214                     watch(actorRef);
215
216                     return actorRef;
217                 } catch (Exception e) {
218                     throw new RuntimeException(e);
219                 }
220
221             }
222         };
223
224
225     }
226 }