Merge "Bug #1532 Neutron Port bindings missing Security Group List"
[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.exceptions.UnknownMessageException;
13 import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
14 import org.opendaylight.controller.cluster.datastore.messages.CloseTransaction;
15 import org.opendaylight.controller.cluster.datastore.messages.CloseTransactionReply;
16 import org.opendaylight.controller.cluster.datastore.messages.DeleteData;
17 import org.opendaylight.controller.cluster.datastore.messages.DeleteDataReply;
18 import org.opendaylight.controller.cluster.datastore.messages.MergeData;
19 import org.opendaylight.controller.cluster.datastore.messages.MergeDataReply;
20 import org.opendaylight.controller.cluster.datastore.messages.ReadData;
21 import org.opendaylight.controller.cluster.datastore.messages.ReadDataReply;
22 import org.opendaylight.controller.cluster.datastore.messages.ReadyTransaction;
23 import org.opendaylight.controller.cluster.datastore.messages.ReadyTransactionReply;
24 import org.opendaylight.controller.cluster.datastore.messages.WriteData;
25 import org.opendaylight.controller.cluster.datastore.messages.WriteDataReply;
26 import org.opendaylight.controller.cluster.datastore.modification.CompositeModification;
27 import org.opendaylight.controller.cluster.datastore.modification.DeleteModification;
28 import org.opendaylight.controller.cluster.datastore.modification.MergeModification;
29 import org.opendaylight.controller.cluster.datastore.modification.Modification;
30 import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
31 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
32 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
33 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
34 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
35 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
36
37 import java.util.Collections;
38
39 import static org.junit.Assert.assertEquals;
40 import static org.junit.Assert.assertTrue;
41
42 public class ShardTransactionTest extends AbstractActorTest {
43     private static ListeningExecutorService storeExecutor =
44         MoreExecutors.listeningDecorator(MoreExecutors.sameThreadExecutor());
45
46     private static final InMemoryDOMDataStore store =
47         new InMemoryDOMDataStore("OPER", storeExecutor, MoreExecutors.sameThreadExecutor());
48
49     private static final SchemaContext testSchemaContext = TestModel.createTestContext();
50
51     private static final ShardIdentifier SHARD_IDENTIFIER =
52         ShardIdentifier.builder().memberName("member-1")
53             .shardName("inventory").type("config").build();
54
55
56     static {
57         store.onGlobalContextUpdated(testSchemaContext);
58     }
59
60     @Test
61     public void testOnReceiveReadData() throws Exception {
62         new JavaTestKit(getSystem()) {{
63             final ActorRef shard = getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP));
64             final Props props =
65                 ShardTransaction.props(store.newReadOnlyTransaction(), shard, testSchemaContext);
66             final ActorRef subject = getSystem().actorOf(props, "testReadData");
67
68             new Within(duration("1 seconds")) {
69                 @Override
70                 protected void run() {
71
72                     subject.tell(
73                         new ReadData(YangInstanceIdentifier.builder().build()).toSerializable(),
74                         getRef());
75
76                     final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
77                         // do not put code outside this method, will run afterwards
78                         @Override
79                         protected String match(Object in) {
80                             if (in.getClass().equals(ReadDataReply.SERIALIZABLE_CLASS)) {
81                               if (ReadDataReply.fromSerializable(testSchemaContext,YangInstanceIdentifier.builder().build(), in)
82                                   .getNormalizedNode()!= null) {
83                                     return "match";
84                                 }
85                                 return null;
86                             } else {
87                                 throw noMatch();
88                             }
89                         }
90                     }.get(); // this extracts the received message
91
92                     assertEquals("match", out);
93
94                     expectNoMsg();
95                 }
96
97
98             };
99         }};
100     }
101
102     @Test
103     public void testOnReceiveReadDataWhenDataNotFound() throws Exception {
104         new JavaTestKit(getSystem()) {{
105             final ActorRef shard = getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP));
106             final Props props =
107                 ShardTransaction.props( store.newReadOnlyTransaction(), shard, testSchemaContext);
108             final ActorRef subject = getSystem().actorOf(props, "testReadDataWhenDataNotFound");
109
110             new Within(duration("1 seconds")) {
111                 @Override
112                 protected void run() {
113
114                     subject.tell(
115                         new ReadData(TestModel.TEST_PATH).toSerializable(),
116                         getRef());
117
118                     final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
119                         // do not put code outside this method, will run afterwards
120                         @Override
121                         protected String match(Object in) {
122                             if (in.getClass().equals(ReadDataReply.SERIALIZABLE_CLASS)) {
123                                 if (ReadDataReply.fromSerializable(testSchemaContext,TestModel.TEST_PATH, in)
124                                     .getNormalizedNode()
125                                     == null) {
126                                     return "match";
127                                 }
128                                 return null;
129                             } else {
130                                 throw noMatch();
131                             }
132                         }
133                     }.get(); // this extracts the received message
134
135                     assertEquals("match", out);
136
137                     expectNoMsg();
138                 }
139
140
141             };
142         }};
143     }
144
145     private void assertModification(final ActorRef subject,
146         final Class<? extends Modification> modificationType) {
147         new JavaTestKit(getSystem()) {{
148             new Within(duration("1 seconds")) {
149                 @Override
150                 protected void run() {
151                     subject
152                         .tell(new ShardTransaction.GetCompositedModification(),
153                             getRef());
154
155                     final CompositeModification compositeModification =
156                         new ExpectMsg<CompositeModification>(duration("1 seconds"), "match hint") {
157                             // do not put code outside this method, will run afterwards
158                             @Override
159                             protected CompositeModification match(Object in) {
160                                 if (in instanceof ShardTransaction.GetCompositeModificationReply) {
161                                     return ((ShardTransaction.GetCompositeModificationReply) in)
162                                         .getModification();
163                                 } else {
164                                     throw noMatch();
165                                 }
166                             }
167                         }.get(); // this extracts the received message
168
169                     assertTrue(
170                         compositeModification.getModifications().size() == 1);
171                     assertEquals(modificationType,
172                         compositeModification.getModifications().get(0)
173                             .getClass());
174
175                 }
176             };
177         }};
178     }
179
180     @Test
181     public void testOnReceiveWriteData() throws Exception {
182         new JavaTestKit(getSystem()) {{
183             final ActorRef shard = getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP));
184             final Props props =
185                 ShardTransaction.props(store.newWriteOnlyTransaction(), shard, TestModel.createTestContext());
186             final ActorRef subject =
187                 getSystem().actorOf(props, "testWriteData");
188
189             new Within(duration("1 seconds")) {
190                 @Override
191                 protected void run() {
192
193                     subject.tell(new WriteData(TestModel.TEST_PATH,
194                         ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(),
195                         getRef());
196
197                     final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
198                         // do not put code outside this method, will run afterwards
199                         @Override
200                         protected String match(Object in) {
201                             if (in.getClass().equals(WriteDataReply.SERIALIZABLE_CLASS)) {
202                                 return "match";
203                             } else {
204                                 throw noMatch();
205                             }
206                         }
207                     }.get(); // this extracts the received message
208
209                     assertEquals("match", out);
210
211                     assertModification(subject, WriteModification.class);
212                     expectNoMsg();
213                 }
214
215
216             };
217         }};
218     }
219
220     @Test
221     public void testOnReceiveMergeData() throws Exception {
222         new JavaTestKit(getSystem()) {{
223             final ActorRef shard = getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP));
224             final Props props =
225                 ShardTransaction.props(store.newReadWriteTransaction(), shard, testSchemaContext);
226             final ActorRef subject =
227                 getSystem().actorOf(props, "testMergeData");
228
229             new Within(duration("1 seconds")) {
230                 @Override
231                 protected void run() {
232
233                     subject.tell(new MergeData(TestModel.TEST_PATH,
234                         ImmutableNodes.containerNode(TestModel.TEST_QNAME), testSchemaContext).toSerializable(),
235                         getRef());
236
237                     final String out = new ExpectMsg<String>(duration("500 milliseconds"), "match hint") {
238                         // do not put code outside this method, will run afterwards
239                         @Override
240                         protected String match(Object in) {
241                             if (in.getClass().equals(MergeDataReply.SERIALIZABLE_CLASS)) {
242                                 return "match";
243                             } else {
244                                 throw noMatch();
245                             }
246                         }
247                     }.get(); // this extracts the received message
248
249                     assertEquals("match", out);
250
251                     assertModification(subject, MergeModification.class);
252
253                     expectNoMsg();
254                 }
255
256
257             };
258         }};
259     }
260
261     @Test
262     public void testOnReceiveDeleteData() throws Exception {
263         new JavaTestKit(getSystem()) {{
264             final ActorRef shard = getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP));
265             final Props props =
266                 ShardTransaction.props( store.newWriteOnlyTransaction(), shard, TestModel.createTestContext());
267             final ActorRef subject =
268                 getSystem().actorOf(props, "testDeleteData");
269
270             new Within(duration("1 seconds")) {
271                 @Override
272                 protected void run() {
273
274                     subject.tell(new DeleteData(TestModel.TEST_PATH).toSerializable(), getRef());
275
276                     final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
277                         // do not put code outside this method, will run afterwards
278                         @Override
279                         protected String match(Object in) {
280                             if (in.getClass().equals(DeleteDataReply.SERIALIZABLE_CLASS)) {
281                                 return "match";
282                             } else {
283                                 throw noMatch();
284                             }
285                         }
286                     }.get(); // this extracts the received message
287
288                     assertEquals("match", out);
289
290                     assertModification(subject, DeleteModification.class);
291                     expectNoMsg();
292                 }
293
294
295             };
296         }};
297     }
298
299
300     @Test
301     public void testOnReceiveReadyTransaction() throws Exception {
302         new JavaTestKit(getSystem()) {{
303             final ActorRef shard = getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP));
304             final Props props =
305                 ShardTransaction.props( store.newReadWriteTransaction(), shard, TestModel.createTestContext());
306             final ActorRef subject =
307                 getSystem().actorOf(props, "testReadyTransaction");
308
309             new Within(duration("1 seconds")) {
310                 @Override
311                 protected void run() {
312
313                     subject.tell(new ReadyTransaction().toSerializable(), getRef());
314
315                     final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
316                         // do not put code outside this method, will run afterwards
317                         @Override
318                         protected String match(Object in) {
319                             if (in.getClass().equals(ReadyTransactionReply.SERIALIZABLE_CLASS)) {
320                                 return "match";
321                             } else {
322                                 throw noMatch();
323                             }
324                         }
325                     }.get(); // this extracts the received message
326
327                     assertEquals("match", out);
328
329                     expectNoMsg();
330                 }
331
332
333             };
334         }};
335
336     }
337
338     @Test
339     public void testOnReceiveCloseTransaction() throws Exception {
340         new JavaTestKit(getSystem()) {{
341             final ActorRef shard = getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP));
342             final Props props =
343                 ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
344             final ActorRef subject =
345                 getSystem().actorOf(props, "testCloseTransaction");
346
347             watch(subject);
348
349             new Within(duration("2 seconds")) {
350                 @Override
351                 protected void run() {
352
353                     subject.tell(new CloseTransaction().toSerializable(), getRef());
354
355                     final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
356                         // do not put code outside this method, will run afterwards
357                         @Override
358                         protected String match(Object in) {
359                             if (in.getClass().equals(CloseTransactionReply.SERIALIZABLE_CLASS)) {
360                                 return "match";
361                             } else {
362                                 throw noMatch();
363                             }
364                         }
365                     }.get(); // this extracts the received message
366
367                     assertEquals("match", out);
368
369                     final String termination = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
370                         // do not put code outside this method, will run afterwards
371                         @Override
372                         protected String match(Object in) {
373                             if (in instanceof Terminated) {
374                                 return "match";
375                             } else {
376                                 throw noMatch();
377                             }
378                         }
379                     }.get(); // this extracts the received message
380
381
382                     expectNoMsg();
383                 }
384
385
386             };
387         }};
388
389     }
390
391
392   @Test
393   public void testNegativePerformingWriteOperationOnReadTransaction() throws Exception {
394     try {
395
396         final ActorRef shard = getSystem().actorOf(Shard.props(SHARD_IDENTIFIER, Collections.EMPTY_MAP));
397         final Props props =
398             ShardTransaction.props(store.newReadOnlyTransaction(), shard, TestModel.createTestContext());
399          final TestActorRef subject = TestActorRef.apply(props,getSystem());
400
401         subject.receive(new DeleteData(TestModel.TEST_PATH).toSerializable(), ActorRef.noSender());
402         Assert.assertFalse(true);
403
404
405     } catch (Exception cs) {
406       assertEquals(UnknownMessageException.class.getSimpleName(), cs.getClass().getSimpleName());
407       assertTrue(cs.getMessage(), cs.getMessage().startsWith("Unknown message received "));
408     }
409   }
410 }