[ONOS-7116] Implement MeterProgrammable and MeterDriverProvider
Change-Id: I398edda11a6b77b66d79758cf3afab42976e8ff3
diff --git a/core/net/src/test/java/org/onosproject/net/meter/impl/MeterManagerTest.java b/core/net/src/test/java/org/onosproject/net/meter/impl/MeterManagerTest.java
index 51d3384..0ac5d85 100644
--- a/core/net/src/test/java/org/onosproject/net/meter/impl/MeterManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/meter/impl/MeterManagerTest.java
@@ -15,12 +15,16 @@
*/
package org.onosproject.net.meter.impl;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.onlab.junit.TestTools;
import org.onlab.junit.TestUtils;
import org.onlab.packet.IpAddress;
+import org.onosproject.cfg.ComponentConfigAdapter;
import org.onosproject.cluster.ClusterServiceAdapter;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.DefaultControllerNode;
@@ -28,7 +32,20 @@
import org.onosproject.common.event.impl.TestEventDispatcher;
import org.onosproject.incubator.store.meter.impl.DistributedMeterStore;
import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.behaviour.MeterQuery;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.driver.DefaultDriver;
+import org.onosproject.net.driver.DriverRegistry;
+import org.onosproject.net.driver.impl.DriverManager;
+import org.onosproject.net.driver.impl.DriverRegistryManager;
import org.onosproject.net.meter.Band;
import org.onosproject.net.meter.DefaultBand;
import org.onosproject.net.meter.DefaultMeter;
@@ -39,10 +56,12 @@
import org.onosproject.net.meter.MeterId;
import org.onosproject.net.meter.MeterOperation;
import org.onosproject.net.meter.MeterOperations;
+import org.onosproject.net.meter.MeterProgrammable;
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;
@@ -50,7 +69,11 @@
import java.util.Collections;
import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
@@ -69,9 +92,27 @@
// Test ip address
private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
- // Provider id used during the tests
private static final ProviderId PID = new ProviderId("of", "foo");
+ private static final ProviderId PROGRAMMABLE_PROVIDER = new ProviderId("foo", "foo");
+ private static final DeviceId PROGRAMMABLE_DID = DeviceId.deviceId("test:002");
+
+ private static final DefaultAnnotations ANNOTATIONS =
+ DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, "foo").build();
+
+ private static final Device PROGRAMMABLE_DEV =
+ new DefaultDevice(PROGRAMMABLE_PROVIDER, PROGRAMMABLE_DID, Device.Type.SWITCH,
+ "", "", "", "", null, ANNOTATIONS);
+
+
+ private MeterService service;
+
+ // Test Driver service used during the tests
+ private DriverManager driverService;
+
+ // Test device service used during the tests
+ private DeviceService deviceService;
+
// Test provider used during the tests
private TestProvider provider;
@@ -95,7 +136,7 @@
private MeterId mid1 = MeterId.meterId(1);
// Bands used during the tests
- private Band b1 = DefaultBand.builder()
+ private static Band b1 = DefaultBand.builder()
.ofType(Band.Type.DROP)
.withRate(500)
.build();
@@ -116,6 +157,14 @@
.withBands(Collections.singletonList(b1))
.build();
+ private static Meter mProgrammable = DefaultMeter.builder()
+ .forDevice(PROGRAMMABLE_DID)
+ .fromApp(APP_ID)
+ .withId(MeterId.meterId(1))
+ .withUnit(Meter.Unit.KB_PER_SEC)
+ .withBands(Collections.singletonList(b1))
+ .build();
+
// Meter requests used during the tests
private MeterRequest.Builder m1Request = DefaultMeterRequest.builder()
.forDevice(did1)
@@ -128,6 +177,12 @@
.withUnit(Meter.Unit.KB_PER_SEC)
.withBands(Collections.singletonList(b1));
+ private MeterRequest.Builder mProgrammableRequest = DefaultMeterRequest.builder()
+ .forDevice(PROGRAMMABLE_DID)
+ .fromApp(APP_ID)
+ .withUnit(Meter.Unit.KB_PER_SEC)
+ .withBands(Collections.singletonList(b1));
+
// Meter features used during the tests
private MeterFeatures mef1 = DefaultMeterFeatures.builder().forDevice(did1)
.withMaxMeters(3L)
@@ -148,14 +203,27 @@
.withMaxColors((byte) 0)
.build();
+
@Before
public void setup() {
+ //Init step for the deviceService
+ deviceService = new TestDeviceService();
+ //Init step for the driver registry and driver service.
+ DriverRegistryManager driverRegistry = new DriverRegistryManager();
+ driverService = new TestDriverManager(driverRegistry, deviceService);
+ driverRegistry.addDriver(new DefaultDriver("foo", ImmutableList.of(), "",
+ "", "",
+ ImmutableMap.of(MeterProgrammable.class,
+ TestMeterProgrammable.class, MeterQuery.class, TestMeterQuery.class),
+ ImmutableMap.of()));
+
// Init step for the store
meterStore = new DistributedMeterStore();
// Let's initialize some internal services of the store
TestUtils.setField(meterStore, "storageService", new TestStorageService());
TestUtils.setField(meterStore, "clusterService", new TestClusterService());
TestUtils.setField(meterStore, "mastershipService", new TestMastershipService());
+ TestUtils.setField(meterStore, "driverService", driverService);
// Activate the store
meterStore.activate();
// Init step for the manager
@@ -163,11 +231,19 @@
// Let's initialize some internal services of the manager
TestUtils.setField(manager, "store", meterStore);
injectEventDispatcher(manager, new TestEventDispatcher());
+ manager.deviceService = deviceService;
+ manager.mastershipService = new TestMastershipService();
+ manager.cfgService = new ComponentConfigAdapter();
+ TestUtils.setField(manager, "storageService", new TestStorageService());
// Init the reference of the registry
registry = manager;
+
+ manager.driverService = driverService;
+
// Activate the manager
- manager.activate();
+ manager.activate(null);
// Initialize the test provider
+
provider = new TestProvider(PID);
// Register the provider against the manager
providerService = registry.register(provider);
@@ -337,6 +413,61 @@
assertTrue("The meter was not removed", manager.getMeters(did2).size() == 0);
}
+ @Test
+ public void testAddFromMeterProgrammable() {
+
+ // Init store
+ initMeterStore();
+
+ manager.submit(mProgrammableRequest.add());
+
+ TestTools.assertAfter(500, () -> {
+
+ assertTrue("The meter was not added", manager.getAllMeters().size() == 1);
+
+ assertThat(manager.getMeter(PROGRAMMABLE_DID, MeterId.meterId(1)), is(mProgrammable));
+ });
+
+ }
+
+ @Test
+ public void testAddBatchFromMeterProgrammable() {
+
+ // Init store
+ initMeterStore();
+
+ List<MeterOperation> operations = ImmutableList.of(new MeterOperation(mProgrammable, MeterOperation.Type.ADD));
+ manager.defaultProvider().performMeterOperation(PROGRAMMABLE_DID, new MeterOperations(operations));
+
+ TestTools.assertAfter(500, () -> {
+
+ assertTrue("The meter was not added", meterOperations.size() == 1);
+
+ assertTrue("Wrong Meter Operation", meterOperations.get(0).meter().id().equals(mProgrammable.id()));
+ });
+
+ }
+
+ @Test
+ public void testGetFromMeterProgrammable() {
+
+ // Init store
+ initMeterStore();
+
+ MeterDriverProvider fallback = (MeterDriverProvider) manager.defaultProvider();
+
+ testAddFromMeterProgrammable();
+
+ fallback.init(manager.deviceService, fallback.meterProviderService, manager.mastershipService, 1);
+
+ TestTools.assertAfter(2000, () -> {
+ assertTrue("The meter was not added", manager.getAllMeters().size() == 1);
+ Meter m = manager.getMeters(PROGRAMMABLE_DID).iterator().next();
+ assertEquals("incorrect state", MeterState.ADDED, m.state());
+ });
+
+ }
+
// Test cluster service
private final class TestClusterService extends ClusterServiceAdapter {
@@ -354,6 +485,65 @@
}
+ private static class TestDeviceService extends DeviceServiceAdapter {
+ @Override
+ public int getDeviceCount() {
+ return 1;
+ }
+
+ @Override
+ public Iterable<Device> getDevices() {
+ return ImmutableList.of(PROGRAMMABLE_DEV);
+ }
+
+ @Override
+ public Iterable<Device> getAvailableDevices() {
+ return getDevices();
+ }
+
+ @Override
+ public Device getDevice(DeviceId deviceId) {
+ return PROGRAMMABLE_DEV;
+ }
+ }
+
+ private class TestDriverManager extends DriverManager {
+ TestDriverManager(DriverRegistry registry, DeviceService deviceService) {
+ this.registry = registry;
+ this.deviceService = deviceService;
+ activate();
+ }
+ }
+
+ public static class TestMeterQuery extends AbstractHandlerBehaviour
+ implements MeterQuery {
+ private static final long MAX_METER = 0x00000FFF;
+
+ @Override
+ public long getMaxMeters() {
+ return MAX_METER;
+ }
+ }
+
+ private static List<MeterOperation> meterOperations = new ArrayList<>();
+
+ public static class TestMeterProgrammable extends AbstractHandlerBehaviour
+ implements MeterProgrammable {
+
+ @Override
+ public CompletableFuture<Boolean> performMeterOperation(MeterOperation meterOp) {
+ return CompletableFuture.completedFuture(meterOperations.add(meterOp));
+ }
+
+ @Override
+ public CompletableFuture<Collection<Meter>> getMeters() {
+ //ADD METER
+ DefaultMeter mProgrammableAdded = (DefaultMeter) mProgrammable;
+ mProgrammableAdded.setState(MeterState.ADDED);
+ return CompletableFuture.completedFuture(ImmutableList.of(mProgrammableAdded));
+ }
+ }
+
private class TestProvider extends AbstractProvider implements MeterProvider {
protected TestProvider(ProviderId id) {
@@ -377,6 +567,11 @@
public NodeId getMasterFor(DeviceId deviceId) {
return NID_LOCAL;
}
+
+ @Override
+ public MastershipRole getLocalRole(DeviceId deviceId) {
+ return MastershipRole.MASTER;
+ }
}
}