Merge "Reorganize project feature config options"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index cd4faea..e6442c7 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -143,36 +143,37 @@
 # catalog, the first found one is used.
 #region = RegionOne
 
+# Expected first device name when a volume is attached to an instance
+volume_device_name = vdb
+
+[compute-feature-enabled]
 # Does the Compute API support creation of images?
-create_image_enabled = true
+create_image = true
 
 # For resize to work with libvirt/kvm, one of the following must be true:
 # Single node: allow_resize_to_same_host=true must be set in nova.conf
 # Cluster: the 'nova' user must have scp access between cluster nodes
-resize_available = true
+resize = true
 
 # Does the compute API support changing the admin password?
-change_password_available = true
+change_password = false
 
 # Run live migration tests (requires 2 hosts)
-live_migration_available = false
+live_migration = false
 
 # Use block live migration (Otherwise, non-block migration will be
 # performed, which requires XenServer pools in case of using XS)
-use_block_migration_for_live_migration = false
+block_migration_for_live_migration = false
 
 # Supports iSCSI block migration - depends on a XAPI supporting
 # relax-xsm-sr-check
-block_migrate_supports_cinder_iscsi = false
+block_migrate_cinder_iscsi = false
 
 # When set to false, disk config tests are forced to skip
-disk_config_enabled = true
+disk_config = true
 
 # When set to false, flavor extra data tests are forced to skip
-flavor_extra_enabled = true
-
-# Expected first device name when a volume is attached to an instance
-volume_device_name = vdb
+flavor_extra = true
 
 [compute-admin]
 # This should be the username of a user WITH administrative privileges
@@ -258,10 +259,8 @@
 # Number of seconds to time out on waiting for a volume
 # to be available or reach an expected status
 build_timeout = 300
-# Runs Cinder multi-backend tests (requires 2 backends declared in cinder.conf)
-# They must have different volume_backend_name (backend1_name and backend2_name
-# have to be different)
-multi_backend_enabled = false
+# If multi_backend is enabled there must be 2 volume_backend_names (
+# backend1_name and backend2_name) which have to be different)
 backend1_name = BACKEND_1
 backend2_name = BACKEND_2
 # Protocol and vendor of volume backend to target when testing volume-types.
@@ -269,6 +268,10 @@
 storage_protocol = iSCSI
 vendor_name = Open Source
 
+[volume-feature-enabled]
+#Runs Cinder multi-backend tests (requires 2 backends declared in cinder.conf)
+multi_backend = false
+
 [object-storage]
 # This section contains configuration options used when executing tests
 # against the OpenStack Object Storage API.
@@ -291,14 +294,16 @@
 # Number of seconds to wait while looping to check the status of a
 # container to container synchronization
 container_sync_interval = 5
-# Set to true if the Account Quota middleware is enabled
-accounts_quotas_available = true
-# Set to true if the Container Quota middleware is enabled
-container_quotas_available = true
 
 # Set operator role for tests that require creating a container
 operator_role = Member
 
+[object-feature-enabled]
+# Set to True if the Account Quota middleware is enabled
+accounts_quotas = True
+# Set to True if the Container Quota middleware is enabled
+container_quotas = True
+
 [boto]
 # This section contains configuration options used when executing tests
 # with boto.
diff --git a/tempest/api/compute/__init__.py b/tempest/api/compute/__init__.py
index 2c21740..a528754 100644
--- a/tempest/api/compute/__init__.py
+++ b/tempest/api/compute/__init__.py
@@ -22,11 +22,11 @@
 LOG = logging.getLogger(__name__)
 
 CONFIG = config.TempestConfig()
-CREATE_IMAGE_ENABLED = CONFIG.compute.create_image_enabled
-RESIZE_AVAILABLE = CONFIG.compute.resize_available
-CHANGE_PASSWORD_AVAILABLE = CONFIG.compute.change_password_available
-DISK_CONFIG_ENABLED = CONFIG.compute.disk_config_enabled
-FLAVOR_EXTRA_DATA_ENABLED = CONFIG.compute.flavor_extra_enabled
+CREATE_IMAGE_ENABLED = CONFIG.compute_feature_enabled.create_image
+RESIZE_AVAILABLE = CONFIG.compute_feature_enabled.resize
+CHANGE_PASSWORD_AVAILABLE = CONFIG.compute_feature_enabled.change_password
+DISK_CONFIG_ENABLED = CONFIG.compute_feature_enabled.disk_config
+FLAVOR_EXTRA_DATA_ENABLED = CONFIG.compute_feature_enabled.flavor_extra
 MULTI_USER = True
 
 
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 6f50a02..fc4a5e0 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -32,7 +32,8 @@
 
 class ServerActionsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
-    resize_available = tempest.config.TempestConfig().compute.resize_available
+    resize_available = tempest.config.TempestConfig().\
+        compute_feature_enabled.resize
     run_ssh = tempest.config.TempestConfig().compute.run_ssh
 
     def setUp(self):
diff --git a/tempest/api/compute/test_live_block_migration.py b/tempest/api/compute/test_live_block_migration.py
index bb8b372..7f68ab5 100644
--- a/tempest/api/compute/test_live_block_migration.py
+++ b/tempest/api/compute/test_live_block_migration.py
@@ -59,7 +59,8 @@
     def _migrate_server_to(self, server_id, dest_host):
         _resp, body = self.admin_servers_client.live_migrate_server(
             server_id, dest_host,
-            self.config.compute.use_block_migration_for_live_migration)
+            self.config.compute_feature_enabled.
+            block_migration_for_live_migration)
         return body
 
     def _get_host_other_than(self, host):
@@ -97,7 +98,7 @@
             self.volumes_client.wait_for_volume_status(volume_id, 'available')
         self.volumes_client.delete_volume(volume_id)
 
-    @testtools.skipIf(not CONF.compute.live_migration_available,
+    @testtools.skipIf(not CONF.compute_feature_enabled.live_migration,
                       'Live migration not available')
     @attr(type='gate')
     def test_live_block_migration(self):
@@ -112,7 +113,7 @@
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
         self.assertEqual(target_host, self._get_host_for_server(server_id))
 
-    @testtools.skipIf(not CONF.compute.live_migration_available,
+    @testtools.skipIf(not CONF.compute_feature_enabled.live_migration,
                       'Live migration not available')
     @attr(type='gate')
     def test_invalid_host_for_migration(self):
@@ -124,10 +125,12 @@
                           server_id, target_host)
         self.assertEqual('ACTIVE', self._get_server_status(server_id))
 
-    @testtools.skipIf(not CONF.compute.live_migration_available or
-                      not CONF.compute.use_block_migration_for_live_migration,
+    @testtools.skipIf(not CONF.compute_feature_enabled.live_migration or not
+                      CONF.compute_feature_enabled.
+                      block_migration_for_live_migration,
                       'Block Live migration not available')
-    @testtools.skipIf(not CONF.compute.block_migrate_supports_cinder_iscsi,
+    @testtools.skipIf(not CONF.compute_feature_enabled.
+                      block_migrate_cinder_iscsi,
                       'Block Live migration not configured for iSCSI')
     @attr(type='gate')
     def test_iscsi_volume(self):
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index 65fe1ac..a90d3f4 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -20,14 +20,14 @@
 from tempest import clients
 from tempest.common.utils.data_utils import arbitrary_string
 from tempest.common.utils.data_utils import rand_name
-import tempest.config
+from tempest import config
 from tempest import exceptions
 from tempest.test import attr
 
 
 class AccountQuotasTest(base.BaseObjectTest):
     accounts_quotas_available = \
-        tempest.config.TempestConfig().object_storage.accounts_quotas_available
+        config.TempestConfig().object_storage_feature_enabled.accounts_quotas
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/object_storage/test_container_quotas.py b/tempest/api/object_storage/test_container_quotas.py
index 31fe711..2e0d76a 100644
--- a/tempest/api/object_storage/test_container_quotas.py
+++ b/tempest/api/object_storage/test_container_quotas.py
@@ -33,7 +33,7 @@
 class ContainerQuotasTest(base.BaseObjectTest):
     """Attemps to test the perfect behavior of quotas in a container."""
     container_quotas_available = \
-        config.TempestConfig().object_storage.container_quotas_available
+        config.TempestConfig().object_storage_feature_enabled.container_quotas
 
     def setUp(self):
         """Creates and sets a container with quotas.
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index 797aa71..eada639 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -28,7 +28,7 @@
     @classmethod
     def setUpClass(cls):
         super(VolumeMultiBackendTest, cls).setUpClass()
-        if not cls.config.volume.multi_backend_enabled:
+        if not cls.config.volume_feature_enabled.multi_backend:
             raise cls.skipException("Cinder multi-backend feature disabled")
 
         cls.backend1_name = cls.config.volume.backend1_name
diff --git a/tempest/config.py b/tempest/config.py
index 18eac02..4bae9e4 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -137,28 +137,6 @@
                default="password",
                help="Password used to authenticate to an instance using "
                     "the alternate image."),
-    cfg.BoolOpt('resize_available',
-                default=False,
-                help="Does the test environment support resizing?"),
-    cfg.BoolOpt('live_migration_available',
-                default=False,
-                help="Does the test environment support live migration "
-                     "available?"),
-    cfg.BoolOpt('use_block_migration_for_live_migration',
-                default=False,
-                help="Does the test environment use block devices for live "
-                     "migration"),
-    cfg.BoolOpt('block_migrate_supports_cinder_iscsi',
-                default=False,
-                help="Does the test environment block migration support "
-                     "cinder iSCSI volumes"),
-    cfg.BoolOpt('change_password_available',
-                default=False,
-                help="Does the test environment support changing the admin "
-                     "password?"),
-    cfg.BoolOpt('create_image_enabled',
-                default=False,
-                help="Does the test environment support snapshots?"),
     cfg.IntOpt('build_interval',
                default=10,
                help="Time in seconds between build status checks."),
@@ -212,18 +190,47 @@
                default=None,
                help="Path to a private key file for SSH access to remote "
                     "hosts"),
-    cfg.BoolOpt('disk_config_enabled',
-                default=True,
-                help="If false, skip disk config tests"),
-    cfg.BoolOpt('flavor_extra_enabled',
-                default=True,
-                help="If false, skip flavor extra data test"),
     cfg.StrOpt('volume_device_name',
                default='vdb',
                help="Expected device name when a volume is attached to "
                     "an instance")
 ]
 
+compute_features_group = cfg.OptGroup(name='compute-feature-enabled',
+                                      title="Enabled Compute Service Features")
+
+ComputeFeaturesGroup = [
+    cfg.BoolOpt('disk_config',
+                default=True,
+                help="If false, skip disk config tests"),
+    cfg.BoolOpt('flavor_extra',
+                default=True,
+                help="If false, skip flavor extra data test"),
+    cfg.BoolOpt('change_password',
+                default=False,
+                help="Does the test environment support changing the admin "
+                     "password?"),
+    cfg.BoolOpt('create_image',
+                default=False,
+                help="Does the test environment support snapshots?"),
+    cfg.BoolOpt('resize',
+                default=False,
+                help="Does the test environment support resizing?"),
+    cfg.BoolOpt('live_migration',
+                default=False,
+                help="Does the test environment support live migration "
+                     "available?"),
+    cfg.BoolOpt('block_migration_for_live_migration',
+                default=False,
+                help="Does the test environment use block devices for live "
+                     "migration"),
+    cfg.BoolOpt('block_migrate_cinder_iscsi',
+                default=False,
+                help="Does the test environment block migration support "
+                     "cinder iSCSI volumes")
+]
+
+
 compute_admin_group = cfg.OptGroup(name='compute-admin',
                                    title="Compute Admin Options")
 
@@ -317,9 +324,6 @@
                     "of identity.region is used instead. If no such region "
                     "is found in the service catalog, the first found one is "
                     "used."),
-    cfg.BoolOpt('multi_backend_enabled',
-                default=False,
-                help="Runs Cinder multi-backend test (requires 2 backends)"),
     cfg.StrOpt('backend1_name',
                default='BACKEND_1',
                help="Name of the backend1 (must be declared in cinder.conf)"),
@@ -337,6 +341,15 @@
                help='Disk format to use when copying a volume to image'),
 ]
 
+volume_feature_group = cfg.OptGroup(name='volume-feature-enabled',
+                                    title='Enabled Cinder Features')
+
+VolumeFeaturesGroup = [
+    cfg.BoolOpt('multi_backend',
+                default=False,
+                help="Runs Cinder multi-backend test (requires 2 backends)")
+]
+
 
 object_storage_group = cfg.OptGroup(name='object-storage',
                                     title='Object Storage Service Options')
@@ -359,19 +372,26 @@
                default=5,
                help="Number of seconds to wait while looping to check the"
                     "status of a container to container synchronization"),
-    cfg.BoolOpt('accounts_quotas_available',
-                default=True,
-                help="Set to True if the Account Quota middleware is enabled"),
-    cfg.BoolOpt('container_quotas_available',
-                default=True,
-                help="Set to True if the container quota middleware "
-                     "is enabled"),
     cfg.StrOpt('operator_role',
                default='Member',
                help="Role to add to users created for swift tests to "
                     "enable creating containers"),
 ]
 
+object_storage_feature_group = cfg.OptGroup(
+    name='object-storage-feature-enabled',
+    title='Enabled object-storage features')
+
+ObjectStoreFeaturesGroup = [
+    cfg.BoolOpt('container_quotas',
+                default=True,
+                help="Set to True if the container quota middleware "
+                     "is enabled"),
+    cfg.BoolOpt('accounts_quotas',
+                default=True,
+                help="Set to True if the Account Quota middleware is enabled"),
+]
+
 
 orchestration_group = cfg.OptGroup(name='orchestration',
                                    title='Orchestration Service Options')
@@ -614,11 +634,17 @@
         LOG.info("Using tempest config file %s" % path)
 
         register_opt_group(cfg.CONF, compute_group, ComputeGroup)
+        register_opt_group(cfg.CONF, compute_features_group,
+                           ComputeFeaturesGroup)
         register_opt_group(cfg.CONF, identity_group, IdentityGroup)
         register_opt_group(cfg.CONF, image_group, ImageGroup)
         register_opt_group(cfg.CONF, network_group, NetworkGroup)
         register_opt_group(cfg.CONF, volume_group, VolumeGroup)
+        register_opt_group(cfg.CONF, volume_feature_group,
+                           VolumeFeaturesGroup)
         register_opt_group(cfg.CONF, object_storage_group, ObjectStoreGroup)
+        register_opt_group(cfg.CONF, object_storage_feature_group,
+                           ObjectStoreFeaturesGroup)
         register_opt_group(cfg.CONF, orchestration_group, OrchestrationGroup)
         register_opt_group(cfg.CONF, dashboard_group, DashboardGroup)
         register_opt_group(cfg.CONF, boto_group, BotoGroup)
@@ -629,11 +655,15 @@
                            ServiceAvailableGroup)
         register_opt_group(cfg.CONF, debug_group, DebugGroup)
         self.compute = cfg.CONF.compute
+        self.compute_feature_enabled = cfg.CONF['compute-feature-enabled']
         self.identity = cfg.CONF.identity
         self.images = cfg.CONF.image
         self.network = cfg.CONF.network
         self.volume = cfg.CONF.volume
+        self.volume_feature_enabled = cfg.CONF['volume-feature-enabled']
         self.object_storage = cfg.CONF['object-storage']
+        self.object_storage_feature_enabled = cfg.CONF[
+            'object-storage-feature-enabled']
         self.orchestration = cfg.CONF.orchestration
         self.dashboard = cfg.CONF.dashboard
         self.boto = cfg.CONF.boto
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 853b1ba..112c8a2 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -35,7 +35,7 @@
     def setUpClass(cls):
         super(TestServerAdvancedOps, cls).setUpClass()
 
-        if not cls.config.compute.resize_available:
+        if not cls.config.compute_feature_enabled.resize:
             msg = "Skipping test - resize not available on this host"
             raise cls.skipException(msg)