Introducing BandwidthProfileConfigBehaviour to manage policers/markers

- Creating BandwidthProfile Class to represent generic policers/markers
- BandwidthProfile can be Single/Two Rate, Two/Three Color depending on parameters
- Including fromMeter() method to convert a Meter into a BandwidthProfile
- Adding unit tests for BandwidthProfile class
- Creating BandwidthProfileAction class to represent a color (green/yellow/red) action
- BandwidthProfileAction allows remarking one of: DSCP class, IP precedence, Drop precedence
- Adding unit tests for BandwidthProfileAction class
- Creating DscpClass and IPPrecedence Enums and unit tests in org.onlab.packet
- Adding kBps/MBps/GBps methods in org.onlab.util.Bandwidth class

Change-Id: I54156329a527ebd9165d8f55e03e0782925caa2b
diff --git a/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileActionTest.java b/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileActionTest.java
new file mode 100644
index 0000000..e8bc68c
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileActionTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2016-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.net.behaviour;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onlab.packet.DscpClass;
+import static org.onosproject.net.behaviour.BandwidthProfileAction.Action;
+
+/**
+ * Test for BandwidthProfileAction class.
+ */
+public class BandwidthProfileActionTest {
+
+    @Test
+    public void testEquals() {
+        BandwidthProfileAction passAction1 = BandwidthProfileAction.builder()
+                .action(Action.PASS)
+                .build();
+        BandwidthProfileAction passAction2 = BandwidthProfileAction.builder()
+                .action(Action.PASS)
+                .build();
+        BandwidthProfileAction discardAction1 = BandwidthProfileAction.builder()
+                .action(Action.DISCARD)
+                .build();
+        BandwidthProfileAction discardAction2 = BandwidthProfileAction.builder()
+                .action(Action.DISCARD)
+                .build();
+        BandwidthProfileAction remarkAction1 = BandwidthProfileAction.builder()
+                .action(Action.REMARK)
+                .dscpClass(DscpClass.AF11)
+                .build();
+        BandwidthProfileAction remarkAction2 = BandwidthProfileAction.builder()
+                .action(Action.REMARK)
+                .dscpClass(DscpClass.AF11)
+                .build();
+        new EqualsTester()
+                .addEqualityGroup(passAction1, passAction2)
+                .addEqualityGroup(discardAction1, discardAction2)
+                .addEqualityGroup(remarkAction1, remarkAction2)
+                .testEquals();
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileTest.java b/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileTest.java
new file mode 100644
index 0000000..8052593
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/behaviour/BandwidthProfileTest.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2016-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.net.behaviour;
+
+import org.junit.Test;
+import org.onlab.packet.DscpClass;
+import org.onlab.util.Bandwidth;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+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.Meter;
+import org.onosproject.net.meter.MeterId;
+import static org.onosproject.net.behaviour.BandwidthProfileAction.Action;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test for BandwidthProfile class.
+ */
+public class BandwidthProfileTest {
+
+    private static final long ONE = 1L;
+    private static final long ONE_K = 1_000L;
+    private static final long TWO_K = 2_000L;
+    private static final long EIGHT_K = 8_000L;
+    private static final long ONE_M = 1_000_000L;
+    private static final long TEN_M = 10_000_000L;
+
+    @Test
+    public void testMeterConversion() {
+        DeviceId deviceId = DeviceId.deviceId("netconf:10.0.0.1:22");
+        ApplicationId appId = TestApplicationId.create("org.onosproject.foo.app");
+        Meter.Builder meterBuilder = new DefaultMeter.Builder()
+                .withId(MeterId.meterId(ONE))
+                .withUnit(Meter.Unit.KB_PER_SEC)
+                .forDevice(deviceId)
+                .burst();
+
+        // Create Meter with single band
+        Band band1 = DefaultBand.builder()
+                .ofType(Band.Type.DROP)
+                .withRate(TEN_M)
+                .burstSize(TWO_K)
+                .build();
+        Meter meter = meterBuilder
+                .fromApp(appId)
+                .withBands(Arrays.asList(band1))
+                .build();
+        BandwidthProfile bandwidthProfile = BandwidthProfile.fromMeter(meter);
+
+        assertEquals("wrong bw profile name",
+                     bandwidthProfile.name(), meter.id().toString());
+        assertEquals("wrong bw profile type",
+                     bandwidthProfile.type(), BandwidthProfile.Type.sr2CM);
+        assertEquals("wrong bw profile CIR",
+                     bandwidthProfile.cir().bps(), band1.rate() * EIGHT_K, 0);
+        assertEquals("wrong bw profile CBS",
+                     (long) bandwidthProfile.cbs(), (long) band1.burst());
+        assertNull(bandwidthProfile.pir());
+        assertNull(bandwidthProfile.pbs());
+        assertNull(bandwidthProfile.ebs());
+        assertEquals("wrong green action",
+                     bandwidthProfile.greenAction(),
+                     getBuilder(Action.PASS).build());
+        assertNull(bandwidthProfile.yellowAction());
+        assertEquals("wrong red action",
+                     bandwidthProfile.redAction(),
+                     getBuilder(Action.DISCARD).build());
+        assertEquals("wrong color-aware mode",
+                     bandwidthProfile.colorAware(), false);
+
+        // Create Meter with two bands
+        Band band2 = DefaultBand.builder().burstSize(ONE_K)
+                .ofType(Band.Type.REMARK)
+                .dropPrecedence((short) 0b001010)
+                .withRate(ONE_M)
+                .build();
+        meter = meterBuilder
+                .fromApp(appId)
+                .withBands(Arrays.asList(band1, band2))
+                .build();
+        bandwidthProfile = BandwidthProfile.fromMeter(meter);
+
+        assertEquals("wrong bw profile name",
+                     bandwidthProfile.name(), meter.id().toString());
+        assertEquals("wrong bw profile type",
+                     bandwidthProfile.type(), BandwidthProfile.Type.trTCM);
+        assertEquals("wrong bw profile CIR",
+                     bandwidthProfile.cir().bps(), band2.rate() * EIGHT_K, 0);
+        assertEquals("wrong bw profile CBS",
+                     (long) bandwidthProfile.cbs(), (long) band2.burst());
+        assertEquals("wrong bw profile PIR",
+                     bandwidthProfile.pir().bps(), band1.rate() * EIGHT_K, 0);
+        assertEquals("wrong bw profile PBS",
+                     (long) bandwidthProfile.pbs(), (long) band1.burst());
+        assertNull(bandwidthProfile.ebs());
+        assertEquals("wrong green action",
+                     bandwidthProfile.greenAction(),
+                     getBuilder(Action.PASS).build());
+        assertEquals("wrong yellow action",
+                     bandwidthProfile.yellowAction(),
+                     getBuilder(Action.REMARK)
+                             .dscpClass(DscpClass.AF11)
+                             .build());
+        assertEquals("wrong red action",
+                     bandwidthProfile.redAction(),
+                     getBuilder(Action.DISCARD).build());
+        assertEquals("wrong color-aware mode",
+                     bandwidthProfile.colorAware(), false);
+    }
+
+    @Test
+    public void testType() {
+        BandwidthProfile.Builder bwProfileBuilder = BandwidthProfile.builder()
+                .name("profile")
+                .cir(Bandwidth.bps(ONE_M))
+                .cbs((int) ONE_K)
+                .greenAction(getBuilder(Action.PASS).build())
+                .redAction(getBuilder(Action.DISCARD).build())
+                .colorAware(false);
+        assertEquals("wrong bw profile type",
+                     bwProfileBuilder.build().type(),
+                     BandwidthProfile.Type.sr2CM);
+
+        bwProfileBuilder.ebs((int) TWO_K)
+                .yellowAction(getBuilder(Action.REMARK)
+                                      .dscpClass(DscpClass.AF11)
+                                      .build());
+        assertEquals("wrong bw profile type",
+                     bwProfileBuilder.build().type(),
+                     BandwidthProfile.Type.srTCM);
+        bwProfileBuilder.ebs(null);
+
+        bwProfileBuilder.pir(Bandwidth.bps(TEN_M))
+                .pbs((int) TWO_K);
+        assertEquals("wrong bw profile type",
+                     bwProfileBuilder.build().type(),
+                     BandwidthProfile.Type.trTCM);
+    }
+
+    @Test
+    public void testEquals() {
+        BandwidthProfile bwProfile1 = new BandwidthProfile.Builder()
+                .name("profile1")
+                .cir(Bandwidth.bps(ONE_M))
+                .cbs((int) ONE_K)
+                .pir(Bandwidth.bps(TEN_M))
+                .pbs((int) TWO_K)
+                .greenAction(getBuilder(Action.PASS).build())
+                .yellowAction(getBuilder(Action.REMARK)
+                                      .dscpClass(DscpClass.AF11)
+                                      .build())
+                .redAction(getBuilder(Action.DISCARD).build())
+                .colorAware(false)
+                .build();
+        BandwidthProfile bwProfile2 = new BandwidthProfile.Builder()
+                .name("profile2")
+                .cir(Bandwidth.bps(ONE_M))
+                .cbs((int) ONE_K)
+                .pir(Bandwidth.bps(TEN_M))
+                .pbs((int) TWO_K)
+                .greenAction(getBuilder(Action.PASS).build())
+                .yellowAction(getBuilder(Action.REMARK)
+                                      .dscpClass(DscpClass.AF11)
+                                      .build())
+                .redAction(getBuilder(Action.DISCARD).build())
+                .colorAware(false)
+                .build();
+        assertTrue("wrong equals method", bwProfile1.equals(bwProfile2));
+    }
+
+    private static BandwidthProfileAction.Builder getBuilder(Action action) {
+        return new BandwidthProfileAction.Builder().action(action);
+    }
+}