/* * Copyright 2015-present Open Networking Laboratory * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onosproject.incubator.net.meter.impl; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.onlab.junit.TestUtils; import org.onlab.packet.IpAddress; import org.onosproject.cluster.ClusterServiceAdapter; import org.onosproject.cluster.ControllerNode; import org.onosproject.cluster.DefaultControllerNode; import org.onosproject.cluster.NodeId; import org.onosproject.common.event.impl.TestEventDispatcher; import org.onosproject.core.ApplicationId; import org.onosproject.core.DefaultApplicationId; import org.onosproject.incubator.store.meter.impl.DistributedMeterStore; import org.onosproject.mastership.MastershipServiceAdapter; import org.onosproject.net.DeviceId; import org.onosproject.net.meter.Band; import org.onosproject.net.meter.DefaultBand; import org.onosproject.net.meter.DefaultMeter; import org.onosproject.net.meter.DefaultMeterFeatures; import org.onosproject.net.meter.DefaultMeterRequest; import org.onosproject.net.meter.Meter; import org.onosproject.net.meter.MeterFeaturesKey; import org.onosproject.net.meter.MeterId; import org.onosproject.net.meter.MeterOperation; import org.onosproject.net.meter.MeterOperations; import org.onosproject.net.meter.MeterProvider; import org.onosproject.net.meter.MeterProviderRegistry; import org.onosproject.net.meter.MeterProviderService; import org.onosproject.net.meter.MeterRequest; import org.onosproject.net.meter.MeterService; import org.onosproject.net.meter.MeterState; import org.onosproject.net.provider.AbstractProvider; import org.onosproject.net.provider.ProviderId; import org.onosproject.store.service.TestStorageService; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; import static org.hamcrest.Matchers.is; import static org.junit.Assert.*; import static org.onosproject.net.NetTestTools.APP_ID; import static org.onosproject.net.NetTestTools.did; import static org.onosproject.net.NetTestTools.injectEventDispatcher; /** * Meter manager tests. */ public class MeterManagerTest { private static final ProviderId PID = new ProviderId("of", "foo"); private static final NodeId NID_LOCAL = new NodeId("local"); private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1"); private MeterService service; private MeterManager manager; private DistributedMeterStore meterStore; private MeterProviderRegistry registry; private MeterProviderService providerService; private TestProvider provider; private ApplicationId appId; private Meter m1; private Meter m2; private MeterRequest.Builder m1Request; private MeterRequest.Builder m2Request; private MeterRequest.Builder m3Request; private Map<MeterId, Meter> meters = Maps.newHashMap(); @Before public void setup() throws Exception { meterStore = new DistributedMeterStore(); TestUtils.setField(meterStore, "storageService", new TestStorageService()); TestUtils.setField(meterStore, "clusterService", new TestClusterService()); TestUtils.setField(meterStore, "mastershipService", new TestMastershipService()); meterStore.activate(); meterStore.storeMeterFeatures(DefaultMeterFeatures.builder().forDevice(did("1")) .withMaxMeters(255L) .withBandTypes(new HashSet<>()) .withUnits(new HashSet<>()) .hasStats(false) .hasBurst(false) .withMaxBands((byte) 0) .withMaxColors((byte) 0) .build()); meterStore.storeMeterFeatures(DefaultMeterFeatures.builder().forDevice(did("2")) .withMaxMeters(2) .withBandTypes(new HashSet<>()) .withUnits(new HashSet<>()) .hasBurst(false) .hasStats(false) .withMaxBands((byte) 0) .withMaxColors((byte) 0) .build()); manager = new MeterManager(); manager.store = meterStore; TestUtils.setField(manager, "storageService", new TestStorageService()); injectEventDispatcher(manager, new TestEventDispatcher()); service = manager; registry = manager; manager.activate(); provider = new TestProvider(PID); providerService = registry.register(provider); appId = new TestApplicationId(0, "MeterManagerTest"); assertTrue("provider should be registered", registry.getProviders().contains(provider.id())); Band band = DefaultBand.builder() .ofType(Band.Type.DROP) .withRate(500) .build(); m1 = DefaultMeter.builder() .forDevice(did("1")) .fromApp(APP_ID) .withId(MeterId.meterId(1)) .withUnit(Meter.Unit.KB_PER_SEC) .withBands(Collections.singletonList(band)) .build(); m2 = DefaultMeter.builder() .forDevice(did("2")) .fromApp(APP_ID) .withId(MeterId.meterId(1)) .withUnit(Meter.Unit.KB_PER_SEC) .withBands(Collections.singletonList(band)) .build(); m1Request = DefaultMeterRequest.builder() .forDevice(did("1")) .fromApp(APP_ID) .withUnit(Meter.Unit.KB_PER_SEC) .withBands(Collections.singletonList(band)); m2Request = DefaultMeterRequest.builder() .forDevice(did("2")) .fromApp(APP_ID) .withUnit(Meter.Unit.KB_PER_SEC) .withBands(Collections.singletonList(band)); m3Request = DefaultMeterRequest.builder() .forDevice(did("1")) .fromApp(APP_ID) .withUnit(Meter.Unit.KB_PER_SEC) .withBands(Collections.singletonList(band)); } @After public void tearDown() { registry.unregister(provider); assertFalse("provider should not be registered", registry.getProviders().contains(provider.id())); manager.deactivate(); injectEventDispatcher(manager, null); } @Test public void testAddition() { manager.submit(m1Request.add()); assertTrue("The meter was not added", manager.getAllMeters().size() == 1); assertThat(manager.getMeter(did("1"), MeterId.meterId(1)), is(m1)); } @Test public void testRemove() { manager.submit(m1Request.add()); manager.withdraw(m1Request.remove(), m1.id()); assertThat(manager.getMeter(did("1"), MeterId.meterId(1)).state(), is(MeterState.PENDING_REMOVE)); providerService.pushMeterMetrics(m1.deviceId(), Collections.emptyList()); assertTrue("The meter was not removed", manager.getAllMeters().size() == 0); } @Test public void testMultipleDevice() { manager.submit(m1Request.add()); manager.submit(m2Request.add()); assertTrue("The meters were not added", manager.getAllMeters().size() == 2); assertThat(manager.getMeter(did("1"), MeterId.meterId(1)), is(m1)); assertThat(manager.getMeter(did("2"), MeterId.meterId(1)), is(m2)); } @Test public void testMeterFeatures() { assertEquals(meterStore.getMaxMeters(MeterFeaturesKey.key(did("1"))), 255L); assertEquals(meterStore.getMaxMeters(MeterFeaturesKey.key(did("2"))), 2); } @Test public void testMeterReuse() { manager.submit(m1Request.add()); manager.submit(m3Request.add()); Collection<Meter> meters = manager.getMeters(did("1")); Meter m = meters.iterator().next(); MeterRequest mr = DefaultMeterRequest.builder() .forDevice(m.deviceId()) .fromApp(m.appId()) .withBands(m.bands()) .withUnit(m.unit()) .remove(); manager.withdraw(mr, m.id()); mr = DefaultMeterRequest.builder() .forDevice(m.deviceId()) .fromApp(m.appId()) .withBands(m.bands()) .withUnit(m.unit()) .add(); Meter meter = manager.submit(mr); assertTrue("Meter id not reused", m.id().equals(meter.id())); } public class TestApplicationId extends DefaultApplicationId { public TestApplicationId(int id, String name) { super(id, name); } } private class TestProvider extends AbstractProvider implements MeterProvider { protected TestProvider(ProviderId id) { super(PID); } @Override public void performMeterOperation(DeviceId deviceId, MeterOperations meterOps) { //Currently unused. } @Override public void performMeterOperation(DeviceId deviceId, MeterOperation meterOp) { meters.put(meterOp.meter().id(), meterOp.meter()); } } private final class TestClusterService extends ClusterServiceAdapter { ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST); @Override public ControllerNode getLocalNode() { return local; } @Override public Set<ControllerNode> getNodes() { return Sets.newHashSet(); } } private class TestMastershipService extends MastershipServiceAdapter { @Override public NodeId getMasterFor(DeviceId deviceId) { return NID_LOCAL; } } }