experiments: Allow pinging a percentage of nodes
refs: #3265
Change-Id: I80a37d4a8cf6ca5a25d03f1f98cdcf9394feb92f
diff --git a/bin/minindn b/bin/minindn
index e81db21..e081883 100755
--- a/bin/minindn
+++ b/bin/minindn
@@ -106,6 +106,7 @@
self.testbed = False
self.workDir = "/tmp"
self.resultDir = None
+ self.pctTraffic = 1.0
def createResultsDir(resultDir, faces, hr):
if faces == 0:
@@ -167,6 +168,9 @@
parser.add_option("--result-dir", action="store", dest="resultDir", default=None,
help="Specify the full path destination folder where experiment results will be moved")
+ parser.add_option("--pct-traffic", action="store", dest="pctTraffic", type="float", default=1.0,
+ help="Specify the percentage of nodes each node should ping")
+
parser.add_option('--version', '-V', action='callback', callback=printVersion,
help='Displays version information')
@@ -182,6 +186,7 @@
options.testbed = args.testbed
options.workDir = args.workDir
options.resultDir = args.resultDir
+ options.pctTraffic = args.pctTraffic
if options.experimentName is not None and options.experimentName not in ExperimentManager.getExperimentNames():
print("No experiment named %s" % options.experimentName)
@@ -335,7 +340,8 @@
"nodes": nodes,
"ctime": options.ctime,
"nPings": options.nPings,
- "strategy": Nfd.STRATEGY_BEST_ROUTE_V3
+ "strategy": Nfd.STRATEGY_BEST_ROUTE_V3,
+ "pctTraffic": options.pctTraffic
}
experiment = ExperimentManager.create(experimentName, experimentArgs)
diff --git a/ndn/experiments/experiment.py b/ndn/experiments/experiment.py
index d6d5df7..385ff2a 100644
--- a/ndn/experiments/experiment.py
+++ b/ndn/experiments/experiment.py
@@ -23,6 +23,7 @@
import time
import sys
+from itertools import cycle
from ndn import ExperimentManager
@@ -34,6 +35,11 @@
self.convergenceTime = args["ctime"]
self.nPings = args["nPings"]
self.strategy = args["strategy"]
+ self.pctTraffic = float(args["pctTraffic"])
+
+ # Used to restart pings on the recovered node if any
+ self.pingedDict = {}
+
def start(self):
self.setup()
@@ -105,6 +111,36 @@
host.nfd.setStrategy("/ndn/edu", self.strategy)
host.cmd("ndnpingserver /ndn/edu/" + str(host) + " > ping-server &")
+ def startPctPings(self):
+ nNodesToPing = int(round(len(self.net.hosts)*self.pctTraffic))
+ print "Each node will ping %d node(s)" % nNodesToPing
+ # Temporarily store all the nodes being pinged by a particular node
+ nodesPingedList = []
+
+ for host in self.net.hosts:
+ # Create a circular list
+ pool = cycle(self.net.hosts)
+
+ # Move iterator to current node
+ next(x for x in pool if host.name == x.name)
+
+ # Track number of nodes to ping scheduled for this node
+ nNodesScheduled = 0
+
+ while nNodesScheduled < nNodesToPing:
+ other = pool.next()
+
+ # Do not ping self
+ if host.name != other.name:
+ self.ping(host, other, self.nPings)
+ nodesPingedList.append(other)
+
+ # Always increment because in 100% case a node should not ping itself
+ nNodesScheduled = nNodesScheduled + 1
+
+ self.pingedDict[host] = nodesPingedList
+ nodesPingedList = []
+
@staticmethod
def register(name, experimentClass):
ExperimentManager.register(name, experimentClass)
diff --git a/ndn/experiments/failure_experiment.py b/ndn/experiments/failure_experiment.py
index 8bca445..d8d7dc9 100644
--- a/ndn/experiments/failure_experiment.py
+++ b/ndn/experiments/failure_experiment.py
@@ -36,7 +36,7 @@
self.PING_COLLECTION_TIME_AFTER_RECOVERY = 120
def run(self):
- self.startPings()
+ self.startPctPings()
# After the pings are scheduled, collect pings for 1 minute
time.sleep(self.PING_COLLECTION_TIME_BEFORE_FAILURE)
diff --git a/ndn/experiments/multiple_failure_experiment.py b/ndn/experiments/multiple_failure_experiment.py
index bea9a78..2759c67 100644
--- a/ndn/experiments/multiple_failure_experiment.py
+++ b/ndn/experiments/multiple_failure_experiment.py
@@ -36,7 +36,8 @@
self.RECOVERY_INTERVAL = 60
# This is the number of pings required to make it through the full experiment
- nInitialPings = self.PING_COLLECTION_TIME_BEFORE_FAILURE + len(args["net"].hosts)*(self.FAILURE_INTERVAL + self.RECOVERY_INTERVAL)
+ nInitialPings = (self.PING_COLLECTION_TIME_BEFORE_FAILURE +
+ len(args["net"].hosts)*(self.FAILURE_INTERVAL + self.RECOVERY_INTERVAL))
print("Scheduling with %s initial pings" % nInitialPings)
args["nPings"] = nInitialPings
@@ -44,7 +45,7 @@
Experiment.__init__(self, args)
def run(self):
- self.startPings()
+ self.startPctPings()
# After the pings are scheduled, collect pings for 1 minute
time.sleep(self.PING_COLLECTION_TIME_BEFORE_FAILURE)
@@ -56,26 +57,25 @@
# Fail the node
self.failNode(host)
- # Stay in failure state for FAILURE_INTERVAL
+ # Stay in failure state for FAILURE_INTERVAL seconds
time.sleep(self.FAILURE_INTERVAL)
# Bring the node back up
+ start_time = time.time()
self.recoverNode(host)
+ recovery_time = int(time.time() - start_time)
# Number of pings required to reach the end of the test
- nPings = self.RECOVERY_INTERVAL + nNodesRemainingToFail*(self.FAILURE_INTERVAL + self.RECOVERY_INTERVAL)
- nNodesRemainingToFail = nNodesRemainingToFail - 1
+ nNodesRemainingToFail -= 1
+ nPings = ((self.RECOVERY_INTERVAL - recovery_time) +
+ nNodesRemainingToFail*(self.FAILURE_INTERVAL + self.RECOVERY_INTERVAL))
- # Wait for NFD and NLSR to fully recover
- time.sleep(1)
print("Scheduling with %s remaining pings" % nPings)
# Restart pings
- for other in self.net.hosts:
- # Do not ping self
- if host.name != other.name:
- self.ping(host, other, nPings)
+ for nodeToPing in self.pingedDict[host]:
+ self.ping(host, nodeToPing, nPings)
- time.sleep(self.RECOVERY_INTERVAL)
+ time.sleep(self.RECOVERY_INTERVAL - recovery_time)
Experiment.register("multiple-failure", MultipleFailureExperiment)
diff --git a/ndn/experiments/pingall_experiment.py b/ndn/experiments/pingall_experiment.py
index 76f0ef6..60c8e4e 100644
--- a/ndn/experiments/pingall_experiment.py
+++ b/ndn/experiments/pingall_experiment.py
@@ -31,10 +31,11 @@
Experiment.__init__(self, args)
self.COLLECTION_PERIOD_BUFFER = 10
-
+ self.pctTraffic = float(args["pctTraffic"])
+ print "Using %f traffic" % self.pctTraffic
def run(self):
- self.startPings()
+ self.startPctPings()
# For pingall experiment sleep for the number of pings + some offset
time.sleep(self.nPings + self.COLLECTION_PERIOD_BUFFER)