blob: 52970dd2b3bc020e1aae41f9c36ce22a1e6c73d9 [file] [log] [blame]
alshabibe1248b62015-08-20 17:21:55 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
alshabibe1248b62015-08-20 17:21:55 -07003 *
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 */
Ray Milkeyebdd4852017-10-18 16:19:28 -070016package org.onosproject.net.meter.impl;
alshabibe1248b62015-08-20 17:21:55 -070017
Andrea Campanellae3708782017-10-16 16:00:21 +020018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.ImmutableMap;
Charles Chan593acf92017-11-22 13:55:41 -080020import com.google.common.collect.Lists;
alshabibe1248b62015-08-20 17:21:55 -070021import com.google.common.collect.Sets;
pierventree97f4832020-07-13 14:07:05 +020022import org.easymock.EasyMock;
alshabibe1248b62015-08-20 17:21:55 -070023import org.junit.After;
24import org.junit.Before;
25import org.junit.Test;
Andrea Campanellae3708782017-10-16 16:00:21 +020026import org.onlab.junit.TestTools;
alshabibe1248b62015-08-20 17:21:55 -070027import org.onlab.junit.TestUtils;
28import org.onlab.packet.IpAddress;
Charles Chan593acf92017-11-22 13:55:41 -080029import org.onlab.util.KryoNamespace;
30import org.onosproject.TestApplicationId;
Andrea Campanellae3708782017-10-16 16:00:21 +020031import org.onosproject.cfg.ComponentConfigAdapter;
alshabibe1248b62015-08-20 17:21:55 -070032import org.onosproject.cluster.ClusterServiceAdapter;
33import org.onosproject.cluster.ControllerNode;
34import org.onosproject.cluster.DefaultControllerNode;
35import org.onosproject.cluster.NodeId;
36import org.onosproject.common.event.impl.TestEventDispatcher;
alshabibe1248b62015-08-20 17:21:55 -070037import org.onosproject.mastership.MastershipServiceAdapter;
Andrea Campanellae3708782017-10-16 16:00:21 +020038import org.onosproject.net.AnnotationKeys;
39import org.onosproject.net.DefaultAnnotations;
40import org.onosproject.net.DefaultDevice;
41import org.onosproject.net.Device;
alshabibe1248b62015-08-20 17:21:55 -070042import org.onosproject.net.DeviceId;
Andrea Campanellae3708782017-10-16 16:00:21 +020043import org.onosproject.net.MastershipRole;
44import org.onosproject.net.behaviour.MeterQuery;
Thomas Vachuska164ecf62018-05-08 17:29:55 -070045import org.onosproject.net.config.NetworkConfigService;
46import org.onosproject.net.config.NetworkConfigServiceAdapter;
Andrea Campanellae3708782017-10-16 16:00:21 +020047import org.onosproject.net.device.DeviceService;
48import org.onosproject.net.device.DeviceServiceAdapter;
49import org.onosproject.net.driver.AbstractHandlerBehaviour;
50import org.onosproject.net.driver.DefaultDriver;
51import org.onosproject.net.driver.DriverRegistry;
52import org.onosproject.net.driver.impl.DriverManager;
53import org.onosproject.net.driver.impl.DriverRegistryManager;
alshabibe1248b62015-08-20 17:21:55 -070054import org.onosproject.net.meter.Band;
55import org.onosproject.net.meter.DefaultBand;
56import org.onosproject.net.meter.DefaultMeter;
Jordi Ortizaa8de492016-12-01 00:21:36 +010057import org.onosproject.net.meter.DefaultMeterFeatures;
alshabibe1248b62015-08-20 17:21:55 -070058import org.onosproject.net.meter.DefaultMeterRequest;
59import org.onosproject.net.meter.Meter;
Pier Luigif094c612017-10-14 12:15:02 +020060import org.onosproject.net.meter.MeterFeatures;
alshabibe1248b62015-08-20 17:21:55 -070061import org.onosproject.net.meter.MeterId;
62import org.onosproject.net.meter.MeterOperation;
63import org.onosproject.net.meter.MeterOperations;
Andrea Campanellae3708782017-10-16 16:00:21 +020064import org.onosproject.net.meter.MeterProgrammable;
alshabibe1248b62015-08-20 17:21:55 -070065import org.onosproject.net.meter.MeterProvider;
66import org.onosproject.net.meter.MeterProviderRegistry;
67import org.onosproject.net.meter.MeterProviderService;
68import org.onosproject.net.meter.MeterRequest;
Andrea Campanellae3708782017-10-16 16:00:21 +020069import org.onosproject.net.meter.MeterService;
alshabibe1248b62015-08-20 17:21:55 -070070import org.onosproject.net.meter.MeterState;
Carmelo Cascone0761cd32018-08-29 19:22:50 -070071import org.onosproject.net.pi.PiPipeconfServiceAdapter;
alshabibe1248b62015-08-20 17:21:55 -070072import org.onosproject.net.provider.AbstractProvider;
73import org.onosproject.net.provider.ProviderId;
Thomas Vachuska52f2cd12018-11-08 21:20:04 -080074import org.onosproject.store.meter.impl.DistributedMeterStore;
Charles Chan593acf92017-11-22 13:55:41 -080075import org.onosproject.store.service.Serializer;
alshabibe1248b62015-08-20 17:21:55 -070076import org.onosproject.store.service.TestStorageService;
pierventree97f4832020-07-13 14:07:05 +020077import org.osgi.service.component.ComponentContext;
alshabibe1248b62015-08-20 17:21:55 -070078
Andrea Campanellae3708782017-10-16 16:00:21 +020079import java.util.ArrayList;
80import java.util.Collection;
Carmelo Cascone0761cd32018-08-29 19:22:50 -070081import java.util.Collections;
82import java.util.HashSet;
Andrea Campanellae3708782017-10-16 16:00:21 +020083import java.util.List;
alshabibe1248b62015-08-20 17:21:55 -070084import java.util.Set;
pierventree97f4832020-07-13 14:07:05 +020085import java.util.Dictionary;
86import java.util.Hashtable;
Andrea Campanellae3708782017-10-16 16:00:21 +020087import java.util.concurrent.CompletableFuture;
alshabibe1248b62015-08-20 17:21:55 -070088
pierventree97f4832020-07-13 14:07:05 +020089import static org.easymock.EasyMock.expect;
90import static org.easymock.EasyMock.replay;
alshabibe1248b62015-08-20 17:21:55 -070091import static org.hamcrest.Matchers.is;
Carmelo Cascone0761cd32018-08-29 19:22:50 -070092import static org.junit.Assert.assertEquals;
93import static org.junit.Assert.assertFalse;
94import static org.junit.Assert.assertNull;
95import static org.junit.Assert.assertThat;
96import static org.junit.Assert.assertTrue;
alshabibe1248b62015-08-20 17:21:55 -070097import static org.onosproject.net.NetTestTools.APP_ID;
98import static org.onosproject.net.NetTestTools.did;
99import static org.onosproject.net.NetTestTools.injectEventDispatcher;
100
101/**
102 * Meter manager tests.
103 */
104public class MeterManagerTest {
105
Pier Luigif094c612017-10-14 12:15:02 +0200106 // Test node id
alshabibe1248b62015-08-20 17:21:55 -0700107 private static final NodeId NID_LOCAL = new NodeId("local");
Pier Luigif094c612017-10-14 12:15:02 +0200108
109 // Test ip address
alshabibe1248b62015-08-20 17:21:55 -0700110 private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
111
Pier Luigif094c612017-10-14 12:15:02 +0200112 private static final ProviderId PID = new ProviderId("of", "foo");
alshabibe1248b62015-08-20 17:21:55 -0700113
Andrea Campanellae3708782017-10-16 16:00:21 +0200114 private static final ProviderId PROGRAMMABLE_PROVIDER = new ProviderId("foo", "foo");
115 private static final DeviceId PROGRAMMABLE_DID = DeviceId.deviceId("test:002");
116
117 private static final DefaultAnnotations ANNOTATIONS =
118 DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, "foo").build();
119
120 private static final Device PROGRAMMABLE_DEV =
121 new DefaultDevice(PROGRAMMABLE_PROVIDER, PROGRAMMABLE_DID, Device.Type.SWITCH,
122 "", "", "", "", null, ANNOTATIONS);
123
Andrea Campanellae3708782017-10-16 16:00:21 +0200124 private MeterService service;
125
126 // Test Driver service used during the tests
127 private DriverManager driverService;
128
129 // Test device service used during the tests
130 private DeviceService deviceService;
131
Pier Luigif094c612017-10-14 12:15:02 +0200132 // Test provider used during the tests
alshabibe1248b62015-08-20 17:21:55 -0700133 private TestProvider provider;
134
Pier Luigif094c612017-10-14 12:15:02 +0200135 // Meter manager
136 private MeterManager manager;
alshabibe1248b62015-08-20 17:21:55 -0700137
Pier Luigif094c612017-10-14 12:15:02 +0200138 // Meter provider registry
139 private MeterProviderRegistry registry;
alshabibe1248b62015-08-20 17:21:55 -0700140
Pier Luigif094c612017-10-14 12:15:02 +0200141 // Meter provider service
142 private MeterProviderService providerService;
alshabibe1248b62015-08-20 17:21:55 -0700143
Pier Luigif094c612017-10-14 12:15:02 +0200144 // Store under testing
145 private DistributedMeterStore meterStore;
146
147 // Device ids used during the tests
148 private DeviceId did1 = did("1");
149 private DeviceId did2 = did("2");
150
151 // Meter ids used during the tests
152 private MeterId mid1 = MeterId.meterId(1);
153
154 // Bands used during the tests
Andrea Campanellae3708782017-10-16 16:00:21 +0200155 private static Band b1 = DefaultBand.builder()
Pier Luigif094c612017-10-14 12:15:02 +0200156 .ofType(Band.Type.DROP)
157 .withRate(500)
158 .build();
159
160 // Meters used during the tests
161 private Meter m1 = DefaultMeter.builder()
162 .forDevice(did1)
163 .fromApp(APP_ID)
164 .withId(mid1)
165 .withUnit(Meter.Unit.KB_PER_SEC)
166 .withBands(Collections.singletonList(b1))
167 .build();
168 private Meter m2 = DefaultMeter.builder()
169 .forDevice(did2)
170 .fromApp(APP_ID)
171 .withId(mid1)
172 .withUnit(Meter.Unit.KB_PER_SEC)
173 .withBands(Collections.singletonList(b1))
174 .build();
175
Andrea Campanellae3708782017-10-16 16:00:21 +0200176 private static Meter mProgrammable = DefaultMeter.builder()
177 .forDevice(PROGRAMMABLE_DID)
178 .fromApp(APP_ID)
179 .withId(MeterId.meterId(1))
180 .withUnit(Meter.Unit.KB_PER_SEC)
181 .withBands(Collections.singletonList(b1))
182 .build();
183
Pier Luigif094c612017-10-14 12:15:02 +0200184 // Meter requests used during the tests
185 private MeterRequest.Builder m1Request = DefaultMeterRequest.builder()
186 .forDevice(did1)
187 .fromApp(APP_ID)
188 .withUnit(Meter.Unit.KB_PER_SEC)
189 .withBands(Collections.singletonList(b1));
190 private MeterRequest.Builder m2Request = DefaultMeterRequest.builder()
191 .forDevice(did2)
192 .fromApp(APP_ID)
193 .withUnit(Meter.Unit.KB_PER_SEC)
194 .withBands(Collections.singletonList(b1));
195
Andrea Campanellae3708782017-10-16 16:00:21 +0200196 private MeterRequest.Builder mProgrammableRequest = DefaultMeterRequest.builder()
197 .forDevice(PROGRAMMABLE_DID)
198 .fromApp(APP_ID)
199 .withUnit(Meter.Unit.KB_PER_SEC)
200 .withBands(Collections.singletonList(b1));
201
Pier Luigif094c612017-10-14 12:15:02 +0200202 // Meter features used during the tests
203 private MeterFeatures mef1 = DefaultMeterFeatures.builder().forDevice(did1)
204 .withMaxMeters(3L)
205 .withBandTypes(new HashSet<>())
206 .withUnits(new HashSet<>())
207 .hasStats(false)
208 .hasBurst(false)
209 .withMaxBands((byte) 0)
210 .withMaxColors((byte) 0)
211 .build();
212 private MeterFeatures mef2 = DefaultMeterFeatures.builder().forDevice(did2)
213 .withMaxMeters(10L)
214 .withBandTypes(new HashSet<>())
215 .withUnits(new HashSet<>())
216 .hasStats(false)
217 .hasBurst(false)
218 .withMaxBands((byte) 0)
219 .withMaxColors((byte) 0)
220 .build();
alshabibe1248b62015-08-20 17:21:55 -0700221
Andrea Campanellae3708782017-10-16 16:00:21 +0200222
alshabibe1248b62015-08-20 17:21:55 -0700223 @Before
Pier Luigif094c612017-10-14 12:15:02 +0200224 public void setup() {
Andrea Campanellae3708782017-10-16 16:00:21 +0200225 //Init step for the deviceService
226 deviceService = new TestDeviceService();
227 //Init step for the driver registry and driver service.
228 DriverRegistryManager driverRegistry = new DriverRegistryManager();
Thomas Vachuska164ecf62018-05-08 17:29:55 -0700229 driverService = new TestDriverManager(driverRegistry, deviceService, new NetworkConfigServiceAdapter());
Andrea Campanellae3708782017-10-16 16:00:21 +0200230 driverRegistry.addDriver(new DefaultDriver("foo", ImmutableList.of(), "",
231 "", "",
232 ImmutableMap.of(MeterProgrammable.class,
233 TestMeterProgrammable.class, MeterQuery.class, TestMeterQuery.class),
234 ImmutableMap.of()));
235
Pier Luigif094c612017-10-14 12:15:02 +0200236 // Init step for the store
alshabibe1248b62015-08-20 17:21:55 -0700237 meterStore = new DistributedMeterStore();
Pier Luigif094c612017-10-14 12:15:02 +0200238 // Let's initialize some internal services of the store
alshabibe1248b62015-08-20 17:21:55 -0700239 TestUtils.setField(meterStore, "storageService", new TestStorageService());
Andrea Campanellae3708782017-10-16 16:00:21 +0200240 TestUtils.setField(meterStore, "driverService", driverService);
Charles Chan593acf92017-11-22 13:55:41 -0800241
242 // Inject TestApplicationId into the DistributedMeterStore serializer
243 KryoNamespace.Builder testKryoBuilder = TestUtils.getField(meterStore, "APP_KRYO_BUILDER");
244 testKryoBuilder.register(TestApplicationId.class);
245 Serializer testSerializer = Serializer.using(Lists.newArrayList(testKryoBuilder.build()));
246 TestUtils.setField(meterStore, "serializer", testSerializer);
247
Pier Luigif094c612017-10-14 12:15:02 +0200248 // Activate the store
alshabibe1248b62015-08-20 17:21:55 -0700249 meterStore.activate();
Pier Luigif094c612017-10-14 12:15:02 +0200250 // Init step for the manager
alshabibe1248b62015-08-20 17:21:55 -0700251 manager = new MeterManager();
Pier Luigif094c612017-10-14 12:15:02 +0200252 // Let's initialize some internal services of the manager
253 TestUtils.setField(manager, "store", meterStore);
alshabibe1248b62015-08-20 17:21:55 -0700254 injectEventDispatcher(manager, new TestEventDispatcher());
Andrea Campanellae3708782017-10-16 16:00:21 +0200255 manager.deviceService = deviceService;
256 manager.mastershipService = new TestMastershipService();
257 manager.cfgService = new ComponentConfigAdapter();
pierventree97f4832020-07-13 14:07:05 +0200258 manager.clusterService = new TestClusterService();
Pier Luigif094c612017-10-14 12:15:02 +0200259 // Init the reference of the registry
alshabibe1248b62015-08-20 17:21:55 -0700260 registry = manager;
Andrea Campanellae3708782017-10-16 16:00:21 +0200261
262 manager.driverService = driverService;
263
Pier Luigif094c612017-10-14 12:15:02 +0200264 // Activate the manager
pierventree97f4832020-07-13 14:07:05 +0200265 Dictionary<String, Object> cfgDict = new Hashtable<>();
266 ComponentContext componentContext = EasyMock.createMock(ComponentContext.class);
267 expect(componentContext.getProperties()).andReturn(cfgDict);
268 replay(componentContext);
269 manager.activate(componentContext);
Andrea Campanellae3708782017-10-16 16:00:21 +0200270
pierventree97f4832020-07-13 14:07:05 +0200271 // Initialize the test provider
alshabibe1248b62015-08-20 17:21:55 -0700272 provider = new TestProvider(PID);
Pier Luigif094c612017-10-14 12:15:02 +0200273 // Register the provider against the manager
alshabibe1248b62015-08-20 17:21:55 -0700274 providerService = registry.register(provider);
Pier Luigif094c612017-10-14 12:15:02 +0200275 // Verify register
alshabibe1248b62015-08-20 17:21:55 -0700276 assertTrue("provider should be registered",
277 registry.getProviders().contains(provider.id()));
alshabibe1248b62015-08-20 17:21:55 -0700278 }
279
280 @After
281 public void tearDown() {
Pier Luigif094c612017-10-14 12:15:02 +0200282 // Unregister provider
alshabibe1248b62015-08-20 17:21:55 -0700283 registry.unregister(provider);
Pier Luigif094c612017-10-14 12:15:02 +0200284 // Verify unregister
alshabibe1248b62015-08-20 17:21:55 -0700285 assertFalse("provider should not be registered",
286 registry.getProviders().contains(provider.id()));
Pier Luigif094c612017-10-14 12:15:02 +0200287 // Deactivate manager
alshabibe1248b62015-08-20 17:21:55 -0700288 manager.deactivate();
Pier Luigif094c612017-10-14 12:15:02 +0200289 // Remove event dispatcher
alshabibe1248b62015-08-20 17:21:55 -0700290 injectEventDispatcher(manager, null);
Pier Luigif094c612017-10-14 12:15:02 +0200291 // Deactivate store
292 meterStore.deactivate();
alshabibe1248b62015-08-20 17:21:55 -0700293 }
294
Pier Luigif094c612017-10-14 12:15:02 +0200295 private void initMeterStore() {
296 // Let's store feature for device 1
297 meterStore.storeMeterFeatures(mef1);
298 // Let's store feature for device 2
299 meterStore.storeMeterFeatures(mef2);
300 }
301
302 // Emulate metrics coming from the dataplane
303 private void pushMetrics(MeterOperation.Type type, Meter meter) {
304 // If it is an add operation
305 if (type == MeterOperation.Type.ADD) {
306 // Update state to added
307 ((DefaultMeter) meter).setState(MeterState.ADDED);
308 // Push the update in the store
309 providerService.pushMeterMetrics(meter.deviceId(), Collections.singletonList(meter));
310 } else {
311 providerService.pushMeterMetrics(meter.deviceId(), Collections.emptyList());
312 }
313 }
314
315 /**
316 * Test add meter.
317 */
alshabibe1248b62015-08-20 17:21:55 -0700318 @Test
Pier Luigif094c612017-10-14 12:15:02 +0200319 public void testAdd() {
320 // Init store
321 initMeterStore();
322 // Submit meter request
alshabibe1248b62015-08-20 17:21:55 -0700323 manager.submit(m1Request.add());
Pier Luigif094c612017-10-14 12:15:02 +0200324 // Verify add
pierventree97f4832020-07-13 14:07:05 +0200325 assertEquals("The meter was not added", 1, manager.getAllMeters().size());
326 assertEquals("The meter was not added", 1, manager.getMeters(did1).size());
Pier Luigif094c612017-10-14 12:15:02 +0200327 // Get Meter
328 Meter installingMeter = manager.getMeter(did1, mid1);
329 // Verify add of installingMeter and pending add state
330 assertThat(installingMeter, is(m1));
331 // Verify pending add state
332 assertThat(installingMeter.state(), is(MeterState.PENDING_ADD));
333 // Let's simulate a working data-plane
334 pushMetrics(MeterOperation.Type.ADD, installingMeter);
335 // Get meter
336 Meter installedMeter = manager.getMeter(did1, mid1);
337 // Verify installation
338 assertThat(installedMeter.state(), is(MeterState.ADDED));
pierventree97f4832020-07-13 14:07:05 +0200339 assertEquals("The meter was not installed", 1, manager.getAllMeters().size());
340 assertEquals("The meter was not installed", 1, manager.getMeters(did1).size());
alshabibe1248b62015-08-20 17:21:55 -0700341 }
342
Pier Luigif094c612017-10-14 12:15:02 +0200343 /**
344 * Test remove meter.
345 */
alshabibe1248b62015-08-20 17:21:55 -0700346 @Test
347 public void testRemove() {
Pier Luigif094c612017-10-14 12:15:02 +0200348 // Init store
349 initMeterStore();
350 // Submit meter request
alshabibe1248b62015-08-20 17:21:55 -0700351 manager.submit(m1Request.add());
Pier Luigif094c612017-10-14 12:15:02 +0200352 // Withdraw meter
alshabibe1248b62015-08-20 17:21:55 -0700353 manager.withdraw(m1Request.remove(), m1.id());
Pier Luigif094c612017-10-14 12:15:02 +0200354 // Get Meter
355 Meter withdrawingMeter = manager.getMeter(did1, mid1);
356 // Verify withdrawing
357 assertThat(withdrawingMeter.state(), is(MeterState.PENDING_REMOVE));
pierventree97f4832020-07-13 14:07:05 +0200358 assertEquals("The meter was not withdrawn", 1, manager.getAllMeters().size());
359 assertEquals("The meter was not withdrawn", 1, manager.getMeters(did1).size());
Pier Luigif094c612017-10-14 12:15:02 +0200360 // Let's simulate a working data-plane
361 pushMetrics(MeterOperation.Type.REMOVE, withdrawingMeter);
362 // Verify withdrawn
363 assertNull(manager.getMeter(did1, mid1));
pierventree97f4832020-07-13 14:07:05 +0200364 assertEquals("The meter was not removed", 0, manager.getAllMeters().size());
365 assertEquals("The meter was not removed", 0, manager.getMeters(did1).size());
alshabibe1248b62015-08-20 17:21:55 -0700366 }
367
Pier Luigif094c612017-10-14 12:15:02 +0200368 /**
369 * Test add multiple device.
370 */
alshabib70aaa1b2015-09-25 14:30:59 -0700371 @Test
Pier Luigif094c612017-10-14 12:15:02 +0200372 public void testAddMultipleDevice() {
373 // Init store
374 initMeterStore();
375 // Submit meter 1
alshabib70aaa1b2015-09-25 14:30:59 -0700376 manager.submit(m1Request.add());
Pier Luigif094c612017-10-14 12:15:02 +0200377 // Submit meter 2
alshabib70aaa1b2015-09-25 14:30:59 -0700378 manager.submit(m2Request.add());
Pier Luigif094c612017-10-14 12:15:02 +0200379 // Verify add
pierventree97f4832020-07-13 14:07:05 +0200380 assertEquals("The meter was not added", 2, manager.getAllMeters().size());
381 assertEquals("The meter was not added", 1, manager.getMeters(did1).size());
382 assertEquals("The meter was not added", 1, manager.getMeters(did2).size());
Pier Luigif094c612017-10-14 12:15:02 +0200383 // Get Meters
384 Meter installingMeter1 = manager.getMeter(did1, mid1);
385 Meter installingMeter2 = manager.getMeter(did2, mid1);
386 // Verify add of installingMeter
387 assertThat(installingMeter1, is(m1));
388 assertThat(installingMeter2, is(m2));
389 // Verify pending add state
390 assertThat(installingMeter1.state(), is(MeterState.PENDING_ADD));
391 assertThat(installingMeter2.state(), is(MeterState.PENDING_ADD));
392 // Let's simulate a working data-plane
393 pushMetrics(MeterOperation.Type.ADD, installingMeter1);
394 pushMetrics(MeterOperation.Type.ADD, installingMeter2);
395 // Get meter
396 Meter installedMeter1 = manager.getMeter(did1, mid1);
397 Meter installedMeter2 = manager.getMeter(did2, mid1);
398 // Verify installation
399 assertThat(installedMeter1.state(), is(MeterState.ADDED));
400 assertThat(installedMeter2.state(), is(MeterState.ADDED));
pierventree97f4832020-07-13 14:07:05 +0200401 assertEquals("The meter was not installed", 2, manager.getAllMeters().size());
402 assertEquals("The meter was not installed", 1, manager.getMeters(did1).size());
403 assertEquals("The meter was not installed", 1, manager.getMeters(did2).size());
alshabib70aaa1b2015-09-25 14:30:59 -0700404 }
alshabibe1248b62015-08-20 17:21:55 -0700405
Pier Luigif094c612017-10-14 12:15:02 +0200406 /**
407 * Test remove meter.
408 */
Jordi Ortizaa8de492016-12-01 00:21:36 +0100409 @Test
Pier Luigif094c612017-10-14 12:15:02 +0200410 public void testRemoveMultipleDevice() {
411 // Init store
412 initMeterStore();
413 // Submit meter 1
Jordi Ortiz6c847762017-01-30 17:13:05 +0100414 manager.submit(m1Request.add());
Pier Luigif094c612017-10-14 12:15:02 +0200415 // Submit meter 2
416 manager.submit(m2Request.add());
417 // Withdraw meter
418 manager.withdraw(m1Request.remove(), m1.id());
419 // Withdraw meter
420 manager.withdraw(m2Request.remove(), m2.id());
421 // Get Meters
422 Meter withdrawingMeter1 = manager.getMeter(did1, mid1);
423 Meter withdrawingMeter2 = manager.getMeter(did2, mid1);
424 // Verify withdrawing
425 assertThat(withdrawingMeter1.state(), is(MeterState.PENDING_REMOVE));
426 assertThat(withdrawingMeter2.state(), is(MeterState.PENDING_REMOVE));
pierventree97f4832020-07-13 14:07:05 +0200427 assertEquals("The meter was not withdrawn", 2, manager.getAllMeters().size());
428 assertEquals("The meter was not withdrawn", 1, manager.getMeters(did1).size());
429 assertEquals("The meter was not withdrawn", 1, manager.getMeters(did2).size());
Pier Luigif094c612017-10-14 12:15:02 +0200430 // Let's simulate a working data-plane
431 pushMetrics(MeterOperation.Type.REMOVE, withdrawingMeter1);
432 pushMetrics(MeterOperation.Type.REMOVE, withdrawingMeter2);
433 // Verify withdrawn
434 assertNull(manager.getMeter(did1, mid1));
435 assertNull(manager.getMeter(did2, mid1));
pierventree97f4832020-07-13 14:07:05 +0200436 assertEquals("The meter was not removed", 0, manager.getAllMeters().size());
437 assertEquals("The meter was not removed", 0, manager.getMeters(did1).size());
438 assertEquals("The meter was not removed", 0, manager.getMeters(did2).size());
439 }
440
441 /**
442 * Test purge meter.
443 */
444 @Test
445 public void testPurge() {
446 // Init store
447 initMeterStore();
448 // Submit meter request
449 manager.submit(m1Request.add());
450 // Verify submit
451 Meter submittingMeter = manager.getMeter(did1, mid1);
452 assertThat(submittingMeter.state(), is(MeterState.PENDING_ADD));
453 assertEquals("The meter was not added", 1, manager.getAllMeters().size());
454 assertEquals("The meter was not added", 1, manager.getMeters(did1).size());
455 // Purge the meters
456 manager.purgeMeters(did1);
457 // Verify purge
458 assertNull(manager.getMeter(did1, mid1));
459 assertEquals("The meter was not purged", 0, manager.getAllMeters().size());
460 assertEquals("The meter was not purged", 0, manager.getMeters(did1).size());
Jordi Ortiz6c847762017-01-30 17:13:05 +0100461 }
462
Andrea Campanellae3708782017-10-16 16:00:21 +0200463 @Test
464 public void testAddFromMeterProgrammable() {
Andrea Campanellae3708782017-10-16 16:00:21 +0200465 // Init store
466 initMeterStore();
Andrea Campanellae3708782017-10-16 16:00:21 +0200467 manager.submit(mProgrammableRequest.add());
Andrea Campanellae3708782017-10-16 16:00:21 +0200468 TestTools.assertAfter(500, () -> {
pierventree97f4832020-07-13 14:07:05 +0200469 assertEquals("The meter was not added", 1, manager.getAllMeters().size());
Andrea Campanellae3708782017-10-16 16:00:21 +0200470 assertThat(manager.getMeter(PROGRAMMABLE_DID, MeterId.meterId(1)), is(mProgrammable));
471 });
Andrea Campanellae3708782017-10-16 16:00:21 +0200472 }
473
474 @Test
475 public void testAddBatchFromMeterProgrammable() {
Andrea Campanellae3708782017-10-16 16:00:21 +0200476 // Init store
477 initMeterStore();
Andrea Campanellae3708782017-10-16 16:00:21 +0200478 List<MeterOperation> operations = ImmutableList.of(new MeterOperation(mProgrammable, MeterOperation.Type.ADD));
479 manager.defaultProvider().performMeterOperation(PROGRAMMABLE_DID, new MeterOperations(operations));
Andrea Campanellae3708782017-10-16 16:00:21 +0200480 TestTools.assertAfter(500, () -> {
pierventree97f4832020-07-13 14:07:05 +0200481 assertEquals("The meter was not added", 1, meterOperations.size());
482 assertEquals("Wrong Meter Operation", meterOperations.get(0).meter().id(), mProgrammable.id());
Andrea Campanellae3708782017-10-16 16:00:21 +0200483 });
484
485 }
486
487 @Test
488 public void testGetFromMeterProgrammable() {
Andrea Campanellae3708782017-10-16 16:00:21 +0200489 // Init store
490 initMeterStore();
Andrea Campanellae3708782017-10-16 16:00:21 +0200491 MeterDriverProvider fallback = (MeterDriverProvider) manager.defaultProvider();
Andrea Campanellae3708782017-10-16 16:00:21 +0200492 testAddFromMeterProgrammable();
Andrea Campanellae3708782017-10-16 16:00:21 +0200493 fallback.init(manager.deviceService, fallback.meterProviderService, manager.mastershipService, 1);
Andrea Campanellae3708782017-10-16 16:00:21 +0200494 TestTools.assertAfter(2000, () -> {
pierventree97f4832020-07-13 14:07:05 +0200495 assertEquals("The meter was not added", 1, manager.getAllMeters().size());
Andrea Campanellae3708782017-10-16 16:00:21 +0200496 Meter m = manager.getMeters(PROGRAMMABLE_DID).iterator().next();
497 assertEquals("incorrect state", MeterState.ADDED, m.state());
498 });
Andrea Campanellae3708782017-10-16 16:00:21 +0200499 }
500
Pier Luigif094c612017-10-14 12:15:02 +0200501 // Test cluster service
502 private final class TestClusterService extends ClusterServiceAdapter {
Jordi Ortizaa8de492016-12-01 00:21:36 +0100503
Pier Luigif094c612017-10-14 12:15:02 +0200504 private ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
Jordi Ortizaa8de492016-12-01 00:21:36 +0100505
Pier Luigif094c612017-10-14 12:15:02 +0200506 @Override
507 public ControllerNode getLocalNode() {
508 return local;
alshabibe1248b62015-08-20 17:21:55 -0700509 }
Pier Luigif094c612017-10-14 12:15:02 +0200510
511 @Override
512 public Set<ControllerNode> getNodes() {
513 return Sets.newHashSet();
514 }
515
alshabibe1248b62015-08-20 17:21:55 -0700516 }
517
Andrea Campanellae3708782017-10-16 16:00:21 +0200518 private static class TestDeviceService extends DeviceServiceAdapter {
519 @Override
520 public int getDeviceCount() {
521 return 1;
522 }
523
524 @Override
525 public Iterable<Device> getDevices() {
526 return ImmutableList.of(PROGRAMMABLE_DEV);
527 }
528
529 @Override
530 public Iterable<Device> getAvailableDevices() {
531 return getDevices();
532 }
533
534 @Override
535 public Device getDevice(DeviceId deviceId) {
536 return PROGRAMMABLE_DEV;
537 }
538 }
539
540 private class TestDriverManager extends DriverManager {
Thomas Vachuska164ecf62018-05-08 17:29:55 -0700541 TestDriverManager(DriverRegistry registry, DeviceService deviceService,
542 NetworkConfigService networkConfigService) {
Andrea Campanellae3708782017-10-16 16:00:21 +0200543 this.registry = registry;
544 this.deviceService = deviceService;
Thomas Vachuska164ecf62018-05-08 17:29:55 -0700545 this.networkConfigService = networkConfigService;
Carmelo Cascone0761cd32018-08-29 19:22:50 -0700546 this.pipeconfService = new PiPipeconfServiceAdapter();
Andrea Campanellae3708782017-10-16 16:00:21 +0200547 activate();
548 }
549 }
550
551 public static class TestMeterQuery extends AbstractHandlerBehaviour
552 implements MeterQuery {
553 private static final long MAX_METER = 0x00000FFF;
554
555 @Override
556 public long getMaxMeters() {
557 return MAX_METER;
558 }
559 }
560
561 private static List<MeterOperation> meterOperations = new ArrayList<>();
562
563 public static class TestMeterProgrammable extends AbstractHandlerBehaviour
564 implements MeterProgrammable {
565
566 @Override
567 public CompletableFuture<Boolean> performMeterOperation(MeterOperation meterOp) {
568 return CompletableFuture.completedFuture(meterOperations.add(meterOp));
569 }
570
571 @Override
572 public CompletableFuture<Collection<Meter>> getMeters() {
573 //ADD METER
574 DefaultMeter mProgrammableAdded = (DefaultMeter) mProgrammable;
575 mProgrammableAdded.setState(MeterState.ADDED);
576 return CompletableFuture.completedFuture(ImmutableList.of(mProgrammableAdded));
577 }
578 }
579
alshabibe1248b62015-08-20 17:21:55 -0700580 private class TestProvider extends AbstractProvider implements MeterProvider {
581
582 protected TestProvider(ProviderId id) {
583 super(PID);
584 }
585
586 @Override
587 public void performMeterOperation(DeviceId deviceId, MeterOperations meterOps) {
588 //Currently unused.
589 }
590
591 @Override
592 public void performMeterOperation(DeviceId deviceId, MeterOperation meterOp) {
Pier Luigif094c612017-10-14 12:15:02 +0200593 //Currently unused
alshabibe1248b62015-08-20 17:21:55 -0700594 }
595 }
596
Pier Luigif094c612017-10-14 12:15:02 +0200597 // Test mastership service
598 private final class TestMastershipService extends MastershipServiceAdapter {
alshabibe1248b62015-08-20 17:21:55 -0700599 @Override
600 public NodeId getMasterFor(DeviceId deviceId) {
601 return NID_LOCAL;
602 }
Andrea Campanellae3708782017-10-16 16:00:21 +0200603
604 @Override
605 public MastershipRole getLocalRole(DeviceId deviceId) {
606 return MastershipRole.MASTER;
607 }
alshabibe1248b62015-08-20 17:21:55 -0700608 }
Pier Luigif094c612017-10-14 12:15:02 +0200609
alshabibe1248b62015-08-20 17:21:55 -0700610}