package net.floodlightcontroller.debugcounter;
import com.google.common.collect.Lists;
import net.floodlightcontroller.debugcounter.IDebugCounterService.MetaData;
import org.junit.Before;
import org.junit.Test;
import java.util.*;
import static org.junit.Assert.*;
public class DebugCounterServiceTest {
private DebugCounterServiceImpl counterService;
@Before
public void setUp() {
counterService = new DebugCounterServiceImpl();
}
private void
verifyCounters(List<CounterExpectation> expectedCounters,
List<DebugCounterResource> actualCounters) {
List<String> expectedNames = new ArrayList<>();
List<String> actualNames = new ArrayList<>();
for (CounterExpectation ce: expectedCounters) {
expectedNames.add(ce.getModuleName() + "/"
+ ce.getCounterHierarchy());
}
for (DebugCounterResource cr: actualCounters) {
actualNames.add(cr.getModuleName() + "/"
+ cr.getCounterHierarchy());
}
assertEquals(expectedNames, actualNames);
Iterator<CounterExpectation> expectedIter = expectedCounters.iterator();
Iterator<DebugCounterResource> actualIter = actualCounters.iterator();
while(expectedIter.hasNext()) {
// we already know that expected and actual have the same length
CounterExpectation ce = expectedIter.next();
DebugCounterResource cr = actualIter.next();
String curFullName = ce.getModuleName() + "/"
+ ce.getCounterHierarchy();
assertEquals(curFullName,
ce.getModuleName(), cr.getModuleName());
assertEquals(curFullName,
ce.getCounterHierarchy(), cr.getCounterHierarchy());
assertEquals(curFullName,
ce.getDescription(), cr.getCounterDesc());
assertEquals(curFullName,
ce.getValue(), cr.getCounterValue().longValue());
assertEquals(curFullName,
ce.getMetaData(), cr.getMetadata());
}
}
private void verifyCountersEmpty(Iterable<DebugCounterResource> actual) {
assertTrue(Lists.newArrayList(actual).isEmpty());
}
@Test
public void testExceptions() {
//
// Module registration
//
try {
counterService.registerModule(null);
fail("Expected Exception not thrown");
} catch (NullPointerException e) {
// expected
}
try {
counterService.registerModule("");
fail("Expected Exception not thrown");
} catch (IllegalArgumentException e) {
// expected
}
try {
counterService.registerModule("bar/baz");
fail("Expected Exception not thrown");
} catch (IllegalArgumentException e) {
// expected
}
//
// counter registration
//
try {
counterService.registerCounter(null, "bar", "Description");
fail("Expected Exception not thrown");
} catch (NullPointerException e) {
// expected
}
try {
counterService.registerCounter("", "bar", "Description");
fail("Expected Exception not thrown");
} catch (IllegalArgumentException e) {
// expected
}
try {
counterService.registerCounter("foo", "bar", "Description");
fail("Expected Exception not thrown");
} catch (IllegalArgumentException e) {
// expected
}
// Add the module to get past this exception
counterService.registerModule("foo");
try {
counterService.registerCounter("foo", null, "Description");
fail("Expected Exception not thrown");
} catch (NullPointerException e) {
// expected
}
try {
counterService.registerCounter("foo", "", "Description");
fail("Expected Exception not thrown");
} catch (IllegalArgumentException e) {
// expected
}
try {
counterService.registerCounter("foo", "bar/baz", "Description");
fail("Expected Exception not thrown");
} catch (IllegalArgumentException e) {
// expected
}
try {
// test with null array for varargs
counterService.registerCounter("foo", "bar", "Description",
(MetaData[])null);
fail("Expected Exception not thrown");
} catch (NullPointerException e) {
// expected
}
try {
// test with null element for varargs
counterService.registerCounter("foo", "bar", "Description",
(MetaData)null);
fail("Expected Exception not thrown");
} catch (NullPointerException e) {
// expected
}
List<DebugCounterResource> counters =
Lists.newArrayList(counterService.getAllCounterValues());
assertTrue(counters.isEmpty());
counterService.registerCounter("foo", "bar", "Desc");
try {
counterService.registerCounter("foo", "bar/bar/baz", "Desc");
fail("Expected Exception not thrown");
} catch (IllegalArgumentException e) {
// expected
}
}
private static class CounterExpectation {
private String moduleName;
private String counterHierarchy;
private String description;
private final Set<MetaData> metaData = EnumSet.noneOf(MetaData.class);
private long value;
static CounterExpectation create() {
return new CounterExpectation();
}
String getModuleName() {
return moduleName;
}
CounterExpectation moduleName(String moduleName) {
this.moduleName = moduleName;
return this;
}
String getCounterHierarchy() {
return counterHierarchy;
}
CounterExpectation counterHierarchy(String counterHierarchy) {
this.counterHierarchy = counterHierarchy;
return this;
}
String getDescription() {
return description;
}
CounterExpectation description(String description) {
this.description = description;
return this;
}
long getValue() {
return value;
}
CounterExpectation value(long value) {
this.value = value;
return this;
}
Set<MetaData> getMetaData() {
return metaData;
}
CounterExpectation addMetaData(MetaData m) {
this.metaData.add(m);
return this;
}
}
@Test
public void test() {
verifyCountersEmpty(counterService.getAllCounterValues());
List<CounterExpectation> expectedCounters;
assertTrue(counterService.registerModule("moduleB"));
assertFalse(counterService.registerModule("moduleB"));
assertTrue(counterService.registerModule("moduleA"));
assertFalse(counterService.registerModule("moduleA"));
assertTrue(counterService.registerModule("moduleC"));
assertTrue(counterService.registerModule("moduleD"));
IDebugCounter cAaac =
counterService.registerCounter("moduleA", "aac",
"the aac counter",
MetaData.WARN);
CounterExpectation eAaac = CounterExpectation.create()
.moduleName("moduleA")
.counterHierarchy("aac")
.description("the aac counter")
.addMetaData(MetaData.WARN);
expectedCounters = Lists.newArrayList(eAaac);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cAaac.increment();
eAaac.value(1);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cAaac.increment();
eAaac.value(2);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
IDebugCounter cAaaa =
counterService.registerCounter("moduleA", "aaa",
"the aaa counter",
MetaData.ERROR,
MetaData.DROP);
CounterExpectation eAaaa = CounterExpectation.create()
.moduleName("moduleA")
.counterHierarchy("aaa")
.description("the aaa counter")
.addMetaData(MetaData.DROP)
.addMetaData(MetaData.ERROR);
expectedCounters = Lists.newArrayList(eAaaa, eAaac);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cAaaa.increment();
eAaaa.value(1);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
IDebugCounter cAaab =
counterService.registerCounter("moduleA", "aab",
"the aab counter");
CounterExpectation eAaab = CounterExpectation.create()
.moduleName("moduleA")
.counterHierarchy("aab")
.description("the aab counter");
expectedCounters = Lists.newArrayList(eAaaa, eAaab, eAaac);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cAaab.increment();
eAaab.value(1);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
IDebugCounter cAaaaFoo =
counterService.registerCounter("moduleA", "aaa/foo",
"the aaa/foo counter");
CounterExpectation eAaaaFoo = CounterExpectation.create()
.moduleName("moduleA")
.counterHierarchy("aaa/foo")
.description("the aaa/foo counter");
expectedCounters = Lists.newArrayList(eAaaa, eAaaaFoo, eAaab, eAaac);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cAaaaFoo.increment();
cAaaaFoo.increment();
eAaaaFoo.value(2);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
IDebugCounter cAaaaBar =
counterService.registerCounter("moduleA", "aaa/bar",
"the aaa/bar counter");
CounterExpectation eAaaaBar = CounterExpectation.create()
.moduleName("moduleA")
.counterHierarchy("aaa/bar")
.description("the aaa/bar counter");
expectedCounters = Lists.newArrayList(eAaaa, eAaaaBar, eAaaaFoo,
eAaab, eAaac);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cAaaaBar.add(42);
eAaaaBar.value(42);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
IDebugCounter cBfoo =
counterService.registerCounter("moduleB", "foo",
"the foo counter of B");
CounterExpectation eBfoo = CounterExpectation.create()
.moduleName("moduleB")
.counterHierarchy("foo")
.description("the foo counter of B");
expectedCounters = Lists.newArrayList(eAaaa, eAaaaBar, eAaaaFoo,
eAaab, eAaac, eBfoo);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cBfoo.increment();
cBfoo.increment();
cBfoo.increment();
eBfoo.value(3);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
IDebugCounter cCfoobar =
counterService.registerCounter("moduleC", "foobar",
"the foobar counter of C");
CounterExpectation eCfoobar = CounterExpectation.create()
.moduleName("moduleC")
.counterHierarchy("foobar")
.description("the foobar counter of C");
expectedCounters = Lists.newArrayList(eAaaa, eAaaaBar, eAaaaFoo,
eAaab, eAaac, eBfoo, eCfoobar);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cCfoobar.increment();
cCfoobar.increment();
cCfoobar.increment();
cCfoobar.increment();
eCfoobar.value(4);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
IDebugCounter cCfoobar2 =
counterService.registerCounter("moduleC", "foobar",
"the foobar counter of C");
assertSame(cCfoobar, cCfoobar2);
eCfoobar.value(0);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
IDebugCounter cBfooBar =
counterService.registerCounter("moduleB", "foo/bar",
"the foo/bar counter of B");
CounterExpectation eBfooBar = CounterExpectation.create()
.moduleName("moduleB")
.counterHierarchy("foo/bar")
.description("the foo/bar counter of B");
expectedCounters = Lists.newArrayList(eAaaa, eAaaaBar, eAaaaFoo,
eAaab, eAaac, eBfoo,
eBfooBar, eCfoobar);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cBfooBar.increment();
cBfooBar.increment();
cBfooBar.increment();
cBfooBar.increment();
cBfooBar.increment();
eBfooBar.value(5);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
IDebugCounter cAaaaFooBar =
counterService.registerCounter("moduleA", "aaa/foo/bar",
"the aaa/foo/bar counter");
CounterExpectation eAaaaFooBar = CounterExpectation.create()
.moduleName("moduleA")
.counterHierarchy("aaa/foo/bar")
.description("the aaa/foo/bar counter");
expectedCounters = Lists.newArrayList(eAaaa, eAaaaBar, eAaaaFoo,
eAaaaFooBar,
eAaab, eAaac, eBfoo,
eBfooBar, eCfoobar);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cAaaaFooBar.increment();
cAaaaFooBar.increment();
cAaaaFooBar.add(21);
eAaaaFooBar.value(23);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
IDebugCounter cAaaaFooBar2 =
counterService.registerCounter("moduleA", "aaa/foo/bar",
"the aaa/foo/bar counter");
assertSame(cAaaaFooBar, cAaaaFooBar2);
eAaaaFooBar.value(0);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cAaaaFooBar.add(21);
eAaaaFooBar.value(21);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
//
// Test methods that read the counter hierarchy
//
// eAaaa,
// eAaaaBar,
// eAaaaFoo,
// eAaaaFooBar,
// eAaab,
// eAaac,
// eBfoo,
// eBfooBar,
// eCfoobar
verifyCounters(Lists.newArrayList(eAaaa, eAaaaBar, eAaaaFoo,
eAaaaFooBar, eAaab, eAaac),
counterService.getModuleCounterValues("moduleA"));
verifyCounters(Lists.newArrayList(eBfoo, eBfooBar),
counterService.getModuleCounterValues("moduleB"));
verifyCounters(Lists.newArrayList(eCfoobar),
counterService.getModuleCounterValues("moduleC"));
verifyCountersEmpty(counterService.getModuleCounterValues("moduleD"));
verifyCountersEmpty(counterService.getModuleCounterValues("FOOBAR"));
verifyCounters(Lists.newArrayList(eAaaa, eAaaaBar, eAaaaFoo,
eAaaaFooBar),
counterService.getCounterHierarchy("moduleA", "aaa"));
verifyCounters(Lists.newArrayList(eAaaaBar),
counterService.getCounterHierarchy("moduleA", "aaa/bar"));
verifyCounters(Lists.newArrayList(eAaaaFoo, eAaaaFooBar),
counterService.getCounterHierarchy("moduleA", "aaa/foo"));
verifyCounters(Lists.newArrayList(eAaaaFooBar),
counterService.getCounterHierarchy("moduleA", "aaa/foo/bar"));
verifyCountersEmpty(
counterService.getCounterHierarchy("moduleA", "aaa/foo/bar/XXX"));
verifyCountersEmpty(
counterService.getCounterHierarchy("moduleA", "XXX"));
verifyCounters(Lists.newArrayList(eBfoo, eBfooBar),
counterService.getCounterHierarchy("moduleB", "foo"));
verifyCounters(Lists.newArrayList(eBfooBar),
counterService.getCounterHierarchy("moduleB", "foo/bar"));
verifyCountersEmpty(
counterService.getCounterHierarchy("moduleB", "foo/baz"));
//
// Test reset. We already tested that re-registering a single counter
// resets the counter.
//
// eAaaa,
// eAaaaBar,
// eAaaaFoo,
// eAaaaFooBar,
// eAaab,
// eAaac,
// eBfoo,
// eBfooBar,
// eCfoobar
IDebugCounter cAaaaFoo2 =
counterService.registerCounter("moduleA", "aaa/foo",
"the aaa/foo counter");
assertSame(cAaaaFoo, cAaaaFoo2);
eAaaaFoo.value(0);
eAaaaFooBar.value(0);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cAaaaFoo.add(100);
cAaaaFooBar.add(200);
eAaaaFoo.value(100);
eAaaaFooBar.value(200);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
counterService.resetCounterHierarchy("moduleA", "aaa/foo");
eAaaaFoo.value(0);
eAaaaFooBar.value(0);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
cAaaaFoo.add(100);
cAaaaFooBar.add(200);
eAaaaFoo.value(100);
eAaaaFooBar.value(200);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
counterService.resetCounterHierarchy("moduleA", "aaa");
eAaaa.value(0);
eAaaaBar.value(0);
eAaaaFoo.value(0);
eAaaaFooBar.value(0);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
eAaaa.value(10);
eAaaaBar.value(15);
eAaaaFoo.value(20);
eAaaaFooBar.value(30);
cAaaa.add(10);
cAaaaBar.add(15);
cAaaaFoo.add(20);
cAaaaFooBar.add(30);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
counterService.resetAllModuleCounters("moduleA");
eAaaa.value(0);
eAaaaBar.value(0);
eAaaaFoo.value(0);
eAaaaFooBar.value(0);
eAaab.value(0);
eAaac.value(0);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
eAaaa.value(10);
eAaaaBar.value(15);
eAaaaFoo.value(20);
eAaaaFooBar.value(30);
eAaab.value(40);
eAaac.value(50);
cAaaa.add(10);
cAaaaBar.add(15);
cAaaaFoo.add(20);
cAaaaFooBar.add(30);
cAaab.add(40);
cAaac.add(50);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
// re-check getters
verifyCounters(Lists.newArrayList(eAaaa, eAaaaBar, eAaaaFoo,
eAaaaFooBar),
counterService.getCounterHierarchy("moduleA", "aaa"));
verifyCounters(Lists.newArrayList(eAaaaBar),
counterService.getCounterHierarchy("moduleA", "aaa/bar"));
verifyCounters(Lists.newArrayList(eAaaaFoo, eAaaaFooBar),
counterService.getCounterHierarchy("moduleA", "aaa/foo"));
counterService.resetAllCounters();
eAaaa.value(0);
eAaaaBar.value(0);
eAaaaFoo.value(0);
eAaaaFooBar.value(0);
eAaab.value(0);
eAaac.value(0);
eBfoo.value(0);
eBfooBar.value(0);
eCfoobar.value(0);
verifyCounters(expectedCounters, counterService.getAllCounterValues());
}
}