Merge "BUG-997 Consult QNames of yang modules with ietf-netconf-monitoring/netconf...
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / ShardTransactionTest.java
1 package org.opendaylight.controller.cluster.datastore;
2
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;
34
35 import java.util.Collections;
36
37 import static org.junit.Assert.assertEquals;
38 import static org.junit.Assert.assertTrue;
39
40 public class ShardTransactionTest extends AbstractActorTest {
41     private static ListeningExecutorService storeExecutor =
42         MoreExecutors.listeningDecorator(MoreExecutors.sameThreadExecutor());
43
44     private static final InMemoryDOMDataStore store =
45         new InMemoryDOMDataStore("OPER", storeExecutor);
46
47     private static final SchemaContext testSchemaContext = TestModel.createTestContext();
48
49     static {
50         store.onGlobalContextUpdated(testSchemaContext);
51     }
52
53     @Test
54     public void testOnReceiveReadData() throws Exception {
55         new JavaTestKit(getSystem()) {{
56             final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
57             final Props props =
58                 ShardTransaction.props(store.newReadOnlyTransaction(), shard, testSchemaContext);
59             final ActorRef subject = getSystem().actorOf(props, "testReadData");
60
61             new Within(duration("1 seconds")) {
62                 protected void run() {
63
64                     subject.tell(
65                         new ReadData(YangInstanceIdentifier.builder().build()).toSerializable(),
66                         getRef());
67
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) {
74                                     return "match";
75                                 }
76                                 return null;
77                             } else {
78                                 throw noMatch();
79                             }
80                         }
81                     }.get(); // this extracts the received message
82
83                     assertEquals("match", out);
84
85                     expectNoMsg();
86                 }
87
88
89             };
90         }};
91     }
92
93     @Test
94     public void testOnReceiveReadDataWhenDataNotFound() throws Exception {
95         new JavaTestKit(getSystem()) {{
96             final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
97             final Props props =
98                 ShardTransaction.props( store.newReadOnlyTransaction(), shard, testSchemaContext);
99             final ActorRef subject = getSystem().actorOf(props, "testReadDataWhenDataNotFound");
100
101             new Within(duration("1 seconds")) {
102                 protected void run() {
103
104                     subject.tell(
105                         new ReadData(TestModel.TEST_PATH).toSerializable(),
106                         getRef());
107
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)
113                                     .getNormalizedNode()
114                                     == null) {
115                                     return "match";
116                                 }
117                                 return null;
118                             } else {
119                                 throw noMatch();
120                             }
121                         }
122                     }.get(); // this extracts the received message
123
124                     assertEquals("match", out);
125
126                     expectNoMsg();
127                 }
128
129
130             };
131         }};
132     }
133
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() {
139                     subject
140                         .tell(new ShardTransaction.GetCompositedModification(),
141                             getRef());
142
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)
149                                         .getModification();
150                                 } else {
151                                     throw noMatch();
152                                 }
153                             }
154                         }.get(); // this extracts the received message
155
156                     assertTrue(
157                         compositeModification.getModifications().size() == 1);
158                     assertEquals(modificationType,
159                         compositeModification.getModifications().get(0)
160                             .getClass());
161
162                 }
163             };
164         }};
165     }
166
167     @Test
168     public void testOnReceiveWriteData() throws Exception {
169         new JavaTestKit(getSystem()) {{
170             final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
171             final Props props =
172                 ShardTransaction.props(store.newWriteOnlyTransaction(), shard, TestModel.createTestContext());
173             final ActorRef subject =
174                 getSystem().actorOf(props, "testWriteData");
175
176             new Within(duration("1 seconds")) {
177                 protected void run() {
178
179                     subject.tell(new WriteData(TestModel.TEST_PATH,
180                         ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(),
181                         getRef());
182
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)) {
187                                 return "match";
188                             } else {
189                                 throw noMatch();
190                             }
191                         }
192                     }.get(); // this extracts the received message
193
194                     assertEquals("match", out);
195
196                     assertModification(subject, WriteModification.class);
197                     expectNoMsg();
198                 }
199
200
201             };
202         }};
203     }
204
205     @Test
206     public void testOnReceiveMergeData() throws Exception {
207         new JavaTestKit(getSystem()) {{
208             final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
209             final Props props =
210                 ShardTransaction.props(store.newReadWriteTransaction(), shard, testSchemaContext);
211             final ActorRef subject =
212                 getSystem().actorOf(props, "testMergeData");
213
214             new Within(duration("1 seconds")) {
215                 protected void run() {
216
217                     subject.tell(new MergeData(TestModel.TEST_PATH,
218                         ImmutableNodes.containerNode(TestModel.TEST_QNAME), testSchemaContext).toSerializable(),
219                         getRef());
220
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)) {
225                                 return "match";
226                             } else {
227                                 throw noMatch();
228                             }
229                         }
230                     }.get(); // this extracts the received message
231
232                     assertEquals("match", out);
233
234                     assertModification(subject, MergeModification.class);
235
236                     expectNoMsg();
237                 }
238
239
240             };
241         }};
242     }
243
244     @Test
245     public void testOnReceiveDeleteData() throws Exception {
246         new JavaTestKit(getSystem()) {{
247             final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
248             final Props props =
249                 ShardTransaction.props( store.newWriteOnlyTransaction(), shard, TestModel.createTestContext());
250             final ActorRef subject =
251                 getSystem().actorOf(props, "testDeleteData");
252
253             new Within(duration("1 seconds")) {
254                 protected void run() {
255
256                     subject.tell(new DeleteData(TestModel.TEST_PATH).toSerializable(), getRef());
257
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)) {
262                                 return "match";
263                             } else {
264                                 throw noMatch();
265                             }
266                         }
267                     }.get(); // this extracts the received message
268
269                     assertEquals("match", out);
270
271                     assertModification(subject, DeleteModification.class);
272                     expectNoMsg();
273                 }
274
275
276             };
277         }};
278     }
279
280
281     @Test
282     public void testOnReceiveReadyTransaction() throws Exception {
283         new JavaTestKit(getSystem()) {{
284             final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
285             final Props props =
286                 ShardTransaction.props( store.newReadWriteTransaction(), shard, TestModel.createTestContext());
287             final ActorRef subject =
288                 getSystem().actorOf(props, "testReadyTransaction");
289
290             new Within(duration("1 seconds")) {
291                 protected void run() {
292
293                     subject.tell(new ReadyTransaction().toSerializable(), getRef());
294
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)) {
299                                 return "match";
300                             } else {
301                                 throw noMatch();
302                             }
303                         }
304                     }.get(); // this extracts the received message
305
306                     assertEquals("match", out);
307
308                     expectNoMsg();
309                 }
310
311
312             };
313         }};
314
315     }
316
317     @Test
318     public void testOnReceiveCloseTransaction() throws Exception {
319         new JavaTestKit(getSystem()) {{
320             final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
321             final Props props =
322                 ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
323             final ActorRef subject =
324                 getSystem().actorOf(props, "testCloseTransaction");
325
326             watch(subject);
327
328             new Within(duration("2 seconds")) {
329                 protected void run() {
330
331                     subject.tell(new CloseTransaction().toSerializable(), getRef());
332
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)) {
337                                 return "match";
338                             } else {
339                                 throw noMatch();
340                             }
341                         }
342                     }.get(); // this extracts the received message
343
344                     assertEquals("match", out);
345
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) {
350                                 return "match";
351                             } else {
352                                 throw noMatch();
353                             }
354                         }
355                     }.get(); // this extracts the received message
356
357
358                     expectNoMsg();
359                 }
360
361
362             };
363         }};
364
365     }
366
367
368   @Test
369   public void testNegativePerformingWriteOperationOnReadTransaction() throws Exception {
370     try {
371
372         final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
373         final Props props =
374             ShardTransaction.props(store.newReadOnlyTransaction(), shard, TestModel.createTestContext());
375          final TestActorRef subject = TestActorRef.apply(props,getSystem());
376
377         subject.receive(new DeleteData(TestModel.TEST_PATH).toSerializable(), ActorRef.noSender());
378         Assert.assertFalse(true);
379
380
381     } catch (Exception cs) {
382       assertEquals(cs.getClass().getSimpleName(), Exception.class.getSimpleName());
383       assertTrue(cs.getMessage().startsWith("ShardTransaction:handleRecieve received an unknown message"));
384     }
385   }
386 }