]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Use pbr entry_points to setup the cinder scripts
authorThang Pham <thang.g.pham@gmail.com>
Fri, 20 Jun 2014 04:30:36 +0000 (00:30 -0400)
committerThang Pham <thang.g.pham@gmail.com>
Mon, 8 Dec 2014 14:53:22 +0000 (09:53 -0500)
The following patch changes how cinder scripts are
installed and unit tested. This patch moves all the
cinder scripts from bin into cinder/cmd and creates
entry_points for those scripts in setup.cfg. When
cinder is installed, these scripts will be installed
under /usr/local/bin by pbr.

DocImpact: 'host' config option for multiple-storage backends
in cinder.conf is renamed to 'backend_host' in order to avoid
a naming conflict with the 'host' to locate redis
Change-Id: If82cf0c58d765bf79dbf721ca95c10a468940cab
Implements: blueprint unit-test-cases-for-cinder-scripts

14 files changed:
cinder/cmd/__init__.py [new file with mode: 0644]
cinder/cmd/all.py [moved from bin/cinder-all with 87% similarity]
cinder/cmd/api.py [moved from bin/cinder-api with 82% similarity]
cinder/cmd/backup.py [moved from bin/cinder-backup with 74% similarity]
cinder/cmd/manage.py [moved from bin/cinder-manage with 97% similarity]
cinder/cmd/rtstool.py [moved from bin/cinder-rtstool with 99% similarity]
cinder/cmd/scheduler.py [moved from bin/cinder-scheduler with 75% similarity]
cinder/cmd/volume.py [moved from bin/cinder-volume with 75% similarity]
cinder/cmd/volume_usage_audit.py [moved from bin/cinder-volume-usage-audit with 95% similarity]
cinder/test.py
cinder/tests/test_cmd.py [new file with mode: 0755]
run_tests.sh
setup.cfg
tox.ini

diff --git a/cinder/cmd/__init__.py b/cinder/cmd/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
similarity index 87%
rename from bin/cinder-all
rename to cinder/cmd/all.py
index 9bf880c7c3d7b9b319448974231773e1c100b420..de21938e201756ec4187134c9d059e84ca6c8364 100755 (executable)
@@ -25,12 +25,9 @@ continue attempting to launch the rest of the services.
 
 """
 
-
 import eventlet
-
 eventlet.monkey_patch()
 
-import os
 import sys
 import warnings
 
@@ -38,12 +35,6 @@ warnings.simplefilter('once', DeprecationWarning)
 
 from oslo.config import cfg
 
-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
-                                   os.pardir,
-                                   os.pardir))
-if os.path.exists(os.path.join(possible_topdir, "cinder", "__init__.py")):
-    sys.path.insert(0, possible_topdir)
-
 from cinder import i18n
 i18n.enable_lazy()
 
@@ -59,7 +50,7 @@ from cinder import version
 CONF = cfg.CONF
 
 
-if __name__ == '__main__':
+def main():
     CONF(sys.argv[1:], project='cinder',
          version=version.version_string())
     logging.setup("cinder")
similarity index 82%
rename from bin/cinder-api
rename to cinder/cmd/api.py
index dca7541765f60af12006e521b49dee4ae497c8a6..f04b1b9ca0ed0fb7f5f84906386dbe0cacd5b172 100755 (executable)
@@ -20,7 +20,6 @@
 import eventlet
 eventlet.monkey_patch()
 
-import os
 import sys
 import warnings
 
@@ -28,12 +27,6 @@ warnings.simplefilter('once', DeprecationWarning)
 
 from oslo.config import cfg
 
-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
-                                   os.pardir,
-                                   os.pardir))
-if os.path.exists(os.path.join(possible_topdir, "cinder", "__init__.py")):
-    sys.path.insert(0, possible_topdir)
-
 from cinder import i18n
 i18n.enable_lazy()
 
@@ -49,7 +42,7 @@ from cinder import version
 CONF = cfg.CONF
 
 
-if __name__ == '__main__':
+def main():
     CONF(sys.argv[1:], project='cinder',
          version=version.version_string())
     logging.setup("cinder")
similarity index 74%
rename from bin/cinder-backup
rename to cinder/cmd/backup.py
index 1c502fa47f076be192fea73ada35f05df802bd64..8fd8f25be25ac3cccc712e5a4d140efb76905114 100755 (executable)
@@ -17,8 +17,6 @@
 
 """Starter script for Cinder Volume Backup."""
 
-
-import os
 import sys
 import warnings
 
@@ -29,14 +27,6 @@ from oslo.config import cfg
 
 eventlet.monkey_patch()
 
-# If ../cinder/__init__.py exists, add ../ to Python search path, so that
-# it will override what happens to be installed in /usr/(local/)lib/python...
-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
-                                   os.pardir,
-                                   os.pardir))
-if os.path.exists(os.path.join(possible_topdir, 'cinder', '__init__.py')):
-    sys.path.insert(0, possible_topdir)
-
 from cinder import i18n
 i18n.enable_lazy()
 
@@ -51,7 +41,7 @@ from cinder import version
 CONF = cfg.CONF
 
 
-if __name__ == '__main__':
+def main():
     CONF(sys.argv[1:], project='cinder',
          version=version.version_string())
     logging.setup("cinder")
similarity index 97%
rename from bin/cinder-manage
rename to cinder/cmd/manage.py
index 90d8070605c2e3474f36744d6198e17920b56dd1..dcc1ec57b568a97ba775cda167ca1b75388b1aa5 100755 (executable)
@@ -64,14 +64,6 @@ warnings.simplefilter('once', DeprecationWarning)
 from oslo.config import cfg
 from oslo import messaging
 
-# If ../cinder/__init__.py exists, add ../ to Python search path, so that
-# it will override what happens to be installed in /usr/(local/)lib/python...
-POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
-                                   os.pardir,
-                                   os.pardir))
-if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'cinder', '__init__.py')):
-    sys.path.insert(0, POSSIBLE_TOPDIR)
-
 from cinder import i18n
 i18n.enable_lazy()
 
@@ -546,6 +538,3 @@ def main():
     fn = CONF.category.action_fn
     fn_args = fetch_func_args(fn)
     fn(*fn_args)
-
-if __name__ == '__main__':
-    main()
similarity index 99%
rename from bin/cinder-rtstool
rename to cinder/cmd/rtstool.py
index 6d6b7f967d48fc5d771ee9228a5bde35988a60e9..76c4d11b376368440e80bbd38e9c23501f91e633 100755 (executable)
@@ -231,6 +231,3 @@ def main(argv=None):
         usage()
 
     return 0
-
-if __name__ == '__main__':
-    sys.exit(main())
similarity index 75%
rename from bin/cinder-scheduler
rename to cinder/cmd/scheduler.py
index 9c5a8af0aab1885b1256ad517dedd04e8c9521cf..24d9bf7cdf10f17ac1ab61fd863491fd0ab79947 100755 (executable)
 
 """Starter script for Cinder Scheduler."""
 
-
 import eventlet
-
 eventlet.monkey_patch()
 
-import os
 import sys
 import warnings
 
@@ -30,14 +27,6 @@ warnings.simplefilter('once', DeprecationWarning)
 
 from oslo.config import cfg
 
-# If ../cinder/__init__.py exists, add ../ to Python search path, so that
-# it will override what happens to be installed in /usr/(local/)lib/python...
-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
-                                   os.pardir,
-                                   os.pardir))
-if os.path.exists(os.path.join(possible_topdir, 'cinder', '__init__.py')):
-    sys.path.insert(0, possible_topdir)
-
 from cinder import i18n
 i18n.enable_lazy()
 
@@ -52,7 +41,7 @@ from cinder import version
 CONF = cfg.CONF
 
 
-if __name__ == '__main__':
+def main():
     CONF(sys.argv[1:], project='cinder',
          version=version.version_string())
     logging.setup("cinder")
similarity index 75%
rename from bin/cinder-volume
rename to cinder/cmd/volume.py
index 507a92d110c9abf60c83e4f3a52edd139cbe989c..2b3a4dbcdbdb754cc5edeb530b8d27571c36d69a 100755 (executable)
@@ -35,14 +35,6 @@ warnings.simplefilter('once', DeprecationWarning)
 
 from oslo.config import cfg
 
-# If ../cinder/__init__.py exists, add ../ to Python search path, so that
-# it will override what happens to be installed in /usr/(local/)lib/python...
-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
-                                   os.pardir,
-                                   os.pardir))
-if os.path.exists(os.path.join(possible_topdir, 'cinder', '__init__.py')):
-    sys.path.insert(0, possible_topdir)
-
 from cinder import i18n
 i18n.enable_lazy()
 
@@ -54,12 +46,14 @@ from cinder import utils
 from cinder import version
 
 
-host_opt = cfg.StrOpt('host',
-                      help='Backend override of host value.')
+deprecated_host_opt = cfg.DeprecatedOpt('host')
+host_opt = cfg.StrOpt('backend_host', help='Backend override of host value.',
+                      deprecated_opts=[deprecated_host_opt])
+cfg.CONF.register_cli_opt(host_opt)
 CONF = cfg.CONF
 
 
-if __name__ == '__main__':
+def main():
     CONF(sys.argv[1:], project='cinder',
          version=version.version_string())
     logging.setup("cinder")
@@ -67,8 +61,8 @@ if __name__ == '__main__':
     launcher = service.get_launcher()
     if CONF.enabled_backends:
         for backend in CONF.enabled_backends:
-            CONF.register_opts([host_opt], group=backend)
-            backend_host = getattr(CONF, backend).host
+            CONF.register_opt(host_opt, group=backend)
+            backend_host = getattr(CONF, backend).backend_host
             host = "%s@%s" % (backend_host or CONF.host, backend)
             server = service.Service.create(host=host,
                                             service_name=backend,
similarity index 95%
rename from bin/cinder-volume-usage-audit
rename to cinder/cmd/volume_usage_audit.py
index de455afc2e3fbc50b63d69271e247fd248ddd1cd..69391bf5a1bdd83ae5d8a89b9d712a2ba06c6608 100755 (executable)
@@ -35,7 +35,6 @@
 from __future__ import print_function
 
 from datetime import datetime
-import os
 import sys
 import traceback
 import warnings
@@ -44,14 +43,6 @@ warnings.simplefilter('once', DeprecationWarning)
 
 from oslo.config import cfg
 
-# If ../cinder/__init__.py exists, add ../ to Python search path, so that
-# it will override what happens to be installed in /usr/(local/)lib/python...
-POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
-                                   os.pardir,
-                                   os.pardir))
-if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'cinder', '__init__.py')):
-    sys.path.insert(0, POSSIBLE_TOPDIR)
-
 from cinder import i18n
 i18n.enable_lazy()
 from cinder import context
@@ -84,7 +75,7 @@ script_opts = [
 CONF.register_cli_opts(script_opts)
 
 
-if __name__ == '__main__':
+def main():
     admin_context = context.get_admin_context()
     CONF(sys.argv[1:], project='cinder',
          version=version.version_string())
index f487468a0fa6f1648dee5c0bf8ed6c2b45068f17..121a80ca3b13dbcf08b66a5ac660d98c9e2197da 100644 (file)
@@ -32,6 +32,7 @@ import mox
 from oslo.concurrency import lockutils
 from oslo.config import cfg
 from oslo.config import fixture as config_fixture
+from oslo.i18n import _lazy
 from oslo.messaging import conffixture as messaging_conffixture
 from oslo.utils import strutils
 from oslo.utils import timeutils
@@ -112,6 +113,9 @@ class TestCase(testtools.TestCase):
         """Run before each test method to initialize test environment."""
         super(TestCase, self).setUp()
 
+        # Unit tests do not need to use lazy gettext
+        _lazy.enable_lazy(enable=False)
+
         test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0)
         try:
             test_timeout = int(test_timeout)
diff --git a/cinder/tests/test_cmd.py b/cinder/tests/test_cmd.py
new file mode 100755 (executable)
index 0000000..1bf9ae3
--- /dev/null
@@ -0,0 +1,1358 @@
+#    Licensed 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.
+
+import contextlib
+import datetime
+import StringIO
+import sys
+
+import mock
+from oslo.config import cfg
+import rtslib
+
+from cinder.cmd import all as cinder_all
+from cinder.cmd import api as cinder_api
+from cinder.cmd import backup as cinder_backup
+from cinder.cmd import manage as cinder_manage
+from cinder.cmd import rtstool as cinder_rtstool
+from cinder.cmd import scheduler as cinder_scheduler
+from cinder.cmd import volume as cinder_volume
+from cinder.cmd import volume_usage_audit
+from cinder import context
+from cinder import test
+from cinder import version
+
+CONF = cfg.CONF
+
+
+class TestCinderApiCmd(test.TestCase):
+    """Unit test cases for python modules under cinder/cmd."""
+
+    def setUp(self):
+        super(TestCinderApiCmd, self).setUp()
+        sys.argv = ['cinder-api']
+        CONF(sys.argv[1:], project='cinder', version=version.version_string())
+
+    def tearDown(self):
+        super(TestCinderApiCmd, self).tearDown()
+
+    @mock.patch('cinder.service.WSGIService')
+    @mock.patch('cinder.service.process_launcher')
+    @mock.patch('cinder.rpc.init')
+    @mock.patch('cinder.utils.monkey_patch')
+    @mock.patch('cinder.openstack.common.log.setup')
+    def test_main(self, log_setup, monkey_patch, rpc_init, process_launcher,
+                  wsgi_service):
+        launcher = process_launcher.return_value
+        server = wsgi_service.return_value
+        server.workers = mock.sentinel.worker_count
+
+        cinder_api.main()
+
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        monkey_patch.assert_called_once_with()
+        rpc_init.assert_called_once_with(CONF)
+        process_launcher.assert_called_once_with()
+        wsgi_service.assert_called_once_with('osapi_volume')
+        launcher.launch_service.assert_called_once_with(server,
+                                                        workers=server.workers)
+        launcher.wait.assert_called_once_with()
+
+
+class TestCinderBackupCmd(test.TestCase):
+
+    def setUp(self):
+        super(TestCinderBackupCmd, self).setUp()
+        sys.argv = ['cinder-backup']
+        CONF(sys.argv[1:], project='cinder', version=version.version_string())
+
+    def tearDown(self):
+        super(TestCinderBackupCmd, self).tearDown()
+
+    @mock.patch('cinder.service.wait')
+    @mock.patch('cinder.service.serve')
+    @mock.patch('cinder.service.Service.create')
+    @mock.patch('cinder.utils.monkey_patch')
+    @mock.patch('cinder.openstack.common.log.setup')
+    def test_main(self, log_setup, monkey_patch, service_create, service_serve,
+                  service_wait):
+        server = service_create.return_value
+
+        cinder_backup.main()
+
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        monkey_patch.assert_called_once_with()
+        service_create.assert_called_once_with(binary='cinder-backup')
+        service_serve.assert_called_once_with(server)
+        service_wait.assert_called_once_with()
+
+
+class TestCinderAllCmd(test.TestCase):
+
+    def setUp(self):
+        super(TestCinderAllCmd, self).setUp()
+        sys.argv = ['cinder-all']
+        CONF(sys.argv[1:], project='cinder', version=version.version_string())
+
+    def tearDown(self):
+        super(TestCinderAllCmd, self).tearDown()
+
+    @mock.patch('cinder.service.Service.create')
+    @mock.patch('cinder.service.WSGIService')
+    @mock.patch('cinder.service.process_launcher')
+    @mock.patch('cinder.utils.monkey_patch')
+    @mock.patch('cinder.openstack.common.log.getLogger')
+    @mock.patch('cinder.openstack.common.log.setup')
+    def test_main(self, log_setup, get_logger, monkey_patch, process_launcher,
+                  wsgi_service, service_create):
+        launcher = process_launcher.return_value
+        server = wsgi_service.return_value
+        server.workers = mock.sentinel.worker_count
+        service = service_create.return_value
+
+        cinder_all.main()
+
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        get_logger.assert_called_once_with('cinder.all')
+        monkey_patch.assert_called_once_with()
+        process_launcher.assert_called_once_with()
+        wsgi_service.assert_called_once_with('osapi_volume')
+        launcher.launch_service.assert_any_call(server, workers=server.workers)
+
+        service_create.assert_has_calls([mock.call(binary='cinder-volume'),
+                                         mock.call(binary='cinder-scheduler'),
+                                         mock.call(binary='cinder-backup')])
+        self.assertEqual(3, service_create.call_count)
+        launcher.launch_service.assert_has_calls([mock.call(service)] * 3)
+        self.assertEqual(4, launcher.launch_service.call_count)
+
+        launcher.wait.assert_called_once_with()
+
+    @mock.patch('cinder.service.Service.create')
+    @mock.patch('cinder.service.WSGIService')
+    @mock.patch('cinder.service.process_launcher')
+    @mock.patch('cinder.utils.monkey_patch')
+    @mock.patch('cinder.openstack.common.log.getLogger')
+    @mock.patch('cinder.openstack.common.log.setup')
+    def test_main_load_osapi_volume_exception(self, log_setup, get_logger,
+                                              monkey_patch, process_launcher,
+                                              wsgi_service, service_create):
+        launcher = process_launcher.return_value
+        server = wsgi_service.return_value
+        server.workers = mock.sentinel.worker_count
+        mock_log = get_logger.return_value
+
+        for ex in (Exception(), SystemExit()):
+            launcher.launch_service.side_effect = ex
+
+            cinder_all.main()
+
+            self.assertEqual(CONF.project, 'cinder')
+            self.assertEqual(CONF.version, version.version_string())
+            log_setup.assert_called_once_with("cinder")
+            get_logger.assert_called_once_with('cinder.all')
+            monkey_patch.assert_called_once_with()
+            process_launcher.assert_called_once_with()
+            wsgi_service.assert_called_once_with('osapi_volume')
+            launcher.launch_service.assert_any_call(server,
+                                                    workers=server.workers)
+            self.assertTrue(mock_log.exception.called)
+
+            # Reset for the next exception
+            log_setup.reset_mock()
+            get_logger.reset_mock()
+            monkey_patch.reset_mock()
+            process_launcher.reset_mock()
+            wsgi_service.reset_mock()
+            mock_log.reset_mock()
+
+    @mock.patch('cinder.service.Service.create')
+    @mock.patch('cinder.service.WSGIService')
+    @mock.patch('cinder.service.process_launcher')
+    @mock.patch('cinder.utils.monkey_patch')
+    @mock.patch('cinder.openstack.common.log.getLogger')
+    @mock.patch('cinder.openstack.common.log.setup')
+    def test_main_load_binary_exception(self, log_setup, get_logger,
+                                        monkey_patch, process_launcher,
+                                        wsgi_service, service_create):
+        launcher = process_launcher.return_value
+        server = wsgi_service.return_value
+        server.workers = mock.sentinel.worker_count
+        service = service_create.return_value
+        mock_log = get_logger.return_value
+
+        def launch_service(*args, **kwargs):
+            if service in args:
+                raise Exception()
+
+        launcher.launch_service.side_effect = launch_service
+
+        cinder_all.main()
+
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        get_logger.assert_called_once_with('cinder.all')
+        monkey_patch.assert_called_once_with()
+        process_launcher.assert_called_once_with()
+        wsgi_service.assert_called_once_with('osapi_volume')
+        launcher.launch_service.assert_any_call(server,
+                                                workers=server.workers)
+        for binary in ['cinder-volume', 'cinder-scheduler', 'cinder-backup']:
+            service_create.assert_any_call(binary=binary)
+            launcher.launch_service.assert_called_with(service)
+        self.assertTrue(mock_log.exception.called)
+
+
+class TestCinderSchedulerCmd(test.TestCase):
+
+    def setUp(self):
+        super(TestCinderSchedulerCmd, self).setUp()
+        sys.argv = ['cinder-scheduler']
+        CONF(sys.argv[1:], project='cinder', version=version.version_string())
+
+    def tearDown(self):
+        super(TestCinderSchedulerCmd, self).tearDown()
+
+    @mock.patch('cinder.service.wait')
+    @mock.patch('cinder.service.serve')
+    @mock.patch('cinder.service.Service.create')
+    @mock.patch('cinder.utils.monkey_patch')
+    @mock.patch('cinder.openstack.common.log.setup')
+    def test_main(self, log_setup, monkey_patch, service_create,
+                  service_serve, service_wait):
+        server = service_create.return_value
+
+        cinder_scheduler.main()
+
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        monkey_patch.assert_called_once_with()
+        service_create.assert_called_once_with(binary='cinder-scheduler')
+        service_serve.assert_called_once_with(server)
+        service_wait.assert_called_once_with()
+
+
+class TestCinderVolumeCmd(test.TestCase):
+
+    def setUp(self):
+        super(TestCinderVolumeCmd, self).setUp()
+        sys.argv = ['cinder-volume']
+        CONF(sys.argv[1:], project='cinder', version=version.version_string())
+
+    def tearDown(self):
+        super(TestCinderVolumeCmd, self).tearDown()
+
+    @mock.patch('cinder.service.get_launcher')
+    @mock.patch('cinder.service.Service.create')
+    @mock.patch('cinder.utils.monkey_patch')
+    @mock.patch('cinder.openstack.common.log.setup')
+    def test_main(self, log_setup, monkey_patch, service_create,
+                  get_launcher):
+        CONF.set_override('enabled_backends', None)
+        launcher = get_launcher.return_value
+        server = service_create.return_value
+
+        cinder_volume.main()
+
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        monkey_patch.assert_called_once_with()
+        get_launcher.assert_called_once_with()
+        service_create.assert_called_once_with(binary='cinder-volume')
+        launcher.launch_service.assert_called_once_with(server)
+        launcher.wait.assert_called_once_with()
+
+    @mock.patch('cinder.service.get_launcher')
+    @mock.patch('cinder.service.Service.create')
+    @mock.patch('cinder.utils.monkey_patch')
+    @mock.patch('cinder.openstack.common.log.setup')
+    def test_main_with_backends(self, log_setup, monkey_patch, service_create,
+                                get_launcher):
+        backends = ['backend1', 'backend2']
+        CONF.set_override('enabled_backends', backends)
+        launcher = get_launcher.return_value
+
+        cinder_volume.main()
+
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        monkey_patch.assert_called_once_with()
+        get_launcher.assert_called_once_with()
+        self.assertEqual(len(backends), service_create.call_count)
+        self.assertEqual(len(backends), launcher.launch_service.call_count)
+        launcher.wait.assert_called_once_with()
+
+
+class TestCinderManageCmd(test.TestCase):
+
+    def setUp(self):
+        super(TestCinderManageCmd, self).setUp()
+        sys.argv = ['cinder-manage']
+        CONF(sys.argv[1:], project='cinder', version=version.version_string())
+
+    def tearDown(self):
+        super(TestCinderManageCmd, self).tearDown()
+
+    @mock.patch('cinder.openstack.common.uuidutils.is_uuid_like')
+    def test_param2id(self, is_uuid_like):
+        mock_object_id = mock.MagicMock()
+        is_uuid_like.return_value = True
+
+        object_id = cinder_manage.param2id(mock_object_id)
+        self.assertEqual(mock_object_id, object_id)
+        is_uuid_like.assert_called_once_with(mock_object_id)
+
+    @mock.patch('cinder.openstack.common.uuidutils.is_uuid_like')
+    def test_param2id_int_string(self, is_uuid_like):
+        object_id_str = '10'
+        is_uuid_like.return_value = False
+
+        object_id = cinder_manage.param2id(object_id_str)
+        self.assertEqual(10, object_id)
+        is_uuid_like.assert_called_once_with(object_id_str)
+
+    @mock.patch('cinder.db.migration.db_sync')
+    def test_db_commands_sync(self, db_sync):
+        version = mock.MagicMock()
+        db_cmds = cinder_manage.DbCommands()
+        db_cmds.sync(version=version)
+        db_sync.assert_called_once_with(version)
+
+    @mock.patch('cinder.db.migration.db_version')
+    def test_db_commands_version(self, db_version):
+        db_cmds = cinder_manage.DbCommands()
+        db_cmds.version()
+        db_version.assert_called_once_with()
+
+    @mock.patch('cinder.version.version_string')
+    def test_versions_commands_list(self, version_string):
+        version_cmds = cinder_manage.VersionCommands()
+        version_cmds.list()
+        version_string.assert_called_once_with()
+
+    @mock.patch('cinder.version.version_string')
+    def test_versions_commands_call(self, version_string):
+        version_cmds = cinder_manage.VersionCommands()
+        version_cmds.__call__()
+        version_string.assert_called_once_with()
+
+    @mock.patch('cinder.db.service_get_all')
+    @mock.patch('cinder.context.get_admin_context')
+    def test_host_commands_list(self, get_admin_context, service_get_all):
+        get_admin_context.return_value = mock.sentinel.ctxt
+        service_get_all.return_value = [{'host': 'fake-host',
+                                         'availability_zone': 'fake-az'}]
+
+        with mock.patch('sys.stdout', new=StringIO.StringIO()) as fake_out:
+            expected_out = ("%(host)-25s\t%(zone)-15s\n" %
+                            {'host': 'host', 'zone': 'zone'})
+            expected_out += ("%(host)-25s\t%(availability_zone)-15s\n" %
+                             {'host': 'fake-host',
+                              'availability_zone': 'fake-az'})
+            host_cmds = cinder_manage.HostCommands()
+            host_cmds.list()
+
+            get_admin_context.assert_called_once_with()
+            service_get_all.assert_called_once_with(mock.sentinel.ctxt)
+            self.assertEqual(expected_out, fake_out.getvalue())
+
+    @mock.patch('cinder.db.service_get_all')
+    @mock.patch('cinder.context.get_admin_context')
+    def test_host_commands_list_with_zone(self, get_admin_context,
+                                          service_get_all):
+        get_admin_context.return_value = mock.sentinel.ctxt
+        service_get_all.return_value = [{'host': 'fake-host',
+                                         'availability_zone': 'fake-az1'},
+                                        {'host': 'fake-host',
+                                         'availability_zone': 'fake-az2'}]
+
+        with mock.patch('sys.stdout', new=StringIO.StringIO()) as fake_out:
+            expected_out = ("%(host)-25s\t%(zone)-15s\n" %
+                            {'host': 'host', 'zone': 'zone'})
+            expected_out += ("%(host)-25s\t%(availability_zone)-15s\n" %
+                             {'host': 'fake-host',
+                              'availability_zone': 'fake-az1'})
+            host_cmds = cinder_manage.HostCommands()
+            host_cmds.list(zone='fake-az1')
+
+            get_admin_context.assert_called_once_with()
+            service_get_all.assert_called_once_with(mock.sentinel.ctxt)
+            self.assertEqual(expected_out, fake_out.getvalue())
+
+    @mock.patch('cinder.rpc.get_client')
+    @mock.patch('cinder.rpc.init')
+    @mock.patch('cinder.rpc.initialized', return_value=False)
+    @mock.patch('oslo.messaging.Target')
+    def test_volume_commands_init(self, messaging_target, rpc_initialized,
+                                  rpc_init, get_client):
+        CONF.set_override('volume_topic', 'fake-topic')
+        mock_target = messaging_target.return_value
+        mock_rpc_client = get_client.return_value
+
+        volume_cmds = cinder_manage.VolumeCommands()
+        rpc_client = volume_cmds.rpc_client()
+
+        rpc_initialized.assert_called_once_with()
+        rpc_init.assert_called_once_with(CONF)
+        messaging_target.assert_called_once_with(topic='fake-topic')
+        get_client.assert_called_once_with(mock_target)
+        self.assertEqual(mock_rpc_client, rpc_client)
+
+    @mock.patch('cinder.db.volume_get')
+    @mock.patch('cinder.context.get_admin_context')
+    @mock.patch('cinder.rpc.get_client')
+    @mock.patch('cinder.rpc.init')
+    def test_volume_commands_delete(self, rpc_init, get_client,
+                                    get_admin_context, volume_get):
+        ctxt = context.RequestContext('fake-user', 'fake-project')
+        get_admin_context.return_value = ctxt
+        mock_client = mock.MagicMock()
+        cctxt = mock.MagicMock()
+        mock_client.prepare.return_value = cctxt
+        get_client.return_value = mock_client
+        volume_id = '123'
+        volume = {'id': volume_id, 'host': 'fake-host', 'status': 'available'}
+        volume_get.return_value = volume
+
+        volume_cmds = cinder_manage.VolumeCommands()
+        volume_cmds._client = mock_client
+        volume_cmds.delete(volume_id)
+
+        volume_get.assert_called_once_with(ctxt, 123)
+        mock_client.prepare.assert_called_once_with(server=volume['host'])
+        cctxt.cast.assert_called_once_with(ctxt, 'delete_volume',
+                                           volume_id=volume['id'])
+
+    @mock.patch('cinder.db.volume_destroy')
+    @mock.patch('cinder.db.volume_get')
+    @mock.patch('cinder.context.get_admin_context')
+    @mock.patch('cinder.rpc.init')
+    def test_volume_commands_delete_no_host(self, rpc_init, get_admin_context,
+                                            volume_get, volume_destroy):
+        ctxt = context.RequestContext('fake-user', 'fake-project')
+        get_admin_context.return_value = ctxt
+        volume_id = '123'
+        volume = {'id': volume_id, 'host': None, 'status': 'available'}
+        volume_get.return_value = volume
+
+        with mock.patch('sys.stdout', new=StringIO.StringIO()) as fake_out:
+            expected_out = ('Volume not yet assigned to host.\n'
+                            'Deleting volume from database and skipping'
+                            ' rpc.\n')
+            volume_cmds = cinder_manage.VolumeCommands()
+            volume_cmds.delete(volume_id)
+
+            get_admin_context.assert_called_once_with()
+            volume_get.assert_called_once_with(ctxt, 123)
+            volume_destroy.assert_called_once_with(ctxt, 123)
+            self.assertEqual(expected_out, fake_out.getvalue())
+
+    @mock.patch('cinder.db.volume_destroy')
+    @mock.patch('cinder.db.volume_get')
+    @mock.patch('cinder.context.get_admin_context')
+    @mock.patch('cinder.rpc.init')
+    def test_volume_commands_delete_volume_in_use(self, rpc_init,
+                                                  get_admin_context,
+                                                  volume_get, volume_destroy):
+        ctxt = context.RequestContext('fake-user', 'fake-project')
+        get_admin_context.return_value = ctxt
+        volume_id = '123'
+        volume = {'id': volume_id, 'host': 'fake-host', 'status': 'in-use'}
+        volume_get.return_value = volume
+
+        with mock.patch('sys.stdout', new=StringIO.StringIO()) as fake_out:
+            expected_out = ('Volume is in-use.\n'
+                            'Detach volume from instance and then try'
+                            ' again.\n')
+            volume_cmds = cinder_manage.VolumeCommands()
+            volume_cmds.delete(volume_id)
+
+            volume_get.assert_called_once_with(ctxt, 123)
+            self.assertEqual(expected_out, fake_out.getvalue())
+
+    def test_config_commands_list(self):
+        with mock.patch('sys.stdout', new=StringIO.StringIO()) as fake_out:
+            expected_out = ''
+            for key, value in CONF.iteritems():
+                expected_out += '%s = %s' % (key, value) + '\n'
+
+            config_cmds = cinder_manage.ConfigCommands()
+            config_cmds.list()
+
+            self.assertEqual(expected_out, fake_out.getvalue())
+
+    def test_config_commands_list_param(self):
+        with mock.patch('sys.stdout', new=StringIO.StringIO()) as fake_out:
+            CONF.set_override('host', 'fake')
+            expected_out = 'host = fake\n'
+
+            config_cmds = cinder_manage.ConfigCommands()
+            config_cmds.list(param='host')
+
+            self.assertEqual(expected_out, fake_out.getvalue())
+
+    def test_get_log_commands_no_errors(self):
+        with mock.patch('sys.stdout', new=StringIO.StringIO()) as fake_out:
+            CONF.set_override('log_dir', None)
+            expected_out = 'No errors in logfiles!\n'
+
+            get_log_cmds = cinder_manage.GetLogCommands()
+            get_log_cmds.errors()
+
+            self.assertEqual(expected_out, fake_out.getvalue())
+
+    @mock.patch('__builtin__.open')
+    @mock.patch('os.listdir')
+    def test_get_log_commands_errors(self, listdir, open):
+        CONF.set_override('log_dir', 'fake-dir')
+        listdir.return_value = ['fake-error.log']
+
+        with mock.patch('sys.stdout', new=StringIO.StringIO()) as fake_out:
+            open.return_value = StringIO.StringIO(
+                '[ ERROR ] fake-error-message')
+            expected_out = ('fake-dir/fake-error.log:-\n'
+                            'Line 1 : [ ERROR ] fake-error-message\n')
+
+            get_log_cmds = cinder_manage.GetLogCommands()
+            get_log_cmds.errors()
+
+            self.assertEqual(expected_out, fake_out.getvalue())
+            open.assert_called_once_with('fake-dir/fake-error.log', 'r')
+            listdir.assert_called_once_with(CONF.log_dir)
+
+    @mock.patch('__builtin__.open')
+    @mock.patch('os.path.exists')
+    def test_get_log_commands_syslog_no_log_file(self, path_exists, open):
+        path_exists.return_value = False
+
+        get_log_cmds = cinder_manage.GetLogCommands()
+        exit = self.assertRaises(SystemExit, get_log_cmds.syslog)
+
+        self.assertEqual(exit.code, 1)
+        path_exists.assert_any_call('/var/log/syslog')
+        path_exists.assert_any_call('/var/log/messages')
+
+    @mock.patch('cinder.db.backup_get_all')
+    @mock.patch('cinder.context.get_admin_context')
+    def test_backup_commands_list(self, get_admin_context, backup_get_all):
+        ctxt = context.RequestContext('fake-user', 'fake-project')
+        get_admin_context.return_value = ctxt
+        backup = {'id': 1,
+                  'user_id': 'fake-user-id',
+                  'project_id': 'fake-project-id',
+                  'host': 'fake-host',
+                  'display_name': 'fake-display-name',
+                  'container': 'fake-container',
+                  'status': 'fake-status',
+                  'size': 123,
+                  'object_count': 1}
+        backup_get_all.return_value = [backup]
+        with mock.patch('sys.stdout', new=StringIO.StringIO()) as fake_out:
+            hdr = ('%-32s\t%-32s\t%-32s\t%-24s\t%-24s\t%-12s\t%-12s\t%-12s'
+                   '\t%-12s')
+            header = hdr % ('ID',
+                            'User ID',
+                            'Project ID',
+                            'Host',
+                            'Name',
+                            'Container',
+                            'Status',
+                            'Size',
+                            'Object Count')
+            res = ('%-32s\t%-32s\t%-32s\t%-24s\t%-24s\t%-12s\t%-12s\t%-12d'
+                   '\t%-12s')
+            resource = res % (backup['id'],
+                              backup['user_id'],
+                              backup['project_id'],
+                              backup['host'],
+                              backup['display_name'],
+                              backup['container'],
+                              backup['status'],
+                              backup['size'],
+                              1)
+            expected_out = header + '\n' + resource + '\n'
+
+            backup_cmds = cinder_manage.BackupCommands()
+            backup_cmds.list()
+
+            get_admin_context.assert_called_once_with()
+            backup_get_all.assert_called_once_with(ctxt)
+            self.assertEqual(expected_out, fake_out.getvalue())
+
+    @mock.patch('cinder.utils.service_is_up')
+    @mock.patch('cinder.db.service_get_all')
+    @mock.patch('cinder.context.get_admin_context')
+    def test_service_commands_list(self, get_admin_context, service_get_all,
+                                   service_is_up):
+        ctxt = context.RequestContext('fake-user', 'fake-project')
+        get_admin_context.return_value = ctxt
+        service = {'binary': 'cinder-binary',
+                   'host': 'fake-host.fake-domain',
+                   'availability_zone': 'fake-zone',
+                   'updated_at': '2014-06-30 11:22:33',
+                   'disabled': False}
+        service_get_all.return_value = [service]
+        service_is_up.return_value = True
+        with mock.patch('sys.stdout', new=StringIO.StringIO()) as fake_out:
+            format = "%-16s %-36s %-16s %-10s %-5s %-10s"
+            print_format = format % ('Binary',
+                                     'Host',
+                                     'Zone',
+                                     'Status',
+                                     'State',
+                                     'Updated At')
+            service_format = format % (service['binary'],
+                                       service['host'].partition('.')[0],
+                                       service['availability_zone'],
+                                       'enabled',
+                                       ':-)',
+                                       service['updated_at'])
+            expected_out = print_format + '\n' + service_format + '\n'
+
+            service_cmds = cinder_manage.ServiceCommands()
+            service_cmds.list()
+
+            self.assertEqual(expected_out, fake_out.getvalue())
+            get_admin_context.assert_called_with()
+            service_get_all.assert_called_with(ctxt)
+            service_is_up.assert_called_with(service)
+
+    @mock.patch('oslo.config.cfg.ConfigOpts.register_cli_opt')
+    def test_main_argv_lt_2(self, register_cli_opt):
+        script_name = 'cinder-manage'
+        sys.argv = [script_name]
+        CONF(sys.argv[1:], project='cinder', version=version.version_string())
+
+        exit = self.assertRaises(SystemExit, cinder_manage.main)
+
+        self.assertTrue(register_cli_opt.called)
+        self.assertEqual(exit.code, 2)
+
+    @mock.patch('oslo.config.cfg.ConfigOpts.__call__')
+    @mock.patch('cinder.openstack.common.log.setup')
+    @mock.patch('oslo.config.cfg.ConfigOpts.register_cli_opt')
+    def test_main_sudo_failed(self, register_cli_opt, log_setup,
+                              config_opts_call):
+        script_name = 'cinder-manage'
+        sys.argv = [script_name, 'fake_category', 'fake_action']
+        config_opts_call.side_effect = cfg.ConfigFilesNotFoundError(
+            mock.sentinel._namespace)
+
+        exit = self.assertRaises(SystemExit, cinder_manage.main)
+
+        self.assertTrue(register_cli_opt.called)
+        config_opts_call.assert_called_once_with(
+            sys.argv[1:], project='cinder',
+            version=version.version_string())
+        self.assertFalse(log_setup.called)
+        self.assertEqual(exit.code, 2)
+
+    @mock.patch('oslo.config.cfg.ConfigOpts.__call__')
+    @mock.patch('oslo.config.cfg.ConfigOpts.register_cli_opt')
+    def test_main(self, register_cli_opt, config_opts_call):
+        script_name = 'cinder-manage'
+        sys.argv = [script_name, 'config', 'list']
+        action_fn = mock.MagicMock()
+        CONF.category = mock.MagicMock(action_fn=action_fn)
+
+        cinder_manage.main()
+
+        self.assertTrue(register_cli_opt.called)
+        config_opts_call.assert_called_once_with(
+            sys.argv[1:], project='cinder', version=version.version_string())
+        self.assertTrue(action_fn.called)
+
+
+class TestCinderRtstoolCmd(test.TestCase):
+
+    def setUp(self):
+        super(TestCinderRtstoolCmd, self).setUp()
+        sys.argv = ['cinder-rtstool']
+        CONF(sys.argv[1:], project='cinder', version=version.version_string())
+
+    def tearDown(self):
+        super(TestCinderRtstoolCmd, self).tearDown()
+
+    @mock.patch('rtslib.root.RTSRoot')
+    def test_create_rtsllib_error(self, rtsroot):
+        rtsroot.side_effect = rtslib.utils.RTSLibError()
+
+        self.assertRaises(rtslib.utils.RTSLibError, cinder_rtstool.create,
+                          mock.sentinel.backing_device,
+                          mock.sentinel.name,
+                          mock.sentinel.userid,
+                          mock.sentinel.password)
+
+    def _test_create_rtsllib_error_network_portal(self, ip):
+        with contextlib.nested(
+            mock.patch('rtslib.NetworkPortal'),
+            mock.patch('rtslib.LUN'),
+            mock.patch('rtslib.TPG'),
+            mock.patch('rtslib.FabricModule'),
+            mock.patch('rtslib.Target'),
+            mock.patch('rtslib.BlockStorageObject'),
+            mock.patch('rtslib.root.RTSRoot')
+        ) as (network_portal, lun, tpg, fabric_module, target,
+              block_storage_object, rts_root):
+            root_new = mock.MagicMock(storage_objects=mock.MagicMock())
+            rts_root.return_value = root_new
+            block_storage_object.return_value = mock.sentinel.so_new
+            target.return_value = mock.sentinel.target_new
+            fabric_module.return_value = mock.sentinel.fabric_new
+            tpg_new = tpg.return_value
+            lun.return_value = mock.sentinel.lun_new
+
+            if ip == '0.0.0.0':
+                network_portal.side_effect = rtslib.utils.RTSLibError()
+                self.assertRaises(rtslib.utils.RTSLibError,
+                                  cinder_rtstool.create,
+                                  mock.sentinel.backing_device,
+                                  mock.sentinel.name,
+                                  mock.sentinel.userid,
+                                  mock.sentinel.password)
+            else:
+                cinder_rtstool.create(mock.sentinel.backing_device,
+                                      mock.sentinel.name,
+                                      mock.sentinel.userid,
+                                      mock.sentinel.password)
+
+            rts_root.assert_called_once_with()
+            block_storage_object.assert_called_once_with(
+                name=mock.sentinel.name, dev=mock.sentinel.backing_device)
+            target.assert_called_once_with(mock.sentinel.fabric_new,
+                                           mock.sentinel.name, 'create')
+            fabric_module.assert_called_once_with('iscsi')
+            tpg.assert_called_once_with(mock.sentinel.target_new,
+                                        mode='create')
+            tpg_new.set_attribute.assert_called_once_with('authentication',
+                                                          '1')
+            lun.assert_called_once_with(tpg_new,
+                                        storage_object=mock.sentinel.so_new)
+            self.assertEqual(1, tpg_new.enable)
+            network_portal.assert_any_call(tpg_new, ip, 3260,
+                                           mode='any')
+
+            if ip == '::0':
+                network_portal.assert_any_call(tpg_new, ip, 3260, mode='any')
+
+    def test_create_rtsllib_error_network_portal_ipv4(self):
+        self._test_create_rtsllib_error_network_portal('0.0.0.0')
+
+    def test_create_rtsllib_error_network_portal_ipv6(self):
+        self._test_create_rtsllib_error_network_portal('::0')
+
+    def _test_create(self, ip):
+        with contextlib.nested(
+            mock.patch('rtslib.NetworkPortal'),
+            mock.patch('rtslib.LUN'),
+            mock.patch('rtslib.TPG'),
+            mock.patch('rtslib.FabricModule'),
+            mock.patch('rtslib.Target'),
+            mock.patch('rtslib.BlockStorageObject'),
+            mock.patch('rtslib.root.RTSRoot')
+        ) as (network_portal, lun, tpg, fabric_module, target,
+              block_storage_object, rts_root):
+            root_new = mock.MagicMock(storage_objects=mock.MagicMock())
+            rts_root.return_value = root_new
+            block_storage_object.return_value = mock.sentinel.so_new
+            target.return_value = mock.sentinel.target_new
+            fabric_module.return_value = mock.sentinel.fabric_new
+            tpg_new = tpg.return_value
+            lun.return_value = mock.sentinel.lun_new
+
+            def network_portal_exception(*args, **kwargs):
+                if set([tpg_new, '::0', 3260]).issubset(list(args)):
+                    raise rtslib.utils.RTSLibError()
+                else:
+                    pass
+
+            cinder_rtstool.create(mock.sentinel.backing_device,
+                                  mock.sentinel.name,
+                                  mock.sentinel.userid,
+                                  mock.sentinel.password)
+
+            rts_root.assert_called_once_with()
+            block_storage_object.assert_called_once_with(
+                name=mock.sentinel.name, dev=mock.sentinel.backing_device)
+            target.assert_called_once_with(mock.sentinel.fabric_new,
+                                           mock.sentinel.name, 'create')
+            fabric_module.assert_called_once_with('iscsi')
+            tpg.assert_called_once_with(mock.sentinel.target_new,
+                                        mode='create')
+            tpg_new.set_attribute.assert_called_once_with('authentication',
+                                                          '1')
+            lun.assert_called_once_with(tpg_new,
+                                        storage_object=mock.sentinel.so_new)
+            self.assertEqual(1, tpg_new.enable)
+            network_portal.assert_any_call(tpg_new, ip, 3260,
+                                           mode='any')
+
+            if ip == '::0':
+                network_portal.assert_any_call(tpg_new, ip, 3260, mode='any')
+
+    def test_create_ipv4(self):
+        self._test_create('0.0.0.0')
+
+    def test_create_ipv6(self):
+        self._test_create('::0')
+
+    @mock.patch('rtslib.root.RTSRoot')
+    def test_add_initiator_rtslib_error(self, rtsroot):
+        rtsroot.side_effect = rtslib.utils.RTSLibError()
+
+        self.assertRaises(rtslib.utils.RTSLibError,
+                          cinder_rtstool.add_initiator,
+                          mock.sentinel.target_iqn,
+                          mock.sentinel.initiator_iqn,
+                          mock.sentinel.userid,
+                          mock.sentinel.password)
+
+    @mock.patch('rtslib.root.RTSRoot')
+    def test_add_initiator_rtstool_error(self, rtsroot):
+        rtsroot.targets.return_value = {}
+
+        self.assertRaises(cinder_rtstool.RtstoolError,
+                          cinder_rtstool.add_initiator,
+                          mock.sentinel.target_iqn,
+                          mock.sentinel.initiator_iqn,
+                          mock.sentinel.userid,
+                          mock.sentinel.password)
+
+    @mock.patch('rtslib.MappedLUN')
+    @mock.patch('rtslib.NodeACL')
+    @mock.patch('rtslib.root.RTSRoot')
+    def test_add_initiator_acl_exists(self, rtsroot, node_acl, mapped_lun):
+        target_iqn = mock.MagicMock()
+        target_iqn.tpgs.return_value = \
+            [{'node_acls': mock.sentinel.initiator_iqn}]
+        acl = {'node_wwn': mock.sentinel.initiator_iqn}
+        tpg = mock.MagicMock(node_acls=[acl])
+        tpgs = mock.MagicMock()
+        tpgs.next.return_value = tpg
+        target = mock.MagicMock(tpgs=tpgs, wwn=target_iqn)
+        rtsroot.return_value = mock.MagicMock(targets=[target])
+
+        cinder_rtstool.add_initiator(target_iqn,
+                                     mock.sentinel.initiator_iqn,
+                                     mock.sentinel.userid,
+                                     mock.sentinel.password)
+        self.assertFalse(node_acl.called)
+        self.assertFalse(mapped_lun.called)
+
+    @mock.patch('rtslib.MappedLUN')
+    @mock.patch('rtslib.NodeACL')
+    @mock.patch('rtslib.root.RTSRoot')
+    def test_add_initiator(self, rtsroot, node_acl, mapped_lun):
+        target_iqn = mock.MagicMock()
+        target_iqn.tpgs.return_value = \
+            [{'node_acls': mock.sentinel.initiator_iqn}]
+        tpg = mock.MagicMock()
+        target = mock.MagicMock(tpgs=tpg, wwn=target_iqn)
+        rtsroot.return_value = mock.MagicMock(targets=[target])
+
+        acl_new = mock.MagicMock(chap_userid=mock.sentinel.userid,
+                                 chap_password=mock.sentinel.password)
+        node_acl.return_value = acl_new
+
+        cinder_rtstool.add_initiator(target_iqn,
+                                     mock.sentinel.initiator_iqn,
+                                     mock.sentinel.userid,
+                                     mock.sentinel.password)
+        node_acl.assert_called_once_with(tpg.next(),
+                                         mock.sentinel.initiator_iqn,
+                                         mode='create')
+        mapped_lun.assert_called_once_with(acl_new, 0, tpg_lun=0)
+
+    @mock.patch('rtslib.root.RTSRoot')
+    def test_get_targets(self, rtsroot):
+        target = mock.MagicMock()
+        target.dump.return_value = {'wwn': 'fake-wwn'}
+        rtsroot.return_value = mock.MagicMock(targets=[target])
+
+        with mock.patch('sys.stdout', new=StringIO.StringIO()) as fake_out:
+            cinder_rtstool.get_targets()
+
+            self.assertEqual(str(target.wwn), fake_out.getvalue().strip())
+
+    @mock.patch('rtslib.root.RTSRoot')
+    def test_delete(self, rtsroot):
+        target = mock.MagicMock(wwn=mock.sentinel.iqn)
+        storage_object = mock.MagicMock()
+        name = mock.PropertyMock(return_value=mock.sentinel.iqn)
+        type(storage_object).name = name
+        rtsroot.return_value = mock.MagicMock(
+            targets=[target], storage_objects=[storage_object])
+
+        cinder_rtstool.delete(mock.sentinel.iqn)
+
+        target.delete.assert_called_once_with()
+        storage_object.delete.assert_called_once_with()
+
+    def test_usage(self):
+        exit = self.assertRaises(SystemExit, cinder_rtstool.usage)
+
+        self.assertEqual(exit.code, 1)
+
+    @mock.patch('cinder.cmd.rtstool.usage')
+    def test_main_argc_lt_2(self, usage):
+        usage.side_effect = SystemExit(1)
+        sys.argv = ['cinder-rtstool']
+
+        exit = self.assertRaises(SystemExit, cinder_rtstool.usage)
+
+        self.assertTrue(usage.called)
+        self.assertEqual(exit.code, 1)
+
+    def test_main_create_argv_lt_6(self):
+        sys.argv = ['cinder-rtstool', 'create']
+        self._test_main_check_argv()
+
+    def test_main_create_argv_gt_7(self):
+        sys.argv = ['cinder-rtstool', 'create', 'fake-arg1', 'fake-arg2',
+                    'fake-arg3', 'fake-arg4', 'fake-arg5', 'fake-arg6']
+        self._test_main_check_argv()
+
+    def test_main_add_initiator_argv_lt_6(self):
+        sys.argv = ['cinder-rtstool', 'add-initiator']
+        self._test_main_check_argv()
+
+    def test_main_delete_argv_lt_3(self):
+        sys.argv = ['cinder-rtstool', 'delete']
+        self._test_main_check_argv()
+
+    def test_main_no_action(self):
+        sys.argv = ['cinder-rtstool']
+        self._test_main_check_argv()
+
+    def _test_main_check_argv(self):
+        with mock.patch('cinder.cmd.rtstool.usage') as usage:
+            usage.side_effect = SystemExit(1)
+            sys.argv = ['cinder-rtstool', 'create']
+
+            exit = self.assertRaises(SystemExit, cinder_rtstool.main)
+
+            self.assertTrue(usage.called)
+            self.assertEqual(exit.code, 1)
+
+    def test_main_create(self):
+        with mock.patch('cinder.cmd.rtstool.create') as create:
+            sys.argv = ['cinder-rtstool',
+                        'create',
+                        mock.sentinel.backing_device,
+                        mock.sentinel.name,
+                        mock.sentinel.userid,
+                        mock.sentinel.password,
+                        mock.sentinel.initiator_iqns]
+
+            rc = cinder_rtstool.main()
+
+            create.assert_called_once_with(mock.sentinel.backing_device,
+                                           mock.sentinel.name,
+                                           mock.sentinel.userid,
+                                           mock.sentinel.password,
+                                           mock.sentinel.initiator_iqns)
+            self.assertEqual(0, rc)
+
+    def test_main_add_initiator(self):
+        with mock.patch('cinder.cmd.rtstool.add_initiator') as add_initiator:
+            sys.argv = ['cinder-rtstool',
+                        'add-initiator',
+                        mock.sentinel.target_iqn,
+                        mock.sentinel.userid,
+                        mock.sentinel.password,
+                        mock.sentinel.initiator_iqns]
+
+            rc = cinder_rtstool.main()
+
+            add_initiator.assert_called_once_with(
+                mock.sentinel.target_iqn, mock.sentinel.initiator_iqns,
+                mock.sentinel.userid, mock.sentinel.password)
+            self.assertEqual(0, rc)
+
+    def test_main_get_targets(self):
+        with mock.patch('cinder.cmd.rtstool.get_targets') as get_targets:
+            sys.argv = ['cinder-rtstool', 'get-targets']
+
+            rc = cinder_rtstool.main()
+
+            get_targets.assert_called_once_with()
+            self.assertEqual(0, rc)
+
+    def test_main_delete(self):
+        with mock.patch('cinder.cmd.rtstool.delete') as delete:
+            sys.argv = ['cinder-rtstool', 'delete', mock.sentinel.iqn]
+
+            rc = cinder_rtstool.main()
+
+            delete.assert_called_once_with(mock.sentinel.iqn)
+            self.assertEqual(0, rc)
+
+    def test_main_verify(self):
+        with mock.patch('cinder.cmd.rtstool.verify_rtslib') as verify_rtslib:
+            sys.argv = ['cinder-rtstool', 'verify']
+
+            rc = cinder_rtstool.main()
+
+            verify_rtslib.assert_called_once_with()
+            self.assertEqual(0, rc)
+
+
+class TestCinderVolumeUsageAuditCmd(test.TestCase):
+
+    def setUp(self):
+        super(TestCinderVolumeUsageAuditCmd, self).setUp()
+        sys.argv = ['cinder-volume-usage-audit']
+        CONF(sys.argv[1:], project='cinder', version=version.version_string())
+
+    def tearDown(self):
+        super(TestCinderVolumeUsageAuditCmd, self).tearDown()
+
+    @mock.patch('cinder.utils.last_completed_audit_period')
+    @mock.patch('cinder.rpc.init')
+    @mock.patch('cinder.version.version_string')
+    @mock.patch('cinder.openstack.common.log.getLogger')
+    @mock.patch('cinder.openstack.common.log.setup')
+    @mock.patch('cinder.context.get_admin_context')
+    def test_main_time_error(self, get_admin_context, log_setup, get_logger,
+                             version_string, rpc_init,
+                             last_completed_audit_period):
+        CONF.set_override('start_time', '2014-01-01 01:00:00')
+        CONF.set_override('end_time', '2013-01-01 01:00:00')
+        last_completed_audit_period.return_value = (mock.sentinel.begin,
+                                                    mock.sentinel.end)
+
+        exit = self.assertRaises(SystemExit, volume_usage_audit.main)
+
+        get_admin_context.assert_called_once_with()
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        get_logger.assert_called_once_with('cinder')
+        self.assertEqual(exit.code, -1)
+        rpc_init.assert_called_once_with(CONF)
+        last_completed_audit_period.assert_called_once_with()
+
+    @mock.patch('cinder.volume.utils.notify_about_volume_usage')
+    @mock.patch('cinder.db.volume_get_active_by_window')
+    @mock.patch('cinder.utils.last_completed_audit_period')
+    @mock.patch('cinder.rpc.init')
+    @mock.patch('cinder.version.version_string')
+    @mock.patch('cinder.openstack.common.log.getLogger')
+    @mock.patch('cinder.openstack.common.log.setup')
+    @mock.patch('cinder.context.get_admin_context')
+    def test_main_send_create_volume_error(self, get_admin_context, log_setup,
+                                           get_logger, version_string,
+                                           rpc_init,
+                                           last_completed_audit_period,
+                                           volume_get_active_by_window,
+                                           notify_about_volume_usage):
+        CONF.set_override('send_actions', True)
+        CONF.set_override('start_time', '2014-01-01 01:00:00')
+        CONF.set_override('end_time', '2014-02-02 02:00:00')
+        begin = datetime.datetime(2014, 1, 1, 1, 0)
+        end = datetime.datetime(2014, 2, 2, 2, 0)
+        ctxt = context.RequestContext('fake-user', 'fake-project')
+        get_admin_context.return_value = ctxt
+        last_completed_audit_period.return_value = (begin, end)
+        volume1_created = datetime.datetime(2014, 1, 1, 2, 0)
+        volume1_deleted = datetime.datetime(2014, 1, 1, 3, 0)
+        volume1 = mock.MagicMock(id='1', project_id='fake-project',
+                                 created_at=volume1_created,
+                                 deleted_at=volume1_deleted)
+        volume_get_active_by_window.return_value = [volume1]
+        extra_info = {
+            'audit_period_beginning': str(begin),
+            'audit_period_ending': str(end),
+        }
+        local_extra_info = {
+            'audit_period_beginning': str(volume1.created_at),
+            'audit_period_ending': str(volume1.created_at),
+        }
+
+        def _notify_about_volume_usage(*args, **kwargs):
+            if 'create.end' in args:
+                raise Exception()
+            else:
+                pass
+
+        notify_about_volume_usage.side_effect = _notify_about_volume_usage
+
+        volume_usage_audit.main()
+
+        get_admin_context.assert_called_once_with()
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        get_logger.assert_called_once_with('cinder')
+        rpc_init.assert_called_once_with(CONF)
+        last_completed_audit_period.assert_called_once_with()
+        volume_get_active_by_window.assert_called_once_with(ctxt, begin, end)
+        notify_about_volume_usage.assert_any_call(ctxt, volume1, 'exists',
+                                                  extra_usage_info=extra_info)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'create.start', extra_usage_info=local_extra_info)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'create.end', extra_usage_info=local_extra_info)
+
+    @mock.patch('cinder.volume.utils.notify_about_volume_usage')
+    @mock.patch('cinder.db.volume_get_active_by_window')
+    @mock.patch('cinder.utils.last_completed_audit_period')
+    @mock.patch('cinder.rpc.init')
+    @mock.patch('cinder.version.version_string')
+    @mock.patch('cinder.openstack.common.log.getLogger')
+    @mock.patch('cinder.openstack.common.log.setup')
+    @mock.patch('cinder.context.get_admin_context')
+    def test_main_send_delete_volume_error(self, get_admin_context, log_setup,
+                                           get_logger, version_string,
+                                           rpc_init,
+                                           last_completed_audit_period,
+                                           volume_get_active_by_window,
+                                           notify_about_volume_usage):
+        CONF.set_override('send_actions', True)
+        CONF.set_override('start_time', '2014-01-01 01:00:00')
+        CONF.set_override('end_time', '2014-02-02 02:00:00')
+        begin = datetime.datetime(2014, 1, 1, 1, 0)
+        end = datetime.datetime(2014, 2, 2, 2, 0)
+        ctxt = context.RequestContext('fake-user', 'fake-project')
+        get_admin_context.return_value = ctxt
+        last_completed_audit_period.return_value = (begin, end)
+        volume1_created = datetime.datetime(2014, 1, 1, 2, 0)
+        volume1_deleted = datetime.datetime(2014, 1, 1, 3, 0)
+        volume1 = mock.MagicMock(id='1', project_id='fake-project',
+                                 created_at=volume1_created,
+                                 deleted_at=volume1_deleted)
+        volume_get_active_by_window.return_value = [volume1]
+        extra_info = {
+            'audit_period_beginning': str(begin),
+            'audit_period_ending': str(end),
+        }
+        local_extra_info_create = {
+            'audit_period_beginning': str(volume1.created_at),
+            'audit_period_ending': str(volume1.created_at),
+        }
+        local_extra_info_delete = {
+            'audit_period_beginning': str(volume1.deleted_at),
+            'audit_period_ending': str(volume1.deleted_at),
+        }
+
+        def _notify_about_volume_usage(*args, **kwargs):
+            if 'delete.end' in args:
+                raise Exception()
+            else:
+                pass
+
+        notify_about_volume_usage.side_effect = _notify_about_volume_usage
+
+        volume_usage_audit.main()
+
+        get_admin_context.assert_called_once_with()
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        get_logger.assert_called_once_with('cinder')
+        rpc_init.assert_called_once_with(CONF)
+        last_completed_audit_period.assert_called_once_with()
+        volume_get_active_by_window.assert_called_once_with(ctxt, begin, end)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'exists', extra_usage_info=extra_info)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'create.start',
+            extra_usage_info=local_extra_info_create)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'create.end',
+            extra_usage_info=local_extra_info_create)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'delete.start',
+            extra_usage_info=local_extra_info_delete)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'delete.end',
+            extra_usage_info=local_extra_info_delete)
+
+    @mock.patch('cinder.volume.utils.notify_about_snapshot_usage')
+    @mock.patch('cinder.db.snapshot_get_active_by_window')
+    @mock.patch('cinder.volume.utils.notify_about_volume_usage')
+    @mock.patch('cinder.db.volume_get_active_by_window')
+    @mock.patch('cinder.utils.last_completed_audit_period')
+    @mock.patch('cinder.rpc.init')
+    @mock.patch('cinder.version.version_string')
+    @mock.patch('cinder.openstack.common.log.getLogger')
+    @mock.patch('cinder.openstack.common.log.setup')
+    @mock.patch('cinder.context.get_admin_context')
+    def test_main_send_snapshot_error(self, get_admin_context,
+                                      log_setup, get_logger,
+                                      version_string, rpc_init,
+                                      last_completed_audit_period,
+                                      volume_get_active_by_window,
+                                      notify_about_volume_usage,
+                                      snapshot_get_active_by_window,
+                                      notify_about_snapshot_usage):
+        CONF.set_override('send_actions', True)
+        CONF.set_override('start_time', '2014-01-01 01:00:00')
+        CONF.set_override('end_time', '2014-02-02 02:00:00')
+        begin = datetime.datetime(2014, 1, 1, 1, 0)
+        end = datetime.datetime(2014, 2, 2, 2, 0)
+        ctxt = context.RequestContext('fake-user', 'fake-project')
+        get_admin_context.return_value = ctxt
+        last_completed_audit_period.return_value = (begin, end)
+        snapshot1_created = datetime.datetime(2014, 1, 1, 2, 0)
+        snapshot1_deleted = datetime.datetime(2014, 1, 1, 3, 0)
+        snapshot1 = mock.MagicMock(id='1', project_id='fake-project',
+                                   created_at=snapshot1_created,
+                                   deleted_at=snapshot1_deleted)
+        volume_get_active_by_window.return_value = []
+        snapshot_get_active_by_window.return_value = [snapshot1]
+        extra_info = {
+            'audit_period_beginning': str(begin),
+            'audit_period_ending': str(end),
+        }
+        local_extra_info_create = {
+            'audit_period_beginning': str(snapshot1.created_at),
+            'audit_period_ending': str(snapshot1.created_at),
+        }
+        local_extra_info_delete = {
+            'audit_period_beginning': str(snapshot1.deleted_at),
+            'audit_period_ending': str(snapshot1.deleted_at),
+        }
+
+        def _notify_about_snapshot_usage(*args, **kwargs):
+            # notify_about_snapshot_usage raises an exception, but does not
+            # block
+            raise Exception()
+
+        notify_about_snapshot_usage.side_effect = _notify_about_snapshot_usage
+
+        volume_usage_audit.main()
+
+        get_admin_context.assert_called_once_with()
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        get_logger.assert_called_once_with('cinder')
+        rpc_init.assert_called_once_with(CONF)
+        last_completed_audit_period.assert_called_once_with()
+        volume_get_active_by_window.assert_called_once_with(ctxt, begin, end)
+        self.assertFalse(notify_about_volume_usage.called)
+        notify_about_snapshot_usage.assert_any_call(ctxt, snapshot1, 'exists',
+                                                    extra_info)
+        notify_about_snapshot_usage.assert_any_call(
+            ctxt, snapshot1, 'create.start',
+            extra_usage_info=local_extra_info_create)
+        notify_about_snapshot_usage.assert_any_call(
+            ctxt, snapshot1, 'delete.start',
+            extra_usage_info=local_extra_info_delete)
+
+    @mock.patch('cinder.volume.utils.notify_about_snapshot_usage')
+    @mock.patch('cinder.db.snapshot_get_active_by_window')
+    @mock.patch('cinder.volume.utils.notify_about_volume_usage')
+    @mock.patch('cinder.db.volume_get_active_by_window')
+    @mock.patch('cinder.utils.last_completed_audit_period')
+    @mock.patch('cinder.rpc.init')
+    @mock.patch('cinder.version.version_string')
+    @mock.patch('cinder.openstack.common.log.getLogger')
+    @mock.patch('cinder.openstack.common.log.setup')
+    @mock.patch('cinder.context.get_admin_context')
+    def test_main(self, get_admin_context, log_setup, get_logger,
+                  version_string, rpc_init, last_completed_audit_period,
+                  volume_get_active_by_window, notify_about_volume_usage,
+                  snapshot_get_active_by_window, notify_about_snapshot_usage):
+        CONF.set_override('send_actions', True)
+        CONF.set_override('start_time', '2014-01-01 01:00:00')
+        CONF.set_override('end_time', '2014-02-02 02:00:00')
+        begin = datetime.datetime(2014, 1, 1, 1, 0)
+        end = datetime.datetime(2014, 2, 2, 2, 0)
+        ctxt = context.RequestContext('fake-user', 'fake-project')
+        get_admin_context.return_value = ctxt
+        last_completed_audit_period.return_value = (begin, end)
+
+        volume1_created = datetime.datetime(2014, 1, 1, 2, 0)
+        volume1_deleted = datetime.datetime(2014, 1, 1, 3, 0)
+        volume1 = mock.MagicMock(id='1', project_id='fake-project',
+                                 created_at=volume1_created,
+                                 deleted_at=volume1_deleted)
+        volume_get_active_by_window.return_value = [volume1]
+        extra_info = {
+            'audit_period_beginning': str(begin),
+            'audit_period_ending': str(end),
+        }
+        extra_info_volume_create = {
+            'audit_period_beginning': str(volume1.created_at),
+            'audit_period_ending': str(volume1.created_at),
+        }
+        extra_info_volume_delete = {
+            'audit_period_beginning': str(volume1.deleted_at),
+            'audit_period_ending': str(volume1.deleted_at),
+        }
+
+        snapshot1_created = datetime.datetime(2014, 1, 1, 2, 0)
+        snapshot1_deleted = datetime.datetime(2014, 1, 1, 3, 0)
+        snapshot1 = mock.MagicMock(id='1', project_id='fake-project',
+                                   created_at=snapshot1_created,
+                                   deleted_at=snapshot1_deleted)
+        snapshot_get_active_by_window.return_value = [snapshot1]
+        extra_info_snapshot_create = {
+            'audit_period_beginning': str(snapshot1.created_at),
+            'audit_period_ending': str(snapshot1.created_at),
+        }
+        extra_info_snapshot_delete = {
+            'audit_period_beginning': str(snapshot1.deleted_at),
+            'audit_period_ending': str(snapshot1.deleted_at),
+        }
+
+        volume_usage_audit.main()
+
+        get_admin_context.assert_called_once_with()
+        self.assertEqual(CONF.project, 'cinder')
+        self.assertEqual(CONF.version, version.version_string())
+        log_setup.assert_called_once_with("cinder")
+        get_logger.assert_called_once_with('cinder')
+        rpc_init.assert_called_once_with(CONF)
+        last_completed_audit_period.assert_called_once_with()
+        volume_get_active_by_window.assert_called_once_with(ctxt, begin, end)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'exists', extra_usage_info=extra_info)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'create.start',
+            extra_usage_info=extra_info_volume_create)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'create.end',
+            extra_usage_info=extra_info_volume_create)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'delete.start',
+            extra_usage_info=extra_info_volume_delete)
+        notify_about_volume_usage.assert_any_call(
+            ctxt, volume1, 'delete.end',
+            extra_usage_info=extra_info_volume_delete)
+
+        notify_about_snapshot_usage.assert_any_call(ctxt, snapshot1,
+                                                    'exists', extra_info)
+        notify_about_snapshot_usage.assert_any_call(
+            ctxt, snapshot1, 'create.start',
+            extra_usage_info=extra_info_snapshot_create)
+        notify_about_snapshot_usage.assert_any_call(
+            ctxt, snapshot1, 'create.end',
+            extra_usage_info=extra_info_snapshot_create)
+        notify_about_snapshot_usage.assert_any_call(
+            ctxt, snapshot1, 'delete.start',
+            extra_usage_info=extra_info_snapshot_delete)
+        notify_about_snapshot_usage.assert_any_call(
+            ctxt, snapshot1, 'delete.end',
+            extra_usage_info=extra_info_snapshot_delete)
index d7b6fa2c41887e67c91e8dbe843ed25a05c0c6a9..6956d3d5a2be4c915b8712dde0c4e676c2a48d1f 100755 (executable)
@@ -190,7 +190,7 @@ function warn_on_flake8_without_venv {
 function run_pep8 {
   echo "Running flake8 ..."
   warn_on_flake8_without_venv
-  bash -c "${wrapper} flake8 cinder* bin/*"
+  bash -c "${wrapper} flake8"
 }
 
 
index 9fff7803d4c6ced4ef03b6ca472c894d608db0ce..d26905bff5bdef49f63ff1e5dc58ac3da8da4542 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -24,15 +24,6 @@ setup-hooks =
 [files]
 packages =
     cinder
-scripts =
-    bin/cinder-all
-    bin/cinder-api
-    bin/cinder-backup
-    bin/cinder-manage
-    bin/cinder-rtstool
-    bin/cinder-scheduler
-    bin/cinder-volume
-    bin/cinder-volume-usage-audit
 
 [entry_points]
 cinder.scheduler.filters =
@@ -49,7 +40,15 @@ cinder.scheduler.weights =
     ChanceWeigher = cinder.scheduler.weights.chance:ChanceWeigher
     VolumeNumberWeigher = cinder.scheduler.weights.volume_number:VolumeNumberWeigher
 console_scripts =
+    cinder-all = cinder.cmd.all:main
+    cinder-api = cinder.cmd.api:main
+    cinder-backup = cinder.cmd.backup:main
+    cinder-manage = cinder.cmd.manage:main
     cinder-rootwrap = oslo.rootwrap.cmd:main
+    cinder-rtstool = cinder.cmd.rtstool:main
+    cinder-scheduler = cinder.cmd.scheduler:main
+    cinder-volume = cinder.cmd.volume:main
+    cinder-volume-usage-audit = cinder.cmd.volume_usage_audit:main
 # These are for backwards compat with Havana notification_driver configuration values
 oslo.messaging.notify.drivers =
     cinder.openstack.common.notifier.log_notifier = oslo.messaging.notify._impl_log:LogDriver
diff --git a/tox.ini b/tox.ini
index 1b30f096670655b160a61d4325f6cd510cc4eddf..07facce40e26992a0cd45be68e0ec327cc368c83 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -23,7 +23,6 @@ downloadcache = ~/cache/pip
 [testenv:pep8]
 commands =
   flake8 {posargs} . cinder/common
-  flake8 --filename=cinder* bin
   # Check that .po and .pot files are valid:
   bash -c "find cinder -type f -regex '.*\.pot?' -print0|xargs -0 -n 1 msgfmt --check-format -o /dev/null"