Showing
9 changed files
with
254 additions
and
5 deletions
| ... | @@ -21,10 +21,6 @@ | ... | @@ -21,10 +21,6 @@ |
| 21 | <groupId>com.google.guava</groupId> | 21 | <groupId>com.google.guava</groupId> |
| 22 | <artifactId>guava-testlib</artifactId> | 22 | <artifactId>guava-testlib</artifactId> |
| 23 | </dependency> | 23 | </dependency> |
| 24 | - <dependency> | ||
| 25 | - <groupId>org.onlab.onos</groupId> | ||
| 26 | - <artifactId>onlab-misc</artifactId> | ||
| 27 | - </dependency> | ||
| 28 | </dependencies> | 24 | </dependencies> |
| 29 | 25 | ||
| 30 | </project> | 26 | </project> | ... | ... |
| 1 | +package org.onlab.onos.event; | ||
| 2 | + | ||
| 3 | +import org.junit.Test; | ||
| 4 | + | ||
| 5 | +import java.util.List; | ||
| 6 | +import java.util.Timer; | ||
| 7 | + | ||
| 8 | +import static org.junit.Assert.*; | ||
| 9 | +import static org.onlab.junit.TestTools.delay; | ||
| 10 | +import static org.onlab.onos.event.TestEvent.Type.FOO; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * Tests the operation of the accumulator. | ||
| 14 | + */ | ||
| 15 | +public class AbstractEventAccumulatorTest { | ||
| 16 | + | ||
| 17 | + private final Timer timer = new Timer(); | ||
| 18 | + | ||
| 19 | + @Test | ||
| 20 | + public void basics() throws Exception { | ||
| 21 | + TestAccumulator accumulator = new TestAccumulator(); | ||
| 22 | + assertEquals("incorrect timer", timer, accumulator.timer()); | ||
| 23 | + assertEquals("incorrect max events", 5, accumulator.maxEvents()); | ||
| 24 | + assertEquals("incorrect max ms", 100, accumulator.maxBatchMillis()); | ||
| 25 | + assertEquals("incorrect idle ms", 50, accumulator.maxIdleMillis()); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + @Test | ||
| 29 | + public void eventTrigger() { | ||
| 30 | + TestAccumulator accumulator = new TestAccumulator(); | ||
| 31 | + accumulator.add(new TestEvent(FOO, "a")); | ||
| 32 | + accumulator.add(new TestEvent(FOO, "b")); | ||
| 33 | + accumulator.add(new TestEvent(FOO, "c")); | ||
| 34 | + accumulator.add(new TestEvent(FOO, "d")); | ||
| 35 | + assertTrue("should not have fired yet", accumulator.batch.isEmpty()); | ||
| 36 | + accumulator.add(new TestEvent(FOO, "e")); | ||
| 37 | + delay(10); | ||
| 38 | + assertFalse("should have fired", accumulator.batch.isEmpty()); | ||
| 39 | + assertEquals("incorrect batch", "abcde", accumulator.batch); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + @Test | ||
| 43 | + public void timeTrigger() { | ||
| 44 | + TestAccumulator accumulator = new TestAccumulator(); | ||
| 45 | + accumulator.add(new TestEvent(FOO, "a")); | ||
| 46 | + delay(40); | ||
| 47 | + assertTrue("should not have fired yet", accumulator.batch.isEmpty()); | ||
| 48 | + accumulator.add(new TestEvent(FOO, "b")); | ||
| 49 | + delay(40); | ||
| 50 | + assertTrue("should not have fired yet", accumulator.batch.isEmpty()); | ||
| 51 | + accumulator.add(new TestEvent(FOO, "c")); | ||
| 52 | + delay(40); | ||
| 53 | + assertFalse("should have fired", accumulator.batch.isEmpty()); | ||
| 54 | + assertEquals("incorrect batch", "abc", accumulator.batch); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + @Test | ||
| 58 | + public void idleTrigger() { | ||
| 59 | + TestAccumulator accumulator = new TestAccumulator(); | ||
| 60 | + accumulator.add(new TestEvent(FOO, "a")); | ||
| 61 | + assertTrue("should not have fired yet", accumulator.batch.isEmpty()); | ||
| 62 | + accumulator.add(new TestEvent(FOO, "b")); | ||
| 63 | + delay(80); | ||
| 64 | + assertFalse("should have fired", accumulator.batch.isEmpty()); | ||
| 65 | + assertEquals("incorrect batch", "ab", accumulator.batch); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + private class TestAccumulator extends AbstractEventAccumulator { | ||
| 69 | + | ||
| 70 | + String batch = ""; | ||
| 71 | + | ||
| 72 | + protected TestAccumulator() { | ||
| 73 | + super(timer, 5, 100, 50); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + @Override | ||
| 77 | + public void processEvents(List<Event> events) { | ||
| 78 | + for (Event event : events) { | ||
| 79 | + batch += event.subject(); | ||
| 80 | + } | ||
| 81 | + } | ||
| 82 | + } | ||
| 83 | +} |
| ... | @@ -26,11 +26,14 @@ | ... | @@ -26,11 +26,14 @@ |
| 26 | <groupId>com.google.guava</groupId> | 26 | <groupId>com.google.guava</groupId> |
| 27 | <artifactId>guava</artifactId> | 27 | <artifactId>guava</artifactId> |
| 28 | </dependency> | 28 | </dependency> |
| 29 | - | ||
| 30 | <dependency> | 29 | <dependency> |
| 31 | <groupId>org.onlab.onos</groupId> | 30 | <groupId>org.onlab.onos</groupId> |
| 32 | <artifactId>onlab-misc</artifactId> | 31 | <artifactId>onlab-misc</artifactId> |
| 33 | </dependency> | 32 | </dependency> |
| 33 | + <dependency> | ||
| 34 | + <groupId>org.onlab.onos</groupId> | ||
| 35 | + <artifactId>onlab-junit</artifactId> | ||
| 36 | + </dependency> | ||
| 34 | </dependencies> | 37 | </dependencies> |
| 35 | 38 | ||
| 36 | <build> | 39 | <build> | ... | ... |
| ... | @@ -130,6 +130,12 @@ | ... | @@ -130,6 +130,12 @@ |
| 130 | <artifactId>onlab-misc</artifactId> | 130 | <artifactId>onlab-misc</artifactId> |
| 131 | <version>${project.version}</version> | 131 | <version>${project.version}</version> |
| 132 | </dependency> | 132 | </dependency> |
| 133 | + <dependency> | ||
| 134 | + <groupId>org.onlab.onos</groupId> | ||
| 135 | + <artifactId>onlab-junit</artifactId> | ||
| 136 | + <version>1.0.0-SNAPSHOT</version> | ||
| 137 | + <scope>test</scope> | ||
| 138 | + </dependency> | ||
| 133 | 139 | ||
| 134 | <dependency> | 140 | <dependency> |
| 135 | <groupId>org.onlab.onos</groupId> | 141 | <groupId>org.onlab.onos</groupId> | ... | ... |
utils/junit/pom.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
| 5 | + <modelVersion>4.0.0</modelVersion> | ||
| 6 | + | ||
| 7 | + <parent> | ||
| 8 | + <groupId>org.onlab.onos</groupId> | ||
| 9 | + <artifactId>onlab-utils</artifactId> | ||
| 10 | + <version>1.0.0-SNAPSHOT</version> | ||
| 11 | + <relativePath>../pom.xml</relativePath> | ||
| 12 | + </parent> | ||
| 13 | + | ||
| 14 | + <artifactId>onlab-junit</artifactId> | ||
| 15 | + <packaging>bundle</packaging> | ||
| 16 | + | ||
| 17 | + <description>ON.Lab JUnit test utilities</description> | ||
| 18 | + | ||
| 19 | + <dependencies> | ||
| 20 | + <dependency> | ||
| 21 | + <groupId>junit</groupId> | ||
| 22 | + <artifactId>junit</artifactId> | ||
| 23 | + <scope>compile</scope> | ||
| 24 | + </dependency> | ||
| 25 | + <dependency> | ||
| 26 | + <groupId>com.google.guava</groupId> | ||
| 27 | + <artifactId>guava-testlib</artifactId> | ||
| 28 | + <scope>compile</scope> | ||
| 29 | + </dependency> | ||
| 30 | + </dependencies> | ||
| 31 | + | ||
| 32 | +</project> |
| 1 | +package org.onlab.junit; | ||
| 2 | + | ||
| 3 | +import static com.google.common.base.Preconditions.checkArgument; | ||
| 4 | +import static org.junit.Assert.fail; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * Utilities to aid in producing JUnit tests. | ||
| 8 | + */ | ||
| 9 | +public final class TestTools { | ||
| 10 | + | ||
| 11 | + // Prohibit construction | ||
| 12 | + private TestTools() { | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * Suspends the current thread for a specified number of millis. | ||
| 17 | + * | ||
| 18 | + * @param ms number of millis | ||
| 19 | + */ | ||
| 20 | + public static void delay(int ms) { | ||
| 21 | + try { | ||
| 22 | + Thread.sleep(ms); | ||
| 23 | + } catch (InterruptedException e) { | ||
| 24 | + fail("test interrupted"); | ||
| 25 | + } | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * Returns the current time in millis since epoch. | ||
| 30 | + * | ||
| 31 | + * @return current time | ||
| 32 | + */ | ||
| 33 | + public static long now() { | ||
| 34 | + return System.currentTimeMillis(); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Runs the specified runnable until it completes successfully or until the | ||
| 39 | + * specified time expires. If the latter occurs, the first encountered | ||
| 40 | + * assertion on the last attempt will be re-thrown. Errors other than | ||
| 41 | + * assertion errors will be propagated immediately. | ||
| 42 | + * <p> | ||
| 43 | + * Assertions attempts will not be closer than 10 millis apart and no | ||
| 44 | + * further than 50 millis. | ||
| 45 | + * </p> | ||
| 46 | + * | ||
| 47 | + * @param delay number of millis to delay before the first attempt | ||
| 48 | + * @param duration number of milliseconds beyond the current time | ||
| 49 | + * @param assertions test assertions runnable | ||
| 50 | + */ | ||
| 51 | + public static void assertAfter(int delay, int duration, Runnable assertions) { | ||
| 52 | + checkArgument(delay < duration, "delay >= duration"); | ||
| 53 | + long start = now(); | ||
| 54 | + int step = Math.max(Math.min((duration - delay) / 100, 50), 10); | ||
| 55 | + | ||
| 56 | + // Is there an initial delay? | ||
| 57 | + if (delay > 0) { | ||
| 58 | + delay(delay); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + // Keep going until the assertions succeed or until time runs-out. | ||
| 62 | + while (true) { | ||
| 63 | + try { | ||
| 64 | + assertions.run(); | ||
| 65 | + break; | ||
| 66 | + } catch (AssertionError e) { | ||
| 67 | + // If there was an error and time ran out, re-throw it. | ||
| 68 | + if (now() - start > duration) { | ||
| 69 | + throw e; | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + delay(step); | ||
| 73 | + } | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + /** | ||
| 77 | + * Runs the specified runnable until it completes successfully or until the | ||
| 78 | + * specified time expires. If the latter occurs, the first encountered | ||
| 79 | + * assertion on the last attempt will be re-thrown. Errors other than | ||
| 80 | + * assertion errors will be propagated immediately. | ||
| 81 | + * <p> | ||
| 82 | + * Assertions attempts will not be closer than 10 millis apart and no | ||
| 83 | + * further than 50 millis. | ||
| 84 | + * </p> | ||
| 85 | + * | ||
| 86 | + * @param duration number of milliseconds beyond the current time | ||
| 87 | + * @param assertions test assertions runnable | ||
| 88 | + */ | ||
| 89 | + public static void assertAfter(int duration, Runnable assertions) { | ||
| 90 | + assertAfter(0, duration, assertions); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | +} |
| 1 | +package org.onlab.junit; | ||
| 2 | + | ||
| 3 | +import org.junit.Test; | ||
| 4 | + | ||
| 5 | +import static org.junit.Assert.*; | ||
| 6 | +import static org.onlab.junit.TestTools.assertAfter; | ||
| 7 | + | ||
| 8 | +public class TestToolsTest { | ||
| 9 | + | ||
| 10 | + @Test | ||
| 11 | + public void testSuccess() { | ||
| 12 | + assertAfter(10, 100, new Runnable() { | ||
| 13 | + int count = 0; | ||
| 14 | + @Override | ||
| 15 | + public void run() { | ||
| 16 | + if (count++ < 3) { | ||
| 17 | + assertTrue(false); | ||
| 18 | + } | ||
| 19 | + } | ||
| 20 | + }); | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + @Test(expected = AssertionError.class) | ||
| 24 | + public void testFailure() { | ||
| 25 | + assertAfter(100, new Runnable() { | ||
| 26 | + @Override | ||
| 27 | + public void run() { | ||
| 28 | + assertTrue(false); | ||
| 29 | + } | ||
| 30 | + }); | ||
| 31 | + } | ||
| 32 | +} |
| ... | @@ -17,6 +17,7 @@ | ... | @@ -17,6 +17,7 @@ |
| 17 | <description>Domain agnostic ON.Lab utilities</description> | 17 | <description>Domain agnostic ON.Lab utilities</description> |
| 18 | 18 | ||
| 19 | <modules> | 19 | <modules> |
| 20 | + <module>junit</module> | ||
| 20 | <module>misc</module> | 21 | <module>misc</module> |
| 21 | <module>osgi</module> | 22 | <module>osgi</module> |
| 22 | <module>rest</module> | 23 | <module>rest</module> | ... | ... |
-
Please register or login to post a comment