blob: 51d33841c40797df242dd0a40123f49c2ede5169 [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
alshabibe1248b62015-08-20 17:21:55 -070018import com.google.common.collect.Sets;
19import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
22import org.onlab.junit.TestUtils;
23import org.onlab.packet.IpAddress;
24import org.onosproject.cluster.ClusterServiceAdapter;
25import org.onosproject.cluster.ControllerNode;
26import org.onosproject.cluster.DefaultControllerNode;
27import org.onosproject.cluster.NodeId;
28import org.onosproject.common.event.impl.TestEventDispatcher;
alshabibe1248b62015-08-20 17:21:55 -070029import org.onosproject.incubator.store.meter.impl.DistributedMeterStore;
30import org.onosproject.mastership.MastershipServiceAdapter;
31import org.onosproject.net.DeviceId;
32import org.onosproject.net.meter.Band;
33import org.onosproject.net.meter.DefaultBand;
34import org.onosproject.net.meter.DefaultMeter;
Jordi Ortizaa8de492016-12-01 00:21:36 +010035import org.onosproject.net.meter.DefaultMeterFeatures;
alshabibe1248b62015-08-20 17:21:55 -070036import org.onosproject.net.meter.DefaultMeterRequest;
37import org.onosproject.net.meter.Meter;
Pier Luigif094c612017-10-14 12:15:02 +020038import org.onosproject.net.meter.MeterFeatures;
alshabibe1248b62015-08-20 17:21:55 -070039import org.onosproject.net.meter.MeterId;
40import org.onosproject.net.meter.MeterOperation;
41import org.onosproject.net.meter.MeterOperations;
42import org.onosproject.net.meter.MeterProvider;
43import org.onosproject.net.meter.MeterProviderRegistry;
44import org.onosproject.net.meter.MeterProviderService;
45import org.onosproject.net.meter.MeterRequest;
alshabibe1248b62015-08-20 17:21:55 -070046import org.onosproject.net.meter.MeterState;
47import org.onosproject.net.provider.AbstractProvider;
48import org.onosproject.net.provider.ProviderId;
49import org.onosproject.store.service.TestStorageService;
50
51import java.util.Collections;
Jordi Ortizaa8de492016-12-01 00:21:36 +010052import java.util.HashSet;
alshabibe1248b62015-08-20 17:21:55 -070053import java.util.Set;
54
55import static org.hamcrest.Matchers.is;
Jordi Ortizaa8de492016-12-01 00:21:36 +010056import static org.junit.Assert.*;
alshabibe1248b62015-08-20 17:21:55 -070057import static org.onosproject.net.NetTestTools.APP_ID;
58import static org.onosproject.net.NetTestTools.did;
59import static org.onosproject.net.NetTestTools.injectEventDispatcher;
60
61/**
62 * Meter manager tests.
63 */
64public class MeterManagerTest {
65
Pier Luigif094c612017-10-14 12:15:02 +020066 // Test node id
alshabibe1248b62015-08-20 17:21:55 -070067 private static final NodeId NID_LOCAL = new NodeId("local");
Pier Luigif094c612017-10-14 12:15:02 +020068
69 // Test ip address
alshabibe1248b62015-08-20 17:21:55 -070070 private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
71
Pier Luigif094c612017-10-14 12:15:02 +020072 // Provider id used during the tests
73 private static final ProviderId PID = new ProviderId("of", "foo");
alshabibe1248b62015-08-20 17:21:55 -070074
Pier Luigif094c612017-10-14 12:15:02 +020075 // Test provider used during the tests
alshabibe1248b62015-08-20 17:21:55 -070076 private TestProvider provider;
77
Pier Luigif094c612017-10-14 12:15:02 +020078 // Meter manager
79 private MeterManager manager;
alshabibe1248b62015-08-20 17:21:55 -070080
Pier Luigif094c612017-10-14 12:15:02 +020081 // Meter provider registry
82 private MeterProviderRegistry registry;
alshabibe1248b62015-08-20 17:21:55 -070083
Pier Luigif094c612017-10-14 12:15:02 +020084 // Meter provider service
85 private MeterProviderService providerService;
alshabibe1248b62015-08-20 17:21:55 -070086
Pier Luigif094c612017-10-14 12:15:02 +020087 // Store under testing
88 private DistributedMeterStore meterStore;
89
90 // Device ids used during the tests
91 private DeviceId did1 = did("1");
92 private DeviceId did2 = did("2");
93
94 // Meter ids used during the tests
95 private MeterId mid1 = MeterId.meterId(1);
96
97 // Bands used during the tests
98 private Band b1 = DefaultBand.builder()
99 .ofType(Band.Type.DROP)
100 .withRate(500)
101 .build();
102
103 // Meters used during the tests
104 private Meter m1 = DefaultMeter.builder()
105 .forDevice(did1)
106 .fromApp(APP_ID)
107 .withId(mid1)
108 .withUnit(Meter.Unit.KB_PER_SEC)
109 .withBands(Collections.singletonList(b1))
110 .build();
111 private Meter m2 = DefaultMeter.builder()
112 .forDevice(did2)
113 .fromApp(APP_ID)
114 .withId(mid1)
115 .withUnit(Meter.Unit.KB_PER_SEC)
116 .withBands(Collections.singletonList(b1))
117 .build();
118
119 // Meter requests used during the tests
120 private MeterRequest.Builder m1Request = DefaultMeterRequest.builder()
121 .forDevice(did1)
122 .fromApp(APP_ID)
123 .withUnit(Meter.Unit.KB_PER_SEC)
124 .withBands(Collections.singletonList(b1));
125 private MeterRequest.Builder m2Request = DefaultMeterRequest.builder()
126 .forDevice(did2)
127 .fromApp(APP_ID)
128 .withUnit(Meter.Unit.KB_PER_SEC)
129 .withBands(Collections.singletonList(b1));
130
131 // Meter features used during the tests
132 private MeterFeatures mef1 = DefaultMeterFeatures.builder().forDevice(did1)
133 .withMaxMeters(3L)
134 .withBandTypes(new HashSet<>())
135 .withUnits(new HashSet<>())
136 .hasStats(false)
137 .hasBurst(false)
138 .withMaxBands((byte) 0)
139 .withMaxColors((byte) 0)
140 .build();
141 private MeterFeatures mef2 = DefaultMeterFeatures.builder().forDevice(did2)
142 .withMaxMeters(10L)
143 .withBandTypes(new HashSet<>())
144 .withUnits(new HashSet<>())
145 .hasStats(false)
146 .hasBurst(false)
147 .withMaxBands((byte) 0)
148 .withMaxColors((byte) 0)
149 .build();
alshabibe1248b62015-08-20 17:21:55 -0700150
151 @Before
Pier Luigif094c612017-10-14 12:15:02 +0200152 public void setup() {
153 // Init step for the store
alshabibe1248b62015-08-20 17:21:55 -0700154 meterStore = new DistributedMeterStore();
Pier Luigif094c612017-10-14 12:15:02 +0200155 // Let's initialize some internal services of the store
alshabibe1248b62015-08-20 17:21:55 -0700156 TestUtils.setField(meterStore, "storageService", new TestStorageService());
157 TestUtils.setField(meterStore, "clusterService", new TestClusterService());
158 TestUtils.setField(meterStore, "mastershipService", new TestMastershipService());
Pier Luigif094c612017-10-14 12:15:02 +0200159 // Activate the store
alshabibe1248b62015-08-20 17:21:55 -0700160 meterStore.activate();
Pier Luigif094c612017-10-14 12:15:02 +0200161 // Init step for the manager
alshabibe1248b62015-08-20 17:21:55 -0700162 manager = new MeterManager();
Pier Luigif094c612017-10-14 12:15:02 +0200163 // Let's initialize some internal services of the manager
164 TestUtils.setField(manager, "store", meterStore);
alshabibe1248b62015-08-20 17:21:55 -0700165 injectEventDispatcher(manager, new TestEventDispatcher());
Pier Luigif094c612017-10-14 12:15:02 +0200166 // Init the reference of the registry
alshabibe1248b62015-08-20 17:21:55 -0700167 registry = manager;
Pier Luigif094c612017-10-14 12:15:02 +0200168 // Activate the manager
alshabibe1248b62015-08-20 17:21:55 -0700169 manager.activate();
Pier Luigif094c612017-10-14 12:15:02 +0200170 // Initialize the test provider
alshabibe1248b62015-08-20 17:21:55 -0700171 provider = new TestProvider(PID);
Pier Luigif094c612017-10-14 12:15:02 +0200172 // Register the provider against the manager
alshabibe1248b62015-08-20 17:21:55 -0700173 providerService = registry.register(provider);
Pier Luigif094c612017-10-14 12:15:02 +0200174 // Verify register
alshabibe1248b62015-08-20 17:21:55 -0700175 assertTrue("provider should be registered",
176 registry.getProviders().contains(provider.id()));
alshabibe1248b62015-08-20 17:21:55 -0700177 }
178
179 @After
180 public void tearDown() {
Pier Luigif094c612017-10-14 12:15:02 +0200181 // Unregister provider
alshabibe1248b62015-08-20 17:21:55 -0700182 registry.unregister(provider);
Pier Luigif094c612017-10-14 12:15:02 +0200183 // Verify unregister
alshabibe1248b62015-08-20 17:21:55 -0700184 assertFalse("provider should not be registered",
185 registry.getProviders().contains(provider.id()));
Pier Luigif094c612017-10-14 12:15:02 +0200186 // Deactivate manager
alshabibe1248b62015-08-20 17:21:55 -0700187 manager.deactivate();
Pier Luigif094c612017-10-14 12:15:02 +0200188 // Remove event dispatcher
alshabibe1248b62015-08-20 17:21:55 -0700189 injectEventDispatcher(manager, null);
Pier Luigif094c612017-10-14 12:15:02 +0200190 // Deactivate store
191 meterStore.deactivate();
alshabibe1248b62015-08-20 17:21:55 -0700192 }
193
Pier Luigif094c612017-10-14 12:15:02 +0200194 private void initMeterStore() {
195 // Let's store feature for device 1
196 meterStore.storeMeterFeatures(mef1);
197 // Let's store feature for device 2
198 meterStore.storeMeterFeatures(mef2);
199 }
200
201 // Emulate metrics coming from the dataplane
202 private void pushMetrics(MeterOperation.Type type, Meter meter) {
203 // If it is an add operation
204 if (type == MeterOperation.Type.ADD) {
205 // Update state to added
206 ((DefaultMeter) meter).setState(MeterState.ADDED);
207 // Push the update in the store
208 providerService.pushMeterMetrics(meter.deviceId(), Collections.singletonList(meter));
209 } else {
210 providerService.pushMeterMetrics(meter.deviceId(), Collections.emptyList());
211 }
212 }
213
214 /**
215 * Test add meter.
216 */
alshabibe1248b62015-08-20 17:21:55 -0700217 @Test
Pier Luigif094c612017-10-14 12:15:02 +0200218 public void testAdd() {
219 // Init store
220 initMeterStore();
221 // Submit meter request
alshabibe1248b62015-08-20 17:21:55 -0700222 manager.submit(m1Request.add());
Pier Luigif094c612017-10-14 12:15:02 +0200223 // Verify add
alshabibe1248b62015-08-20 17:21:55 -0700224 assertTrue("The meter was not added", manager.getAllMeters().size() == 1);
Pier Luigif094c612017-10-14 12:15:02 +0200225 assertTrue("The meter was not added", manager.getMeters(did1).size() == 1);
226 // Get Meter
227 Meter installingMeter = manager.getMeter(did1, mid1);
228 // Verify add of installingMeter and pending add state
229 assertThat(installingMeter, is(m1));
230 // Verify pending add state
231 assertThat(installingMeter.state(), is(MeterState.PENDING_ADD));
232 // Let's simulate a working data-plane
233 pushMetrics(MeterOperation.Type.ADD, installingMeter);
234 // Get meter
235 Meter installedMeter = manager.getMeter(did1, mid1);
236 // Verify installation
237 assertThat(installedMeter.state(), is(MeterState.ADDED));
238 assertTrue("The meter was not installed", manager.getAllMeters().size() == 1);
239 assertTrue("The meter was not installed", manager.getMeters(did1).size() == 1);
alshabibe1248b62015-08-20 17:21:55 -0700240 }
241
Pier Luigif094c612017-10-14 12:15:02 +0200242 /**
243 * Test remove meter.
244 */
alshabibe1248b62015-08-20 17:21:55 -0700245 @Test
246 public void testRemove() {
Pier Luigif094c612017-10-14 12:15:02 +0200247 // Init store
248 initMeterStore();
249 // Submit meter request
alshabibe1248b62015-08-20 17:21:55 -0700250 manager.submit(m1Request.add());
Pier Luigif094c612017-10-14 12:15:02 +0200251 // Withdraw meter
alshabibe1248b62015-08-20 17:21:55 -0700252 manager.withdraw(m1Request.remove(), m1.id());
Pier Luigif094c612017-10-14 12:15:02 +0200253 // Get Meter
254 Meter withdrawingMeter = manager.getMeter(did1, mid1);
255 // Verify withdrawing
256 assertThat(withdrawingMeter.state(), is(MeterState.PENDING_REMOVE));
257 assertTrue("The meter was not withdrawn", manager.getAllMeters().size() == 1);
258 assertTrue("The meter was not withdrawn", manager.getMeters(did1).size() == 1);
259 // Let's simulate a working data-plane
260 pushMetrics(MeterOperation.Type.REMOVE, withdrawingMeter);
261 // Verify withdrawn
262 assertNull(manager.getMeter(did1, mid1));
alshabibe1248b62015-08-20 17:21:55 -0700263 assertTrue("The meter was not removed", manager.getAllMeters().size() == 0);
Pier Luigif094c612017-10-14 12:15:02 +0200264 assertTrue("The meter was not removed", manager.getMeters(did1).size() == 0);
alshabibe1248b62015-08-20 17:21:55 -0700265 }
266
Pier Luigif094c612017-10-14 12:15:02 +0200267 /**
268 * Test add multiple device.
269 */
alshabib70aaa1b2015-09-25 14:30:59 -0700270 @Test
Pier Luigif094c612017-10-14 12:15:02 +0200271 public void testAddMultipleDevice() {
272 // Init store
273 initMeterStore();
274 // Submit meter 1
alshabib70aaa1b2015-09-25 14:30:59 -0700275 manager.submit(m1Request.add());
Pier Luigif094c612017-10-14 12:15:02 +0200276 // Submit meter 2
alshabib70aaa1b2015-09-25 14:30:59 -0700277 manager.submit(m2Request.add());
Pier Luigif094c612017-10-14 12:15:02 +0200278 // Verify add
279 assertTrue("The meter was not added", manager.getAllMeters().size() == 2);
280 assertTrue("The meter was not added", manager.getMeters(did1).size() == 1);
281 assertTrue("The meter was not added", manager.getMeters(did2).size() == 1);
282 // Get Meters
283 Meter installingMeter1 = manager.getMeter(did1, mid1);
284 Meter installingMeter2 = manager.getMeter(did2, mid1);
285 // Verify add of installingMeter
286 assertThat(installingMeter1, is(m1));
287 assertThat(installingMeter2, is(m2));
288 // Verify pending add state
289 assertThat(installingMeter1.state(), is(MeterState.PENDING_ADD));
290 assertThat(installingMeter2.state(), is(MeterState.PENDING_ADD));
291 // Let's simulate a working data-plane
292 pushMetrics(MeterOperation.Type.ADD, installingMeter1);
293 pushMetrics(MeterOperation.Type.ADD, installingMeter2);
294 // Get meter
295 Meter installedMeter1 = manager.getMeter(did1, mid1);
296 Meter installedMeter2 = manager.getMeter(did2, mid1);
297 // Verify installation
298 assertThat(installedMeter1.state(), is(MeterState.ADDED));
299 assertThat(installedMeter2.state(), is(MeterState.ADDED));
300 assertTrue("The meter was not installed", manager.getAllMeters().size() == 2);
301 assertTrue("The meter was not installed", manager.getMeters(did1).size() == 1);
302 assertTrue("The meter was not installed", manager.getMeters(did2).size() == 1);
alshabib70aaa1b2015-09-25 14:30:59 -0700303 }
alshabibe1248b62015-08-20 17:21:55 -0700304
Pier Luigif094c612017-10-14 12:15:02 +0200305 /**
306 * Test remove meter.
307 */
Jordi Ortizaa8de492016-12-01 00:21:36 +0100308 @Test
Pier Luigif094c612017-10-14 12:15:02 +0200309 public void testRemoveMultipleDevice() {
310 // Init store
311 initMeterStore();
312 // Submit meter 1
Jordi Ortiz6c847762017-01-30 17:13:05 +0100313 manager.submit(m1Request.add());
Pier Luigif094c612017-10-14 12:15:02 +0200314 // Submit meter 2
315 manager.submit(m2Request.add());
316 // Withdraw meter
317 manager.withdraw(m1Request.remove(), m1.id());
318 // Withdraw meter
319 manager.withdraw(m2Request.remove(), m2.id());
320 // Get Meters
321 Meter withdrawingMeter1 = manager.getMeter(did1, mid1);
322 Meter withdrawingMeter2 = manager.getMeter(did2, mid1);
323 // Verify withdrawing
324 assertThat(withdrawingMeter1.state(), is(MeterState.PENDING_REMOVE));
325 assertThat(withdrawingMeter2.state(), is(MeterState.PENDING_REMOVE));
326 assertTrue("The meter was not withdrawn", manager.getAllMeters().size() == 2);
327 assertTrue("The meter was not withdrawn", manager.getMeters(did1).size() == 1);
328 assertTrue("The meter was not withdrawn", manager.getMeters(did2).size() == 1);
329 // Let's simulate a working data-plane
330 pushMetrics(MeterOperation.Type.REMOVE, withdrawingMeter1);
331 pushMetrics(MeterOperation.Type.REMOVE, withdrawingMeter2);
332 // Verify withdrawn
333 assertNull(manager.getMeter(did1, mid1));
334 assertNull(manager.getMeter(did2, mid1));
335 assertTrue("The meter was not removed", manager.getAllMeters().size() == 0);
336 assertTrue("The meter was not removed", manager.getMeters(did1).size() == 0);
337 assertTrue("The meter was not removed", manager.getMeters(did2).size() == 0);
Jordi Ortiz6c847762017-01-30 17:13:05 +0100338 }
339
Pier Luigif094c612017-10-14 12:15:02 +0200340 // Test cluster service
341 private final class TestClusterService extends ClusterServiceAdapter {
Jordi Ortizaa8de492016-12-01 00:21:36 +0100342
Pier Luigif094c612017-10-14 12:15:02 +0200343 private ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
Jordi Ortizaa8de492016-12-01 00:21:36 +0100344
Pier Luigif094c612017-10-14 12:15:02 +0200345 @Override
346 public ControllerNode getLocalNode() {
347 return local;
alshabibe1248b62015-08-20 17:21:55 -0700348 }
Pier Luigif094c612017-10-14 12:15:02 +0200349
350 @Override
351 public Set<ControllerNode> getNodes() {
352 return Sets.newHashSet();
353 }
354
alshabibe1248b62015-08-20 17:21:55 -0700355 }
356
357 private class TestProvider extends AbstractProvider implements MeterProvider {
358
359 protected TestProvider(ProviderId id) {
360 super(PID);
361 }
362
363 @Override
364 public void performMeterOperation(DeviceId deviceId, MeterOperations meterOps) {
365 //Currently unused.
366 }
367
368 @Override
369 public void performMeterOperation(DeviceId deviceId, MeterOperation meterOp) {
Pier Luigif094c612017-10-14 12:15:02 +0200370 //Currently unused
alshabibe1248b62015-08-20 17:21:55 -0700371 }
372 }
373
Pier Luigif094c612017-10-14 12:15:02 +0200374 // Test mastership service
375 private final class TestMastershipService extends MastershipServiceAdapter {
alshabibe1248b62015-08-20 17:21:55 -0700376 @Override
377 public NodeId getMasterFor(DeviceId deviceId) {
378 return NID_LOCAL;
379 }
380 }
Pier Luigif094c612017-10-14 12:15:02 +0200381
alshabibe1248b62015-08-20 17:21:55 -0700382}