Optimizations, Monitoring and Logging
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / ShardTest.java
1 package org.opendaylight.controller.cluster.datastore;
2
3 import akka.actor.ActorRef;
4 import akka.actor.Props;
5 import akka.event.Logging;
6 import akka.testkit.JavaTestKit;
7 import junit.framework.Assert;
8 import org.junit.Test;
9 import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
10 import org.opendaylight.controller.cluster.datastore.messages.CreateTransaction;
11 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionChain;
12 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionChainReply;
13 import org.opendaylight.controller.cluster.datastore.messages.EnableNotification;
14 import org.opendaylight.controller.cluster.datastore.messages.PeerAddressResolved;
15 import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListener;
16 import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListenerReply;
17 import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
18 import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
19 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
20 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
21 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
22 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
23 import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
25 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
26
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.Map;
30
31 import static junit.framework.Assert.assertFalse;
32 import static org.junit.Assert.assertEquals;
33 import static org.junit.Assert.assertTrue;
34
35 public class ShardTest extends AbstractActorTest {
36     @Test
37     public void testOnReceiveCreateTransactionChain() throws Exception {
38         new JavaTestKit(getSystem()) {{
39             final ShardIdentifier identifier =
40                 ShardIdentifier.builder().memberName("member-1")
41                     .shardName("inventory").type("config").build();
42
43             final Props props = Shard.props(identifier, Collections.EMPTY_MAP);
44             final ActorRef subject =
45                 getSystem().actorOf(props, "testCreateTransactionChain");
46
47
48             // Wait for a specific log message to show up
49             final boolean result =
50                 new JavaTestKit.EventFilter<Boolean>(Logging.Info.class
51                 ) {
52                     protected Boolean run() {
53                         return true;
54                     }
55                 }.from(subject.path().toString())
56                     .message("Switching from state Candidate to Leader")
57                     .occurrences(1).exec();
58
59             Assert.assertEquals(true, result);
60
61             new Within(duration("1 seconds")) {
62                 protected void run() {
63
64                     subject.tell(new CreateTransactionChain().toSerializable(), getRef());
65
66                     final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
67                         // do not put code outside this method, will run afterwards
68                         protected String match(Object in) {
69                             if (in.getClass().equals(CreateTransactionChainReply.SERIALIZABLE_CLASS)){
70                                 CreateTransactionChainReply reply =
71                                     CreateTransactionChainReply.fromSerializable(getSystem(),in);
72                                 return reply.getTransactionChainPath()
73                                     .toString();
74                             } else {
75                                 throw noMatch();
76                             }
77                         }
78                     }.get(); // this extracts the received message
79
80                     assertEquals("Unexpected transaction path " + out,
81                         "akka://test/user/testCreateTransactionChain/$a",
82                         out);
83
84                     expectNoMsg();
85                 }
86
87
88             };
89         }};
90     }
91
92     @Test
93     public void testOnReceiveRegisterListener() throws Exception {
94         new JavaTestKit(getSystem()) {{
95             final ShardIdentifier identifier =
96                 ShardIdentifier.builder().memberName("member-1")
97                     .shardName("inventory").type("config").build();
98
99             final Props props = Shard.props(identifier, Collections.EMPTY_MAP);
100             final ActorRef subject =
101                 getSystem().actorOf(props, "testRegisterChangeListener");
102
103             new Within(duration("1 seconds")) {
104                 protected void run() {
105
106                     subject.tell(
107                         new UpdateSchemaContext(SchemaContextHelper.full()),
108                         getRef());
109
110                     subject.tell(new RegisterChangeListener(TestModel.TEST_PATH,
111                         getRef().path(), AsyncDataBroker.DataChangeScope.BASE),
112                         getRef());
113
114                     final Boolean notificationEnabled = new ExpectMsg<Boolean>("enable notification") {
115                         // do not put code outside this method, will run afterwards
116                         protected Boolean match(Object in) {
117                             if(in instanceof EnableNotification){
118                                 return ((EnableNotification) in).isEnabled();
119                             } else {
120                                 throw noMatch();
121                             }
122                         }
123                     }.get(); // this extracts the received message
124
125                     assertFalse(notificationEnabled);
126
127                     final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
128                         // do not put code outside this method, will run afterwards
129                         protected String match(Object in) {
130                             if (in.getClass().equals(RegisterChangeListenerReply.class)) {
131                                 RegisterChangeListenerReply reply =
132                                     (RegisterChangeListenerReply) in;
133                                 return reply.getListenerRegistrationPath()
134                                     .toString();
135                             } else {
136                                 throw noMatch();
137                             }
138                         }
139                     }.get(); // this extracts the received message
140
141                     assertTrue(out.matches(
142                         "akka:\\/\\/test\\/user\\/testRegisterChangeListener\\/\\$.*"));
143                 }
144
145
146             };
147         }};
148     }
149
150     @Test
151     public void testCreateTransaction(){
152         new JavaTestKit(getSystem()) {{
153             final ShardIdentifier identifier =
154                 ShardIdentifier.builder().memberName("member-1")
155                     .shardName("inventory").type("config").build();
156
157             final Props props = Shard.props(identifier, Collections.EMPTY_MAP);
158             final ActorRef subject =
159                 getSystem().actorOf(props, "testCreateTransaction");
160
161
162             // Wait for a specific log message to show up
163             final boolean result =
164                 new JavaTestKit.EventFilter<Boolean>(Logging.Info.class
165                 ) {
166                     protected Boolean run() {
167                         return true;
168                     }
169                 }.from(subject.path().toString())
170                     .message("Switching from state Candidate to Leader")
171                     .occurrences(1).exec();
172
173             Assert.assertEquals(true, result);
174
175             new Within(duration("1 seconds")) {
176                 protected void run() {
177
178                     subject.tell(
179                         new UpdateSchemaContext(TestModel.createTestContext()),
180                         getRef());
181
182                     subject.tell(new CreateTransaction("txn-1", TransactionProxy.TransactionType.READ_ONLY.ordinal() ).toSerializable(),
183                         getRef());
184
185                     final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
186                         // do not put code outside this method, will run afterwards
187                         protected String match(Object in) {
188                             if (in instanceof CreateTransactionReply) {
189                                 CreateTransactionReply reply =
190                                     (CreateTransactionReply) in;
191                                 return reply.getTransactionActorPath()
192                                     .toString();
193                             } else {
194                                 throw noMatch();
195                             }
196                         }
197                     }.get(); // this extracts the received message
198
199                     assertTrue("Unexpected transaction path " + out,
200                         out.contains("akka://test/user/testCreateTransaction/shard-txn-1"));
201                     expectNoMsg();
202                 }
203
204
205             };
206         }};
207     }
208
209     @Test
210     public void testPeerAddressResolved(){
211         new JavaTestKit(getSystem()) {{
212             Map<ShardIdentifier, String> peerAddresses = new HashMap<>();
213
214             final ShardIdentifier identifier =
215                 ShardIdentifier.builder().memberName("member-1")
216                     .shardName("inventory").type("config").build();
217
218             peerAddresses.put(identifier, null);
219             final Props props = Shard.props(identifier, peerAddresses);
220             final ActorRef subject =
221                 getSystem().actorOf(props, "testPeerAddressResolved");
222
223             new Within(duration("1 seconds")) {
224                 protected void run() {
225
226                     subject.tell(
227                         new PeerAddressResolved(identifier, "akka://foobar"),
228                         getRef());
229
230                     expectNoMsg();
231                 }
232
233
234             };
235         }};
236     }
237
238     private AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> noOpDataChangeListener() {
239         return new AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>() {
240             @Override
241             public void onDataChanged(
242                 AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
243
244             }
245         };
246     }
247 }