]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Allow setting a rootwrap cmd for functional tests
authorMaru Newby <marun@redhat.com>
Wed, 2 Jul 2014 00:02:08 +0000 (00:02 +0000)
committerMaru Newby <marun@redhat.com>
Wed, 2 Jul 2014 00:02:08 +0000 (00:02 +0000)
Previously, sudo-requiring functional tests hardcoded the use of
'sudo' as the root helper.  Devstack gate jobs do not allow
password-less invocation of 'sudo', though, so such tests were unable
to run in the gate.  This patch adds the ability to configure the
rootwrap command installed by devstack by setting the OS_ROOTWRAP_CMD
environment variable in the test execution environment, allowing
sudo-requiring tests to run.

Change-Id: I3b8f6b4f14ac1743e08b9401f73951885165350a
Partial-bug: #1336172

neutron/tests/functional/agent/linux/base.py
neutron/tests/functional/agent/linux/test_ovsdb_monitor.py
neutron/tests/functional/base.py [new file with mode: 0644]
neutron/tests/functional/sanity/test_sanity.py

index bdd718c85e18090b35969c6bfac858310148df10..5891c872e9fa66e4cde7d0f54a2c4f13ba628ceb 100644 (file)
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import os
 import random
 
 from neutron.agent.linux import ovs_lib
 from neutron.agent.linux import utils
 from neutron.common import constants as n_const
-from neutron.tests import base
+from neutron.tests.functional import base as functional_base
 
 
 BR_PREFIX = 'test-br'
 
 
-class BaseLinuxTestCase(base.BaseTestCase):
-    def setUp(self, root_helper='sudo'):
-        super(BaseLinuxTestCase, self).setUp()
+class BaseLinuxTestCase(functional_base.BaseSudoTestCase):
 
-        self.root_helper = root_helper
-
-    def check_command(self, cmd, error_text, skip_msg):
+    def check_command(self, cmd, error_text, skip_msg, root_helper=None):
         try:
-            utils.execute(cmd)
+            utils.execute(cmd, root_helper=root_helper)
         except RuntimeError as e:
             if error_text in str(e):
                 self.skipTest(skip_msg)
             raise
 
-    def check_sudo_enabled(self):
-        if os.environ.get('OS_SUDO_TESTING') not in base.TRUE_STRING:
-            self.skipTest('testing with sudo is not enabled')
-
     def get_rand_name(self, max_length, prefix='test'):
         name = prefix + str(random.randint(1, 0x7fffffff))
         return name[:max_length]
@@ -64,8 +55,8 @@ class BaseLinuxTestCase(base.BaseTestCase):
 
 
 class BaseOVSLinuxTestCase(BaseLinuxTestCase):
-    def setUp(self, root_helper='sudo'):
-        super(BaseOVSLinuxTestCase, self).setUp(root_helper)
+    def setUp(self):
+        super(BaseOVSLinuxTestCase, self).setUp()
         self.ovs = ovs_lib.BaseOVS(self.root_helper)
 
     def create_ovs_bridge(self, br_prefix=BR_PREFIX):
index 35ad48d1cac7a132a90903fdcf92955b2e8752ad..9d8570deda17aa6cbac725d5587d7ffa42a68913 100644 (file)
@@ -17,28 +17,30 @@ Tests in this module will be skipped unless:
 
  - ovsdb-client is installed
 
- - ovsdb-client can be invoked via password-less sudo
+ - ovsdb-client can be invoked password-less via the configured root helper
 
- - OS_SUDO_TESTING is set to '1' or 'True' in the test execution
-   environment
-
-
-The jenkins gate does not allow direct sudo invocation during test
-runs, but configuring OS_SUDO_TESTING ensures that developers are
-still able to execute tests that require the capability.
+ - sudo testing is enabled (see neutron.tests.functional.base for details)
 """
 
 import eventlet
 
 from neutron.agent.linux import ovsdb_monitor
-from neutron.tests.functional.agent.linux import base as base_agent
+from neutron.tests.functional.agent.linux import base as linux_base
+from neutron.tests.functional import base as functional_base
 
 
-class BaseMonitorTest(base_agent.BaseOVSLinuxTestCase):
+class BaseMonitorTest(linux_base.BaseOVSLinuxTestCase):
 
     def setUp(self):
-        # Emulate using a rootwrap script with sudo
-        super(BaseMonitorTest, self).setUp(root_helper='sudo sudo')
+        super(BaseMonitorTest, self).setUp()
+
+        rootwrap_not_configured = (self.root_helper ==
+                                   functional_base.SUDO_CMD)
+        if rootwrap_not_configured:
+            # The monitor tests require a nested invocation that has
+            # to be emulated by double sudo if rootwrap is not
+            # configured.
+            self.root_helper = '%s %s' % (self.root_helper, self.root_helper)
 
         self._check_test_requirements()
         self.bridge = self.create_ovs_bridge()
@@ -47,9 +49,10 @@ class BaseMonitorTest(base_agent.BaseOVSLinuxTestCase):
         self.check_sudo_enabled()
         self.check_command(['which', 'ovsdb-client'],
                            'Exit code: 1', 'ovsdb-client is not installed')
-        self.check_command(['sudo', '-n', 'ovsdb-client', 'list-dbs'],
+        self.check_command(['ovsdb-client', 'list-dbs'],
                            'Exit code: 1',
-                           'password-less sudo not granted for ovsdb-client')
+                           'password-less sudo not granted for ovsdb-client',
+                           root_helper=self.root_helper)
 
 
 class TestOvsdbMonitor(BaseMonitorTest):
diff --git a/neutron/tests/functional/base.py b/neutron/tests/functional/base.py
new file mode 100644 (file)
index 0000000..471acae
--- /dev/null
@@ -0,0 +1,53 @@
+# Copyright (c) 2014 OpenStack Foundation.
+# All Rights Reserved.
+#
+#    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 os
+
+from neutron.tests import base
+
+
+SUDO_CMD = 'sudo -n'
+
+
+class BaseSudoTestCase(base.BaseTestCase):
+    """
+    Base class for tests requiring invocation of commands via a root helper.
+
+    Inheritors of this class should call check_sudo_enabled() in
+    setUp() to ensure that tests requiring sudo are skipped unless
+    OS_SUDO_TESTING is set to '1' or 'True' in the test execution
+    environment.  This is intended to allow developers to run the
+    functional suite (e.g. tox -e functional) without test failures if
+    sudo invocations are not allowed.
+
+    Running sudo tests in the upstream gate jobs
+    (*-neutron-dsvm-functional) requires the additional step of
+    setting OS_ROOTWRAP_CMD to the rootwrap command configured by
+    devstack, e.g.
+
+      sudo /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf
+
+    Gate jobs do not allow invocations of sudo without rootwrap to
+    ensure that rootwrap configuration gets as much testing as
+    possible.
+    """
+
+    def setUp(self):
+        super(BaseSudoTestCase, self).setUp()
+        self.root_helper = os.environ.get('OS_ROOTWRAP_CMD', SUDO_CMD)
+
+    def check_sudo_enabled(self):
+        if os.environ.get('OS_SUDO_TESTING') not in base.TRUE_STRING:
+            self.skipTest('testing with sudo is not enabled')
index be35484cb493741b1d494182b0b48887604cb2e3..2873dc7a586656b9efb1c545805a265dfd801cd9 100644 (file)
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import os
-
 from neutron.cmd.sanity import checks
 from neutron.tests import base
+from neutron.tests.functional import base as functional_base
 
 
 class SanityTestCase(base.BaseTestCase):
@@ -34,7 +33,7 @@ class SanityTestCase(base.BaseTestCase):
         checks.nova_notify_supported()
 
 
-class SanityTestCaseRoot(base.BaseTestCase):
+class SanityTestCaseRoot(functional_base.BaseSudoTestCase):
     """Sanity checks that require root access.
 
     Tests that just call checks.some_function() are to ensure that
@@ -43,14 +42,8 @@ class SanityTestCaseRoot(base.BaseTestCase):
     """
     def setUp(self):
         super(SanityTestCaseRoot, self).setUp()
-
-        self.root_helper = 'sudo'
         self.check_sudo_enabled()
 
-    def check_sudo_enabled(self):
-        if os.environ.get('OS_SUDO_TESTING') not in base.TRUE_STRING:
-            self.skipTest('testing with sudo is not enabled')
-
     def test_ovs_vxlan_support_runs(self):
         checks.vxlan_supported(self.root_helper)