Bump odlparent to 5.0.1
[lispflowmapping.git] / mappingservice / implementation / src / test / java / org / opendaylight / lispflowmapping / implementation / timebucket / TimeBucketWheelUnitTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc.  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.lispflowmapping.implementation.timebucket;
9
10 import java.util.ArrayList;
11 import java.util.Date;
12 import java.util.List;
13 import java.util.concurrent.ConcurrentHashMap;
14 import org.junit.Assert;
15 import org.junit.Test;
16 import org.junit.runner.RunWith;
17 import org.mockito.Mockito;
18 import org.opendaylight.lispflowmapping.config.ConfigIni;
19 import org.opendaylight.lispflowmapping.implementation.MappingSystem;
20 import org.opendaylight.lispflowmapping.implementation.timebucket.containers.TimeBucket;
21 import org.opendaylight.lispflowmapping.implementation.timebucket.containers.TimeBucketWheel;
22 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
23 import org.opendaylight.lispflowmapping.lisp.type.MappingData;
24 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.IpAddressBinary;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.Ipv4AddressBinary;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.SiteId;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
32 import org.powermock.api.mockito.PowerMockito;
33 import org.powermock.core.classloader.annotations.PrepareForTest;
34 import org.powermock.modules.junit4.PowerMockRunner;
35 import org.powermock.reflect.Whitebox;
36
37 /**
38  * Created by Shakib Ahmed on 12/13/16.
39  */
40 @RunWith(PowerMockRunner.class)
41 @PrepareForTest(TimeBucketWheel.class)
42 public class TimeBucketWheelUnitTest {
43
44     private static final String IPV4_STRING_1 =         "1.2.3.0";
45     private static final String IPV4_STRING_2 =         "1.2.4.0";
46     private static final String IPV4_STRING_3 =         "1.2.5.0";
47     private static final String IPV4_STRING_4 =         "1.2.6.0";
48     private static final String IPV4_STRING_5 =         "1.2.7.0";
49     private static final Eid IPV4_EID_1 = LispAddressUtil.asIpv4Eid(IPV4_STRING_1);
50     private static final Eid IPV4_EID_2 = LispAddressUtil.asIpv4Eid(IPV4_STRING_2);
51     private static final Eid IPV4_EID_3 = LispAddressUtil.asIpv4Eid(IPV4_STRING_3);
52     private static final Eid IPV4_EID_4 = LispAddressUtil.asIpv4Eid(IPV4_STRING_4);
53     private static final Eid IPV4_EID_5 = LispAddressUtil.asIpv4Eid(IPV4_STRING_5);
54     private static final IpAddressBinary IPV4_SOURCE_RLOC_1 = new IpAddressBinary(
55             new Ipv4AddressBinary(new byte[] {1, 1, 1, 1}));
56
57     private static final int NUMBER_OF_BUCKETS = 4;
58
59     private static final XtrId XTR_ID_1 = new XtrId(new byte[] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1});
60
61     private static final SiteId SITE_ID_1 = new SiteId(new byte[]{1, 1, 1, 1, 1, 1, 1, 1});
62
63     private static final long REGISTRATION_VALIDITY = ConfigIni.getInstance().getRegistrationValiditySb();
64
65     private static ILispDAO daoMock = Mockito.mock(ILispDAO.class);
66     private static MappingSystem mappingSystem = Mockito.mock(MappingSystem.class);
67
68     /**
69      * Tests {@link TimeBucketWheel#add(Eid, MappingData, long)} method for general case.
70      */
71     @Test
72     public void mappingAddedInTheProperBucketGeneralTest() {
73         PowerMockito.mockStatic(System.class);
74
75         long frozenTimeStamp = System.currentTimeMillis();
76         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
77
78         TimeBucketWheel timeBucketWheel = getDefaultTimeBucketWheel();
79
80         final int bucketId1 = timeBucketWheel.add(IPV4_EID_1, getDefaultMappingData(IPV4_EID_1),
81                 System.currentTimeMillis());
82
83         frozenTimeStamp += 1000;
84         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
85
86         final int bucketId2 = timeBucketWheel.add(IPV4_EID_2, getDefaultMappingData(IPV4_EID_2),
87                 System.currentTimeMillis());
88
89         frozenTimeStamp += 1000;
90         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
91
92         final int bucketId3 = timeBucketWheel.add(IPV4_EID_3, getDefaultMappingData(IPV4_EID_3),
93                 System.currentTimeMillis());
94
95         frozenTimeStamp += 1000;
96         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
97
98         final int bucketId4 = timeBucketWheel.add(IPV4_EID_4, getDefaultMappingData(IPV4_EID_4),
99                 System.currentTimeMillis());
100
101         frozenTimeStamp += 1000;
102         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
103
104         final int bucketId5 = timeBucketWheel.add(IPV4_EID_5, getDefaultMappingData(IPV4_EID_5),
105                 System.currentTimeMillis());
106
107         Assert.assertEquals((bucketId1 - 1 + NUMBER_OF_BUCKETS) % NUMBER_OF_BUCKETS, bucketId2);
108         Assert.assertEquals((bucketId2 - 1 + NUMBER_OF_BUCKETS) % NUMBER_OF_BUCKETS, bucketId3);
109         Assert.assertEquals((bucketId3 - 1 + NUMBER_OF_BUCKETS) % NUMBER_OF_BUCKETS, bucketId4);
110         Assert.assertEquals((bucketId4 - 1 + NUMBER_OF_BUCKETS) % NUMBER_OF_BUCKETS, bucketId5);
111     }
112
113     /**
114      * Tests {@link TimeBucketWheel#add(Eid, MappingData, long)} method for add in some bucket in the middle.
115      */
116     @Test
117     public void mappingAddedInTheProperBucketAddInMiddleTest() throws Exception {
118         PowerMockito.mockStatic(System.class);
119
120         long frozenTimeStamp = System.currentTimeMillis();
121         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
122
123         TimeBucketWheel timeBucketWheel = getDefaultTimeBucketWheel();
124
125         checkTooOldMappingCase(timeBucketWheel);
126
127         checkOlderThanCurrentCase(timeBucketWheel);
128
129     }
130
131     private void checkTooOldMappingCase(TimeBucketWheel timeBucketWheel) throws Exception {
132         long frozenTimeStamp = System.currentTimeMillis() - 10000;
133         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
134
135         int bucketId = timeBucketWheel.add(IPV4_EID_1, getDefaultMappingData(IPV4_EID_1),
136                 System.currentTimeMillis());
137
138         int idOfLastBucketInBucketWheel = Whitebox.invokeMethod(timeBucketWheel,
139                 "getLastBucketId");
140
141         Assert.assertEquals(idOfLastBucketInBucketWheel, bucketId);
142
143         //Time resetting to old frozen time
144         frozenTimeStamp = System.currentTimeMillis() + 10000;
145         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
146     }
147
148     private void checkOlderThanCurrentCase(TimeBucketWheel timeBucketWheel) {
149         long frozenTimeStamp = System.currentTimeMillis();
150
151         int bucketId1 = timeBucketWheel.add(IPV4_EID_1, getDefaultMappingData(IPV4_EID_1),
152                 frozenTimeStamp);
153
154         MappingData toBeExpiredMappingData = getDefaultMappingData(IPV4_EID_2);
155
156         int bucketId2 = timeBucketWheel.add(IPV4_EID_2, toBeExpiredMappingData,
157                 frozenTimeStamp - 1000);
158
159         Assert.assertEquals((bucketId1 + 1) % NUMBER_OF_BUCKETS, bucketId2);
160
161         //expired at proper time
162         frozenTimeStamp = frozenTimeStamp + 3000;
163         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
164
165         timeBucketWheel.clearExpiredMappingAndRotate();
166
167         Mockito.verify(mappingSystem).handleSbExpiredMapping(IPV4_EID_2, null, toBeExpiredMappingData);
168     }
169
170
171     /**
172      * Tests {@link TimeBucketWheel#refreshMappping(Eid, MappingData, long, int)} method.
173      * {@link ClassCastException} can be thrown.
174      */
175     @Test
176     public void mappingRefreshedProperlyTest() {
177         PowerMockito.mockStatic(System.class);
178
179         long frozenTimeStamp = System.currentTimeMillis();
180         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
181
182         TimeBucketWheel timeBucketWheel = getDefaultTimeBucketWheel();
183
184         final int bucketId1 = timeBucketWheel.add(IPV4_EID_1, getDefaultMappingData(IPV4_EID_1),
185                 System.currentTimeMillis());
186
187         frozenTimeStamp += 2000;
188         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
189
190         MappingData newMappingData = getDefaultMappingData(IPV4_EID_1);
191
192         int currentBucketId = timeBucketWheel.refreshMappping(IPV4_EID_1, newMappingData,
193                 System.currentTimeMillis(), bucketId1);
194
195         List<TimeBucket> bucketList = extractBucketList(timeBucketWheel);
196
197         TimeBucket pastTimeBucket = bucketList.get(bucketId1);
198
199         MappingData oldStoredMappingData = getMappingDataFromTimeBucket(pastTimeBucket, IPV4_EID_1);
200
201         Assert.assertNull(oldStoredMappingData);
202
203         TimeBucket presentTimeBucket = bucketList.get(currentBucketId);
204
205         MappingData newStoredMappingData = getMappingDataFromTimeBucket(presentTimeBucket, IPV4_EID_1);
206
207         Assert.assertEquals(newMappingData, newStoredMappingData);
208     }
209
210     private List<TimeBucket> extractBucketList(TimeBucketWheel timeBucketWheel) {
211         List<TimeBucket> bucketList;
212         try {
213             bucketList = (List<TimeBucket>) Whitebox.getInternalState(timeBucketWheel, "bucketList");
214         } catch (ClassCastException e) {
215             throw e;
216         }
217         return bucketList;
218     }
219
220     private MappingData getMappingDataFromTimeBucket(TimeBucket timeBucket, Eid eid) {
221         ConcurrentHashMap<Eid, MappingData> bucketElements;
222
223         try {
224             bucketElements = (ConcurrentHashMap<Eid, MappingData>) Whitebox.getInternalState(timeBucket,
225                     "bucketElements");
226         } catch (ClassCastException e) {
227             throw e;
228         }
229
230         return bucketElements.get(eid);
231     }
232
233     /**
234      * Tests {@link TimeBucketWheel#clearExpiredMappingAndRotate(long)} method.
235      * {@link ClassCastException} can be thrown.
236      */
237     @Test
238     public void expiredMappingClearedProperlyTest() {
239         PowerMockito.mockStatic(System.class);
240
241         long frozenTimeStamp = System.currentTimeMillis();
242         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
243
244         TimeBucketWheel timeBucketWheel = getDefaultTimeBucketWheel();
245
246         MappingData mappingData = getDefaultMappingData(IPV4_EID_1);
247         timeBucketWheel.add(IPV4_EID_1, mappingData,
248                 System.currentTimeMillis());
249
250         frozenTimeStamp = System.currentTimeMillis() + 4000;
251         PowerMockito.when(System.currentTimeMillis()).thenReturn(frozenTimeStamp);
252
253         timeBucketWheel.clearExpiredMappingAndRotate(frozenTimeStamp);
254
255         Mockito.verify(mappingSystem).handleSbExpiredMapping(IPV4_EID_1, null, mappingData);
256     }
257
258
259     private MappingData getDefaultMappingDataWithProperTimestamp(Eid eid, long timeStamp) {
260         MappingData mappingData = getDefaultMappingData(eid);
261         Date date = new Date();
262         date.setTime(timeStamp);
263         mappingData.setTimestamp(date);
264         return mappingData;
265     }
266
267     private static TimeBucketWheel getDefaultTimeBucketWheel() {
268         return new TimeBucketWheel(4, 3000, mappingSystem);
269     }
270
271     private static MappingData getDefaultMappingData(Eid eid) {
272         return getDefaultMappingData(eid,null);
273     }
274
275     private static MappingData getDefaultMappingData(Eid eid, MappingRecord mappingRecord) {
276         if (mappingRecord == null) {
277             mappingRecord = getDefaultMappingRecordBuilder(eid).build();
278         }
279         return new MappingData(mappingRecord, System.currentTimeMillis());
280     }
281
282     private static MappingRecordBuilder getDefaultMappingRecordBuilder(Eid eid) {
283         return new MappingRecordBuilder()
284                 .setEid(eid)
285                 .setLocatorRecord(new ArrayList<>())
286                 .setRecordTtl(2)
287                 .setAction(MappingRecord.Action.NativelyForward)
288                 .setAuthoritative(true)
289                 .setMapVersion((short) 1)
290                 .setSiteId(SITE_ID_1)
291                 .setSourceRloc(IPV4_SOURCE_RLOC_1)
292                 .setTimestamp(new Date().getTime())
293                 .setXtrId(XTR_ID_1);
294     }
295 }