Prevent ConfigPusher from killing its thread
[controller.git] / opendaylight / md-sal / clustered-data-store / implementation / src / test / java / org / opendaylight / controller / datastore / internal / ClusteredDataStoreImplTest.java
1 package org.opendaylight.controller.datastore.internal;
2
3 import org.junit.Before;
4 import org.junit.Test;
5 import org.mockito.Mockito;
6 import org.opendaylight.controller.clustering.services.CacheConfigException;
7 import org.opendaylight.controller.clustering.services.CacheExistException;
8 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
9 import org.opendaylight.controller.clustering.services.IClusterServices;
10 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
11 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
12 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
13 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
14
15 import java.util.EnumSet;
16 import java.util.Map;
17 import java.util.concurrent.ConcurrentHashMap;
18 import java.util.concurrent.ConcurrentMap;
19
20 import static junit.framework.Assert.assertEquals;
21 import static junit.framework.Assert.assertNotNull;
22 import static junit.framework.Assert.assertNull;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.never;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27
28 public class ClusteredDataStoreImplTest {
29     @Before
30     public void setUp(){
31
32     }
33
34     @Test
35     public void constructor_WhenPassedANullClusteringServices_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
36         try {
37             new ClusteredDataStoreImpl(null);
38         } catch(NullPointerException npe){
39             assertEquals("clusterGlobalServices cannot be null", npe.getMessage());
40         }
41     }
42
43     @Test
44     public void constructor_WhenClusteringServicesReturnsANullOperationalDataCache_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
45         try {
46             new ClusteredDataStoreImpl(mock(IClusterGlobalServices.class));
47         } catch(NullPointerException npe){
48             assertEquals("operationalDataCache cannot be null", npe.getMessage());
49         }
50     }
51
52     @Test
53     public void constructor_WhenClusteringServicesReturnsANullOConfigurationDataCache_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
54         IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
55
56         // Confused about the following line?
57         // See this http://stackoverflow.com/questions/10952629/a-strange-generics-edge-case-with-mockito-when-and-generic-type-inference
58         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(new ConcurrentHashMap<Object, Object>());
59
60
61         try {
62             new ClusteredDataStoreImpl(mockClusterGlobalServices);
63         } catch(NullPointerException npe){
64             assertEquals("configurationDataCache cannot be null", npe.getMessage());
65         }
66     }
67
68     @Test
69     public void constructor_WhenOperationalDataCacheIsAlreadyPresent_ShouldNotAttemptToCreateCache() throws CacheExistException, CacheConfigException {
70         IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
71
72         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.getCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE)).thenReturn(new ConcurrentHashMap<Object, Object>());
73         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.getCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE)).thenReturn(new ConcurrentHashMap<Object, Object>());
74
75         new ClusteredDataStoreImpl(mockClusterGlobalServices);
76
77         verify(mockClusterGlobalServices, never()).createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
78     }
79
80     @Test
81     public void constructor_WhenConfigurationDataCacheIsAlreadyPresent_ShouldNotAttemptToCreateCache() throws CacheExistException, CacheConfigException {
82         IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
83
84         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.getCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE)).thenReturn(new ConcurrentHashMap<Object, Object>());
85         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.getCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE)).thenReturn(new ConcurrentHashMap<Object, Object>());
86
87         new ClusteredDataStoreImpl(mockClusterGlobalServices);
88
89         verify(mockClusterGlobalServices, never()).createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
90     }
91
92
93     @Test
94     public void constructor_WhenPassedAValidClusteringServices_ShouldNotThrowAnyExceptions() throws CacheExistException, CacheConfigException {
95         IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
96
97         new ClusteredDataStoreImpl(mockClusterGlobalServices);
98     }
99
100
101     @Test
102     public void readOperationalData_WhenPassedANullPath_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
103         IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
104
105         ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
106
107         try {
108             store.readOperationalData(null);
109         } catch(NullPointerException npe){
110             assertEquals("path cannot be null", npe.getMessage());
111         }
112     }
113
114     @Test
115     public void readOperationalData_WhenPassedAKeyThatDoesNotExistInTheCache_ShouldReturnNull() throws CacheExistException, CacheConfigException {
116         InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
117
118         IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
119
120         ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
121
122         assertNull(store.readOperationalData(path));
123     }
124
125     @Test
126     public void readOperationalData_WhenPassedAKeyThatDoesExistInTheCache_ShouldReturnTheValueObject() throws CacheExistException, CacheConfigException {
127         InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
128
129         IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
130
131         ConcurrentMap<InstanceIdentifier, CompositeNode> mockOperationalDataCache = mock(ConcurrentMap.class);
132
133         CompositeNode valueObject = mock(CompositeNode.class);
134
135         when(mockOperationalDataCache.get(path)).thenReturn(valueObject);
136
137         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache);
138         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(new ConcurrentHashMap<Object, Object>());
139
140
141         ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
142
143         assertEquals(valueObject, store.readOperationalData(path));
144     }
145
146
147
148     @Test
149     public void readConfigurationData_WhenPassedANullPath_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
150
151         IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
152
153         ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
154
155         try {
156             store.readConfigurationData(null);
157         } catch(NullPointerException npe){
158             assertEquals("path cannot be null", npe.getMessage());
159         }
160     }
161
162
163     @Test
164     public void readConfigurationData_WhenPassedAKeyThatDoesNotExistInTheCache_ShouldReturnNull() throws CacheExistException, CacheConfigException {
165         InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
166
167         IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
168
169         ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
170
171         assertNull(store.readConfigurationData(path));
172     }
173
174     @Test
175     public void readConfigurationData_WhenPassedAKeyThatDoesExistInTheCache_ShouldReturnTheValueObject() throws CacheExistException, CacheConfigException {
176         InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
177
178         IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
179
180         ConcurrentMap<InstanceIdentifier, CompositeNode> mockConfigurationDataCache = mock(ConcurrentMap.class);
181
182         CompositeNode valueObject = mock(CompositeNode.class);
183
184         when(mockConfigurationDataCache.get(path)).thenReturn(valueObject);
185
186         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class));
187         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache);
188
189
190         ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
191
192         assertEquals(valueObject, store.readConfigurationData(path));
193     }
194
195
196     @Test
197     public void requestCommit_ShouldReturnADataTransaction() throws CacheExistException, CacheConfigException {
198         IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
199
200         ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
201
202         assertNotNull(store.requestCommit(mock(DataModification.class)));
203
204
205     }
206
207     @Test
208     public void finishingADataTransaction_ShouldUpdateTheUnderlyingCache() throws CacheExistException, CacheConfigException {
209         IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
210
211         ConcurrentMap mockConfigurationDataCache = mock(ConcurrentMap.class);
212         ConcurrentMap mockOperationalDataCache = mock(ConcurrentMap.class);
213
214         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache);
215         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache);
216
217         ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
218
219         DataModification mockModification = mock(DataModification.class);
220
221         Map configurationData = mock(Map.class);
222         Map operationalData = mock(Map.class);
223
224         when(mockModification.getUpdatedConfigurationData()).thenReturn(configurationData);
225         when(mockModification.getUpdatedOperationalData()).thenReturn(operationalData);
226
227         DataCommitHandler.DataCommitTransaction<InstanceIdentifier, CompositeNode> transaction = store.requestCommit(mockModification);
228
229         transaction.finish();
230
231         verify(mockConfigurationDataCache).putAll(mockModification.getUpdatedConfigurationData());
232         verify(mockOperationalDataCache).putAll(mockModification.getUpdatedOperationalData());
233     }
234
235
236     @Test
237     public void rollingBackADataTransaction_ShouldDoNothing() throws CacheExistException, CacheConfigException {
238         IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
239
240         ConcurrentMap mockConfigurationDataCache = mock(ConcurrentMap.class);
241         ConcurrentMap mockOperationalDataCache = mock(ConcurrentMap.class);
242
243         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache);
244         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache);
245
246         ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
247
248         DataModification mockModification = mock(DataModification.class);
249
250         Map configurationData = mock(Map.class);
251         Map operationalData = mock(Map.class);
252
253         when(mockModification.getUpdatedConfigurationData()).thenReturn(configurationData);
254         when(mockModification.getUpdatedOperationalData()).thenReturn(operationalData);
255
256         DataCommitHandler.DataCommitTransaction<InstanceIdentifier, CompositeNode> transaction = store.requestCommit(mockModification);
257
258         transaction.rollback();
259
260         verify(mockConfigurationDataCache, never()).putAll(mockModification.getUpdatedConfigurationData());
261         verify(mockOperationalDataCache, never()).putAll(mockModification.getUpdatedOperationalData());
262
263     }
264
265
266     private IClusterGlobalServices createClusterGlobalServices() throws CacheExistException, CacheConfigException {
267         IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
268
269         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class));
270         Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class));
271
272         return mockClusterGlobalServices;
273     }
274 }