per-test logfiles
The new --log-dir option creates a directory with one log file for every test
(plus main.log for the oft script). It takes precedence over the --log-file
option if both are specified.
The --log-append option and the ability to pass "-" or "stderr" to --log-file
have been removed.
diff --git a/src/python/oftest/__init__.py b/src/python/oftest/__init__.py
index 9199b1a..c78bb67 100644
--- a/src/python/oftest/__init__.py
+++ b/src/python/oftest/__init__.py
@@ -1,5 +1,7 @@
'''Docstring to silence pylint; ignores --ignore option for __init__.py'''
import sys
+import os
+import logging
# Global config dictionary
# Populated by oft.
@@ -8,3 +10,31 @@
# Global DataPlane instance used by all tests.
# Populated by oft.
dataplane_instance = None
+
+def open_logfile(name):
+ """
+ (Re)open logfile
+
+ When using a log directory a new logfile is created for each test. The same
+ code is used to implement a single logfile in the absence of --log-dir.
+ """
+
+ _format = "%(asctime)s.%(msecs)03d %(name)-10s: %(levelname)-8s: %(message)s"
+ _datefmt = "%H:%M:%S"
+
+ if config["log_dir"] != None:
+ filename = os.path.join(config["log_dir"], name) + ".log"
+ else:
+ filename = config["log_file"]
+
+ logger = logging.getLogger()
+
+ # Remove any existing handlers
+ for handler in logger.handlers:
+ logger.removeHandler(handler)
+ handler.close()
+
+ # Add a new handler
+ handler = logging.FileHandler(filename, mode='a')
+ handler.setFormatter(logging.Formatter(_format, _datefmt))
+ logger.addHandler(handler)
diff --git a/src/python/oftest/base_tests.py b/src/python/oftest/base_tests.py
index a1eec43..3b59bc1 100644
--- a/src/python/oftest/base_tests.py
+++ b/src/python/oftest/base_tests.py
@@ -14,13 +14,25 @@
import oftest.dataplane as dataplane
import ofp
-class SimpleProtocol(unittest.TestCase):
+class BaseTest(unittest.TestCase):
+ def __str__(self):
+ return self.id().replace('.runTest', '')
+
+ def setUp(self):
+ oftest.open_logfile(str(self))
+ logging.info("** START TEST CASE " + str(self))
+
+ def tearDown(self):
+ logging.info("** END TEST CASE " + str(self))
+
+class SimpleProtocol(BaseTest):
"""
Root class for setting up the controller
"""
def setUp(self):
- logging.info("** START TEST CASE " + str(self))
+ BaseTest.setUp(self)
+
self.controller = controller.Controller(
switch=config["switch_ip"],
host=config["controller_host"],
@@ -73,10 +85,10 @@
self.supported_actions = parent.supported_actions
def tearDown(self):
- logging.info("** END TEST CASE " + str(self))
self.controller.shutdown()
self.controller.join()
del self.controller
+ BaseTest.tearDown(self)
def assertTrue(self, cond, msg):
if not cond:
@@ -102,20 +114,17 @@
self.dataplane = parent.dataplane
def tearDown(self):
- logging.info("Teardown for simple dataplane test")
SimpleProtocol.tearDown(self)
- logging.info("Teardown done")
-class DataPlaneOnly(unittest.TestCase):
+class DataPlaneOnly(BaseTest):
"""
Root class that sets up only the dataplane
"""
def setUp(self):
- logging.info("** START DataPlaneOnly CASE " + str(self))
+ BaseTest.setUp(self)
self.dataplane = oftest.dataplane_instance
self.dataplane.flush()
def tearDown(self):
- logging.info("Teardown for simple dataplane test")
- logging.info("Teardown done")
+ BaseTest.tearDown(self)