bloodhound-mq / t115 / t115_r1423431_product_envs_testing.diff

The branch 't115_product_env' does not exist.
# HG changeset patch
# Parent 3292eb0a088d03616efea3545ab8737cb72d0098
BH Theme #115 : Test cases for product environments

diff -r 3292eb0a088d bloodhound_multiproduct/tests/config.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bloodhound_multiproduct/tests/config.py	Sun Jan 06 22:52:04 2013 -0500
@@ -0,0 +1,94 @@
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+"""Tests for Apache(TM) Bloodhound's product configuration objects"""
+
+from ConfigParser import ConfigParser
+import os.path
+from StringIO import StringIO
+import unittest
+
+from trac.config import Option, _to_utf8
+from trac.tests.config import ConfigurationTestCase
+
+from multiproduct.api import MultiProductSystem
+from multiproduct.config import Configuration
+from multiproduct.model import Product, ProductSetting
+from tests.env import MultiproductTestCase
+
+class ProductConfigTestCase(ConfigurationTestCase, MultiproductTestCase):
+    r"""Test cases for Trac configuration objects rewritten for product 
+    scope.
+    """
+    def setUp(self):
+        r"""Replace Trac environment with product environment
+        """
+        self.env = self._setup_test_env()
+
+        # Dummy config file, a sibling of trac.ini
+        self.filename = os.path.join(self.env.path, 'conf', 'product.ini')
+
+        self._upgrade_mp(self.env)
+        self._setup_test_log(self.env)
+        self._load_product_from_data(self.env, self.default_product)
+        self._orig_registry = Option.registry
+        Option.registry = {}
+
+    def tearDown(self):
+        Option.registry = self._orig_registry
+        self.env = None
+
+    def _read(self, parents=None, product=None):
+        r"""Override superclass method by returning product-aware configuration
+        object retrieving settings from the database. Such objects will replace
+        instances of `trac.config.Configuration` used in inherited test cases.
+        """
+        if product is None:
+            product = self.default_product
+        return Configuration(self.env, product, parents)
+
+    def _write(self, lines, product=None):
+        r"""Override superclass method by writing configuration values
+        to the database rather than ini file in the filesystem.
+        """
+        if product is None:
+            product = self.default_product
+        fp = StringIO(('\n'.join(lines + [''])).encode('utf-8'))
+        parser = ConfigParser()
+        parser.readfp(fp, 'bh-product-test')
+        with self.env.db_transaction as db:
+            # Delete existing setting for target product , if any
+            for setting in ProductSetting.select(self.env, db, 
+                    {'product' : product}):
+                setting.delete()
+            # Insert new options
+            for section in parser.sections():
+                option_key = dict(section=_to_utf8(section), product=product)
+                for option, value in parser.items(section):
+                    option_key.update(dict(option=_to_utf8(option)))
+                    setting = ProductSetting(self.env)
+                    setting._data.update(option_key)
+                    setting.value = _to_utf8(value)
+                    setting.insert()
+
+def suite():
+    return unittest.makeSuite(ProductConfigTestCase,'test')
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='suite')
+
diff -r 3292eb0a088d bloodhound_multiproduct/tests/env.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bloodhound_multiproduct/tests/env.py	Sun Jan 06 22:52:04 2013 -0500
@@ -0,0 +1,139 @@
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+"""Tests for Apache(TM) Bloodhound's product environments"""
+
+import os.path
+import shutil
+import tempfile
+import unittest
+
+from trac.test import EnvironmentStub
+from trac.tests.env import EnvironmentTestCase
+
+from multiproduct.api import MultiProductSystem
+from multiproduct.env import ProductEnvironment
+from multiproduct.model import Product
+
+# FIXME: Subclass TestCase explictly ?
+class MultiproductTestCase(unittest.TestCase):
+    r"""Mixin providing access to multi-product testing extensions.
+
+    This class serves to the purpose of upgrading existing Trac test cases
+    with multi-product super-powers while still providing the foundations
+    to create product-specific subclasses.
+    """
+
+    # Product data
+
+    default_product = 'tp1'
+    MAX_TEST_PRODUCT = 3
+
+    PRODUCT_DATA = dict(
+            ['tp' + str(i), {'prefix':'tp' + str(i),
+                             'name' : 'test product ' + str(i),
+                             'description' : 'desc for tp' + str(i)}]
+            for i in xrange(1, MAX_TEST_PRODUCT)
+        )
+
+    # Test setup
+
+    def _setup_test_env(self, create_folder=True, path=None):
+        r"""Prepare a new test environment . 
+        
+        Optionally set its path to a meaningful location (temp folder
+        if `path` is `None`).
+        """
+        self.env = env = EnvironmentStub(enable=['trac.*', 'multiproduct.*'])
+        if create_folder:
+            if path is None:
+                env.path = tempfile.mkdtemp('bh-product-tempenv')
+            else:
+                env.path = path
+        return env
+
+    def _setup_test_log(self, env):
+        r"""Ensure test product with prefix is loaded
+        """
+        logdir = tempfile.gettempdir()
+        logpath = os.path.join(logdir, 'trac-testing.log')
+        config = env.config
+        config.set('logging', 'log_file', logpath)
+        config.set('logging', 'log_type', 'file')
+        config.set('logging', 'log_level', 'DEBUG')
+        config.save()
+        env.setup_log()
+        env.log.info('%s test case: %s %s',
+                '-' * 10, self.id(), '-' * 10)
+
+    def _load_product_from_data(self, env, prefix):
+        r"""Ensure test product with prefix is loaded
+        """
+        # TODO: Use fixtures implemented in #314
+        product_data = self.PRODUCT_DATA[prefix]
+        product = Product(env)
+        product._data.update(product_data)
+        product.insert()
+
+    def _upgrade_mp(self, env):
+        r"""Apply multi product upgrades
+        """
+        self.mpsystem = MultiProductSystem(env)
+        try:
+            self.mpsystem.upgrade_environment(env.db_transaction)
+        except OperationalError:
+            # table remains but database version is deleted
+            pass
+
+class ProductEnvTestCase(EnvironmentTestCase, MultiproductTestCase):
+    r"""Test cases for Trac environments rewritten for product environments
+    """
+
+    # Test setup
+
+    def setUp(self):
+        r"""Replace Trac environment with product environment
+        """
+        EnvironmentTestCase.setUp(self)
+        try:
+            self.global_env = self.env
+            self._setup_test_log(self.global_env)
+            self._upgrade_mp(self.global_env)
+            self._load_product_from_data(self.global_env, self.default_product)
+            try:
+                self.env = ProductEnvironment(self.global_env, self.default_product)
+            except :
+                # All tests should fail if anything goes wrong
+                self.global_env.log.exception('Error creating product environment')
+                self.env = None
+        except:
+            shutil.rmtree(self.env.path)
+            raise
+
+    def tearDown(self):
+        # Discard product environment
+        self.env = self.global_env
+
+        EnvironmentTestCase.tearDown(self)
+
+def suite():
+    return unittest.makeSuite(ProductEnvTestCase,'test')
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='suite')
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.