blob: ee4d75c0b48680de240f7fcdd4e59ff75b6f57ac [file] [log] [blame]
Pier Luigif094c612017-10-14 12:15:02 +02001/*
2 * Copyright 2017-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Thomas Vachuska52f2cd12018-11-08 21:20:04 -080017package org.onosproject.store.meter.impl;
Pier Luigif094c612017-10-14 12:15:02 +020018
Charles Chan593acf92017-11-22 13:55:41 -080019import com.google.common.collect.Lists;
Pier Luigif094c612017-10-14 12:15:02 +020020import org.junit.After;
21import org.junit.Before;
22import org.junit.Test;
23import org.onlab.junit.TestUtils;
Charles Chan593acf92017-11-22 13:55:41 -080024import org.onlab.util.KryoNamespace;
25import org.onosproject.TestApplicationId;
Pier Luigif094c612017-10-14 12:15:02 +020026import org.onosproject.net.DeviceId;
27import org.onosproject.net.behaviour.MeterQuery;
28import org.onosproject.net.driver.Behaviour;
29import org.onosproject.net.driver.Driver;
30import org.onosproject.net.driver.DriverData;
31import org.onosproject.net.driver.DriverHandler;
32import org.onosproject.net.driver.DriverServiceAdapter;
33import org.onosproject.net.meter.Band;
34import org.onosproject.net.meter.DefaultBand;
35import org.onosproject.net.meter.DefaultMeter;
36import org.onosproject.net.meter.DefaultMeterFeatures;
37import org.onosproject.net.meter.Meter;
pierventre3b39bd82021-08-18 09:40:14 +020038import org.onosproject.net.meter.MeterCellId;
Pier Luigif094c612017-10-14 12:15:02 +020039import org.onosproject.net.meter.MeterFeatures;
Pier Luigif094c612017-10-14 12:15:02 +020040import org.onosproject.net.meter.MeterId;
41import org.onosproject.net.meter.MeterKey;
pierventre3b39bd82021-08-18 09:40:14 +020042import org.onosproject.net.meter.MeterScope;
Pier Luigif094c612017-10-14 12:15:02 +020043import org.onosproject.net.meter.MeterState;
pierventre3b39bd82021-08-18 09:40:14 +020044import org.onosproject.net.meter.MeterTableKey;
45import org.onosproject.net.pi.model.PiMeterId;
46import org.onosproject.net.pi.runtime.PiMeterCellId;
Charles Chan593acf92017-11-22 13:55:41 -080047import org.onosproject.store.service.Serializer;
Pier Luigif094c612017-10-14 12:15:02 +020048import org.onosproject.store.service.TestStorageService;
49
pierventre44220052020-09-22 12:51:06 +020050import java.util.Collection;
Pier Luigif094c612017-10-14 12:15:02 +020051import java.util.Collections;
52import java.util.HashSet;
Pier Luigif094c612017-10-14 12:15:02 +020053import java.util.concurrent.CompletableFuture;
54import java.util.concurrent.ExecutionException;
55
56import static org.hamcrest.Matchers.is;
57import static org.junit.Assert.*;
58import static org.onosproject.net.NetTestTools.APP_ID;
Daniele Moro43ac2892021-07-15 17:02:59 +020059import static org.onosproject.net.NetTestTools.APP_ID_2;
Pier Luigif094c612017-10-14 12:15:02 +020060import static org.onosproject.net.NetTestTools.did;
61
62/**
63 * Meter store tests.
64 */
65public class DistributedMeterStoreTest {
pierventre26ac1512021-09-10 09:37:29 +020066
Pier Luigif094c612017-10-14 12:15:02 +020067 private DistributedMeterStore meterStore;
68
Pier Luigif094c612017-10-14 12:15:02 +020069 private DeviceId did1 = did("1");
70 private DeviceId did2 = did("2");
71 private DeviceId did3 = did("3");
72 private DeviceId did4 = did("4");
73
Pier Luigif094c612017-10-14 12:15:02 +020074 private MeterId mid1 = MeterId.meterId(1);
75 private MeterId mid2 = MeterId.meterId(2);
Daniele Moro43ac2892021-07-15 17:02:59 +020076 private MeterId mid3 = MeterId.meterId(3);
pierventre26ac1512021-09-10 09:37:29 +020077 private MeterId mid5 = MeterId.meterId(5);
78 private MeterId mid6 = MeterId.meterId(6);
Pier Luigibdcd9672017-10-13 13:54:48 +020079 private MeterId mid10 = MeterId.meterId(10);
pierventre3b39bd82021-08-18 09:40:14 +020080 private MeterCellId cid4 = PiMeterCellId.ofIndirect(
81 PiMeterId.of("foo"), 4);
82 private MeterCellId invalidCid = PiMeterCellId.ofIndirect(
83 PiMeterId.of("foo"), 11);
Pier Luigif094c612017-10-14 12:15:02 +020084
Pier Luigif094c612017-10-14 12:15:02 +020085 private Band b1 = DefaultBand.builder()
86 .ofType(Band.Type.DROP)
87 .withRate(500)
88 .build();
89
Pier Luigif094c612017-10-14 12:15:02 +020090 private Meter m1 = DefaultMeter.builder()
91 .forDevice(did1)
92 .fromApp(APP_ID)
93 .withId(mid1)
94 .withUnit(Meter.Unit.KB_PER_SEC)
95 .withBands(Collections.singletonList(b1))
96 .build();
Daniele Moro43ac2892021-07-15 17:02:59 +020097 private Meter m2 = DefaultMeter.builder()
98 .forDevice(did1)
99 .fromApp(APP_ID_2)
100 .withCellId(mid2)
101 .withUnit(Meter.Unit.KB_PER_SEC)
102 .withBands(Collections.singletonList(b1))
103 .build();
Daniele Moro43ac2892021-07-15 17:02:59 +0200104 private Meter m3 = DefaultMeter.builder()
105 .forDevice(did2)
106 .fromApp(APP_ID_2)
107 .withCellId(mid3)
108 .withUnit(Meter.Unit.KB_PER_SEC)
109 .withBands(Collections.singletonList(b1))
110 .build();
pierventre3b39bd82021-08-18 09:40:14 +0200111 private Meter m4 = DefaultMeter.builder()
112 .forDevice(did3)
113 .fromApp(APP_ID)
114 .withCellId(cid4)
115 .withUnit(Meter.Unit.KB_PER_SEC)
116 .withBands(Collections.singletonList(b1))
117 .build();
118
Pier Luigif094c612017-10-14 12:15:02 +0200119 private MeterFeatures mef1 = DefaultMeterFeatures.builder().forDevice(did1)
120 .withMaxMeters(3L)
121 .withBandTypes(new HashSet<>())
122 .withUnits(new HashSet<>())
123 .hasStats(false)
124 .hasBurst(false)
125 .withMaxBands((byte) 0)
126 .withMaxColors((byte) 0)
127 .build();
128 private MeterFeatures mef2 = DefaultMeterFeatures.builder().forDevice(did2)
129 .withMaxMeters(10L)
130 .withBandTypes(new HashSet<>())
131 .withUnits(new HashSet<>())
132 .hasStats(false)
133 .hasBurst(false)
134 .withMaxBands((byte) 0)
135 .withMaxColors((byte) 0)
136 .build();
pierventre3b39bd82021-08-18 09:40:14 +0200137 private MeterFeatures mef3 = DefaultMeterFeatures.builder().forDevice(did3)
138 .withStartIndex(0L)
139 .withEndIndex(10L)
140 .withScope(MeterScope.of("foo"))
141 .withBandTypes(new HashSet<>())
142 .withUnits(new HashSet<>())
143 .hasStats(false)
144 .hasBurst(false)
145 .withMaxBands((byte) 0)
146 .withMaxColors((byte) 0)
147 .build();
Pier Luigif094c612017-10-14 12:15:02 +0200148
149 @Before
150 public void setup() {
Pier Luigif094c612017-10-14 12:15:02 +0200151 meterStore = new DistributedMeterStore();
pierventre26ac1512021-09-10 09:37:29 +0200152
Pier Luigif094c612017-10-14 12:15:02 +0200153 TestUtils.setField(meterStore, "storageService", new TestStorageService());
Pier Luigif094c612017-10-14 12:15:02 +0200154 TestUtils.setField(meterStore, "driverService", new TestDriverService());
Charles Chan593acf92017-11-22 13:55:41 -0800155 KryoNamespace.Builder testKryoBuilder = TestUtils.getField(meterStore, "APP_KRYO_BUILDER");
156 testKryoBuilder.register(TestApplicationId.class);
157 Serializer testSerializer = Serializer.using(Lists.newArrayList(testKryoBuilder.build()));
158 TestUtils.setField(meterStore, "serializer", testSerializer);
159
Pier Luigif094c612017-10-14 12:15:02 +0200160 meterStore.activate();
161 }
162
163 @After
164 public void tearDown() {
Pier Luigif094c612017-10-14 12:15:02 +0200165 meterStore.deactivate();
166 }
167
pierventre3b39bd82021-08-18 09:40:14 +0200168 private void initMeterStore(boolean enableUserDefinedIndex) {
169 meterStore.userDefinedIndexMode(enableUserDefinedIndex);
Pier Luigif094c612017-10-14 12:15:02 +0200170 meterStore.storeMeterFeatures(mef1);
Pier Luigif094c612017-10-14 12:15:02 +0200171 meterStore.storeMeterFeatures(mef2);
pierventre3b39bd82021-08-18 09:40:14 +0200172 meterStore.storeMeterFeatures(mef3);
Pier Luigif094c612017-10-14 12:15:02 +0200173 }
174
175 /**
176 * Test proper store of meter features.
177 */
178 @Test
179 public void testStoreMeterFeatures() {
pierventre26ac1512021-09-10 09:37:29 +0200180 initMeterStore(false);
181
182 assertThat(meterStore.getMaxMeters(MeterTableKey.key(did1, MeterScope.globalScope())), is(3L));
183 assertThat(meterStore.getMaxMeters(MeterTableKey.key(did2, MeterScope.globalScope())), is(10L));
Pier Luigif094c612017-10-14 12:15:02 +0200184 }
185
186 /**
187 * Test proper delete of meter features.
188 */
189 @Test
190 public void testDeleteMeterFeatures() {
pierventre26ac1512021-09-10 09:37:29 +0200191 initMeterStore(false);
192 assertThat(meterStore.getMaxMeters(MeterTableKey.key(did1, MeterScope.globalScope())), is(3L));
193
Pier Luigif094c612017-10-14 12:15:02 +0200194 meterStore.deleteMeterFeatures(did1);
pierventre26ac1512021-09-10 09:37:29 +0200195 assertThat(meterStore.getMaxMeters(MeterTableKey.key(did1, MeterScope.globalScope())), is(0L));
Pier Luigif094c612017-10-14 12:15:02 +0200196 }
197
198 /**
199 * Test proper allocation of meter ids.
200 */
201 @Test
202 public void testAllocateId() {
pierventre3b39bd82021-08-18 09:40:14 +0200203 initMeterStore(false);
pierventre26ac1512021-09-10 09:37:29 +0200204
205 assertThat(mid1, is(meterStore.allocateMeterId(did1, MeterScope.globalScope())));
206 assertThat(mid2, is(meterStore.allocateMeterId(did1, MeterScope.globalScope())));
Pier Luigif094c612017-10-14 12:15:02 +0200207 }
208
209 /**
210 * Test proper free of meter ids.
211 */
212 @Test
213 public void testFreeId() {
pierventre3b39bd82021-08-18 09:40:14 +0200214 initMeterStore(false);
pierventre26ac1512021-09-10 09:37:29 +0200215 assertThat(mid1, is(meterStore.allocateMeterId(did1, MeterScope.globalScope())));
216
217 // Verify reuse strategy
Pier Luigif094c612017-10-14 12:15:02 +0200218 meterStore.freeMeterId(did1, mid1);
pierventre26ac1512021-09-10 09:37:29 +0200219 assertThat(mid1, is(meterStore.allocateMeterId(did1, MeterScope.globalScope())));
220
221 // Following free does not have effect
Pier Luigibdcd9672017-10-13 13:54:48 +0200222 meterStore.freeMeterId(did1, mid10);
pierventre26ac1512021-09-10 09:37:29 +0200223 assertThat(mid2, is(meterStore.allocateMeterId(did1, MeterScope.globalScope())));
Pier Luigif094c612017-10-14 12:15:02 +0200224 }
225
226 /**
227 * Test proper reuse of meter ids.
228 */
229 @Test
230 public void testReuseId() {
pierventre3b39bd82021-08-18 09:40:14 +0200231 initMeterStore(false);
pierventre26ac1512021-09-10 09:37:29 +0200232
233 MeterCellId meterIdOne = meterStore.allocateMeterId(did2, MeterScope.globalScope());
Pier Luigif094c612017-10-14 12:15:02 +0200234 meterStore.freeMeterId(did2, meterIdOne);
pierventre26ac1512021-09-10 09:37:29 +0200235 CompletableFuture<MeterCellId> future = CompletableFuture.supplyAsync(
236 () -> meterStore.allocateMeterId(did2, MeterScope.globalScope())
Pier Luigif094c612017-10-14 12:15:02 +0200237 );
pierventre26ac1512021-09-10 09:37:29 +0200238 MeterCellId meterIdTwo = meterStore.allocateMeterId(did2, MeterScope.globalScope());
Pier Luigif094c612017-10-14 12:15:02 +0200239 try {
240 meterIdOne = future.get();
241 } catch (InterruptedException | ExecutionException e) {
242 e.printStackTrace();
243 }
Pier Luigif094c612017-10-14 12:15:02 +0200244 assertNotEquals("Ids should be different", meterIdOne, meterIdTwo);
245
Pier Luigif094c612017-10-14 12:15:02 +0200246 meterStore.freeMeterId(did1, meterIdOne);
Pier Luigif094c612017-10-14 12:15:02 +0200247 meterStore.freeMeterId(did1, meterIdTwo);
pierventre26ac1512021-09-10 09:37:29 +0200248 meterIdOne = meterStore.allocateMeterId(did2, MeterScope.globalScope());
249 meterStore.allocateMeterId(did2, MeterScope.globalScope());
250 MeterCellId meterIdThree = meterStore.allocateMeterId(did2, MeterScope.globalScope());
251 MeterCellId meterIdFour = meterStore.allocateMeterId(did2, MeterScope.globalScope());
Pier Luigif094c612017-10-14 12:15:02 +0200252 meterStore.freeMeterId(did1, meterIdOne);
Pier Luigif094c612017-10-14 12:15:02 +0200253 meterStore.freeMeterId(did1, meterIdThree);
Pier Luigif094c612017-10-14 12:15:02 +0200254 meterStore.freeMeterId(did1, meterIdFour);
Pier Luigif094c612017-10-14 12:15:02 +0200255 future = CompletableFuture.supplyAsync(
pierventre26ac1512021-09-10 09:37:29 +0200256 () -> meterStore.allocateMeterId(did2, MeterScope.globalScope())
Pier Luigif094c612017-10-14 12:15:02 +0200257 );
pierventre26ac1512021-09-10 09:37:29 +0200258 MeterCellId meterAnotherId = meterStore.allocateMeterId(did2, MeterScope.globalScope());
Pier Luigif094c612017-10-14 12:15:02 +0200259 try {
260 meterAnotherId = future.get();
261 } catch (InterruptedException | ExecutionException e) {
262 e.printStackTrace();
263 }
Pier Luigif094c612017-10-14 12:15:02 +0200264 assertNotEquals("Ids should be different", meterAnotherId, meterIdOne);
265 }
266
267 /**
268 * Test query meters mechanism.
269 */
270 @Test
271 public void testQueryMeters() {
pierventre3b39bd82021-08-18 09:40:14 +0200272 initMeterStore(false);
pierventre26ac1512021-09-10 09:37:29 +0200273
274 assertThat(mid1, is(meterStore.allocateMeterId(did3, MeterScope.globalScope())));
275 assertNull(meterStore.allocateMeterId(did4, MeterScope.globalScope()));
Pier Luigif094c612017-10-14 12:15:02 +0200276 }
277
278 /**
279 * Test max meter error.
280 */
281 @Test
282 public void testMaxMeterError() {
pierventre3b39bd82021-08-18 09:40:14 +0200283 initMeterStore(false);
pierventre26ac1512021-09-10 09:37:29 +0200284
285 assertThat(mid1, is(meterStore.allocateMeterId(did1, MeterScope.globalScope())));
286 assertThat(mid2, is(meterStore.allocateMeterId(did1, MeterScope.globalScope())));
287 assertThat(mid3, is(meterStore.allocateMeterId(did1, MeterScope.globalScope())));
288 assertNull(meterStore.allocateMeterId(did1, MeterScope.globalScope()));
Pier Luigif094c612017-10-14 12:15:02 +0200289 }
290
291 /**
292 * Test store meter.
293 */
294 @Test
295 public void testStoreMeter() {
pierventre3b39bd82021-08-18 09:40:14 +0200296 initMeterStore(false);
pierventre26ac1512021-09-10 09:37:29 +0200297
298 MeterCellId idOne = meterStore.allocateMeterId(did1, MeterScope.globalScope());
Pier Luigif094c612017-10-14 12:15:02 +0200299 assertThat(mid1, is(idOne));
pierventre26ac1512021-09-10 09:37:29 +0200300
Pier Luigif094c612017-10-14 12:15:02 +0200301 Meter meterOne = DefaultMeter.builder()
302 .forDevice(did1)
303 .fromApp(APP_ID)
304 .withId(mid1)
305 .withUnit(Meter.Unit.KB_PER_SEC)
306 .withBands(Collections.singletonList(b1))
307 .build();
Pier Luigif094c612017-10-14 12:15:02 +0200308 ((DefaultMeter) meterOne).setState(MeterState.PENDING_ADD);
pierventre26ac1512021-09-10 09:37:29 +0200309 meterStore.addOrUpdateMeter(meterOne);
Pier Luigif094c612017-10-14 12:15:02 +0200310 MeterKey meterKey = MeterKey.key(did1, mid1);
Pier Luigif094c612017-10-14 12:15:02 +0200311 assertThat(1, is(meterStore.getAllMeters().size()));
312 assertThat(1, is(meterStore.getAllMeters(did1).size()));
313 assertThat(m1, is(meterStore.getMeter(meterKey)));
314 }
315
316 /**
317 * Test delete meter.
318 */
319 @Test
320 public void testDeleteMeter() {
pierventre3b39bd82021-08-18 09:40:14 +0200321 initMeterStore(false);
pierventre26ac1512021-09-10 09:37:29 +0200322
323 MeterCellId idOne = meterStore.allocateMeterId(did1, MeterScope.globalScope());
Pier Luigif094c612017-10-14 12:15:02 +0200324 assertThat(mid1, is(idOne));
pierventre26ac1512021-09-10 09:37:29 +0200325
Pier Luigif094c612017-10-14 12:15:02 +0200326 Meter meterOne = DefaultMeter.builder()
327 .forDevice(did1)
328 .fromApp(APP_ID)
329 .withId(mid1)
330 .withUnit(Meter.Unit.KB_PER_SEC)
331 .withBands(Collections.singletonList(b1))
332 .build();
Pier Luigif094c612017-10-14 12:15:02 +0200333 ((DefaultMeter) meterOne).setState(MeterState.PENDING_ADD);
pierventre26ac1512021-09-10 09:37:29 +0200334 meterStore.addOrUpdateMeter(meterOne);
Pier Luigif094c612017-10-14 12:15:02 +0200335 ((DefaultMeter) meterOne).setState(MeterState.PENDING_REMOVE);
Pier Luigif094c612017-10-14 12:15:02 +0200336 MeterKey meterKey = MeterKey.key(did1, mid1);
Pier Luigif094c612017-10-14 12:15:02 +0200337 meterStore.deleteMeter(meterOne);
Pier Luigif094c612017-10-14 12:15:02 +0200338 CompletableFuture<Void> future = CompletableFuture.runAsync(
pierventre26ac1512021-09-10 09:37:29 +0200339 () -> meterStore.purgeMeter(meterOne)
Pier Luigif094c612017-10-14 12:15:02 +0200340 );
Pier Luigif094c612017-10-14 12:15:02 +0200341 try {
342 future.get();
343 } catch (InterruptedException | ExecutionException e) {
344 e.printStackTrace();
345 }
Pier Luigif094c612017-10-14 12:15:02 +0200346 assertThat(0, is(meterStore.getAllMeters().size()));
347 assertThat(0, is(meterStore.getAllMeters(did1).size()));
348 assertNull(meterStore.getMeter(meterKey));
pierventre26ac1512021-09-10 09:37:29 +0200349 assertThat(mid1, is(meterStore.allocateMeterId(did1, MeterScope.globalScope())));
Pier Luigif094c612017-10-14 12:15:02 +0200350 }
351
352 /**
353 * Test no delete meter.
354 */
355 @Test
356 public void testNoDeleteMeter() {
pierventre3b39bd82021-08-18 09:40:14 +0200357 initMeterStore(false);
pierventre26ac1512021-09-10 09:37:29 +0200358
359 MeterCellId idOne = meterStore.allocateMeterId(did1, MeterScope.globalScope());
Pier Luigif094c612017-10-14 12:15:02 +0200360 MeterKey keyOne = MeterKey.key(did1, idOne);
Pier Luigif094c612017-10-14 12:15:02 +0200361 Meter meterOne = DefaultMeter.builder()
362 .forDevice(did1)
363 .fromApp(APP_ID)
364 .withId(mid1)
365 .withUnit(Meter.Unit.KB_PER_SEC)
366 .withBands(Collections.singletonList(b1))
367 .build();
Pier Luigif094c612017-10-14 12:15:02 +0200368 ((DefaultMeter) meterOne).setState(MeterState.PENDING_REMOVE);
Pier Luigif094c612017-10-14 12:15:02 +0200369 meterStore.deleteMeter(meterOne);
Pier Luigif094c612017-10-14 12:15:02 +0200370 assertThat(0, is(meterStore.getAllMeters().size()));
371 assertThat(0, is(meterStore.getAllMeters(did1).size()));
372 assertNull(meterStore.getMeter(keyOne));
373 }
374
pierventre1b8afbc2020-07-13 14:07:05 +0200375 /**
376 * Test purge meter.
377 */
378 @Test
pierventre26ac1512021-09-10 09:37:29 +0200379 public void testPurgeMeters() {
pierventre1b8afbc2020-07-13 14:07:05 +0200380 testStoreMeter();
pierventre26ac1512021-09-10 09:37:29 +0200381
382 meterStore.purgeMeters(did1);
pierventre1b8afbc2020-07-13 14:07:05 +0200383 MeterKey keyOne = MeterKey.key(did1, mid1);
384 assertThat(0, is(meterStore.getAllMeters().size()));
385 assertThat(0, is(meterStore.getAllMeters(did1).size()));
386 assertNull(meterStore.getMeter(keyOne));
Pier Luigif094c612017-10-14 12:15:02 +0200387 }
388
pierventre44220052020-09-22 12:51:06 +0200389 /**
Daniele Moro43ac2892021-07-15 17:02:59 +0200390 * Test purge meter given device and application.
391 */
392 @Test
pierventre26ac1512021-09-10 09:37:29 +0200393 public void testPurgeMetersDeviceAndApp() {
pierventre3b39bd82021-08-18 09:40:14 +0200394 initMeterStore(false);
pierventre26ac1512021-09-10 09:37:29 +0200395
Daniele Moro43ac2892021-07-15 17:02:59 +0200396 ((DefaultMeter) m1).setState(MeterState.PENDING_ADD);
397 ((DefaultMeter) m2).setState(MeterState.PENDING_ADD);
398 ((DefaultMeter) m3).setState(MeterState.PENDING_ADD);
pierventre26ac1512021-09-10 09:37:29 +0200399 meterStore.addOrUpdateMeter(m1);
400 meterStore.addOrUpdateMeter(m2);
401 meterStore.addOrUpdateMeter(m3);
Daniele Moro43ac2892021-07-15 17:02:59 +0200402 assertThat(3, is(meterStore.getAllMeters().size()));
403
404 meterStore.purgeMeters(did1, APP_ID_2);
Daniele Moro43ac2892021-07-15 17:02:59 +0200405 MeterKey keyTwo = MeterKey.key(did1, mid2);
406 assertThat(2, is(meterStore.getAllMeters().size()));
407 assertThat(1, is(meterStore.getAllMeters(did1).size()));
408 assertThat(1, is(meterStore.getAllMeters(did2).size()));
409 assertNull(meterStore.getMeter(keyTwo));
410 }
411
412 /**
pierventre44220052020-09-22 12:51:06 +0200413 * Test getMeters API immutability.
414 */
415 @Test
416 public void testGetMetersImmutability() {
pierventre3b39bd82021-08-18 09:40:14 +0200417 initMeterStore(false);
pierventre44220052020-09-22 12:51:06 +0200418
pierventre26ac1512021-09-10 09:37:29 +0200419 MeterCellId idOne = meterStore.allocateMeterId(did1, MeterScope.globalScope());
pierventre44220052020-09-22 12:51:06 +0200420 assertThat(mid1, is(idOne));
pierventre44220052020-09-22 12:51:06 +0200421 Meter meterOne = DefaultMeter.builder()
422 .forDevice(did1)
423 .fromApp(APP_ID)
424 .withId(mid1)
425 .withUnit(Meter.Unit.KB_PER_SEC)
426 .withBands(Collections.singletonList(b1))
427 .build();
pierventre44220052020-09-22 12:51:06 +0200428 ((DefaultMeter) meterOne).setState(MeterState.PENDING_ADD);
pierventre26ac1512021-09-10 09:37:29 +0200429 meterStore.addOrUpdateMeter(meterOne);
pierventre44220052020-09-22 12:51:06 +0200430
pierventre44220052020-09-22 12:51:06 +0200431 Collection<Meter> meters = meterStore.getAllMeters();
432 Collection<Meter> metersDevice = meterStore.getAllMeters(did1);
433 assertThat(1, is(meters.size()));
434 assertThat(1, is(metersDevice.size()));
435
pierventre26ac1512021-09-10 09:37:29 +0200436 MeterCellId idTwo = meterStore.allocateMeterId(did1, MeterScope.globalScope());
pierventre44220052020-09-22 12:51:06 +0200437 assertThat(mid2, is(idTwo));
pierventre44220052020-09-22 12:51:06 +0200438 Meter meterTwo = DefaultMeter.builder()
439 .forDevice(did1)
440 .fromApp(APP_ID)
441 .withId(mid2)
442 .withUnit(Meter.Unit.KB_PER_SEC)
443 .withBands(Collections.singletonList(b1))
444 .build();
pierventre44220052020-09-22 12:51:06 +0200445 ((DefaultMeter) meterTwo).setState(MeterState.PENDING_ADD);
pierventre26ac1512021-09-10 09:37:29 +0200446 meterStore.addOrUpdateMeter(meterTwo);
pierventre44220052020-09-22 12:51:06 +0200447
448 assertThat(1, is(meters.size()));
449 assertThat(1, is(metersDevice.size()));
pierventre44220052020-09-22 12:51:06 +0200450 meters = meterStore.getAllMeters();
451 metersDevice = meterStore.getAllMeters(did1);
452 assertThat(2, is(meters.size()));
453 assertThat(2, is(metersDevice.size()));
pierventre3b39bd82021-08-18 09:40:14 +0200454 }
pierventre44220052020-09-22 12:51:06 +0200455
pierventre3b39bd82021-08-18 09:40:14 +0200456 /**
457 * Test invalid allocation of a cell id.
458 */
459 @Test(expected = IllegalArgumentException.class)
460 public void testInvalidCellId() {
461 initMeterStore(true);
pierventre26ac1512021-09-10 09:37:29 +0200462
pierventre3b39bd82021-08-18 09:40:14 +0200463 // MF defines an end index equals to 10
464 Meter meterBad = DefaultMeter.builder()
465 .forDevice(did3)
466 .fromApp(APP_ID)
467 .withCellId(invalidCid)
468 .withUnit(Meter.Unit.KB_PER_SEC)
469 .withBands(Collections.singletonList(b1))
470 .build();
471 ((DefaultMeter) meterBad).setState(MeterState.PENDING_ADD);
pierventre26ac1512021-09-10 09:37:29 +0200472 meterStore.addOrUpdateMeter(meterBad);
pierventre3b39bd82021-08-18 09:40:14 +0200473 }
pierventre44220052020-09-22 12:51:06 +0200474
pierventre3b39bd82021-08-18 09:40:14 +0200475 /**
476 * Test enabling user defined index mode.
477 */
478 @Test
479 public void testEnableUserDefinedIndex() {
480 initMeterStore(false);
pierventre26ac1512021-09-10 09:37:29 +0200481
pierventre3b39bd82021-08-18 09:40:14 +0200482 assertTrue(meterStore.userDefinedIndexMode(true));
483 }
484
485 /**
486 * Test invalid enabling user defined index mode.
487 */
488 @Test
489 public void testInvalidEnableUserDefinedIndex() {
490 testStoreMeter();
pierventre26ac1512021-09-10 09:37:29 +0200491
pierventre3b39bd82021-08-18 09:40:14 +0200492 assertFalse(meterStore.userDefinedIndexMode(true));
493 }
494
495 /**
496 * Test disabling user defined index mode.
497 */
498 @Test
499 public void testDisableUserDefinedIndex() {
500 initMeterStore(true);
pierventre26ac1512021-09-10 09:37:29 +0200501
pierventre3b39bd82021-08-18 09:40:14 +0200502 assertFalse(meterStore.userDefinedIndexMode(false));
503 }
504
505 /**
506 * Test store meter in user defined index mode.
507 */
508 @Test
509 public void testStoreMeterInUserDefinedIndexMode() {
510 initMeterStore(true);
pierventre26ac1512021-09-10 09:37:29 +0200511
pierventre3b39bd82021-08-18 09:40:14 +0200512 Meter meterOne = DefaultMeter.builder()
513 .forDevice(did3)
514 .fromApp(APP_ID)
515 .withCellId(cid4)
516 .withUnit(Meter.Unit.KB_PER_SEC)
517 .withBands(Collections.singletonList(b1))
518 .build();
pierventre3b39bd82021-08-18 09:40:14 +0200519 ((DefaultMeter) meterOne).setState(MeterState.PENDING_ADD);
pierventre26ac1512021-09-10 09:37:29 +0200520 meterStore.addOrUpdateMeter(meterOne);
pierventre3b39bd82021-08-18 09:40:14 +0200521 MeterKey meterKey = MeterKey.key(did3, cid4);
pierventre3b39bd82021-08-18 09:40:14 +0200522 assertThat(1, is(meterStore.getAllMeters().size()));
523 assertThat(1, is(meterStore.getAllMeters(did3).size()));
524 assertThat(m4, is(meterStore.getMeter(meterKey)));
525 }
526
527 /**
528 * Test invalid disabling user defined index mode.
529 */
530 @Test
531 public void testInvalidDisableUserDefinedIndex() {
532 testStoreMeterInUserDefinedIndexMode();
pierventre26ac1512021-09-10 09:37:29 +0200533
pierventre3b39bd82021-08-18 09:40:14 +0200534 assertTrue(meterStore.userDefinedIndexMode(false));
535 }
536
537 /**
538 * Test allocation of meter ids in user defined index mode.
539 */
540 @Test
541 public void testAllocateIdInUserDefinedIndexMode() {
542 initMeterStore(true);
pierventre26ac1512021-09-10 09:37:29 +0200543
544 assertNull(meterStore.allocateMeterId(did1, MeterScope.globalScope()));
pierventre3b39bd82021-08-18 09:40:14 +0200545 }
546
547 /**
548 * Test free of meter ids in user defined index mode.
549 */
550 @Test
551 public void testFreeIdInUserMode() {
552 initMeterStore(true);
pierventre26ac1512021-09-10 09:37:29 +0200553
pierventre3b39bd82021-08-18 09:40:14 +0200554 meterStore.freeMeterId(did1, mid1);
555 MeterTableKey globalKey = MeterTableKey.key(did1, MeterScope.globalScope());
556 assertNotNull(meterStore.availableMeterIds.get(globalKey));
557 assertTrue(meterStore.availableMeterIds.get(globalKey).isEmpty());
558 }
559
560 /**
561 * Test delete meter in user defined index mode.
562 */
563 @Test
564 public void testDeleteMeterInUserDefinedIndexMode() {
565 initMeterStore(true);
pierventre26ac1512021-09-10 09:37:29 +0200566
pierventre3b39bd82021-08-18 09:40:14 +0200567 Meter meterOne = DefaultMeter.builder()
568 .forDevice(did3)
569 .fromApp(APP_ID)
570 .withCellId(cid4)
571 .withUnit(Meter.Unit.KB_PER_SEC)
572 .withBands(Collections.singletonList(b1))
573 .build();
574 ((DefaultMeter) meterOne).setState(MeterState.PENDING_ADD);
pierventre26ac1512021-09-10 09:37:29 +0200575 meterStore.addOrUpdateMeter(meterOne);
pierventre3b39bd82021-08-18 09:40:14 +0200576
577 ((DefaultMeter) meterOne).setState(MeterState.PENDING_REMOVE);
578 MeterKey meterKey = MeterKey.key(did3, cid4);
579 meterStore.deleteMeter(meterOne);
580 CompletableFuture<Void> future = CompletableFuture.runAsync(
581 () -> meterStore.purgeMeter(meterOne)
582 );
583
584 try {
585 future.get();
586 } catch (InterruptedException | ExecutionException e) {
587 e.printStackTrace();
588 }
589 assertThat(0, is(meterStore.getAllMeters().size()));
590 assertThat(0, is(meterStore.getAllMeters(did3).size()));
591 assertNull(meterStore.getMeter(meterKey));
592 MeterTableKey globalKey = MeterTableKey.key(did1, MeterScope.globalScope());
593 assertNotNull(meterStore.availableMeterIds.get(globalKey));
594 assertTrue(meterStore.availableMeterIds.get(globalKey).isEmpty());
pierventre44220052020-09-22 12:51:06 +0200595 }
596
Pier Luigif094c612017-10-14 12:15:02 +0200597 private class TestDriverService extends DriverServiceAdapter {
598 @Override
599 public DriverHandler createHandler(DeviceId deviceId, String... credentials) {
600 return deviceId.equals(did3) ? new TestDriverHandler() : null;
601 }
602 }
603
Pier Luigif094c612017-10-14 12:15:02 +0200604 private class TestDriverHandler implements DriverHandler {
605
606 @Override
607 public Driver driver() {
608 return null;
609 }
610
611 @Override
612 public DriverData data() {
613 return null;
614 }
615
616 @Override
617 @SuppressWarnings("unchecked")
618 public <T extends Behaviour> T behaviour(Class<T> behaviourClass) {
619 return (T) new TestMeterQuery();
620 }
621
622 @Override
623 public <T> T get(Class<T> serviceClass) {
624 return null;
625 }
626
627 @Override
628 public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) {
629 return true;
630 }
631 }
632
Pier Luigif094c612017-10-14 12:15:02 +0200633 private class TestMeterQuery implements MeterQuery {
634
635 @Override
636 public DriverData data() {
637 return null;
638 }
639
640 @Override
641 public void setData(DriverData data) {
642
643 }
644 @Override
645 public DriverHandler handler() {
646 return null;
647 }
648
649 @Override
650 public void setHandler(DriverHandler handler) {
651
652 }
653
654 @Override
655 public long getMaxMeters() {
656 return 100;
657 }
658 }
659
660}