merge 3.25 heads 3.25
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 30 Mar 2017 10:37:55 +0200
branch3.25
changeset 12123 1cf37b28aa23
parent 12122 92aef8c6e7c8 (diff)
parent 12114 40446d4e1ee2 (current diff)
child 12124 392d6d599286
merge 3.25 heads
cubicweb/hooks/logstats.py
--- a/.hgignore	Wed Mar 29 13:29:41 2017 +0200
+++ b/.hgignore	Thu Mar 30 10:37:55 2017 +0200
@@ -13,6 +13,7 @@
 ^doc/book/en/apidoc$
 \.old$
 \.pybuild
+cubicweb/server/test/data/slapd.conf
 debian/python-cubicweb
 debian/*.log
 debian/*.substvars
--- a/cubicweb/cwconfig.py	Wed Mar 29 13:29:41 2017 +0200
+++ b/cubicweb/cwconfig.py	Thu Mar 30 10:37:55 2017 +0200
@@ -511,8 +511,11 @@
 
     @classmethod
     def available_cubes(cls):
+        """Return a list of available cube names.
+
+        For cube as package, name is equal to python package's name.
+        """
         cubes = set()
-        prefix = 'cubicweb_'
         for entry_point in pkg_resources.iter_entry_points(
                 group='cubicweb.cubes', name=None):
             try:
@@ -521,11 +524,11 @@
                 continue
             else:
                 modname = module.__name__
-                if not modname.startswith(prefix):
+                if not modname.startswith('cubicweb_'):
                     cls.warning('entry point %s does not appear to be a cube',
                                 entry_point)
                     continue
-                cubes.add(modname[len(prefix):])
+                cubes.add(modname)
         # Legacy cubes.
         for directory in cls.cubes_search_path():
             if not exists(directory):
--- a/cubicweb/cwctl.py	Wed Mar 29 13:29:41 2017 +0200
+++ b/cubicweb/cwctl.py	Thu Mar 30 10:37:55 2017 +0200
@@ -89,6 +89,18 @@
     return modes
 
 
+def available_cube_names(cwcfg):
+    """Return a list of available cube names, with 'cubicweb_' prefix dropped.
+    """
+    def drop_prefix(cube):
+        prefix = 'cubicweb_'
+        if cube.startswith(prefix):
+            cube = cube[len(prefix):]
+        return cube
+
+    return [drop_prefix(cube) for cube in cwcfg.available_cubes()]
+
+
 class InstanceCommand(Command):
     """base class for command taking 0 to n instance id as arguments
     (0 meaning all registered instances)
@@ -220,14 +232,15 @@
             cfgpb = ConfigurationProblem(cwcfg)
             try:
                 cubesdir = pathsep.join(cwcfg.cubes_search_path())
-                namesize = max(len(x) for x in cwcfg.available_cubes())
+                cube_names = available_cube_names(cwcfg)
+                namesize = max(len(x) for x in cube_names)
             except ConfigurationError as ex:
                 print('No cubes available:', ex)
             except ValueError:
                 print('No cubes available in %s' % cubesdir)
             else:
                 print('Available cubes (%s):' % cubesdir)
-                for cube in cwcfg.available_cubes():
+                for cube in cube_names:
                     try:
                         tinfo = cwcfg.cube_pkginfo(cube)
                         tversion = tinfo.version
@@ -360,7 +373,7 @@
         except ConfigurationError as ex:
             print(ex)
             print('\navailable cubes:', end=' ')
-            print(', '.join(cwcfg.available_cubes()))
+            print(', '.join(available_cube_names(cwcfg)))
             return
         # create the registry directory for this instance
         print('\n'+underline_title('Creating the instance %s' % appid))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cubicweb/test/data/libpython/cubicweb_mycube/ccplugin.py	Thu Mar 30 10:37:55 2017 +0200
@@ -0,0 +1,1 @@
+# simply there to test ccplugin module autoloading
--- a/cubicweb/test/unittest_cwconfig.py	Wed Mar 29 13:29:41 2017 +0200
+++ b/cubicweb/test/unittest_cwconfig.py	Thu Mar 30 10:37:55 2017 +0200
@@ -23,7 +23,7 @@
 import sys
 import os
 import pkgutil
-from os.path import dirname, join, abspath
+from os.path import dirname, join
 from pkg_resources import EntryPoint, Distribution
 import unittest
 
@@ -31,7 +31,6 @@
 from six import PY3
 
 from logilab.common.modutils import cleanup_sys_modules
-from logilab.common.changelog import Version
 
 from cubicweb.devtools import ApptestConfiguration
 from cubicweb.devtools.testlib import BaseTestCase, TemporaryDirectory
@@ -43,9 +42,9 @@
     parts = path.split(os.sep)
     for i, part in reversed(tuple(enumerate(parts))):
         if part.startswith('cubicweb_'):
-            return os.sep.join([part[len('cubicweb_'):]] + parts[i+1:])
+            return os.sep.join([part[len('cubicweb_'):]] + parts[i + 1:])
         if part.startswith('cubicweb') or part == 'legacy_cubes':
-            return os.sep.join(parts[i+1:])
+            return os.sep.join(parts[i + 1:])
     raise Exception('duh? %s' % path)
 
 
@@ -93,6 +92,21 @@
             del sys.modules[module]
 
 
+def iter_entry_points(group, name):
+    """Mock pkg_resources.iter_entry_points to yield EntryPoint from
+    packages found in test/data/libpython even though these are not
+    installed.
+    """
+    libpython = CubicWebConfigurationTC.datapath('libpython')
+    prefix = 'cubicweb_'
+    for pkgname in os.listdir(libpython):
+        if not pkgname.startswith(prefix):
+            continue
+        location = join(libpython, pkgname)
+        yield EntryPoint(pkgname[len(prefix):], pkgname,
+                         dist=Distribution(location))
+
+
 class CubicWebConfigurationTC(BaseTestCase):
 
     @classmethod
@@ -109,27 +123,14 @@
 
     def tearDown(self):
         ApptestConfiguration.CUBES_PATH = []
-
-    def iter_entry_points(group, name):
-        """Mock pkg_resources.iter_entry_points to yield EntryPoint from
-        packages found in test/data/libpython even though these are not
-        installed.
-        """
-        libpython = CubicWebConfigurationTC.datapath('libpython')
-        prefix = 'cubicweb_'
-        for pkgname in os.listdir(libpython):
-            if not pkgname.startswith(prefix):
-                continue
-            location = join(libpython, pkgname)
-            yield EntryPoint(pkgname[len(prefix):], pkgname,
-                             dist=Distribution(location))
+        cleanup_sys_modules([self.datapath('libpython')])
 
     @patch('pkg_resources.iter_entry_points', side_effect=iter_entry_points)
     def test_available_cubes(self, mock_iter_entry_points):
         expected_cubes = [
-            'card', 'comment', 'email', 'file',
-            'forge', 'localperms',
-            'mycube', 'tag',
+            'card', 'comment', 'cubicweb_comment', 'cubicweb_email', 'file',
+            'cubicweb_file', 'cubicweb_forge', 'localperms',
+            'cubicweb_mycube', 'tag',
         ]
         self._test_available_cubes(expected_cubes)
         mock_iter_entry_points.assert_called_once_with(
@@ -142,17 +143,17 @@
         # forge depends on email and file and comment
         # email depends on file
         self.assertEqual(self.config.reorder_cubes(['file', 'email', 'forge']),
-                          ('forge', 'email', 'file'))
+                         ('forge', 'email', 'file'))
         self.assertEqual(self.config.reorder_cubes(['email', 'file', 'forge']),
-                          ('forge', 'email', 'file'))
+                         ('forge', 'email', 'file'))
         self.assertEqual(self.config.reorder_cubes(['email', 'forge', 'file']),
-                          ('forge', 'email', 'file'))
+                         ('forge', 'email', 'file'))
         self.assertEqual(self.config.reorder_cubes(['file', 'forge', 'email']),
-                          ('forge', 'email', 'file'))
+                         ('forge', 'email', 'file'))
         self.assertEqual(self.config.reorder_cubes(['forge', 'file', 'email']),
-                          ('forge', 'email', 'file'))
+                         ('forge', 'email', 'file'))
         self.assertEqual(self.config.reorder_cubes(('forge', 'email', 'file')),
-                          ('forge', 'email', 'file'))
+                         ('forge', 'email', 'file'))
 
     def test_reorder_cubes_recommends(self):
         from cubicweb_comment import __pkginfo__ as comment_pkginfo
@@ -164,20 +165,19 @@
             # email recommends comment
             # comment recommends file
             self.assertEqual(self.config.reorder_cubes(('forge', 'email', 'file', 'comment')),
-                              ('forge', 'email', 'comment', 'file'))
+                             ('forge', 'email', 'comment', 'file'))
             self.assertEqual(self.config.reorder_cubes(('forge', 'email', 'comment', 'file')),
-                              ('forge', 'email', 'comment', 'file'))
+                             ('forge', 'email', 'comment', 'file'))
             self.assertEqual(self.config.reorder_cubes(('forge', 'comment', 'email', 'file')),
-                              ('forge', 'email', 'comment', 'file'))
+                             ('forge', 'email', 'comment', 'file'))
             self.assertEqual(self.config.reorder_cubes(('comment', 'forge', 'email', 'file')),
-                              ('forge', 'email', 'comment', 'file'))
+                             ('forge', 'email', 'comment', 'file'))
         finally:
             comment_pkginfo.__recommends_cubes__ = {}
 
     def test_expand_cubes(self):
         self.assertEqual(self.config.expand_cubes(('email', 'comment')),
-                          ['email', 'comment', 'file'])
-
+                         ['email', 'comment', 'file'])
 
     def test_init_cubes_ignore_pyramid_cube(self):
         warning_msg = 'cubicweb-pyramid got integrated into CubicWeb'
@@ -186,6 +186,15 @@
         self.assertIn(warning_msg, cm.output[0])
         self.assertNotIn('pyramid', self.config._cubes)
 
+    @patch('pkg_resources.iter_entry_points', side_effect=iter_entry_points)
+    def test_ccplugin_modname(self, mock_iter_entry_points):
+        self.config.load_cwctl_plugins()
+        mock_iter_entry_points.assert_called_once_with(
+            group='cubicweb.cubes', name=None)
+        self.assertNotIn('cubes.mycube.ccplugin', sys.modules, sorted(sys.modules))
+        self.assertIn('cubicweb_mycube.ccplugin', sys.modules, sorted(sys.modules))
+
+
 class CubicWebConfigurationWithLegacyCubesTC(CubicWebConfigurationTC):
 
     @classmethod
@@ -225,13 +234,13 @@
         self.assertNotEqual(dirname(email.__file__), self.config.CUBES_DIR)
         self.config.__class__.CUBES_PATH = [self.custom_cubes_dir]
         self.assertEqual(self.config.cubes_search_path(),
-                          [self.custom_cubes_dir, self.config.CUBES_DIR])
+                         [self.custom_cubes_dir, self.config.CUBES_DIR])
         self.config.__class__.CUBES_PATH = [self.custom_cubes_dir,
                                             self.config.CUBES_DIR, 'unexistant']
         # filter out unexistant and duplicates
         self.assertEqual(self.config.cubes_search_path(),
-                          [self.custom_cubes_dir,
-                           self.config.CUBES_DIR])
+                         [self.custom_cubes_dir,
+                          self.config.CUBES_DIR])
         self.assertIn('mycube', self.config.available_cubes())
         # test cubes python path
         self.config.adjust_sys_path()
@@ -273,7 +282,12 @@
             self.assertEqual(self.config['allow-email-login'], result)
         finally:
             del os.environ['CW_ALLOW_EMAIL_LOGIN']
-            
+
+    def test_ccplugin_modname(self):
+        self.config.load_cwctl_plugins()
+        self.assertIn('cubes.mycube.ccplugin', sys.modules, sorted(sys.modules))
+        self.assertNotIn('cubicweb_mycube.ccplugin', sys.modules, sorted(sys.modules))
+
 
 class FindPrefixTC(unittest.TestCase):
 
@@ -350,7 +364,7 @@
     def test_upper_candidate_prefix(self):
         with TemporaryDirectory() as prefix:
             self.make_dirs(prefix, 'share', 'cubicweb')
-            self.make_dirs(prefix, 'bell', 'bob',  'share', 'cubicweb')
+            self.make_dirs(prefix, 'bell', 'bob', 'share', 'cubicweb')
             file_path = self.make_file(prefix, 'bell', 'toto.py')
             self.assertEqual(_find_prefix(file_path), prefix)
 
--- a/cubicweb/test/unittest_cwctl.py	Wed Mar 29 13:29:41 2017 +0200
+++ b/cubicweb/test/unittest_cwctl.py	Thu Mar 30 10:37:55 2017 +0200
@@ -23,14 +23,20 @@
 
 from six import PY2
 
-from cubicweb.cwconfig import CubicWebConfiguration
+from mock import patch
+
 from cubicweb.cwctl import ListCommand
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.server.migractions import ServerMigrationHelper
 
+import unittest_cwconfig
+
 
 class CubicWebCtlTC(unittest.TestCase):
 
+    setUpClass = unittest_cwconfig.CubicWebConfigurationTC.setUpClass
+    tearDownClass = unittest_cwconfig.CubicWebConfigurationTC.tearDownClass
+
     def setUp(self):
         self.stream = BytesIO() if PY2 else StringIO()
         sys.stdout = self.stream
@@ -38,8 +44,12 @@
     def tearDown(self):
         sys.stdout = sys.__stdout__
 
-    def test_list(self):
+    @patch('pkg_resources.iter_entry_points', side_effect=unittest_cwconfig.iter_entry_points)
+    def test_list(self, mock_iter_entry_points):
         ListCommand(None).run([])
+        self.assertNotIn('cubicweb_', self.stream.getvalue())
+        mock_iter_entry_points.assert_called_once_with(
+            group='cubicweb.cubes', name=None)
 
     def test_list_configurations(self):
         ListCommand(None).run(['configurations'])
@@ -58,10 +68,11 @@
                                         interactive=False,
                                         # hack so it don't try to load fs schema
                                         schema=1)
-            scripts = {'script1.py': list(),
-                       'script2.py': ['-v'],
-                       'script3.py': ['-vd', '-f', 'FILE.TXT'],
-                      }
+            scripts = {
+                'script1.py': list(),
+                'script2.py': ['-v'],
+                'script3.py': ['-vd', '-f', 'FILE.TXT'],
+            }
             mih.cmd_process_script(join(self.datadir, 'scripts', 'script1.py'),
                                    funcname=None)
             for script, args in scripts.items():
--- a/flake8-ok-files.txt	Wed Mar 29 13:29:41 2017 +0200
+++ b/flake8-ok-files.txt	Thu Mar 30 10:37:55 2017 +0200
@@ -84,6 +84,8 @@
 cubicweb/test/data/server_migration/bootstrapmigration_repository.py
 cubicweb/test/data/views.py
 cubicweb/test/unittest_binary.py
+cubicweb/test/unittest_cwconfig.py
+cubicweb/test/unittest_cwctl.py
 cubicweb/test/unittest_mail.py
 cubicweb/test/unittest_repoapi.py
 cubicweb/test/unittest_req.py