Implement ExperimentManager
refs: #2852
Change-Id: I49b50989477914ae4b076d6d39ca661f50fc92aa
diff --git a/ndn/__init__.py b/ndn/__init__.py
index e69de29..0f0d0e4 100644
--- a/ndn/__init__.py
+++ b/ndn/__init__.py
@@ -0,0 +1 @@
+import experiment_manager as ExperimentManager
\ No newline at end of file
diff --git a/ndn/experiment_manager.py b/ndn/experiment_manager.py
new file mode 100644
index 0000000..69dad29
--- /dev/null
+++ b/ndn/experiment_manager.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+
+import os
+
+class _ExperimentManager:
+
+ class Error(Exception):
+ def __init__(self, what):
+ self.what = what
+ def __str__(self):
+ return repr(self.what)
+
+ instance = None
+
+ def __init__(self):
+ self.experiments = {}
+
+ def loadModules(self):
+ currentDir = os.path.dirname(__file__)
+ experimentDir = "%s/%s" % (currentDir, "experiments")
+ experimentModule = "ndn.experiments"
+
+ # Import and register experiments
+ for root, dirs, files in os.walk(experimentDir):
+ for filename in files:
+ if filename.endswith(".py") and filename != "__init__.py":
+ module = filename.replace(".py", "")
+ __import__("%s.%s" % (experimentModule, module))
+
+ def register(self, name, experimentClass):
+ if name not in self.experiments:
+ self.experiments[name] = experimentClass
+ else:
+ raise _ExperimentManager.Error("Experiment '%s' has already been registered" % name)
+
+ def create(self, name, args):
+ if name in self.experiments:
+ return self.experiments[name](args)
+ else:
+ return None
+
+def __getInstance():
+ if _ExperimentManager.instance is None:
+ _ExperimentManager.instance = _ExperimentManager()
+ _ExperimentManager.instance.loadModules()
+
+ return _ExperimentManager.instance
+
+def register(name, experimentClass):
+ manager = __getInstance()
+ manager.register(name, experimentClass)
+
+def create(name, args):
+ manager = __getInstance()
+ return manager.create(name, args)
+
+def getExperimentNames():
+ manager = __getInstance()
+
+ experimentNames = []
+
+ for key in manager.experiments:
+ experimentNames.append(key)
+
+ return experimentNames
diff --git a/ndn/experiments/experiment.py b/ndn/experiments/experiment.py
index 80fba81..d549828 100644
--- a/ndn/experiments/experiment.py
+++ b/ndn/experiments/experiment.py
@@ -3,14 +3,16 @@
import time
import sys
+from ndn import ExperimentManager
+
class Experiment:
- def __init__(self, net, nodes, convergenceTime, nPings, strategy):
- self.net = net
- self.nodes = nodes
- self.convergenceTime = convergenceTime
- self.nPings = nPings
- self.strategy = strategy
+ def __init__(self, args):
+ self.net = args["net"]
+ self.nodes = args["nodes"]
+ self.convergenceTime = args["ctime"]
+ self.nPings = args["nPings"]
+ self.strategy = args["strategy"]
def start(self):
self.setup()
@@ -71,3 +73,7 @@
if host.name != other.name:
self.ping(host, other, self.nPings)
+ @staticmethod
+ def register(name, experimentClass):
+ ExperimentManager.register(name, experimentClass)
+
diff --git a/ndn/experiments/failure_experiment.py b/ndn/experiments/failure_experiment.py
index d4e9380..bae70c1 100644
--- a/ndn/experiments/failure_experiment.py
+++ b/ndn/experiments/failure_experiment.py
@@ -7,9 +7,10 @@
class FailureExperiment(Experiment):
- def __init__(self, net, nodes, convergenceTime, strategy):
+ def __init__(self, args):
+ args["nPings"] = 300
+ Experiment.__init__(self, args)
- Experiment.__init__(self, net, nodes, convergenceTime, 300, strategy)
self.PING_COLLECTION_TIME_BEFORE_FAILURE = 60
self.PING_COLLECTION_TIME_AFTER_RECOVERY = 90
@@ -40,3 +41,5 @@
# Collect pings for more seconds after CSU is up
time.sleep(self.PING_COLLECTION_TIME_AFTER_RECOVERY)
+
+Experiment.register("failure", FailureExperiment)
diff --git a/ndn/experiments/multiple_failure_experiment.py b/ndn/experiments/multiple_failure_experiment.py
index db7d536..27c372a 100644
--- a/ndn/experiments/multiple_failure_experiment.py
+++ b/ndn/experiments/multiple_failure_experiment.py
@@ -7,7 +7,7 @@
class MultipleFailureExperiment(Experiment):
- def __init__(self, net, nodes, convergenceTime, strategy):
+ def __init__(self, args):
self.PING_COLLECTION_TIME_BEFORE_FAILURE = 60
@@ -15,10 +15,12 @@
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(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)
- Experiment.__init__(self, net, nodes, convergenceTime, nInitialPings, strategy)
+ args["nPings"] = nInitialPings
+
+ Experiment.__init__(self, args)
def failNode(self, host):
print("Bringing %s down" % host.name)
@@ -65,3 +67,5 @@
self.ping(host, other, nPings)
time.sleep(self.RECOVERY_INTERVAL)
+
+Experiment.register("multiple-failure", MultipleFailureExperiment)
diff --git a/ndn/experiments/pingall_experiment.py b/ndn/experiments/pingall_experiment.py
index 3bbfc1f..28ad27f 100644
--- a/ndn/experiments/pingall_experiment.py
+++ b/ndn/experiments/pingall_experiment.py
@@ -6,9 +6,9 @@
class PingallExperiment(Experiment):
- def __init__(self, net, nodes, convergenceTime, nPings, strategy):
+ def __init__(self, args):
- Experiment.__init__(self, net, nodes, convergenceTime, nPings, strategy)
+ Experiment.__init__(self, args)
self.COLLECTION_PERIOD_BUFFER = 10
@@ -17,3 +17,5 @@
# For pingall experiment sleep for the number of pings + some offset
time.sleep(self.nPings + self.COLLECTION_PERIOD_BUFFER)
+
+Experiment.register("pingall", PingallExperiment)