summaryrefslogtreecommitdiffstats
path: root/framework/src/onos/utils/misc/src/test/java/org/onlab/util
diff options
context:
space:
mode:
authorAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
committerAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
commit13d05bc8458758ee39cb829098241e89616717ee (patch)
tree22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/utils/misc/src/test/java/org/onlab/util
parent6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (diff)
ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60
Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd
Diffstat (limited to 'framework/src/onos/utils/misc/src/test/java/org/onlab/util')
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/AbstractAccumulatorTest.java184
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/BandwidthTest.java82
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/BlockingBooleanTest.java210
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/BoundedThreadPoolTest.java227
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/ByteArraySizeHashPrinterTest.java53
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/CounterTest.java86
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/FrequencyTest.java107
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/GroupedThreadFactoryTest.java53
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java85
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/PositionalParameterStringFormatterTest.java61
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/RetryingFunctionTest.java94
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/SharedExecutorsTest.java54
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java105
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/ToolsTest.java76
14 files changed, 1477 insertions, 0 deletions
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/AbstractAccumulatorTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/AbstractAccumulatorTest.java
new file mode 100644
index 00000000..02f0deb1
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/AbstractAccumulatorTest.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2015 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.onlab.util;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Timer;
+import java.util.stream.IntStream;
+
+import static org.junit.Assert.*;
+import static org.onlab.junit.TestTools.assertAfter;
+import static org.onlab.junit.TestTools.delay;
+
+/**
+ * Tests the operation of the accumulator.
+ */
+public class AbstractAccumulatorTest {
+
+ private final Timer timer = new Timer();
+
+ @Test
+ public void basics() throws Exception {
+ TestAccumulator accumulator = new TestAccumulator();
+ assertEquals("incorrect timer", timer, accumulator.timer());
+ assertEquals("incorrect max events", 5, accumulator.maxItems());
+ assertEquals("incorrect max ms", 100, accumulator.maxBatchMillis());
+ assertEquals("incorrect idle ms", 70, accumulator.maxIdleMillis());
+ }
+
+ @Ignore("FIXME: timing sensitive test failing randomly.")
+ @Test
+ public void eventTrigger() {
+ TestAccumulator accumulator = new TestAccumulator();
+ accumulator.add(new TestItem("a"));
+ accumulator.add(new TestItem("b"));
+ accumulator.add(new TestItem("c"));
+ accumulator.add(new TestItem("d"));
+ assertTrue("should not have fired yet", accumulator.batch.isEmpty());
+ accumulator.add(new TestItem("e"));
+ delay(20);
+ assertFalse("should have fired", accumulator.batch.isEmpty());
+ assertEquals("incorrect batch", "abcde", accumulator.batch);
+ }
+
+ @Ignore("FIXME: timing sensitive test failing randomly.")
+ @Test
+ public void timeTrigger() {
+ TestAccumulator accumulator = new TestAccumulator();
+ accumulator.add(new TestItem("a"));
+ delay(30);
+ assertTrue("should not have fired yet", accumulator.batch.isEmpty());
+ accumulator.add(new TestItem("b"));
+ delay(30);
+ assertTrue("should not have fired yet", accumulator.batch.isEmpty());
+ accumulator.add(new TestItem("c"));
+ delay(30);
+ assertTrue("should not have fired yet", accumulator.batch.isEmpty());
+ accumulator.add(new TestItem("d"));
+ delay(60);
+ assertFalse("should have fired", accumulator.batch.isEmpty());
+ assertEquals("incorrect batch", "abcd", accumulator.batch);
+ }
+
+ @Ignore("FIXME: timing sensitive test failing randomly.")
+ @Test
+ public void idleTrigger() {
+ TestAccumulator accumulator = new TestAccumulator();
+ accumulator.add(new TestItem("a"));
+ assertTrue("should not have fired yet", accumulator.batch.isEmpty());
+ accumulator.add(new TestItem("b"));
+ delay(80);
+ assertFalse("should have fired", accumulator.batch.isEmpty());
+ assertEquals("incorrect batch", "ab", accumulator.batch);
+ }
+
+ @Ignore("FIXME: timing sensitive test failing randomly.")
+ @Test
+ public void readyIdleTrigger() {
+ TestAccumulator accumulator = new TestAccumulator();
+ accumulator.ready = false;
+ accumulator.add(new TestItem("a"));
+ assertTrue("should not have fired yet", accumulator.batch.isEmpty());
+ accumulator.add(new TestItem("b"));
+ delay(80);
+ assertTrue("should not have fired yet", accumulator.batch.isEmpty());
+ accumulator.ready = true;
+ delay(80);
+ assertFalse("should have fired", accumulator.batch.isEmpty());
+ assertEquals("incorrect batch", "ab", accumulator.batch);
+ }
+
+ @Ignore("FIXME: timing sensitive test failing randomly.")
+ @Test
+ public void readyLongTrigger() {
+ TestAccumulator accumulator = new TestAccumulator();
+ accumulator.ready = false;
+ delay(120);
+ assertTrue("should not have fired yet", accumulator.batch.isEmpty());
+ accumulator.add(new TestItem("a"));
+ assertTrue("should not have fired yet", accumulator.batch.isEmpty());
+ accumulator.ready = true;
+ delay(80);
+ assertFalse("should have fired", accumulator.batch.isEmpty());
+ assertEquals("incorrect batch", "a", accumulator.batch);
+ }
+
+ @Ignore("FIXME: timing sensitive test failing randomly.")
+ @Test
+ public void readyMaxTrigger() {
+ TestAccumulator accumulator = new TestAccumulator();
+ accumulator.ready = false;
+ accumulator.add(new TestItem("a"));
+ accumulator.add(new TestItem("b"));
+ accumulator.add(new TestItem("c"));
+ accumulator.add(new TestItem("d"));
+ accumulator.add(new TestItem("e"));
+ accumulator.add(new TestItem("f"));
+ assertTrue("should not have fired yet", accumulator.batch.isEmpty());
+ accumulator.ready = true;
+ accumulator.add(new TestItem("g"));
+ delay(5);
+ assertFalse("should have fired", accumulator.batch.isEmpty());
+ assertEquals("incorrect batch", "abcdefg", accumulator.batch);
+ }
+
+ @Ignore("FIXME: timing sensitive test failing randomly.")
+ @Test
+ public void stormTest() {
+ TestAccumulator accumulator = new TestAccumulator();
+ IntStream.range(0, 1000).forEach(i -> accumulator.add(new TestItem("#" + i)));
+ assertAfter(100, () -> assertEquals("wrong item count", 1000, accumulator.itemCount));
+ assertEquals("wrong batch count", 200, accumulator.batchCount);
+ }
+
+ private class TestItem {
+ private final String s;
+
+ public TestItem(String s) {
+ this.s = s;
+ }
+ }
+
+ private class TestAccumulator extends AbstractAccumulator<TestItem> {
+
+ String batch = "";
+ boolean ready = true;
+ int batchCount = 0;
+ int itemCount = 0;
+
+ protected TestAccumulator() {
+ super(timer, 5, 100, 70);
+ }
+
+ @Override
+ public void processItems(List<TestItem> items) {
+ batchCount++;
+ itemCount += items.size();
+ for (TestItem item : items) {
+ batch += item.s;
+ }
+ }
+
+ @Override
+ public boolean isReady() {
+ return ready;
+ }
+ }
+
+}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BandwidthTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BandwidthTest.java
new file mode 100644
index 00000000..a3baf06c
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BandwidthTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2015 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.onlab.util;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.lessThan;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for Bandwidth.
+ */
+public class BandwidthTest {
+
+ private final Bandwidth small = Bandwidth.kbps(100.0);
+ private final Bandwidth large = Bandwidth.mbps(1.0);
+
+ /**
+ * Tests equality of Bandwidth instances.
+ */
+ @Test
+ public void testEquality() {
+ new EqualsTester()
+ .addEqualityGroup(Bandwidth.kbps(1000.0), Bandwidth.kbps(1000.0), Bandwidth.mbps(1.0))
+ .addEqualityGroup(Bandwidth.gbps(1.0))
+ .testEquals();
+ }
+
+ /**
+ * Tests add operation of two Bandwidths.
+ */
+ @Test
+ public void testAdd() {
+ Bandwidth expected = Bandwidth.kbps(1100.0);
+
+ assertThat(small.add(large), is(expected));
+ }
+
+ /**
+ * Tests subtract operation of two Bandwidths.
+ */
+ @Test
+ public void testSubtract() {
+ Bandwidth expected = Bandwidth.kbps(900.0);
+
+ assertThat(large.subtract(small), is(expected));
+ }
+
+ /**
+ * Tests if the first object is less than the second object.
+ */
+ @Test
+ public void testLessThan() {
+ assertThat(small, is(lessThan(large)));
+ assertThat(small.isLessThan(large), is(true));
+ }
+
+ /**
+ * Tests if the first object is greater than the second object.
+ */
+ @Test
+ public void testGreaterThan() {
+ assertThat(large, is(greaterThan(small)));
+ assertThat(large.isGreaterThan(small), is(true));
+ }
+}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BlockingBooleanTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BlockingBooleanTest.java
new file mode 100644
index 00000000..2d8b688e
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BlockingBooleanTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2015 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.onlab.util;
+
+import org.apache.commons.lang.mutable.MutableBoolean;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests of the BlockingBoolean utility.
+ */
+public class BlockingBooleanTest {
+
+ private static final int TIMEOUT = 100; //ms
+
+ @Test
+ public void basics() {
+ BlockingBoolean b = new BlockingBoolean(false);
+ assertEquals(false, b.get());
+ b.set(true);
+ assertEquals(true, b.get());
+ b.set(true);
+ assertEquals(true, b.get());
+ b.set(false);
+ assertEquals(false, b.get());
+ }
+
+ private void waitChange(boolean value, int numThreads) {
+ BlockingBoolean b = new BlockingBoolean(!value);
+
+ CountDownLatch latch = new CountDownLatch(numThreads);
+ ExecutorService exec = Executors.newFixedThreadPool(numThreads);
+ for (int i = 0; i < numThreads; i++) {
+ exec.submit(() -> {
+ try {
+ b.await(value);
+ latch.countDown();
+ } catch (InterruptedException e) {
+ fail();
+ }
+ });
+ }
+ b.set(value);
+ try {
+ assertTrue(latch.await(TIMEOUT, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail();
+ }
+ exec.shutdown();
+ }
+
+ @Test
+ public void waitTrueChange() {
+ waitChange(true, 4);
+ }
+
+ @Test
+ public void waitFalseChange() {
+ waitChange(false, 4);
+ }
+
+ @Test
+ public void waitSame() {
+ BlockingBoolean b = new BlockingBoolean(true);
+
+ CountDownLatch latch = new CountDownLatch(1);
+ ExecutorService exec = Executors.newSingleThreadExecutor();
+ exec.submit(() -> {
+ try {
+ b.await(true);
+ latch.countDown();
+ } catch (InterruptedException e) {
+ fail();
+ }
+ });
+ try {
+ assertTrue(latch.await(TIMEOUT, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail();
+ }
+ exec.shutdown();
+ }
+
+ @Test
+ public void someWait() {
+ BlockingBoolean b = new BlockingBoolean(false);
+
+ int numThreads = 4;
+ CountDownLatch sameLatch = new CountDownLatch(numThreads / 2);
+ CountDownLatch waitLatch = new CountDownLatch(numThreads / 2);
+
+ ExecutorService exec = Executors.newFixedThreadPool(numThreads);
+ for (int i = 0; i < numThreads; i++) {
+ final boolean value = (i % 2 == 1);
+ exec.submit(() -> {
+ try {
+ b.await(value);
+ if (value) {
+ waitLatch.countDown();
+ } else {
+ sameLatch.countDown();
+ }
+ } catch (InterruptedException e) {
+ fail();
+ }
+ });
+ }
+ try {
+ assertTrue(sameLatch.await(TIMEOUT, TimeUnit.MILLISECONDS));
+ assertEquals(waitLatch.getCount(), numThreads / 2);
+ } catch (InterruptedException e) {
+ fail();
+ }
+ b.set(true);
+ try {
+ assertTrue(waitLatch.await(TIMEOUT, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail();
+ }
+ exec.shutdown();
+ }
+
+ @Test
+ public void waitTimeout() {
+ BlockingBoolean b = new BlockingBoolean(true);
+
+ CountDownLatch latch = new CountDownLatch(1);
+ ExecutorService exec = Executors.newSingleThreadExecutor();
+ exec.submit(() -> {
+ try {
+ if (!b.await(false, 1, TimeUnit.NANOSECONDS)) {
+ latch.countDown();
+ } else {
+ fail();
+ }
+ } catch (InterruptedException e) {
+ fail();
+ }
+ });
+ try {
+ assertTrue(latch.await(TIMEOUT, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail();
+ }
+ exec.shutdown();
+
+ }
+
+ @Test
+ @Ignore
+ public void samePerf() {
+ int iters = 10_000;
+
+ BlockingBoolean b1 = new BlockingBoolean(false);
+ long t1 = System.nanoTime();
+ for (int i = 0; i < iters; i++) {
+ b1.set(false);
+ }
+ long t2 = System.nanoTime();
+ MutableBoolean b2 = new MutableBoolean(false);
+ for (int i = 0; i < iters; i++) {
+ b2.setValue(false);
+ }
+ long t3 = System.nanoTime();
+ System.out.println((t2 - t1) + " " + (t3 - t2) + " " + ((t2 - t1) <= (t3 - t2)));
+ }
+
+ @Test
+ @Ignore
+ public void changePerf() {
+ int iters = 10_000;
+
+ BlockingBoolean b1 = new BlockingBoolean(false);
+ boolean v = true;
+ long t1 = System.nanoTime();
+ for (int i = 0; i < iters; i++) {
+ b1.set(v);
+ v = !v;
+ }
+ long t2 = System.nanoTime();
+ MutableBoolean b2 = new MutableBoolean(false);
+ for (int i = 0; i < iters; i++) {
+ b2.setValue(v);
+ v = !v;
+ }
+ long t3 = System.nanoTime();
+ System.out.println((t2 - t1) + " " + (t3 - t2) + " " + ((t2 - t1) <= (t3 - t2)));
+ }
+
+}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BoundedThreadPoolTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BoundedThreadPoolTest.java
new file mode 100644
index 00000000..c6132de1
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BoundedThreadPoolTest.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2015 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.onlab.util;
+
+import com.google.common.collect.Lists;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.junit.Assert.*;
+import static org.onlab.util.BoundedThreadPool.*;
+import static org.onlab.util.Tools.namedThreads;
+
+/**
+ * Test of BoundedThreadPool.
+ */
+public final class BoundedThreadPoolTest {
+
+ @Test
+ public void simpleJob() {
+ final Thread myThread = Thread.currentThread();
+ final AtomicBoolean sameThread = new AtomicBoolean(true);
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ BoundedThreadPool exec = newSingleThreadExecutor(namedThreads("test"));
+ exec.submit(() -> {
+ sameThread.set(myThread.equals(Thread.currentThread()));
+ latch.countDown();
+ });
+
+ try {
+ assertTrue("Job not run", latch.await(100, TimeUnit.MILLISECONDS));
+ assertFalse("Runnable used caller thread", sameThread.get());
+ } catch (InterruptedException e) {
+ fail();
+ } finally {
+ exec.shutdown();
+ }
+
+ // TODO perhaps move to tearDown
+ try {
+ assertTrue(exec.awaitTermination(1, TimeUnit.SECONDS));
+ } catch (InterruptedException e) {
+ fail();
+ }
+ }
+
+ private List<CountDownLatch> fillExecutor(BoundedThreadPool exec) {
+ int numThreads = exec.getMaximumPoolSize();
+ List<CountDownLatch> latches = Lists.newArrayList();
+ final CountDownLatch started = new CountDownLatch(numThreads);
+ List<CountDownLatch> finished = Lists.newArrayList();
+
+ // seed the executor's threads
+ for (int i = 0; i < numThreads; i++) {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final CountDownLatch fin = new CountDownLatch(1);
+ latches.add(latch);
+ finished.add(fin);
+ exec.submit(() -> {
+ try {
+ started.countDown();
+ latch.await();
+ fin.countDown();
+ } catch (InterruptedException e) {
+ fail();
+ }
+ });
+ }
+ try {
+ assertTrue(started.await(100, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail();
+ }
+ // fill the queue
+ CountDownLatch startedBlocked = new CountDownLatch(1);
+ while (exec.getQueue().remainingCapacity() > 0) {
+ final CountDownLatch latch = new CountDownLatch(1);
+ latches.add(latch);
+ exec.submit(() -> {
+ try {
+ startedBlocked.countDown();
+ latch.await();
+ } catch (InterruptedException e) {
+ fail();
+ }
+ });
+ }
+
+ latches.remove(0).countDown(); // release one of the executors
+ // ... we need to do this because load is recomputed when jobs are taken
+ // Note: For this to work, 1 / numThreads must be less than the load threshold (0.2)
+
+ // verify that the old job has terminated
+ try {
+ assertTrue("Job didn't finish",
+ finished.remove(0).await(100, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail();
+ }
+
+ // verify that a previously blocked thread has started
+ try {
+ assertTrue(startedBlocked.await(10, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail();
+ }
+
+
+ // add another job to fill the queue
+ final CountDownLatch latch = new CountDownLatch(1);
+ latches.add(latch);
+ exec.submit(() -> {
+ try {
+ latch.await();
+ } catch (InterruptedException e) {
+ fail();
+ }
+ });
+ assertEquals(exec.getQueue().size(), maxQueueSize);
+
+ return latches;
+ }
+
+ @Test
+ public void releaseOneThread() {
+ maxQueueSize = 10;
+ BoundedThreadPool exec = newFixedThreadPool(4, namedThreads("test"));
+ List<CountDownLatch> latches = fillExecutor(exec);
+
+ CountDownLatch myLatch = new CountDownLatch(1);
+ ExecutorService myExec = Executors.newSingleThreadExecutor();
+ Future<Thread> expected = myExec.submit(Thread::currentThread);
+
+ assertEquals(exec.getQueue().size(), maxQueueSize);
+ long start = System.nanoTime();
+ Future<Thread> actual = myExec.submit(() -> {
+ return exec.submit(() -> {
+ myLatch.countDown();
+ return Thread.currentThread();
+ }).get();
+ });
+
+ try {
+ assertFalse("Thread should still be blocked",
+ myLatch.await(10, TimeUnit.MILLISECONDS));
+
+ latches.remove(0).countDown(); // release the first thread
+ assertFalse("Thread should still be blocked",
+ myLatch.await(10, TimeUnit.MILLISECONDS));
+ latches.remove(0).countDown(); // release the second thread
+
+ assertTrue("Thread should be unblocked",
+ myLatch.await(10, TimeUnit.MILLISECONDS));
+ long delta = System.nanoTime() - start;
+ double load = exec.getQueue().size() / (double) maxQueueSize;
+ assertTrue("Load is greater than threshold", load <= 0.8);
+ assertTrue("Load is less than threshold", load >= 0.6);
+ assertEquals("Work done on wrong thread", expected.get(), actual.get());
+ assertTrue("Took more than one second", delta < Math.pow(10, 9));
+ } catch (InterruptedException | ExecutionException e) {
+ fail();
+ } finally {
+ latches.forEach(CountDownLatch::countDown);
+ exec.shutdown();
+ }
+
+ // TODO perhaps move to tearDown
+ try {
+ assertTrue(exec.awaitTermination(1, TimeUnit.SECONDS));
+ } catch (InterruptedException e) {
+ fail();
+ }
+
+ }
+
+ @Test
+ public void highLoadTimeout() {
+ maxQueueSize = 10;
+ BoundedThreadPool exec = newFixedThreadPool(2, namedThreads("test"));
+ List<CountDownLatch> latches = fillExecutor(exec);
+
+ // true if the job is executed and it is done on the test thread
+ final AtomicBoolean sameThread = new AtomicBoolean(false);
+ final Thread myThread = Thread.currentThread();
+ long start = System.nanoTime();
+ exec.submit(() -> {
+ sameThread.set(myThread.equals(Thread.currentThread()));
+ });
+
+ long delta = System.nanoTime() - start;
+ assertEquals(maxQueueSize, exec.getQueue().size());
+ assertTrue("Work done on wrong thread (or didn't happen)", sameThread.get());
+ assertTrue("Took less than one second. Actual: " + delta / 1_000_000.0 + "ms",
+ delta > Math.pow(10, 9));
+ assertTrue("Took more than two seconds", delta < 2 * Math.pow(10, 9));
+ latches.forEach(CountDownLatch::countDown);
+ exec.shutdown();
+
+ // TODO perhaps move to tearDown
+ try {
+ assertTrue(exec.awaitTermination(1, TimeUnit.SECONDS));
+ } catch (InterruptedException e) {
+ fail();
+ }
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ByteArraySizeHashPrinterTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ByteArraySizeHashPrinterTest.java
new file mode 100644
index 00000000..e3a5e945
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ByteArraySizeHashPrinterTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2014 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.onlab.util;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+/**
+ * Test cases for byte[] pretty printer.
+ */
+public class ByteArraySizeHashPrinterTest {
+
+ /**
+ * Test method for {@link org.onlab.util.ByteArraySizeHashPrinter#toString()}.
+ */
+ @Test
+ public void testToStringNull() {
+ final byte[] none = null;
+
+ assertEquals("byte[]{null}", String.valueOf(ByteArraySizeHashPrinter.of(none)));
+ assertNull(ByteArraySizeHashPrinter.orNull(none));
+ }
+
+ /**
+ * Test method for {@link org.onlab.util.ByteArraySizeHashPrinter#toString()}.
+ */
+ @Test
+ public void testToString() {
+ final byte[] some = new byte[] {2, 5, 0, 1 };
+ final String expected = "byte[]{length=" + some.length + ", hash=" + Arrays.hashCode(some) + "}";
+
+ assertEquals(expected, String.valueOf(ByteArraySizeHashPrinter.of(some)));
+ assertNotNull(ByteArraySizeHashPrinter.orNull(some));
+ }
+
+}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/CounterTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/CounterTest.java
new file mode 100644
index 00000000..d30e1b59
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/CounterTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2014 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.onlab.util;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.onlab.junit.TestTools.delay;
+
+/**
+ * Tests of the Counter utility.
+ */
+public class CounterTest {
+
+ @Test
+ public void basics() {
+ Counter tt = new Counter();
+ assertEquals("incorrect number of bytes", 0L, tt.total());
+ assertEquals("incorrect throughput", 0.0, tt.throughput(), 0.0001);
+ tt.add(1234567890L);
+ assertEquals("incorrect number of bytes", 1234567890L, tt.total());
+ assertTrue("incorrect throughput", 1234567890.0 < tt.throughput());
+ delay(1500);
+ tt.add(1L);
+ assertEquals("incorrect number of bytes", 1234567891L, tt.total());
+ assertTrue("incorrect throughput", 1234567891.0 > tt.throughput());
+ tt.reset();
+ assertEquals("incorrect number of bytes", 0L, tt.total());
+ assertEquals("incorrect throughput", 0.0, tt.throughput(), 0.0001);
+ }
+
+ @Test
+ public void freeze() {
+ Counter tt = new Counter();
+ tt.add(123L);
+ assertEquals("incorrect number of bytes", 123L, tt.total());
+ delay(1000);
+ tt.freeze();
+ tt.add(123L);
+ assertEquals("incorrect number of bytes", 123L, tt.total());
+
+ double d = tt.duration();
+ double t = tt.throughput();
+ assertEquals("incorrect duration", d, tt.duration(), 0.0001);
+ assertEquals("incorrect throughput", t, tt.throughput(), 0.0001);
+ assertEquals("incorrect number of bytes", 123L, tt.total());
+ }
+
+ @Test
+ public void reset() {
+ Counter tt = new Counter();
+ tt.add(123L);
+ assertEquals("incorrect number of bytes", 123L, tt.total());
+
+ double d = tt.duration();
+ double t = tt.throughput();
+ assertEquals("incorrect duration", d, tt.duration(), 0.0001);
+ assertEquals("incorrect throughput", t, tt.throughput(), 0.0001);
+ assertEquals("incorrect number of bytes", 123L, tt.total());
+
+ tt.reset();
+ assertEquals("incorrect throughput", 0.0, tt.throughput(), 0.0001);
+ assertEquals("incorrect number of bytes", 0, tt.total());
+ }
+
+ @Test
+ public void syntheticTracker() {
+ Counter tt = new Counter(5000, 1000, 6000);
+ assertEquals("incorrect duration", 1, tt.duration(), 0.1);
+ assertEquals("incorrect throughput", 1000, tt.throughput(), 1.0);
+ }
+}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/FrequencyTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/FrequencyTest.java
new file mode 100644
index 00000000..727c0f73
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/FrequencyTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2015 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.onlab.util;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onlab.junit.ImmutableClassChecker;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.lessThan;
+
+public class FrequencyTest {
+
+ private final Frequency frequency1 = Frequency.ofMHz(1000);
+ private final Frequency sameFrequency1 = Frequency.ofMHz(1000);
+ private final Frequency frequency2 = Frequency.ofGHz(1000);
+ private final Frequency sameFrequency2 = Frequency.ofGHz(1000);
+ private final Frequency moreSameFrequency2 = Frequency.ofTHz(1);
+ private final Frequency frequency3 = Frequency.ofTHz(193.1);
+ private final Frequency sameFrequency3 = Frequency.ofGHz(193100);
+
+ /**
+ * Tests immutability of Frequency.
+ */
+ @Test
+ public void testImmutability() {
+ ImmutableClassChecker.assertThatClassIsImmutable(Frequency.class);
+ }
+
+ /**
+ * Tests equality of Frequency instances.
+ */
+ @Test
+ public void testEquality() {
+ new EqualsTester()
+ .addEqualityGroup(frequency1, sameFrequency1)
+ .addEqualityGroup(frequency2, sameFrequency2, moreSameFrequency2)
+ .addEqualityGroup(frequency3, sameFrequency3)
+ .testEquals();
+ }
+
+ /**
+ * Tests the first object is less than the second object.
+ */
+ @Test
+ public void testLessThan() {
+ assertThat(frequency1, is(lessThan(frequency2)));
+ assertThat(frequency1.isLessThan(frequency2), is(true));
+ }
+
+ @Test
+ public void testGreaterThan() {
+ assertThat(frequency2, is(greaterThan(frequency1)));
+ assertThat(frequency2.isGreaterThan(frequency1), is(true));
+ }
+
+ /**
+ * Tests add operation of two Frequencies.
+ */
+ @Test
+ public void testAdd() {
+ Frequency low = Frequency.ofMHz(100);
+ Frequency high = Frequency.ofGHz(1);
+ Frequency expected = Frequency.ofMHz(1100);
+
+ assertThat(low.add(high), is(expected));
+ }
+
+ /**
+ * Tests subtract operation of two Frequencies.
+ */
+ @Test
+ public void testSubtract() {
+ Frequency high = Frequency.ofGHz(1);
+ Frequency low = Frequency.ofMHz(100);
+ Frequency expected = Frequency.ofMHz(900);
+
+ assertThat(high.subtract(low), is(expected));
+ }
+
+ /**
+ * Tests multiply operation of Frequency.
+ */
+ @Test
+ public void testMultiply() {
+ Frequency frequency = Frequency.ofMHz(1000);
+ long factor = 5;
+ Frequency expected = Frequency.ofGHz(5);
+
+ assertThat(frequency.multiply(5), is(expected));
+ }
+}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/GroupedThreadFactoryTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/GroupedThreadFactoryTest.java
new file mode 100644
index 00000000..5be1cda4
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/GroupedThreadFactoryTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 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.onlab.util;
+
+import org.junit.Test;
+import org.onlab.junit.TestTools;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests of the group thread factory.
+ */
+public class GroupedThreadFactoryTest {
+
+ @Test
+ public void basics() {
+ GroupedThreadFactory a = GroupedThreadFactory.groupedThreadFactory("foo");
+ GroupedThreadFactory b = GroupedThreadFactory.groupedThreadFactory("foo");
+ assertSame("factories should be same", a, b);
+
+ assertTrue("wrong toString", a.toString().contains("foo"));
+ Thread t = a.newThread(() -> TestTools.print("yo"));
+ assertSame("wrong group", a.threadGroup(), t.getThreadGroup());
+ }
+
+ @Test
+ public void hierarchical() {
+ GroupedThreadFactory a = GroupedThreadFactory.groupedThreadFactory("foo/bar");
+ GroupedThreadFactory b = GroupedThreadFactory.groupedThreadFactory("foo/goo");
+ GroupedThreadFactory p = GroupedThreadFactory.groupedThreadFactory("foo");
+
+ assertSame("groups should be same", p.threadGroup(), a.threadGroup().getParent());
+ assertSame("groups should be same", p.threadGroup(), b.threadGroup().getParent());
+
+ assertEquals("wrong name", "foo/bar", a.threadGroup().getName());
+ assertEquals("wrong name", "foo/goo", b.threadGroup().getName());
+ assertEquals("wrong name", "foo", p.threadGroup().getName());
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java
new file mode 100644
index 00000000..27652123
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2014 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.onlab.util;
+
+import org.junit.Test;
+
+import com.esotericsoftware.minlog.Log;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the Hexstring.
+ *
+ */
+
+public class HexStringTest extends TestCase {
+
+ @Test
+ public void testMarshalling() throws Exception {
+ String dpidStr = "00:00:00:23:20:2d:16:71";
+ long dpid = HexString.toLong(dpidStr);
+ String testStr = HexString.toHexString(dpid);
+ TestCase.assertEquals(dpidStr, testStr);
+ }
+
+ @Test
+ public void testToLong() {
+ String dpidStr = "3e:1f:01:fc:72:8c:63:31";
+ long valid = 0x3e1f01fc728c6331L;
+ long testLong = HexString.toLong(dpidStr);
+ TestCase.assertEquals(valid, testLong);
+ }
+
+ @Test
+ public void testToLongMSB() {
+ String dpidStr = "ca:7c:5e:d1:64:7a:95:9b";
+ long valid = -3856102927509056101L;
+ long testLong = HexString.toLong(dpidStr);
+ TestCase.assertEquals(valid, testLong);
+ }
+
+ @Test
+ public void testToLongError() {
+ String dpidStr = "09:08:07:06:05:04:03:02:01";
+ try {
+ HexString.toLong(dpidStr);
+ fail("HexString.toLong() should have thrown a NumberFormatException");
+ } catch (NumberFormatException expected) {
+ Log.info("HexString.toLong() have thrown a NumberFormatException");
+ }
+ }
+
+ @Test
+ public void testToStringBytes() {
+ byte[] dpid = {0, 0, 0, 0, 0, 0, 0, -1 };
+ String valid = "00:00:00:00:00:00:00:ff";
+ String testString = HexString.toHexString(dpid);
+ TestCase.assertEquals(valid, testString);
+ }
+
+ @Test
+ public void testFromHexStringError() {
+ String invalidStr = "00:00:00:00:00:00:ffff";
+ try {
+ HexString.fromHexString(invalidStr);
+ fail("HexString.fromHexString() should have thrown a NumberFormatException");
+ } catch (NumberFormatException expected) {
+ Log.info("HexString.toLong() have thrown a NumberFormatException");
+ }
+ }
+}
+
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/PositionalParameterStringFormatterTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/PositionalParameterStringFormatterTest.java
new file mode 100644
index 00000000..9758511f
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/PositionalParameterStringFormatterTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015 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.onlab.util;
+
+import static org.junit.Assert.*;
+import static org.onlab.util.PositionalParameterStringFormatter.format;
+
+import org.junit.Test;
+
+public class PositionalParameterStringFormatterTest {
+
+ @Test
+ public void testFormat0() {
+ String fmt = "Some string 1 2 3";
+ assertEquals("Some string 1 2 3", format(fmt));
+ }
+
+ @Test
+ public void testFormat1() {
+ String fmt = "Some string {} 2 3";
+ assertEquals("Some string 1 2 3", format(fmt, 1));
+ }
+
+ @Test
+ public void testFormat2() {
+ String fmt = "Some string {} 2 {}";
+ assertEquals("Some string 1 2 3", format(fmt, 1, "3"));
+ }
+
+ @Test
+ public void testFormatNull() {
+ String fmt = "Some string {} 2 {}";
+ assertEquals("Some string 1 2 null", format(fmt, 1, null));
+ }
+
+ @Test
+ public void testFormatExtraBracket() {
+ String fmt = "Some string {} 2 {}";
+ assertEquals("Some string 1 2 {}", format(fmt, 1));
+ }
+
+ @Test
+ public void testFormatMissingBracket() {
+ String fmt = "Some string 1 2 3";
+ assertEquals("Some string 1 2 3", format(fmt, 7));
+ }
+}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/RetryingFunctionTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/RetryingFunctionTest.java
new file mode 100644
index 00000000..4b08d2fc
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/RetryingFunctionTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2015 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.onlab.util;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for RetryingFunction.
+ *
+ */
+public class RetryingFunctionTest {
+
+ private int round;
+
+ @Before
+ public void setUp() {
+ round = 1;
+ }
+
+ @After
+ public void tearDown() {
+ round = 0;
+ }
+
+ @Test(expected = RetryableException.class)
+ public void testNoRetries() {
+ new RetryingFunction<>(this::succeedAfterOneFailure, RetryableException.class, 0, 10).apply(null);
+ }
+
+ @Test
+ public void testSuccessAfterOneRetry() {
+ new RetryingFunction<>(this::succeedAfterOneFailure, RetryableException.class, 1, 10).apply(null);
+ }
+
+ @Test(expected = RetryableException.class)
+ public void testFailureAfterOneRetry() {
+ new RetryingFunction<>(this::succeedAfterTwoFailures, RetryableException.class, 1, 10).apply(null);
+ }
+
+ @Test
+ public void testFailureAfterTwoRetries() {
+ new RetryingFunction<>(this::succeedAfterTwoFailures, RetryableException.class, 2, 10).apply(null);
+ }
+
+ @Test(expected = NonRetryableException.class)
+ public void testFailureWithNonRetryableFailure() {
+ new RetryingFunction<>(this::failCompletely, RetryableException.class, 2, 10).apply(null);
+ }
+
+ private String succeedAfterOneFailure(String input) {
+ if (round++ <= 1) {
+ throw new RetryableException();
+ } else {
+ return "pass";
+ }
+ }
+
+ private String succeedAfterTwoFailures(String input) {
+ if (round++ <= 2) {
+ throw new RetryableException();
+ } else {
+ return "pass";
+ }
+ }
+
+ private String failCompletely(String input) {
+ if (round++ <= 1) {
+ throw new NonRetryableException();
+ } else {
+ return "pass";
+ }
+ }
+
+ private class RetryableException extends RuntimeException {
+ }
+
+ private class NonRetryableException extends RuntimeException {
+ }
+}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SharedExecutorsTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SharedExecutorsTest.java
new file mode 100644
index 00000000..1730ca1f
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SharedExecutorsTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2015 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.onlab.util;
+
+import org.junit.Test;
+
+import java.util.concurrent.ExecutorService;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests of the SharedExecutors Test.
+ */
+public class SharedExecutorsTest {
+
+ @Test
+ public void singleThread() {
+ ExecutorService a = SharedExecutors.getSingleThreadExecutor();
+ assertNotNull("ExecutorService must not be null", a);
+ ExecutorService b = SharedExecutors.getSingleThreadExecutor();
+ assertSame("factories should be same", a, b);
+
+ }
+
+ @Test
+ public void poolThread() {
+ ExecutorService a = SharedExecutors.getPoolThreadExecutor();
+ assertNotNull("ExecutorService must not be null", a);
+ ExecutorService b = SharedExecutors.getPoolThreadExecutor();
+ assertSame("factories should be same", a, b);
+
+ }
+
+ @Test
+ public void timer() {
+ java.util.Timer a = SharedExecutors.getTimer();
+ assertNotNull("Timer must not be null", a);
+ java.util.Timer b = SharedExecutors.getTimer();
+ assertSame("factories should be same", a, b);
+ }
+}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java
new file mode 100644
index 00000000..c15cc8a6
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2015 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.onlab.util;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static junit.framework.TestCase.fail;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Unit tests for the sliding window counter.
+ */
+
+@Ignore("Disable these for now because of intermittent load related failures on Jenkins runs.")
+public class SlidingWindowCounterTest {
+
+ private SlidingWindowCounter counter;
+
+ @Before
+ public void setUp() {
+ counter = new SlidingWindowCounter(2);
+ }
+
+ @After
+ public void tearDown() {
+ counter.destroy();
+ }
+
+ @Test
+ public void testIncrementCount() {
+ assertEquals(0, counter.get(1));
+ assertEquals(0, counter.get(2));
+ counter.incrementCount();
+ assertEquals(1, counter.get(1));
+ assertEquals(1, counter.get(2));
+ counter.incrementCount(2);
+ assertEquals(3, counter.get(2));
+ }
+
+ @Test
+ public void testSlide() {
+ counter.incrementCount();
+ counter.advanceHead();
+ assertEquals(0, counter.get(1));
+ assertEquals(1, counter.get(2));
+ counter.incrementCount(2);
+ assertEquals(2, counter.get(1));
+ assertEquals(3, counter.get(2));
+ }
+
+ @Test
+ public void testWrap() {
+ counter.incrementCount();
+ counter.advanceHead();
+ counter.incrementCount(2);
+ counter.advanceHead();
+ assertEquals(0, counter.get(1));
+ assertEquals(2, counter.get(2));
+ counter.advanceHead();
+ assertEquals(0, counter.get(1));
+ assertEquals(0, counter.get(2));
+
+ }
+
+ @Test
+ public void testCornerCases() {
+ try {
+ counter.get(3);
+ fail("Exception should have been thrown");
+ } catch (IllegalArgumentException e) {
+ assertTrue(true);
+ }
+
+ try {
+ new SlidingWindowCounter(0);
+ fail("Exception should have been thrown");
+ } catch (IllegalArgumentException e) {
+ assertTrue(true);
+ }
+
+ try {
+ new SlidingWindowCounter(-1);
+ fail("Exception should have been thrown");
+ } catch (IllegalArgumentException e) {
+ assertTrue(true);
+ }
+ }
+}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ToolsTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ToolsTest.java
new file mode 100644
index 00000000..56f0f957
--- /dev/null
+++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ToolsTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2014-2015 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.onlab.util;
+
+import org.junit.Test;
+import org.onlab.junit.TestTools;
+
+import java.util.concurrent.ThreadFactory;
+
+import static org.junit.Assert.*;
+import static org.onlab.junit.TestTools.assertAfter;
+
+/**
+ * Test of the miscellaneous tools.
+ */
+public class ToolsTest {
+
+ @Test
+ public void fromHex() throws Exception {
+ assertEquals(15, Tools.fromHex("0f"));
+ assertEquals(16, Tools.fromHex("10"));
+ assertEquals(65535, Tools.fromHex("ffff"));
+ assertEquals(4096, Tools.fromHex("1000"));
+ assertEquals(0xffffffffffffffffL, Tools.fromHex("ffffffffffffffff"));
+ }
+
+ @Test
+ public void toHex() throws Exception {
+ assertEquals("0f", Tools.toHex(15, 2));
+ assertEquals("ffff", Tools.toHex(65535, 4));
+ assertEquals("1000", Tools.toHex(4096, 4));
+ assertEquals("000000000000000f", Tools.toHex(15));
+ assertEquals("ffffffffffffffff", Tools.toHex(0xffffffffffffffffL));
+
+ }
+
+ @Test
+ public void namedThreads() {
+ ThreadFactory f = Tools.namedThreads("foo-%d");
+ Thread t = f.newThread(() -> TestTools.print("yo"));
+ assertTrue("wrong pattern", t.getName().startsWith("foo-"));
+ }
+
+ @Test
+ public void groupedThreads() {
+ ThreadFactory f = Tools.groupedThreads("foo/bar-me", "foo-%d");
+ Thread t = f.newThread(() -> TestTools.print("yo"));
+ assertTrue("wrong pattern", t.getName().startsWith("foo-bar-me-foo-"));
+ assertTrue("wrong group", t.getThreadGroup().getName().equals("foo/bar-me"));
+ }
+
+ @Test
+ public void exceptionHandler() throws InterruptedException {
+ ThreadFactory f = Tools.namedThreads("foo");
+ Thread t = f.newThread(() -> {
+ throw new IllegalStateException("BOOM!");
+ });
+ assertNotNull("thread should have exception handler", t.getUncaughtExceptionHandler());
+ t.start();
+ assertAfter(100, () -> assertEquals("incorrect thread state", Thread.State.TERMINATED, t.getState()));
+ }
+
+}