Skip to content
Snippets Groups Projects
Commit 61dfccbb authored by Saurav Das's avatar Saurav Das
Browse files

Registering counters returns an IDebugCounter instead of a counterID.

Fixing the REST API to account for hierarchical counters
More unit tests.
parent 2bafce37
No related branches found
No related tags found
No related merge requests found
......@@ -54,32 +54,33 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
* protected class to store counter information
*/
public static class CounterInfo {
String moduleCounterName;
String moduleCounterHierarchy;
String counterDesc;
CounterType ctype;
String moduleName;
String counterName;
String counterHierarchy;
int counterId;
boolean enabled;
Object[] metaData;
public CounterInfo(int counterId, boolean enabled, Object[] metaData,
String moduleName, String counterName,
String desc, CounterType ctype) {
this.moduleCounterName = moduleName + "/" + counterName;
public CounterInfo(int counterId, boolean enabled,
String moduleName, String counterHierarchy,
String desc, CounterType ctype, Object... metaData) {
this.moduleCounterHierarchy = moduleName + "/" + counterHierarchy;
this.moduleName = moduleName;
this.counterName = counterName;
this.counterHierarchy = counterHierarchy;
this.counterDesc = desc;
this.ctype = ctype;
this.counterId = counterId;
this.enabled = enabled;
this.metaData = metaData;
}
public String getModuleCounterName() { return moduleCounterName; }
public String getModuleCounterHierarchy() { return moduleCounterHierarchy; }
public String getCounterDesc() { return counterDesc; }
public CounterType getCtype() { return ctype; }
public String getModuleName() { return moduleName; }
public String getCounterName() { return counterName; }
public String getCounterHierarchy() { return counterHierarchy; }
public int getCounterId() { return counterId; }
public boolean isEnabled() { return enabled; }
public Object[] getMetaData() { return metaData; }
......@@ -180,42 +181,93 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
}
};
//*******************************
// IDebugCounter
//*******************************
private class CounterImpl implements IDebugCounter {
private final int counterId;
public CounterImpl(int counterId) {
this.counterId = counterId;
}
@Override
public void updateCounterWithFlush() {
if (!validCounterId()) return;
updateCounter(counterId, 1, true);
}
@Override
public void updateCounterNoFlush() {
if (!validCounterId()) return;
updateCounter(counterId, 1, false);
}
@Override
public void updateCounterWithFlush(int incr) {
if (!validCounterId()) return;
updateCounter(counterId, incr, true);
}
@Override
public void updateCounterNoFlush(int incr) {
if (!validCounterId()) return;
updateCounter(counterId, incr, false);
}
@Override
public long getCounterValue() {
if (!validCounterId()) return -1;
return allCounters[counterId].cvalue.get();
}
private boolean validCounterId() {
if (counterId < 0 || counterId >= MAX_COUNTERS) {
log.error("Invalid counterId invoked");
return false;
}
return true;
}
}
//*******************************
// IDebugCounterService
//*******************************
@Override
public int registerCounter(String moduleName, String counterName,
String counterDescription, CounterType counterType,
Object[] metaData) throws MaxCountersRegistered{
public IDebugCounter registerCounter(String moduleName, String counterHierarchy,
String counterDescription, CounterType counterType,
Object... metaData) throws MaxCountersRegistered{
// check if counter already exists
if (!moduleCounters.containsKey(moduleName)) {
moduleCounters.putIfAbsent(moduleName,
new ConcurrentHashMap<String, CounterIndexStore>());
}
RetCtrInfo rci = getCounterId(moduleName, counterName);
RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
if (rci.allLevelsFound) {
// counter exists
log.info("Counter exists for {}/{} -- resetting counters", moduleName,
counterName);
resetCounterHierarchy(moduleName, counterName);
return rci.ctrIds[rci.foundUptoLevel-1];
counterHierarchy);
resetCounterHierarchy(moduleName, counterHierarchy);
return new CounterImpl(rci.ctrIds[rci.foundUptoLevel-1]);
}
// check for validity of counter
if (rci.levels.length > MAX_HIERARCHY) {
log.error("Registry of counterName {} exceeds max hierachy {}.. aborting",
counterName, MAX_HIERARCHY);
return -1;
log.error("Registry of counterHierarchy {} exceeds max hierachy {}.. aborting",
counterHierarchy, MAX_HIERARCHY);
return new CounterImpl(-1);
}
if (rci.foundUptoLevel < rci.levels.length-1) {
String needToRegister = "";
for (int i=0; i<=rci.foundUptoLevel; i++) {
needToRegister += rci.levels[i];
}
log.error("Attempting to register hierarchical counterName {}, "+
log.error("Attempting to register hierarchical counterHierarchy {}, "+
"but parts of hierarchy missing. Please register {} first ",
counterName, needToRegister);
return -1;
counterHierarchy, needToRegister);
return new CounterImpl(-1);
}
// get a new counter id
......@@ -225,8 +277,9 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
}
// create storage for counter
boolean enabled = (counterType == CounterType.ALWAYS_COUNT) ? true : false;
CounterInfo ci = new CounterInfo(counterId, enabled, metaData, moduleName,
counterName, counterDescription, counterType);
CounterInfo ci = new CounterInfo(counterId, enabled, moduleName,
counterHierarchy, counterDescription,
counterType, metaData);
allCounters[counterId] = new DebugCounterInfo(ci);
// account for the new counter in the module counter hierarchy
......@@ -236,17 +289,10 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
if (enabled) {
currentCounters.add(counterId);
}
return counterId;
return new CounterImpl(counterId);
}
@Override
public void updateCounter(int counterId, boolean flushNow) {
updateCounter(counterId, 1, flushNow);
}
@Override
public void updateCounter(int counterId, int incr, boolean flushNow) {
private void updateCounter(int counterId, int incr, boolean flushNow) {
if (counterId < 0 || counterId >= MAX_COUNTERS) return;
LocalCounterInfo[] thiscounters = this.threadlocalCounters.get();
......@@ -285,7 +331,6 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
}
}
}
}
@Override
......@@ -319,14 +364,16 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
// the global set.
Sets.SetView<Integer> sv = Sets.difference(currentCounters, thisset);
for (int counterId : sv) {
if (thiscounters[counterId] != null) thiscounters[counterId].enabled = true;
thisset.add(counterId);
if (thiscounters[counterId] != null) {
thiscounters[counterId].enabled = true;
thisset.add(counterId);
}
}
}
@Override
public void resetCounterHierarchy(String moduleName, String counterName) {
RetCtrInfo rci = getCounterId(moduleName, counterName);
public void resetCounterHierarchy(String moduleName, String counterHierarchy) {
RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
if (!rci.allLevelsFound) {
String missing = rci.levels[rci.foundUptoLevel];
log.error("Cannot reset counter hierarchy - missing counter {}", missing);
......@@ -371,8 +418,8 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
}
@Override
public void enableCtrOnDemand(String moduleName, String counterName) {
RetCtrInfo rci = getCounterId(moduleName, counterName);
public void enableCtrOnDemand(String moduleName, String counterHierarchy) {
RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
if (!rci.allLevelsFound) {
String missing = rci.levels[rci.foundUptoLevel];
log.error("Cannot enable counter - counter not found {}", missing);
......@@ -385,8 +432,8 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
}
@Override
public void disableCtrOnDemand(String moduleName, String counterName) {
RetCtrInfo rci = getCounterId(moduleName, counterName);
public void disableCtrOnDemand(String moduleName, String counterHierarchy) {
RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
if (!rci.allLevelsFound) {
String missing = rci.levels[rci.foundUptoLevel];
log.error("Cannot disable counter - counter not found {}", missing);
......@@ -403,8 +450,8 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
@Override
public List<DebugCounterInfo> getCounterHierarchy(String moduleName,
String counterName) {
RetCtrInfo rci = getCounterId(moduleName, counterName);
String counterHierarchy) {
RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
if (!rci.allLevelsFound) {
String missing = rci.levels[rci.foundUptoLevel];
log.error("Cannot fetch counter - counter not found {}", missing);
......@@ -452,9 +499,10 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
}
@Override
public boolean containsModuleCounterName(String moduleName, String counterName) {
public boolean containsModuleCounterHierarchy(String moduleName,
String counterHierarchy) {
if (!moduleCounters.containsKey(moduleName)) return false;
RetCtrInfo rci = getCounterId(moduleName, counterName);
RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
return rci.allLevelsFound;
}
......@@ -469,7 +517,7 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
protected class RetCtrInfo {
boolean allLevelsFound; // counter indices found all the way down the hierarchy
boolean hierarchical; // true if counterName is hierarchical
boolean hierarchical; // true if counterHierarchy is hierarchical
int foundUptoLevel;
int[] ctrIds;
String[] levels;
......@@ -495,12 +543,15 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
}
protected RetCtrInfo getCounterId(String moduleName, String counterName) {
protected RetCtrInfo getCounterId(String moduleName, String counterHierarchy) {
RetCtrInfo rci = new RetCtrInfo();
Map<String, CounterIndexStore> templevel = moduleCounters.get(moduleName);
rci.levels = counterName.split("/");
rci.levels = counterHierarchy.split("/");
if (rci.levels.length > 1) rci.hierarchical = true;
if (templevel == null) return rci;
if (templevel == null) {
log.error("moduleName {} does not exist in debugCounters", moduleName);
return rci;
}
/*
if (rci.levels.length > MAX_HIERARCHY) {
......@@ -514,7 +565,7 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
if (templevel != null) {
CounterIndexStore cis = templevel.get(rci.levels[i]) ;
if (cis == null) {
// could not find counterName part at this level
// could not find counterHierarchy part at this level
break;
} else {
rci.ctrIds[i] = cis.index;
......@@ -526,7 +577,7 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
}
} else {
// there are no more levels, which means that some part of the
// counterName has no corresponding map
// counterHierarchy has no corresponding map
break;
}
}
......@@ -592,7 +643,8 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
}
}
protected void printAllCounters() {
protected void printAllCounterIds() {
log.info("<moduleCounterHierarchy>");
Set<String> keys = moduleCounters.keySet();
for (String key : keys) {
log.info("ModuleName: {}", key);
......@@ -618,6 +670,7 @@ public class DebugCounter implements IFloodlightModule, IDebugCounterService {
}
}
}
log.info("<\\moduleCounterHierarchy>");
}
//*******************************
......
package net.floodlightcontroller.debugcounter;
public interface IDebugCounter {
/**
* Increments the counter by 1 thread-locally, and immediately flushes to
* the global counter storage. This method should be used for counters that
* are updated outside the OF message processing pipeline.
*/
void updateCounterWithFlush();
/**
* Increments the counter by 1 thread-locally. Flushing to the global
* counter storage is delayed (happens with flushCounters() in IDebugCounterService),
* resulting in higher performance. This method should be used for counters
* updated in the OF message processing pipeline.
*/
void updateCounterNoFlush();
/**
* Increments the counter thread-locally by the 'incr' specified, and immediately
* flushes to the global counter storage. This method should be used for counters
* that are updated outside the OF message processing pipeline.
*/
void updateCounterWithFlush(int incr);
/**
* Increments the counter thread-locally by the 'incr' specified. Flushing to the global
* counter storage is delayed (happens with flushCounters() in IDebugCounterService),
* resulting in higher performance. This method should be used for counters
* updated in the OF message processing pipeline.
*/
void updateCounterNoFlush(int incr);
/**
* Retrieve the value of the counter from the global counter store
*/
long getCounterValue();
}
......@@ -19,7 +19,7 @@ public interface IDebugCounterService extends IFloodlightService {
/**
* A limit on the maximum number of counters that can be created
*/
public static final int MAX_COUNTERS = 10000;
public static final int MAX_COUNTERS = 5000;
/**
* exception thrown when MAX_COUNTERS have been registered
......@@ -37,9 +37,9 @@ public interface IDebugCounterService extends IFloodlightService {
* All modules that wish to have the DebugCounterService count for them, must
* register their counters by making this call (typically from that module's
* 'startUp' method). The counter can then be updated, displayed, reset etc.
* using the registered moduleCounterName.
* using the registered moduleCounterHierarchy.
*
* @param moduleCounterName the counter name which MUST be have the following
* @param moduleCounterHierarchy the counter name which MUST be have the following
* syntax: <module name>-<counter name>
* eg.: linkdiscovery-incoming
* There should be only a single '-' in the name
......@@ -52,24 +52,11 @@ public interface IDebugCounterService extends IFloodlightService {
* methods in this API -- i.e. registering them is
* not enough to start counting.
* @return false if the counter has already been registered
* or if the moduleCounterName is not as expected.
* or if the moduleCounterHierarchy is not as expected.
*/
public int registerCounter(String moduleName, String counterName,
String counterDescription, CounterType counterType,
Object[] metaData) throws MaxCountersRegistered;
/**
* Increments the counter by 1, if the counter is meant to be always counted,
* or if the counter has been enabled for counting.
* @param moduleCounterName the registered counter name.
*/
void updateCounter(int counterId, boolean flushNow);
/**
* Increments the counter by the number specified
* @param moduleCounterName the registered counter name.
*/
void updateCounter(int counterId, int incr, boolean flushNow);
public IDebugCounter registerCounter(String moduleName, String counterHierarchy,
String counterDescription, CounterType counterType,
Object... metaData) throws MaxCountersRegistered;
/**
* Update the global counter map with values from the thread local maps. This
......@@ -83,9 +70,9 @@ public interface IDebugCounterService extends IFloodlightService {
* Resets the value of the counter to zero if it is currently enabled. Note
* that with live traffic, it is not necessary that the counter will display
* zero with a get call as it may get updated between the reset and get calls.
* @param moduleCounterName the registered counter name.
* @param moduleCounterHierarchy the registered counter name.
*/
void resetCounterHierarchy(String moduleName, String counterName);
void resetCounterHierarchy(String moduleName, String counterHierarchy);
/**
* Resets the values of all counters that are currently enabled to zero.
......@@ -95,7 +82,7 @@ public interface IDebugCounterService extends IFloodlightService {
/**
* Resets the values of all counters that are currently active and belong
* to a module with the given 'moduleName'. The moduleName MUST be the
* part of the moduleCounterName with which the counters were registered.
* part of the moduleCounterHierarchy with which the counters were registered.
* eg. if 'linkdiscovery-incoming' and 'linkdiscovery-lldpeol' are two counters
* the module name is 'linkdiscovery'
* @param moduleName
......@@ -109,28 +96,28 @@ public interface IDebugCounterService extends IFloodlightService {
* enough (as is the case for CounterType.ALWAYS_COUNT). Note that newly
* enabled counter starts from an initial value of zero.
*
* @param moduleCounterName the registered counter name.
* @param moduleCounterHierarchy the registered counter name.
*/
public void enableCtrOnDemand(String moduleName, String counterName);
public void enableCtrOnDemand(String moduleName, String counterHierarchy);
/**
* This method applies only to CounterType.ALWAYS_COUNT. It is used to disable
* counting on this counter. Note that disabling a counter results in a loss
* of the counter value. When re-enabled the counter will restart from zero.
*
* @param moduleCounterName the registered counter name.
* @param moduleCounterHierarchy the registered counter name.
*/
public void disableCtrOnDemand(String moduleName, String counterName);
public void disableCtrOnDemand(String moduleName, String counterHierarchy);
/**
* Get counter value and associated information for a specific counter if it
* is active.
*
* @param moduleCounterName
* @param moduleCounterHierarchy
* @return DebugCounterInfo or null if the counter could not be found
*/
public List<DebugCounterInfo> getCounterHierarchy(String moduleName,
String counterName);
String counterHierarchy);
/**
* Get counter values and associated information for all active counters
......@@ -149,15 +136,15 @@ public interface IDebugCounterService extends IFloodlightService {
public List<DebugCounterInfo> getModuleCounterValues(String moduleName);
/**
* Convenience method to figure out if the the given 'moduleCounterName' corresponds
* to a registered moduleCounterName or not. Note that the counter may or
* Convenience method to figure out if the the given 'moduleCounterHierarchy' corresponds
* to a registered moduleCounterHierarchy or not. Note that the counter may or
* may not be enabled for counting, but if it is registered the method will
* return true.
*
* @param param
* @return false if moduleCounterName is not a registered counter
* @return false if moduleCounterHierarchy is not a registered counter
*/
public boolean containsModuleCounterName(String moduleName, String counterName);
public boolean containsModuleCounterHierarchy(String moduleName, String counterHierarchy);
/**
* Convenience method to figure out if the the given 'moduleName' corresponds
......
......@@ -70,23 +70,23 @@ public class NullDebugCounter implements IFloodlightModule, IDebugCounterService
@Override
public void resetCounterHierarchy(String moduleName, String counterName) {
public void resetCounterHierarchy(String moduleName, String counterHierarchy) {
}
@Override
public void enableCtrOnDemand(String moduleName, String counterName) {
public void enableCtrOnDemand(String moduleName, String counterHierarchy) {
}
@Override
public void disableCtrOnDemand(String moduleName, String counterName) {
public void disableCtrOnDemand(String moduleName, String counterHierarchy) {
}
@Override
public List<DebugCounterInfo> getCounterHierarchy(String moduleName,
String counterName) {
String counterHierarchy) {
return null;
}
......@@ -101,8 +101,8 @@ public class NullDebugCounter implements IFloodlightModule, IDebugCounterService
}
@Override
public boolean containsModuleCounterName(String moduleName,
String counterName) {
public boolean containsModuleCounterHierarchy(String moduleName,
String counterHierarchy) {
return false;
}
......@@ -113,26 +113,15 @@ public class NullDebugCounter implements IFloodlightModule, IDebugCounterService
@Override
public
int
registerCounter(String moduleName, String counterName,
IDebugCounter
registerCounter(String moduleName, String counterHierarchy,
String counterDescription,
CounterType counterType, Object[] metaData)
throws MaxCountersRegistered {
// TODO Auto-generated method stub
return 0;
}
@Override
public void updateCounter(int counterId, boolean flushNow) {
// TODO Auto-generated method stub
CounterType counterType, Object... metaData)
throws MaxCountersRegistered {
return null;
}
@Override
public void updateCounter(int counterId, int incr, boolean flushNow) {
// TODO Auto-generated method stub
}
}
......@@ -95,9 +95,9 @@ public class DebugCounterResource extends DebugCounterResourceBase {
* The Reset command will reset the counter specified as well as all counters
* in the hierarchical levels below. For example, if a counter hierarchy exists
* as switch/00:00:00:00:01:02:03:04/pktin/drops, then a reset command with just
* the moduleName (param1=switch) and counterName (param2=00:00:00:00:01:02:03:04)
* the moduleName (param1=switch) and counterHierarchy (param2=00:00:00:00:01:02:03:04)
* will reset all counters for that switch. Continuing the example -
* for a counterName (param2=00:00:00:00:01:02:03:04 and param3=pktin), the reset
* for a counterHierarchy (param2=00:00:00:00:01:02:03:04 and param3=pktin), the reset
* command will remove all pktin counters for that switch.
*
* The enable/disable command will ONLY disable a specific counter (and only if
......@@ -123,18 +123,18 @@ public class DebugCounterResource extends DebugCounterResourceBase {
choice = Option.ALL;
}
String counterName = "";
String counterHierarchy = "";
if (param2 != null) {
counterName += "/" + param2;
counterHierarchy += "/" + param2;
if (param3 != null) {
counterName += "/" + param3;
counterHierarchy += "/" + param3;
if (param4 != null) {
counterName += "/" + param4;
counterHierarchy += "/" + param4;
}
}
}
if (!moduleName.equals("all") && counterName.equals("")) {
if (!moduleName.equals("all") && counterHierarchy.equals("")) {
// only module name specified
boolean isRegistered = debugCounter.containsModuleName(param1);
if (isRegistered) {
......@@ -142,10 +142,10 @@ public class DebugCounterResource extends DebugCounterResourceBase {
} else {
choice = Option.ERROR_BAD_MODULE_NAME;
}
} else if (!moduleName.equals("all") && !counterName.equals("")) {
} else if (!moduleName.equals("all") && !counterHierarchy.equals("")) {
// both module and counter names specified
boolean isRegistered = debugCounter.containsModuleCounterName(moduleName,
counterName);
boolean isRegistered = debugCounter.
containsModuleCounterHierarchy(moduleName, counterHierarchy);
if (isRegistered) {
choice = Option.MODULE_COUNTER_HIERARCHY;
} else {
......@@ -171,11 +171,11 @@ public class DebugCounterResource extends DebugCounterResourceBase {
break;
case MODULE_COUNTER_HIERARCHY:
if (reset)
debugCounter.resetCounterHierarchy(moduleName, counterName);
debugCounter.resetCounterHierarchy(moduleName, counterHierarchy);
else if (turnOnOff && postData.getEnable())
debugCounter.enableCtrOnDemand(moduleName, counterName);
debugCounter.enableCtrOnDemand(moduleName, counterHierarchy);
else if (turnOnOff && !postData.getEnable())
debugCounter.disableCtrOnDemand(moduleName, counterName);
debugCounter.disableCtrOnDemand(moduleName, counterHierarchy);
break;
case ERROR_BAD_MODULE_NAME:
output.error = "Module name has no corresponding registered counters";
......@@ -226,16 +226,17 @@ public class DebugCounterResource extends DebugCounterResourceBase {
choice = Option.ALL;
}
String counterName = "";
String counterHierarchy = "";
if (param2 != null) {
counterName += "/" + param2;
counterHierarchy += "/" + param2;
if (param3 != null) {
counterName += "/" + param3;
counterHierarchy += "/" + param3;
if (param4 != null) {
counterName += "/" + param4;
counterHierarchy += "/" + param4;
}
}
boolean isRegistered = debugCounter.containsModuleCounterName(param1, counterName);
boolean isRegistered = debugCounter.
containsModuleCounterHierarchy(param1, counterHierarchy);
if (isRegistered) {
choice = Option.MODULE_COUNTER_HIERARCHY;
} else {
......@@ -261,7 +262,7 @@ public class DebugCounterResource extends DebugCounterResourceBase {
populateCounters(debugCounter.getModuleCounterValues(param1), output);
break;
case MODULE_COUNTER_HIERARCHY:
populateCounters(debugCounter.getCounterHierarchy(param1, counterName),
populateCounters(debugCounter.getCounterHierarchy(param1, counterHierarchy),
output);
break;
case ERROR_BAD_MODULE_NAME:
......@@ -281,7 +282,7 @@ public class DebugCounterResource extends DebugCounterResourceBase {
DebugCounterInfoOutput output) {
if (debugCounterInfo != null)
output.counterMap.put(debugCounterInfo.getCounterInfo().
getModuleCounterName(),
getModuleCounterHierarchy(),
debugCounterInfo);
}
......
......@@ -60,7 +60,7 @@ public class CounterHierarchyPutTest extends FloodlightTestCase {
printRCI("got ==>", rci);
printRCI("exp ==>", exp);
assertEquals(rci, exp);
dc.printAllCounters();
dc.printAllCounterIds();
// add and then check for 2nd level of hierarchy
dc.addToModuleCounterHierarchy("switch", 77, rci);
rci = dc.getCounterId("switch", counterName);
......@@ -72,7 +72,7 @@ public class CounterHierarchyPutTest extends FloodlightTestCase {
exp.levels = counterName.split("/");
printRCI("got ==>", rci);
printRCI("exp ==>", exp);
dc.printAllCounters();
dc.printAllCounterIds();
assertEquals(rci, exp);
counterName = "100hp/pktin/drops";
......@@ -86,7 +86,7 @@ public class CounterHierarchyPutTest extends FloodlightTestCase {
printRCI("got ==>", rci);
printRCI("exp ==>", exp);
assertEquals(rci, exp);
dc.printAllCounters();
dc.printAllCounterIds();
// add and then check for 3rd level of hierarchy
dc.addToModuleCounterHierarchy("switch", 132, rci);
rci = dc.getCounterId("switch", counterName);
......@@ -99,7 +99,7 @@ public class CounterHierarchyPutTest extends FloodlightTestCase {
exp.levels = counterName.split("/");
printRCI("got ==>", rci);
printRCI("exp ==>", exp);
dc.printAllCounters();
dc.printAllCounterIds();
assertEquals(rci, exp);
}
......
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.debugcounter.IDebugCounterService.MaxCountersRegistered;
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 MaxCountersRegistered {
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 MaxCountersRegistered {
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()));
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment