Package Products :: Package ZenUtils :: Module ZenDocTest |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenUtils.ZenDocTest

      1  ##############################################################################
      2  #
      3  # Copyright (C) Zenoss, Inc. 2007, all rights reserved.
      4  #
      5  # This content is made available according to terms specified in
      6  # License.zenoss under the directory where your Zenoss product is installed.
      7  #
      8  ##############################################################################
      9
     10
     11  import unittest
     12  import doctest
     13  import transaction
     14  import socket
     15  import Globals
     16
     17  import zope.component
     18  from zope.traversing.adapters import DefaultTraversable
     19
     20  from AccessControl.SecurityManagement import newSecurityManager
     21  from AccessControl.SecurityManagement import noSecurityManager
     22
     23  from Products.ZenUtils.ZeoConn import ZeoConn
     24
     25
     26 -class TestSuiteWithHooks(unittest.TestSuite):
     27      """
     28      A modified TestSuite that provides hooks for startUp and tearDown methods.
     29      """
     30 -    def run(self, result):
     31          self.startUp()
     32          unittest.TestSuite.run(self, result)
     33          self.tearDown()
     34
     35 -    def startUp(self):
     36          pass
     37
     38 -    def tearDown(self):
     39          pass
     40
     41
     42 -class ZenDocTestRunner(object):
     43      """
     44      Extracts doctests from the docstrings of a Zenoss module
     45      and runs them in an environment similar to that of zendmd.
     46
     47      Example usage:
     48          zdtr = ZenDocTestRunner()
     49          zdtr.add_modules("Products.ZenModel.ZenModelBase")
     50          zdtr.run()
     51      """
     52
     53      modules = []
     54      conn = None
     55
     56 -    def _find_relstorage_adapter_config(self):
     57          from App.config import getConfiguration
     58          zope_config = getConfiguration()
     59          for db in zope_config.databases:
     60              if db.name == 'main':
     61                  return db.config.storage.config.adapter.config
     62
     63 -    def setUp(self):
     64          import Products.ZenossStartup
     65          from Products.Five import zcml
     66          zcml.load_site()
     67
     68          zope.component.provideAdapter(DefaultTraversable, (None,))
     69          if not self.conn:
     70              adapter_config = self._find_relstorage_adapter_config()
     71              if adapter_config:
     72                  self.conn = ZeoConn(zodb_host=adapter_config.host,
     73                          zodb_port=adapter_config.port,
     74                          zodb_user=adapter_config.user,
     75                          zodb_password=adapter_config.passwd,
     76                          zodb_db=adapter_config.db,
     77                          zodb_socket=adapter_config.unix_socket)
     78              else:
     79                  self.conn = ZeoConn()
     80
     81          self.app = self.conn.app
     82          self.login()
     83          self.dmd = self.app.zport.dmd
     84          find = self.dmd.Devices.findDevice
     85          self.globals = dict(
     86              app = self.app,
     87              zport = self.app.zport,
     88              dmd = self.dmd,
     89              find = find,
     90              devices = self.dmd.Devices,
     91              sync = self.dmd._p_jar.sync,
     92              commit = transaction.commit,
     93              abort = transaction.abort,
     94              me = find(socket.getfqdn())
     95          )
     96
     97 -    def tearDown(self):
     98          self.logout()
     99          self.conn.closedb()
    100
    101 -    def login(self, name='admin', userfolder=None):
    102          '''Logs in.'''
    103          if userfolder is None:
    104              userfolder = self.app.acl_users
    105          user = userfolder.getUserById(name)
    106          if user is None: return
    107          if not hasattr(user, 'aq_base'):
    108              user = user.__of__(userfolder)
    109          newSecurityManager(None, user)
    110
    111 -    def logout(self):
    112          noSecurityManager()
    113
    114 -    def doctest_setUp(self, testObject):
    115          self.login()
    116          self.globals['sync']()
    117          testObject.globs.update(self.globals)
    118
    119 -    def doctest_tearDown(self, testObject):
    120          self.logout()
    121          testObject.globs['abort']()
    122          self.globals['sync']()
    123
    124 -    def add_modules(self, mods):
    125          """
    126          Add Zenoss modules to be tested.
    127
    128          @param mods: One or more module objects or dotted names.
    129          @type mods: module or list
    130          """
    131          if not isinstance(mods, list): mods = [mods]
    132          self.modules.extend(mods)
    133
    134 -    def get_suites(self):
    135          """
    136          Returns a doctest.DocTestSuite for each module
    137          in self.modules.
    138
    139          Provided for integration with existing unittest framework.
    140          """
    141          self.setUp()
    142          doctest.DocTestFinder(exclude_empty=True)
    143          suites = []
    144          for mod in self.modules:
    145              try:
    146                  dtsuite = doctest.DocTestSuite(
    147                      mod,
    148                      optionflags=doctest.NORMALIZE_WHITESPACE,
    149                      setUp = self.doctest_setUp,
    150                      tearDown = self.doctest_tearDown
    151                  )
    152              except ValueError:
    153                  pass
    154              else:
    155                  suites.append(dtsuite)
    156          return suites
    157
    158 -    def run(self):
    159          """
    160          Run the doctests found in the modules added to this instance.
    161
    162          This method sets up the zendmd global variables, creates a
    163          test suite for each module that has been added, and runs
    164          all suites.
    165          """
    166          suite = unittest.TestSuite()
    167          for dtsuite in self.get_suites():
    168              suite.addTest(dtsuite)
    169          runner = unittest.TextTestRunner()
    170          runner.run(suite)
    171          self.tearDown()
    172