package net.floodlightcontroller.debugcounter; import java.util.Arrays; import java.util.List; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.floodlightcontroller.debugcounter.DebugCounter.DebugCounterInfo; import net.floodlightcontroller.debugcounter.IDebugCounterService.CounterType; import net.floodlightcontroller.test.FloodlightTestCase; public class DebugCounterTest extends FloodlightTestCase { DebugCounter dc; protected static Logger log = LoggerFactory.getLogger(DebugCounterTest.class); IDebugCounter S1, S2, S1_pi, S1_pi_d, S1_pi_e, S1_po, L_t; List<DebugCounterInfo> dclist; @Override @Before public void setUp() throws Exception { dc = new DebugCounter(); S1 = dc.registerCounter("switch", "01", "switch01", CounterType.ALWAYS_COUNT); S2 = dc.registerCounter("switch", "02", "switch02", CounterType.ALWAYS_COUNT); S1_pi = dc.registerCounter("switch", "01/pktin", "switch01-pktin", CounterType.ALWAYS_COUNT); S1_pi_d = dc.registerCounter("switch", "01/pktin/drops", "switch01-pktin drops for all reasons", CounterType.ALWAYS_COUNT, "warn"); S1_pi_e = dc.registerCounter("switch", "01/pktin/err", "switch01-pktin errors", CounterType.ALWAYS_COUNT, "error", "snmp"); S1_po = dc.registerCounter("switch", "01/pktout", "switch01-pktout", CounterType.ALWAYS_COUNT); L_t = dc.registerCounter("linkd", "tunnel", "tunnel links", CounterType.ALWAYS_COUNT); } @Test public void testBasicCounterWorking() { dc.printAllCounterIds(); S1.updateCounterNoFlush(); assertEquals(S1.getCounterValue(), 0); S1.updateCounterWithFlush(); assertEquals(S1.getCounterValue(), 2); S1.updateCounterNoFlush(30); assertEquals(S1.getCounterValue(), 2); S1.updateCounterWithFlush(10); assertEquals(S1.getCounterValue(), 42); S1.updateCounterNoFlush(); assertEquals(S1.getCounterValue(), 42); dc.flushCounters(); assertEquals(S1.getCounterValue(), 43); } @Test public void testCounterHierarchy() { S1.updateCounterNoFlush(); S2.updateCounterNoFlush(2); L_t.updateCounterNoFlush(3); S1_pi.updateCounterNoFlush(10); S1_po.updateCounterNoFlush(20); S1_pi_d.updateCounterNoFlush(100); S1_pi_e.updateCounterNoFlush(105); dc.flushCounters(); checkCounters(1, 2, 3, 10, 20, 100, 105); } private void checkCounters(long S1_val, long S2_val, long L_t_val, // 1st level long S1_pi_val, long S1_po_val, // 2nd level long S1_pi_d_val, long S1_pi_e_val) { // 3rd level assertEquals(S1.getCounterValue(), S1_val); assertEquals(S2.getCounterValue(), S2_val); assertEquals(L_t.getCounterValue(), L_t_val); assertEquals(S1_pi.getCounterValue(), S1_pi_val); assertEquals(S1_po.getCounterValue(), S1_po_val); assertEquals(S1_pi_d.getCounterValue(), S1_pi_d_val); assertEquals(S1_pi_e.getCounterValue(), S1_pi_e_val); } @Test public void testBasicCounterReset() { testCounterHierarchy(); dc.resetCounterHierarchy("linkd", "tunnel"); checkCounters(1, 2, 0, 10, 20, 100, 105); // missing counter dc.resetCounterHierarchy("switch", "S2"); checkCounters(1, 2, 0, 10, 20, 100, 105); // missing module dc.resetCounterHierarchy("swicth", "02"); checkCounters(1, 2, 0, 10, 20, 100, 105); // the actual counter dc.resetCounterHierarchy("switch", "02"); checkCounters(1, 0, 0, 10, 20, 100, 105); // leafs dc.resetCounterHierarchy("switch", "01/pktin/err"); checkCounters(1, 0, 0, 10, 20, 100, 0); dc.resetCounterHierarchy("switch", "01/pktin/drops"); checkCounters(1, 0, 0, 10, 20, 0, 0); } @Test public void testHierarchicalCounterReset1() { testCounterHierarchy(); dc.resetCounterHierarchy("switch", "01/pktin"); checkCounters(1, 2, 3, 0, 20, 0, 0); } @Test public void testHierarchicalCounterReset2() { testCounterHierarchy(); dc.resetCounterHierarchy("switch", "01"); checkCounters(0, 2, 3, 0, 0, 0, 0); } @Test public void testHierarchicalCounterReset3() { testCounterHierarchy(); dc.resetAllModuleCounters("switch"); checkCounters(0, 0, 3, 0, 0, 0, 0); dc.resetAllModuleCounters("linkd"); checkCounters(0, 0, 0, 0, 0, 0, 0); testCounterHierarchy(); } @Test public void testHierarchicalCounterReset4() { testCounterHierarchy(); dc.resetAllCounters(); checkCounters(0, 0, 0, 0, 0, 0, 0); testCounterHierarchy(); } private void verifyCounters(List<DebugCounterInfo> dclist, Long...longs ) { List<Long> a = Arrays.asList(longs.clone()); for (DebugCounterInfo dci : dclist) { assertEquals(true, a.contains(dci.cvalue.get())); } assertEquals(dclist.size(), longs.length); } @Test public void testBasicCounterGet() { testCounterHierarchy(); dclist = dc.getCounterHierarchy("switch", "02"); verifyCounters(dclist, 2L); dclist = dc.getCounterHierarchy("linkd", "tunnel"); verifyCounters(dclist, 3L); dclist = dc.getCounterHierarchy("switch", "01/pktin/err"); verifyCounters(dclist, 105L); dclist = dc.getCounterHierarchy("switch", "01/pktin/drops"); verifyCounters(dclist, 100L); } @Test public void testHierarchicalCounterGet() { testCounterHierarchy(); dclist = dc.getCounterHierarchy("switch", "01/pktin"); verifyCounters(dclist, 10L, 100L, 105L); dclist = dc.getCounterHierarchy("switch", "01"); verifyCounters(dclist, 1L, 20L, 10L, 100L, 105L); dclist = dc.getModuleCounterValues("switch"); verifyCounters(dclist, 2L, 1L, 20L, 10L, 100L, 105L); dclist = dc.getModuleCounterValues("linkd"); verifyCounters(dclist, 3L); dclist = dc.getAllCounterValues(); verifyCounters(dclist, 3L, 2L, 1L, 20L, 10L, 100L, 105L); } @Test public void testEnableDisableCounter() throws Exception { testCounterHierarchy(); IDebugCounter S1_pi_u, S1_fm, S1_fm_d; S1_pi_u = dc.registerCounter("switch", "01/pktin/unknowns", "switch01-pktin unknowns", CounterType.COUNT_ON_DEMAND, "warn"); dclist = dc.getCounterHierarchy("switch", "01/pktin"); verifyCounters(dclist, 0L, 10L, 100L, 105L); S1_pi_u.updateCounterWithFlush(112); dclist = dc.getCounterHierarchy("switch", "01/pktin"); verifyCounters(dclist, 0L, 10L, 100L, 105L); dc.enableCtrOnDemand("switch", "01/pktin/unknowns"); dclist = dc.getCounterHierarchy("switch", "01/pktin"); verifyCounters(dclist, 0L, 10L, 100L, 105L); dc.flushCounters(); // required for sync of thread-local store to global store S1_pi_u.updateCounterWithFlush(112); assertEquals(112L, S1_pi_u.getCounterValue()); dclist = dc.getCounterHierarchy("switch", "01/pktin"); verifyCounters(dclist, 10L, 100L, 105L, 112L); S1_pi_u.updateCounterWithFlush(); dclist = dc.getCounterHierarchy("switch", "01/pktin"); verifyCounters(dclist, 10L, 100L, 105L, 113L); dc.disableCtrOnDemand("switch", "01/pktin/unknowns"); S1_pi_u.updateCounterWithFlush(); S1_pi_u.updateCounterWithFlush(); S1_pi_u.updateCounterWithFlush(); dclist = dc.getCounterHierarchy("switch", "01/pktin"); verifyCounters(dclist, 10L, 100L, 105L, 0L); //cannot disable ALWAYS_COUNT counter dc.disableCtrOnDemand("switch", "01/pktin/err"); S1_pi_e.updateCounterWithFlush(); dclist = dc.getCounterHierarchy("switch", "01/pktin"); verifyCounters(dclist, 10L, 100L, 106L, 0L); //enable/disable counter inside hierarchy S1_fm = dc.registerCounter("switch", "01/fm", "switch01-flow-mods", CounterType.COUNT_ON_DEMAND, "warn"); S1_fm_d = dc.registerCounter("switch", "01/fm/dup", "switch01- duplicate flow mods", CounterType.ALWAYS_COUNT, "warn"); S1_fm.updateCounterWithFlush(8000); S1_fm_d.updateCounterWithFlush(5000); dclist = dc.getCounterHierarchy("switch", "01/fm"); verifyCounters(dclist, 5000L, 0L); dc.enableCtrOnDemand("switch", "01/fm"); dc.flushCounters(); S1_fm.updateCounterWithFlush(8000); S1_fm_d.updateCounterWithFlush(5000); dclist = dc.getCounterHierarchy("switch", "01/fm"); verifyCounters(dclist, 10000L, 8000L); dc.disableCtrOnDemand("switch", "01/fm"); S1_fm.updateCounterWithFlush(8000); S1_fm_d.updateCounterWithFlush(5000); dclist = dc.getCounterHierarchy("switch", "01/fm"); verifyCounters(dclist, 15000L, 0L); } @Test public void testCounterReregistry() throws Exception { testCounterHierarchy(); checkCounters(1, 2, 3, 10, 20, 100, 105); S1 = dc.registerCounter("switch", "01", "switch01", CounterType.ALWAYS_COUNT); checkCounters(0, 2, 3, 0, 0, 0, 0); // switch 1 counter re-setted assertEquals(0, S1.getCounterValue()); } @Test public void testContains() { testCounterHierarchy(); assertTrue(dc.containsModuleName("switch")); assertTrue(dc.containsModuleName("linkd")); assertTrue(dc.containsModuleCounterHierarchy("switch", "01")); assertTrue(dc.containsModuleCounterHierarchy("switch", "02")); assertFalse(dc.containsModuleCounterHierarchy("switch", "03")); assertTrue(dc.containsModuleCounterHierarchy("switch", "01/pktin")); assertTrue(dc.containsModuleCounterHierarchy("switch", "01/pktout")); assertTrue(dc.containsModuleCounterHierarchy("switch", "01/pktin/err")); assertTrue(dc.containsModuleCounterHierarchy("switch", "01/pktin/drops")); assertFalse(dc.containsModuleCounterHierarchy("switch", "01/pktin/unknowns")); assertFalse(dc.containsModuleCounterHierarchy("switch", "01/pktin/errr")); } @Test public void testMetadata() { testCounterHierarchy(); dclist = dc.getCounterHierarchy("switch", "01/pktin/err"); for (DebugCounterInfo dc : dclist) { assertTrue(dc.cinfo.metaData[0].equals("error")); assertTrue(dc.cinfo.metaData[1].equals("snmp")); log.info("metadata: {}", Arrays.toString(dc.cinfo.getMetaData())); } verifyCounters(dclist, 105L); dclist = dc.getCounterHierarchy("switch", "02"); for (DebugCounterInfo dc : dclist) { assertTrue(dc.cinfo.getMetaData().length == 0); log.info("metadata: {}", Arrays.toString(dc.cinfo.getMetaData())); } } @Test public void testMissingHierarchy() { } }