Implement a nose cordtest plugin to restore test case configuration after failure/errors.
This is especially useful for tests like vsg where after a failure, one wants to restore back the original config.
The user needs to implement a:
configRestore @classmethod in their test case class to restore the configuration on test failures/errors.

Change-Id: I810e1586173bcd1066b42b6ce5cf815834cd38b8
diff --git a/src/test/utils/CordTestConfig.py b/src/test/utils/CordTestConfig.py
index fc4aafe..74c4889 100644
--- a/src/test/utils/CordTestConfig.py
+++ b/src/test/utils/CordTestConfig.py
@@ -3,6 +3,50 @@
 import json
 import os
 from nose.tools import assert_not_equal
+from nose.plugins import Plugin
+from CordTestUtils import log_test as log
+
+log.setLevel('INFO')
+
+class CordTestConfigRestore(Plugin):
+    name = 'cordTestConfigRestore'
+    context = None
+    restore_methods = ('configRestore', 'config_restore',)
+
+    def options(self, parser, env=os.environ):
+        super(CordTestConfigRestore, self).options(parser, env = env)
+
+    def configure(self, options, conf):
+        self.enabled = True
+
+    #just save the test case context on start
+    def startContext(self, context):
+        if inspect.isclass(context) and issubclass(context, unittest.TestCase):
+            if context.__name__.endswith('exchange'):
+                self.context = context
+
+    #reset the context on exit
+    def afterContext(self, context):
+        if inspect.isclass(context) and issubclass(context, unittest.TestCase):
+            if context.__name__.endswith('exchange'):
+                self.context = None
+
+    def doFailure(self, test, exception):
+        if self.context:
+            log.info('Inside test case failure for test: %s' %self.context.__name__)
+            for restore_method in self.restore_methods:
+                if hasattr(self.context, restore_method):
+                    method = getattr(self.context, restore_method)
+                    #check only for class/static methods
+                    if method.__self__ is self.context:
+                        method()
+                        break
+
+    def addError(self, test, exception):
+        self.doFailure(test, exception)
+
+    def addFailure(self, test, exception):
+        self.doFailure(test, exception)
 
 def setup_module(module):
     class_test = None