Deprecate DOMDataTreeProducer-related classes
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / sharding / CDSShardAccessImplTest.java
1 /*
2  * Copyright (c) 2017 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 package org.opendaylight.controller.cluster.sharding;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
12 import static org.junit.Assert.fail;
13 import static org.mockito.ArgumentMatchers.any;
14 import static org.mockito.ArgumentMatchers.eq;
15 import static org.mockito.Mockito.doNothing;
16 import static org.mockito.Mockito.doReturn;
17 import static org.mockito.Mockito.doThrow;
18 import static org.mockito.Mockito.mock;
19 import static org.mockito.Mockito.verify;
20 import static org.mockito.Mockito.verifyNoMoreInteractions;
21
22 import akka.actor.ActorRef;
23 import akka.dispatch.Futures;
24 import java.util.Optional;
25 import java.util.concurrent.TimeUnit;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.opendaylight.controller.cluster.datastore.AbstractActorTest;
29 import org.opendaylight.controller.cluster.datastore.DatastoreContext;
30 import org.opendaylight.controller.cluster.datastore.exceptions.LocalShardNotFoundException;
31 import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
32 import org.opendaylight.controller.cluster.dom.api.LeaderLocation;
33 import org.opendaylight.controller.cluster.dom.api.LeaderLocationListener;
34 import org.opendaylight.controller.cluster.dom.api.LeaderLocationListenerRegistration;
35 import org.opendaylight.controller.cluster.raft.LeadershipTransferFailedException;
36 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
37 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
38 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
39 import scala.concurrent.Future;
40 import scala.concurrent.duration.FiniteDuration;
41
42 @Deprecated(forRemoval = true)
43 public class CDSShardAccessImplTest extends AbstractActorTest {
44
45     private static final DOMDataTreeIdentifier TEST_ID =
46             new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH);
47
48     private CDSShardAccessImpl shardAccess;
49     private ActorUtils context;
50
51     @Before
52     public void setUp() {
53         context = mock(ActorUtils.class);
54         final DatastoreContext datastoreContext = DatastoreContext.newBuilder().build();
55         doReturn(Optional.of(getSystem().deadLetters())).when(context).findLocalShard(any());
56         doReturn(datastoreContext).when(context).getDatastoreContext();
57         doReturn(getSystem()).when(context).getActorSystem();
58         shardAccess = new CDSShardAccessImpl(TEST_ID, context);
59     }
60
61     @Test
62     @SuppressWarnings("checkstyle:IllegalCatch")
63     public void testRegisterLeaderLocationListener() {
64         final LeaderLocationListener listener1 = mock(LeaderLocationListener.class);
65
66         // first registration should be OK
67         shardAccess.registerLeaderLocationListener(listener1);
68
69         // second registration should fail with IllegalArgumentEx
70         try {
71             shardAccess.registerLeaderLocationListener(listener1);
72             fail("Should throw exception");
73         } catch (final Exception e) {
74             assertTrue(e instanceof IllegalArgumentException);
75         }
76
77         // null listener registration should fail with NPE
78         try {
79             shardAccess.registerLeaderLocationListener(null);
80             fail("Should throw exception");
81         } catch (final Exception e) {
82             assertTrue(e instanceof NullPointerException);
83         }
84
85         // registering listener on closed shard access should fail with IllegalStateEx
86         final LeaderLocationListener listener2 = mock(LeaderLocationListener.class);
87         shardAccess.close();
88         try {
89             shardAccess.registerLeaderLocationListener(listener2);
90             fail("Should throw exception");
91         } catch (final Exception ex) {
92             assertTrue(ex instanceof IllegalStateException);
93         }
94     }
95
96     @Test
97     @SuppressWarnings("checkstyle:IllegalCatch")
98     public void testOnLeaderLocationChanged() {
99         final LeaderLocationListener listener1 = mock(LeaderLocationListener.class);
100         doThrow(new RuntimeException("Failed")).when(listener1).onLeaderLocationChanged(any());
101         final LeaderLocationListener listener2 = mock(LeaderLocationListener.class);
102         doNothing().when(listener2).onLeaderLocationChanged(any());
103         final LeaderLocationListener listener3 = mock(LeaderLocationListener.class);
104         doNothing().when(listener3).onLeaderLocationChanged(any());
105
106         final LeaderLocationListenerRegistration<?> reg1 = shardAccess.registerLeaderLocationListener(listener1);
107         final LeaderLocationListenerRegistration<?> reg2 = shardAccess.registerLeaderLocationListener(listener2);
108         final LeaderLocationListenerRegistration<?> reg3 = shardAccess.registerLeaderLocationListener(listener3);
109
110         // Error in listener1 should not affect dispatching change to other listeners
111         shardAccess.onLeaderLocationChanged(LeaderLocation.LOCAL);
112         verify(listener1).onLeaderLocationChanged(eq(LeaderLocation.LOCAL));
113         verify(listener2).onLeaderLocationChanged(eq(LeaderLocation.LOCAL));
114         verify(listener3).onLeaderLocationChanged(eq(LeaderLocation.LOCAL));
115
116         // Closed listeners shouldn't see new leader location changes
117         reg1.close();
118         reg2.close();
119         shardAccess.onLeaderLocationChanged(LeaderLocation.REMOTE);
120         verify(listener3).onLeaderLocationChanged(eq(LeaderLocation.REMOTE));
121         verifyNoMoreInteractions(listener1);
122         verifyNoMoreInteractions(listener2);
123
124         // Closed shard access should not dispatch any new events
125         shardAccess.close();
126         shardAccess.onLeaderLocationChanged(LeaderLocation.UNKNOWN);
127         verifyNoMoreInteractions(listener1);
128         verifyNoMoreInteractions(listener2);
129         verifyNoMoreInteractions(listener3);
130
131         reg3.close();
132     }
133
134     @Test
135     @SuppressWarnings("checkstyle:IllegalCatch")
136     public void testGetShardIdentifier() {
137         assertEquals(shardAccess.getShardIdentifier(), TEST_ID);
138
139         // closed shard access should throw illegal state
140         shardAccess.close();
141         try {
142             shardAccess.getShardIdentifier();
143             fail("Exception expected");
144         } catch (final Exception e) {
145             assertTrue(e instanceof IllegalStateException);
146         }
147     }
148
149     @Test
150     @SuppressWarnings("checkstyle:IllegalCatch")
151     public void testGetLeaderLocation() {
152         // new shard access does not know anything about leader location
153         assertEquals(shardAccess.getLeaderLocation(), LeaderLocation.UNKNOWN);
154
155         // we start getting leader location changes notifications
156         shardAccess.onLeaderLocationChanged(LeaderLocation.LOCAL);
157         assertEquals(shardAccess.getLeaderLocation(), LeaderLocation.LOCAL);
158
159         shardAccess.onLeaderLocationChanged(LeaderLocation.REMOTE);
160         shardAccess.onLeaderLocationChanged(LeaderLocation.UNKNOWN);
161         assertEquals(shardAccess.getLeaderLocation(), LeaderLocation.UNKNOWN);
162
163         // closed shard access throws illegal state
164         shardAccess.close();
165         try {
166             shardAccess.getLeaderLocation();
167             fail("Should have failed with IllegalStateEx");
168         } catch (Exception e) {
169             assertTrue(e instanceof IllegalStateException);
170         }
171     }
172
173     @Test
174     @SuppressWarnings("checkstyle:IllegalCatch")
175     public void testMakeLeaderLocal() throws Exception {
176         final FiniteDuration timeout = new FiniteDuration(5, TimeUnit.SECONDS);
177         final ActorRef localShardRef = mock(ActorRef.class);
178         final Future<ActorRef> localShardRefFuture = Futures.successful(localShardRef);
179         doReturn(localShardRefFuture).when(context).findLocalShardAsync(any());
180
181         // MakeLeaderLocal will reply with success
182         doReturn(Futures.successful(null)).when(context).executeOperationAsync((ActorRef) any(), any(), any());
183         doReturn(getSystem().dispatcher()).when(context).getClientDispatcher();
184         assertEquals(waitOnAsyncTask(shardAccess.makeLeaderLocal(), timeout), null);
185
186         // MakeLeaderLocal will reply with failure
187         doReturn(Futures.failed(new LeadershipTransferFailedException("Failure")))
188                 .when(context).executeOperationAsync((ActorRef) any(), any(), any());
189
190         try {
191             waitOnAsyncTask(shardAccess.makeLeaderLocal(), timeout);
192             fail("makeLeaderLocal operation should not be successful");
193         } catch (final Exception e) {
194             assertTrue(e instanceof LeadershipTransferFailedException);
195         }
196
197         // we don't even find local shard
198         doReturn(Futures.failed(new LocalShardNotFoundException("Local shard not found")))
199                 .when(context).findLocalShardAsync(any());
200
201         try {
202             waitOnAsyncTask(shardAccess.makeLeaderLocal(), timeout);
203             fail("makeLeaderLocal operation should not be successful");
204         } catch (final Exception e) {
205             assertTrue(e instanceof LeadershipTransferFailedException);
206             assertTrue(e.getCause() instanceof LocalShardNotFoundException);
207         }
208
209         // closed shard access should throw IllegalStateEx
210         shardAccess.close();
211         try {
212             shardAccess.makeLeaderLocal();
213             fail("Should have thrown IllegalStateEx. ShardAccess is closed");
214         } catch (final Exception e) {
215             assertTrue(e instanceof IllegalStateException);
216         }
217     }
218 }