Skip to content

/ Zope / gocept svn checkins / Archive / 2008 / 2008-08 / SVN: r6456 - in gocept.cxoracle: . trunk trunk/src trunk/src/gocept trunk/src/gocept/cxoracle

[ << ] [ >> ]

[ SVN: r6444 - gocept.imapapi/trunk/gocept/imapapi ... ] [ SVN: r6464 - in gocept.cxoracle: branches tags / ... ]

SVN: r6456 - in gocept.cxoracle: . trunk trunk/src trunk/src/gocept trunk/src/gocept/cxoracle
Christian Zagrodnick <cz(at)gocept.com>
2008-08-29 09:30:06 [ FULL ]
Author: zagy
Date: Fri Aug 29 09:30:04 2008
New Revision: 6456

Log:
importing recipe to install cx_Oracle in buildout



Added:
   gocept.cxoracle/
   gocept.cxoracle/trunk/
   gocept.cxoracle/trunk/README.txt   (contents, props changed)
   gocept.cxoracle/trunk/setup.py   (contents, props changed)
   gocept.cxoracle/trunk/src/
   gocept.cxoracle/trunk/src/gocept/
   gocept.cxoracle/trunk/src/gocept/__init__.py   (contents, props changed)
   gocept.cxoracle/trunk/src/gocept/cxoracle/
   gocept.cxoracle/trunk/src/gocept/cxoracle/__init__.py   (contents, props
changed)
   gocept.cxoracle/trunk/src/gocept/cxoracle/recipe.py   (contents, props
changed)

Added: gocept.cxoracle/trunk/README.txt
==============================================================================
--- (empty file)
+++ gocept.cxoracle/trunk/README.txt	Fri Aug 29 09:30:04 2008
(at)(at) -0,0 +1 (at)(at)
+XXX

Added: gocept.cxoracle/trunk/setup.py
==============================================================================
--- (empty file)
+++ gocept.cxoracle/trunk/setup.py	Fri Aug 29 09:30:04 2008
(at)(at) -0,0 +1,32 (at)(at)
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt
+
+from setuptools import setup, find_packages
+
+name = "gocept.cxoracle"
+
+classifiers = []
+
+setup(
+    name = name,
+    version = "dev",
+    author = "Christian Zagrodnick",
+    author_email = "cz(at)gocept.com",
+    description = \
+    "zc.buildout recipe for installing cx_Oracle",
+    long_description = open("README.txt").read(),
+    license = "ZPL 2.1",
+    classifiers = classifiers,
+    url = "http://svn.gocept.com/repos/gocept/"
+ name,
+    download_url = \
+    "https://svn.gocept.com/repos/gocept/"
+    "%(name)s/trunk#egg=%(name)s-dev" % {"name": name},
+    packages = find_packages("src"),
+    include_package_data = True,
+    package_dir = {"": "src"},
+    namespace_packages = ["gocept"],
+    install_requires = ["zc.buildout", "setuptools"],
+    extras_require = {"test": ["zope.testing"]},
+    entry_points = {"zc.buildout": ["default = %s.recipe:CxOracle" % name,],},
+    )
+

Added: gocept.cxoracle/trunk/src/gocept/__init__.py
==============================================================================
--- (empty file)
+++ gocept.cxoracle/trunk/src/gocept/__init__.py	Fri Aug 29 09:30:04 2008
(at)(at) -0,0 +1,8 (at)(at)
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt
+#namespace package boilerplate
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError, e:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

Added: gocept.cxoracle/trunk/src/gocept/cxoracle/__init__.py
==============================================================================
--- (empty file)
+++ gocept.cxoracle/trunk/src/gocept/cxoracle/__init__.py	Fri Aug 29 09:30:04
2008
(at)(at) -0,0 +1,2 (at)(at)
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt

Added: gocept.cxoracle/trunk/src/gocept/cxoracle/recipe.py
==============================================================================
--- (empty file)
+++ gocept.cxoracle/trunk/src/gocept/cxoracle/recipe.py	Fri Aug 29 09:30:04
2008
(at)(at) -0,0 +1,68 (at)(at)
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt
+
+import re
+import os
+import os.path
+import shutil
+import subprocess
+import tempfile
+
+
+class CxOracle(object):
+
+    client_library_pattern = re.compile(
+        r'^(libclntsh)\.([[a-z]+)\.([\d.]+)$')
+
+    def __init__(self, buildout, name, options):
+        self.buildout = buildout
+        self.name = name
+        self.options = options
+        self.part_directory = os.path.join(
+            buildout['buildout']['parts-directory'],
+            name)
+
+    def install(self):
+        if os.path.isdir(self.part_directory):
+            shutil.rmtree(self.part_directory)
+        os.mkdir(self.part_directory)
+        self.prepare_oracle_home()
+        return self.part_directory
+
+    def prepare_oracle_home(self):
+        self.unzip(self.options['instant-client'])
+        self.unzip(self.options['instant-sdk'])
+
+        symlink_source = None
+        for filename in os.listdir(self.part_directory):
+            m = self.client_library_pattern.match(filename)
+            if m is not None:
+                library_base_name = m.group(2)
+                library_kind = m.group(2)
+                version = m.group(3)
+                symlink_source = filename
+                break
+        if symlink_source is None:
+            raise Exception('Could not find libclntsh.')
+
+        symlink_target = '%s.%s' % (library_base_name, library_kind)
+        os.symlink(os.path.join(self.part_directory, symlink_source),
+                   os.path.join(self.part_directory, symlink_target))
+
+    def unzip(self, filename):
+        extract_dir = tempfile.mkdtemp()
+        try:
+
+            call = ['unzip', filename, '-d', extract_dir]
+            retcode = subprocess.call(call)
+            if retcode != 0:
+                raise Exception('Extraction of file %r failed' % extract_dir)
+
+            contents = os.listdir(extract_dir)
+            assert len(contents) == 1
+            root = os.path.join(extract_dir, contents[0])
+            for filename in os.listdir(root):
+                shutil.move(os.path.join(root, filename),
+                            os.path.join(self.part_directory, filename))
+        finally:
+            shutil.rmtree(extract_dir)

SVN: r6458 - gocept.cxoracle/trunk/src/gocept/cxoracle
Christian Zagrodnick <cz(at)gocept.com>
2008-08-29 12:01:28 [ FULL ]
Author: zagy
Date: Fri Aug 29 12:01:27 2008
New Revision: 6458

Log:
added a loader which sets the right environment for cx_Oracle


Added:
   gocept.cxoracle/trunk/src/gocept/cxoracle/loader.c   (contents, props
changed)
Modified:
   gocept.cxoracle/trunk/src/gocept/cxoracle/recipe.py

Added: gocept.cxoracle/trunk/src/gocept/cxoracle/loader.c
==============================================================================
--- (empty file)
+++ gocept.cxoracle/trunk/src/gocept/cxoracle/loader.c	Fri Aug 29 12:01:27 2008
(at)(at) -0,0 +1,23 (at)(at)
+/* load python with set envvars */
+
+#include <stdlib.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#include <stdio.h>
+
+int main(int argc, char* argv[]) {
+
+    struct utsname uinfo;
+    char *varname;
+
+    uname(&uinfo);
+    if (strcmp(uinfo.sysname, "Darwin") == 0) {
+        varname = "DYLD_LIBRARY_PATH";
+    } else {
+        varname = "LD_LIBRARY_PATH";
+    }
+    setenv(varname, ORACLE_HOME, 1);
+    setenv("ORACLE_HOME", ORACLE_HOME, 1);
+
+    execvp(PYTHON_EXECUTABLE, argv);
+}

Modified: gocept.cxoracle/trunk/src/gocept/cxoracle/recipe.py
==============================================================================
--- gocept.cxoracle/trunk/src/gocept/cxoracle/recipe.py	(original)
+++ gocept.cxoracle/trunk/src/gocept/cxoracle/recipe.py	Fri Aug 29 12:01:27
2008
(at)(at) -1,11 +1,14 (at)(at)
 # Copyright (c) 2008 gocept gmbh & co. kg
 # See also LICENSE.txt
 
+import distutils.ccompiler
 import re
 import os
 import os.path
 import shutil
+import stat
 import subprocess
+import sys
 import tempfile
 
 
(at)(at) -18,18 +21,27 (at)(at)
         self.buildout = buildout
         self.name = name
         self.options = options
-        self.part_directory = os.path.join(
+        self.part_directory = options['oracle-home'] = os.path.join(
             buildout['buildout']['parts-directory'],
             name)
+        options.setdefault('loader-name', name)
+        self.loader = options['_loader_path'] = os.path.join(
+            buildout['buildout']['bin-directory'], options['loader-name'])
+        options['executable'] = self.loader
 
     def install(self):
         if os.path.isdir(self.part_directory):
             shutil.rmtree(self.part_directory)
         os.mkdir(self.part_directory)
         self.prepare_oracle_home()
-        return self.part_directory
+        self.create_loader()
+        return self.part_directory, self.loader
+
+    def update(self):
+        pass
 
     def prepare_oracle_home(self):
+        """Prepare the part directory to contain all the libraries
required."""
         self.unzip(self.options['instant-client'])
         self.unzip(self.options['instant-sdk'])
 
(at)(at) -37,7 +49,7 (at)(at)
         for filename in os.listdir(self.part_directory):
             m = self.client_library_pattern.match(filename)
             if m is not None:
-                library_base_name = m.group(2)
+                library_base_name = m.group(1)
                 library_kind = m.group(2)
                 version = m.group(3)
                 symlink_source = filename
(at)(at) -49,14 +61,42 (at)(at)
         os.symlink(os.path.join(self.part_directory, symlink_source),
                    os.path.join(self.part_directory, symlink_target))
 
+    def create_loader(self):
+        old_cwd = os.getcwd()
+        work_dir = tempfile.mkdtemp()
+        try:
+            os.chdir(work_dir)
+            shutil.copy(os.path.join(os.path.dirname(__file__), 'loader.c'),
+                        os.path.join(work_dir, 'loader.c'))
+
+            compiler = distutils.ccompiler.new_compiler()
+            compiler.define_macro('PYTHON_EXECUTABLE',
+                                  '"%s"' % sys.executable)
+            compiler.define_macro('ORACLE_HOME',
+                                  '"%s"' % self.options['oracle-home'])
+
+            compiler.compile(['loader.c'])
+            compiler.link_executable(['loader.o'],
self.options['loader-name'])
+            shutil.move(os.path.join(work_dir, self.options['loader-name']),
+                        self.loader)
+        finally:
+            os.chdir(old_cwd)
+            shutil.rmtree(work_dir)
+
+
     def unzip(self, filename):
+        """Helper to unzip an archive to the parts directory."""
         extract_dir = tempfile.mkdtemp()
         try:
 
-            call = ['unzip', filename, '-d', extract_dir]
-            retcode = subprocess.call(call)
-            if retcode != 0:
-                raise Exception('Extraction of file %r failed' % extract_dir)
+            call = subprocess.Popen(
+                ['unzip', filename, '-d', extract_dir],
+                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+            stdout, stderr = call.communicate()
+
+            if call.returncode != 0:
+                raise Exception('Extraction of file %r failed.' % filename)
 
             contents = os.listdir(extract_dir)
             assert len(contents) == 1

SVN: r6460 - in gocept.cxoracle/trunk: . src/gocept/cxoracle
Christian Zagrodnick <cz(at)gocept.com>
2008-08-29 13:52:52 [ FULL ]
Author: zagy
Date: Fri Aug 29 13:52:50 2008
New Revision: 6460

Log:
added tests
added a buildout

added long_description / readme


Added:
   gocept.cxoracle/trunk/bootstrap.py   (contents, props changed)
   gocept.cxoracle/trunk/buildout.cfg
   gocept.cxoracle/trunk/src/gocept/cxoracle/README.txt   (contents, props
changed)
   gocept.cxoracle/trunk/src/gocept/cxoracle/basiclite-darwin.zip   (contents,
props changed)
   gocept.cxoracle/trunk/src/gocept/cxoracle/basiclite-linux.zip   (contents,
props changed)
   gocept.cxoracle/trunk/src/gocept/cxoracle/sdk-darwin.zip   (contents, props
changed)
   gocept.cxoracle/trunk/src/gocept/cxoracle/sdk-linux.zip   (contents, props
changed)
   gocept.cxoracle/trunk/src/gocept/cxoracle/tests.py   (contents, props
changed)
Modified:
   gocept.cxoracle/trunk/   (props changed)
   gocept.cxoracle/trunk/README.txt
   gocept.cxoracle/trunk/setup.py

Modified: gocept.cxoracle/trunk/README.txt
==============================================================================
--- gocept.cxoracle/trunk/README.txt	(original)
+++ gocept.cxoracle/trunk/README.txt	Fri Aug 29 13:52:50 2008
(at)(at) -1 +1,21 (at)(at)
-XXX
+gocept.cxoracle - A zc.buildout recipe to easily get cx_Oracle running
+
+An example buildout might look like this::
+
+    [buildout]
+    develop = .
+    parts = python-oracle cx_Oracle test
+    python = python-oracle
+
+    [python-oracle]
+    recipe = gocept.cxoracle
+    instant-client = .../instantclient-basiclite-macosx-10.2.0.4.0.zip
+    instant-sdk = .../instantclient-sdk-macosx-10.2.0.4.0.zip
+
+    [cx_Oracle]
+    recipe = zc.recipe.egg:custom
+    egg = cx_Oracle
+
+    [test]
+    recipe = zc.recipe.testrunner
+    eggs = test.some.egg

Added: gocept.cxoracle/trunk/bootstrap.py
==============================================================================
--- (empty file)
+++ gocept.cxoracle/trunk/bootstrap.py	Fri Aug 29 13:52:50 2008
(at)(at) -0,0 +1,55 (at)(at)
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+try:
+    import pkg_resources
+except ImportError:
+    ez = {}
+    exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                         ).read() in ez
+    ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+    import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+    cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+    os.P_WAIT, sys.executable, sys.executable,
+    '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+    dict(os.environ,
+         PYTHONPATH=
+         ws.find(pkg_resources.Requirement.parse('setuptools')).location
+         ),
+    ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)

Added: gocept.cxoracle/trunk/buildout.cfg
==============================================================================
--- (empty file)
+++ gocept.cxoracle/trunk/buildout.cfg	Fri Aug 29 13:52:50 2008
(at)(at) -0,0 +1,8 (at)(at)
+[buildout]
+develop = .
+parts = test
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = gocept.cxoracle [test]
+defaults = ["-v", "-s", "gocept.cxoracle"]

Modified: gocept.cxoracle/trunk/setup.py
==============================================================================
--- gocept.cxoracle/trunk/setup.py	(original)
+++ gocept.cxoracle/trunk/setup.py	Fri Aug 29 13:52:50 2008
(at)(at) -14,7 +14,9 (at)(at)
     author_email = "cz(at)gocept.com",
     description = \
     "zc.buildout recipe for installing cx_Oracle",
-    long_description = open("README.txt").read(),
+    long_description = (
+        open("README.txt").read() + '\n\n' +
+        open(os.path.join('src', 'gocept', 'cxoracle', 'README.txt')).read()),
     license = "ZPL 2.1",
     classifiers = classifiers,
     url = "http://svn.gocept.com/repos/gocept/"
+ name,

Added: gocept.cxoracle/trunk/src/gocept/cxoracle/README.txt
==============================================================================
--- (empty file)
+++ gocept.cxoracle/trunk/src/gocept/cxoracle/README.txt	Fri Aug 29 13:52:50
2008
(at)(at) -0,0 +1,172 (at)(at)
+gocept.cxoracle - A zc.buildout recipe to easily get cx_Oracle running
+======================================================================
+
+The main purpose is to set up the environment required to build a cx_Oracle
egg
+and then provide a loader which sets environment variables required to load
the
+shared libraries.
+
+Oracle doesn't allow the libraries required to be distributed freely. That
+means that they must be downloaded by the user or developer from
+http://www.oracle.com/technology/software/tech/oci/instantclient/index.html
+
+Two archives are required per architecture / operating system:
+
+1. Instant client basic lite
+2. The SDK
+
+>>> import os.path
+>>> basiclite = os.path.join(
+...     os.path.dirname(__file__), 'basiclite-linux.zip')
+>>> sdk = os.path.join(
+...     os.path.dirname(__file__), 'sdk-linux.zip')
+
+Both files have to be configured in the buildout:
+
+>>> write("buildout.cfg", """
+... [buildout]
+... parts = python-oracle
+... python = python-oracle
+...
+... [python-oracle]
+... recipe = gocept.cxoracle
+... instant-client = %(basiclite)s
+... instant-sdk = %(sdk)s
+...
+... """ % {'basiclite': basiclite,
+...        'sdk': sdk}
+... )
+
+>>> print system(buildout),
+Installing python-oracle.
+
+We have an oracle-home now in the parts. It contains the contents of both
+archives mixed together *plus* a symlink for ``libclntsh.so ->
+libclntsh.so.10.1``:
+
+>>> ls('parts', 'python-oracle')
+-  BASIC_LITE_README
+-  classes12.jar
+-  genezi
+-  libclntsh.so
+-  libclntsh.so.10.1
+-  libnnz10.so
+-  libocci.so.10.1
+-  libociicus.so
+-  libocijdbc10.so
+-  ojdbc14.jar
+d  sdk
+
+>>> import os
+>>> os.path.islink(os.path.join('parts', 'python-oracle',
'libclntsh.so'))
+True
+>>> os.readlink(os.path.join('parts', 'python-oracle',
'libclntsh.so'))
+'.../parts/python-oracle/libclntsh.so.10.1'
+
+
+In the bin directory there is a wrapper which sets the ``LD_LIBRARY_PATH`` (or
+``DYLD_LIBRARY_PATH`` on darwin) and the ``ORACLE_HOME`` environment
variables:
+
+>>> ls('bin')
+-  buildout
+-  python-oracle
+
+The wrapper can be called like any python interpreter:
+
+>>> system(os.path.join('bin', 'python-oracle') +
+...     """ -c "import os; print os.environ['ORACLE_HOME']" """)
+'.../parts/python-oracle\n'
+
+>>> script = '''\
+... import os
+... import sys
+... if sys.platform == 'darwin':
+...     varname = 'DYLD_LIBRARY_PATH'
+... else:
+...     varname = 'LD_LIBRARY_PATH'
+... print os.environ[varname]
+... '''
+
+>>> system(os.path.join('bin', 'python-oracle') +
+...     """ -c "%s" """ % script)
+'.../parts/python-oracle\n'
+
+
+On Mac OS X / Darwin the libraries are not called .so but .dylib. The recipe
+handles this correctly:
+
+
+>>> basiclite = os.path.join(
+...     os.path.dirname(__file__), 'basiclite-darwin.zip')
+>>> sdk = os.path.join(
+...     os.path.dirname(__file__), 'sdk-darwin.zip')
+
+Both files have to be configured in the buildout:
+
+>>> write("buildout.cfg", """
+... [buildout]
+... parts = python-oracle
+... python = python-oracle
+...
+... [python-oracle]
+... recipe = gocept.cxoracle
+... instant-client = %(basiclite)s
+... instant-sdk = %(sdk)s
+...
+... """ % {'basiclite': basiclite,
+...        'sdk': sdk}
+... )
+
+>>> print system(buildout),
+Uninstalling python-oracle.
+Installing python-oracle.
+
+The archives are merged as for linux, the a symlink is  ``libclntsh.dylib
->
+libclntsh.dylib.10.1`` this time:
+
+>>> ls('parts', 'python-oracle')
+    -  BASIC_LITE_README
+    -  classes12.jar
+    -  genezi
+    -  libclntsh.dylib
+    -  libclntsh.dylib.10.1
+    -  libnnz10.dylib
+    -  libocci.dylib.10.1
+    -  libociicus.dylib
+    -  libocijdbc10.dylib
+    -  libocijdbc10.jnilib
+    -  ojdbc14.jar
+    d  sdk
+
+
+>>> import os
+>>> os.path.islink(os.path.join('parts', 'python-oracle',
'libclntsh.dylib'))
+True
+>>> os.readlink(os.path.join('parts', 'python-oracle',
'libclntsh.dylib'))
+'.../parts/python-oracle/libclntsh.dylib.10.1'
+
+When an archive cannot be extracted we'll get an informative error:
+
+>>> write("buildout.cfg", """
+... [buildout]
+... parts = python-oracle
+... python = python-oracle
+...
+... [python-oracle]
+... recipe = gocept.cxoracle
+... instant-client = /does/not/exist
+... instant-sdk = %(sdk)s
+...
+... """ % {'sdk': sdk}
+... )
+
+>>> print system(buildout),
+Uninstalling python-oracle.
+Installing python-oracle.
+While:
+  Installing python-oracle.
+<BLANKLINE>
+An internal error occured due to a bug in either zc.buildout or in a
+recipe being used:
+Traceback (most recent call last):
+    ...
+Exception: Extraction of file '/does/not/exist' failed.

Added: gocept.cxoracle/trunk/src/gocept/cxoracle/basiclite-darwin.zip
==============================================================================
Binary file. No diff available.

Added: gocept.cxoracle/trunk/src/gocept/cxoracle/basiclite-linux.zip
==============================================================================
Binary file. No diff available.

Added: gocept.cxoracle/trunk/src/gocept/cxoracle/sdk-darwin.zip
==============================================================================
Binary file. No diff available.

Added: gocept.cxoracle/trunk/src/gocept/cxoracle/sdk-linux.zip
==============================================================================
Binary file. No diff available.

Added: gocept.cxoracle/trunk/src/gocept/cxoracle/tests.py
==============================================================================
--- (empty file)
+++ gocept.cxoracle/trunk/src/gocept/cxoracle/tests.py	Fri Aug 29 13:52:50 2008
(at)(at) -0,0 +1,28 (at)(at)
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt
+
+import unittest
+
+import zope.testing.doctest
+
+import zc.buildout.testing
+
+
+flags = (zope.testing.doctest.NORMALIZE_WHITESPACE |
+         zope.testing.doctest.ELLIPSIS)
+
+
+def setUp(test):
+    zc.buildout.testing.buildoutSetUp(test)
+    zc.buildout.testing.install_develop("gocept.cxoracle", test)
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(zope.testing.doctest.DocFileSuite(
+        "README.txt",
+        setUp=setUp,
+        tearDown=zc.buildout.testing.buildoutTearDown,
+        package="gocept.cxoracle",
+        optionflags=flags))
+    return suite

MailBoxer