summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlois Mahdal <amahdal@redhat.com>2014-05-19 18:35:52 +0200
committerAlois Mahdal <amahdal@redhat.com>2014-05-22 15:28:02 +0200
commit20599516607bb1e496aa5753abed670219e3e05e (patch)
treed36bd96190848d3389f6c2b0fb420928926ca44b
parent85d895d42f6cc651a5ad3969ee4a6e82ffddd03c (diff)
downloadopenlmi-providers-20599516607bb1e496aa5753abed670219e3e05e.tar.gz
openlmi-providers-20599516607bb1e496aa5753abed670219e3e05e.tar.xz
openlmi-providers-20599516607bb1e496aa5753abed670219e3e05e.zip
Add BaseTestDriver base class
This will be used for indication test cases
-rw-r--r--src/python/lmi/test/util.py119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/python/lmi/test/util.py b/src/python/lmi/test/util.py
index a28369e..7574751 100644
--- a/src/python/lmi/test/util.py
+++ b/src/python/lmi/test/util.py
@@ -20,6 +20,8 @@
LMI test utilities.
"""
+import abc
+import copy
import os
import hashlib
import pywbem
@@ -467,3 +469,120 @@ class PackedSequence(object):
@classmethod
def normalize(cls, seq):
return str(cls(seq))
+
+
+class BaseTestDriver(object):
+ """
+ Common test driver base class.
+
+ As user of this class, all you need to do is instantiate
+ the driver and call run method.
+
+ options is a dict holding general options that need to be
+ specified for the process to work, but are not part of test
+ definition. This is passed during instantiation, typically
+ in a setUp method, and can be accessed as self.options.
+
+ Other argument for initiating is default_argset, which can
+ be used to prepare fallback values for cases that omit
+ values from argset in run() call. However, default_argset
+ should only be used in marginal cases; most of the time
+ it's better to be explicit, or to consider moving the value
+ to options.
+
+ As test developer, you need to implement at least _do_run
+ method. Also if you need to call a cleanup method after
+ each test, append that to cleanup_handlers. Passing
+ arguments to cleanup methods is not supported.
+
+ Use of options vs. argset
+
+ Typical example when we want to use options would be, when
+ writing functional data-driven tests for a server that,
+ say, accepts two arguments from range 0 to 100. We want to
+ cover the argument input values, we don't care about on
+ which TCP port the server will run.
+
+ So instead of saying
+
+ argsets = [
+ {'addr': 'localhost, 'port': 1234, 'arg1': 0, 'arg2' 0}
+ {'addr': 'localhost, 'port': 1234, 'arg1': 0, 'arg2' 1}
+ {'addr': 'localhost, 'port': 1234, 'arg1': 1, 'arg2' 0}
+ {'addr': 'localhost, 'port': 1234, 'arg1': 1, 'arg2' 1}
+ ...
+ ]
+ for argset in argsets:
+ drv = OurServerTestDriver()
+ result = drv.run(argset)
+
+ we say:
+
+ argsets = [
+ {'arg1': 0, 'arg2' 0}
+ {'arg1': 0, 'arg2' 1}
+ {'arg1': 1, 'arg2' 0}
+ {'arg1': 1, 'arg2' 1}
+ ...
+ ]
+ for argset in argsets:
+ drv = OurServerTestDriver(options={'addr': 'localhost',
+ 'port': 1234})
+ result = drv.run(argset)
+
+ so we can concentrate on coverage instead of boring environment
+ details.
+ """
+ __metaclass__ = abc.ABCMeta
+
+ # # internal
+ #
+
+ def __init__(self, options, default_argset={}):
+ self.options = options
+ self.argset = copy.deepcopy(default_argset)
+ self.result = None
+ self.cleanup_handlers = []
+
+ def __cleanup(self):
+ """
+ Run each handler from self.cleanup_handlers
+ """
+ [h() for h in self.cleanup_handlers]
+
+ # # virtual
+ #
+
+ @abc.abstractmethod
+ def _do_run(self):
+ """
+ Abstract method to implement body of run() method
+
+ This method needs to be overriden in subclass, and deal
+ with actual running of the test. self.argset and
+ self.options are already assigned.
+
+ return value of this method will become return value of
+ run()
+
+ Methods registered in self.cleanup_handlers will be
+ called after this method.
+ """
+ pass
+
+ # # public
+ #
+
+ def run(self, argset):
+ """
+ Run the actual test with argset
+
+ Will set argset correctly, run the implemented _do_run
+ method and eventually call any cleanup handlers.
+
+ Return value is that of the _do_run method
+ """
+ self.argset.update(argset)
+ result = self._do_run()
+ self.__cleanup()
+ return result