Merge "Merge server response schema into one file"
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 4fe2e9f..e21deea 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -40,6 +40,24 @@
Eventually the config options for providing credentials to tempest will be
deprecated and removed in favor of the accounts.yaml file.
+Keystone Connection Info
+^^^^^^^^^^^^^^^^^^^^^^^^
+In order for tempest to be able to talk to your OpenStack deployment you need
+to provide it with information about how it communicates with keystone.
+This involves configuring the following options in the identity section:
+
+ #. auth_version
+ #. uri
+ #. uri_v3
+
+The *auth_version* option is used to tell tempest whether it should be using
+keystone's v2 or v3 api for communicating with keystone. (except for the
+identity api tests which will test a specific version) The 2 uri options are
+used to tell tempest the url of the keystone endpoint. The *uri* option is used
+for keystone v2 request and *uri_v3* is used for keystone v3. You want to ensure
+that which ever version you set for *auth_version* has its uri option defined.
+
+
Credential Provider Mechanisms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -123,3 +141,233 @@
is that if a test requires specific roles on accounts these tests can not be
run. This is because the config options do not give sufficient flexibility to
describe the roles assigned to a user for running the tests.
+
+Compute
+-------
+
+Flavors
+^^^^^^^
+For tempest to be able to create servers you need to specify flavors that it
+can use to boot the servers with. There are 2 options in the tempest config
+for doing this:
+
+ #. flavor_ref
+ #. flavor_ref_alt
+
+Both of these options are in the compute section of the config file and take
+in the flavor id (not the name) from nova. The *flavor_ref* option is what will
+be used for booting almost all of the guests, *flavor_ref_alt* is only used in
+tests where 2 different sized servers are required. (for example a resize test)
+
+Using a smaller flavor is generally recommended, when larger flavors are used
+the extra time required to bring up servers will likely affect total run time
+and probably require tweaking timeout values to ensure tests have ample time to
+finish.
+
+Images
+^^^^^^
+Just like with flavors, tempest needs to know which images to use for booting
+servers. There are 2 options in the compute section just like with flavors:
+
+ #. image_ref
+ #. image_ref_alt
+
+Both options are expecting an image id (not name) from nova. The *image_ref*
+option is what what will be used for booting the majority of servers in tempest.
+*image_ref_alt* is used for tests that require 2 images such as rebuild. If 2
+images are not available you can set both options to the same image_ref and
+those tests will be skipped.
+
+There are also options in the scenario section for images:
+
+ #. img_file
+ #. img_dir
+ #. aki_img_file
+ #. ari_img_file
+ #. ami_img_file
+ #. img_container_format
+ #. img_disk_format
+
+however unlike the other image options these are used for a very small subset
+of scenario tests which are uploading an image. These options are used to tell
+tempest where an image file is located and describe it's metadata for when it's
+uploaded.
+
+The behavior of these options is a bit convoluted (which will likely be fixed
+in future versions). You first need to specify *img_dir*, which is the directory
+tempest will look for the image files in. First it will check if the filename
+set for *img_file* could be found in *img_dir*. If it is found then the
+*img_container_format* and *img_disk_format* options are used to upload that
+image to glance. However if it's not found tempest will look for the 3 uec image
+file name options as a fallback. If neither is found the tests requiring an
+image to upload will fail.
+
+It is worth pointing out that using `cirros`_ is a very good choice for running
+tempest. It's what is used for upstream testing, they boot quickly and have a
+small footprint.
+
+.. _cirros: https://launchpad.net/cirros
+
+Networking
+----------
+OpenStack has a myriad of different networking configurations possible and
+depending on which of the 2 network backends, nova-network or neutron, you are
+using things can vary drastically. Due to this complexity Tempest has to provide
+a certain level of flexibility in it's configuration to ensure it will work
+against any cloud. This ends up causing a large number of permutations in
+Tempest's config around network configuration.
+
+
+Enabling Remote Access to Created Servers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+When Tempest creates servers for testing, some tests require being able to
+connect those servers. Depending on the configuration of the cloud, the methods
+for doing this can be different. In certain configurations it is required to
+specify a single network with server create calls. Accordingly, Tempest provides
+a few different methods for providing this information in configuration to try
+and ensure that regardless of the clouds configuration it'll still be able to
+run. This section covers the different methods of configuring Tempest to provide
+a network when creating servers.
+
+Fixed Network Name
+""""""""""""""""""
+This is the simplest method of specifying how networks should be used. You can
+just specify a single network name/label to use for all server creations. The
+limitation with this is that all tenants/projects and users must be able to see
+that network name/label if they were to perform a network list and be able to
+use it.
+
+If no network name is assigned in the config file and none of the below
+alternatives are used, then Tempest will not specify a network on server
+creations, which depending on the cloud configuration might prevent them from
+booting.
+
+To set a fixed network name simply do:
+
+ #. Set the fixed_network_name option in the compute group
+
+In the case that the configured fixed network name can not be found by a user
+network list call, it will be treated like one was not provided except that a
+warning will be logged stating that it couldn't be found.
+
+
+Accounts File
+"""""""""""""
+If you are using an accounts file to provide credentials for running Tempest
+then you can leverage it to also specify which network should be used with
+server creations on a per tenant/project and user pair basis. This provides
+the necessary flexibility to work with more intricate networking configurations
+by enabling the user to specify exactly which network to use for which
+tenants/projects. You can refer to the accounts.yaml sample file included in
+the tempest repo for the syntax around specifying networks in the file.
+
+However, specifying a network is not required when using an accounts file. If
+one is not specified you can use a fixed network name to specify the network to
+use when creating servers just as without an accounts file. However, any network
+specified in the accounts file will take precedence over the fixed network name
+provided. If no network is provided in the accounts file and a fixed network
+name is not set then no network will be included in create server requests.
+
+If a fixed network is provided and the accounts.yaml file also contains networks
+this has the benefit of enabling a couple more tests which require a static
+network to perform operations like server lists with a network filter. If a
+fixed network name is not provided these tests are skipped. Additionally, if a
+fixed network name is provided it will serve as a fallback in case of a
+misconfiguration or a missing network in the accounts file.
+
+
+With Tenant Isolation
+"""""""""""""""""""""
+With tenant isolation enabled and using nova-network then nothing changes. Your
+only option for configuration is to either set a fixed network name or not.
+However, in most cases it shouldn't matter because nova-network should have no
+problem booting a server with multiple networks. If this is not the case for
+your cloud then using an accounts file is recommended because it provides the
+necessary flexibility to describe your configuration. Tenant isolation is not
+able to dynamically allocate things as necessary if neutron is not enabled.
+
+With neutron and tenant isolation enabled there should not be any additional
+configuration necessary to enable Tempest to create servers with working
+networking, assuming you have properly configured the network section to work
+for your cloud. Tempest will dynamically create the neutron resources necessary
+to enable using servers with that network. Also, just as with the accounts
+file, if you specify a fixed network name while using neutron and tenant
+isolation it will enable running tests which require a static network and it
+will additionally be used as a fallback for server creation. However, unlike
+accounts.yaml this should never be triggered.
+
+Configuring Available Services
+------------------------------
+OpenStack is really a constellation of several different projects which
+are running together to create a cloud. However which projects you're running
+is not set in stone, and which services are running is up to the deployer.
+Tempest however needs to know which services are available so it can figure
+out which tests it is able to run and certain setup steps which differ based
+on the available services.
+
+The *service_available* section of the config file is used to set which
+services are available. It contains a boolean option for each service (except
+for keystone which is a hard requirement) set it to True if the service is
+available or False if it is not.
+
+Service Catalog
+^^^^^^^^^^^^^^^
+Each project which has its own REST API contains an entry in the service
+catalog. Like most things in OpenStack this is also completely configurable.
+However, for tempest to be able to figure out the endpoints to send REST API
+calls for each service to it needs to know how that project is defined in the
+service catalog. There are 3 options for each service section to accomplish
+this:
+
+ #. catalog_type
+ #. endpoint_type
+ #. region
+
+Setting *catalog_type* and *endpoint_type* should normally give Tempest enough
+information to determine which endpoint it should pull from the service
+catalog to use for talking to that particular service. However, if you're cloud
+has multiple regions available and you need to specify a particular one to use
+a service you can set the *region* option in that service's section.
+
+It should also be noted that the default values for these options are set
+to what devstack uses. (which is a de facto standard for service catalog
+entries) So often nothing actually needs to be set on these options to enable
+communication to a particular service. It is only if you are either not using
+the same *catalog_type* as devstack or you want Tempest to talk to a different
+endpoint type instead of publicURL for a service that these need to be changed.
+
+
+Service feature configuration
+-----------------------------
+
+OpenStack provides its deployers a myriad of different configuration options
+to enable anyone deploying it to create a cloud tailor-made for any individual
+use case. It provides options for several different backend type, databases,
+message queues, etc. However, the downside to this configurability is that
+certain operations and features aren't supported depending on the configuration.
+These features may or may not be discoverable from the API so the burden is
+often on the user to figure out what the cloud they're talking to supports.
+Besides the obvious interoperability issues with this it also leaves Tempest
+in an interesting situation trying to figure out which tests are expected to
+work. However, Tempest tests do not rely on dynamic api discovery for a feature
+(assuming one exists). Instead Tempest has to be explicitly configured as to
+which optional features are enabled. This is in order to prevent bugs in the
+discovery mechanisms from masking failures.
+
+The service feature-enabled config sections are how Tempest addresses the
+optional feature question. Each service that has tests for optional features
+contains one of these sections. The only options in it are boolean options
+with the name of a feature which is used. If it is set to false any test which
+depends on that functionality will be skipped. For a complete list of all these
+options refer to the sample config file.
+
+
+API Extensions
+^^^^^^^^^^^^^^
+The service feature-enabled sections often contain an *api-extensions* option
+(or in the case of swift a *discoverable_apis* option) this is used to tell
+tempest which api extensions (or configurable middleware) is used in your
+deployment. It has 2 valid config states, either it contains a single value
+"all" (which is the default) which means that every api extension is assumed
+to be enabled, or it is set to a list of each individual extension that is
+enabled for that service.
diff --git a/requirements.txt b/requirements.txt
index bf7471e..0d7fc0d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -12,7 +12,6 @@
python-glanceclient>=0.15.0
python-cinderclient>=1.1.0
python-heatclient>=0.3.0
-python-swiftclient>=2.2.0
testrepository>=0.0.18
oslo.concurrency>=1.8.0,<1.9.0 # Apache-2.0
oslo.config>=1.9.3,<1.10.0 # Apache-2.0
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index 3a34a2e..c4cb11a 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -102,7 +102,7 @@
aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- body = self.client.get_aggregate(aggregate['id'])
+ body = self.client.show_aggregate(aggregate['id'])
self.assertEqual(aggregate['name'], body['name'])
self.assertEqual(aggregate['availability_zone'],
body['availability_zone'])
@@ -114,7 +114,7 @@
self.assertEqual(meta, body["metadata"])
# verify the metadata has been set
- body = self.client.get_aggregate(aggregate['id'])
+ body = self.client.show_aggregate(aggregate['id'])
self.assertEqual(meta, body["metadata"])
@test.attr(type='gate')
@@ -198,7 +198,7 @@
self.client.add_host(aggregate['id'], self.host)
self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
- body = self.client.get_aggregate(aggregate['id'])
+ body = self.client.show_aggregate(aggregate['id'])
self.assertEqual(aggregate_name, body['name'])
self.assertIsNone(body['availability_zone'])
self.assertIn(self.host, body['hosts'])
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index f6d6ad3..882986c 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -110,7 +110,7 @@
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(lib_exc.Forbidden,
- self.user_client.get_aggregate,
+ self.user_client.show_aggregate,
aggregate['id'])
@test.attr(type=['negative', 'gate'])
@@ -125,7 +125,7 @@
def test_aggregate_get_details_with_invalid_id(self):
# Get aggregate details with invalid id should raise exceptions.
self.assertRaises(lib_exc.NotFound,
- self.client.get_aggregate, -1)
+ self.client.show_aggregate, -1)
@test.attr(type=['negative', 'gate'])
@test.idempotent_id('0ef07828-12b4-45ba-87cc-41425faf5711')
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index eadc15a..1ec171b 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -32,12 +32,12 @@
@test.idempotent_id('d3431479-8a09-4f76-aa2d-26dc580cb27c')
def test_get_availability_zone_list(self):
# List of availability zone
- availability_zone = self.client.get_availability_zone_list()
+ availability_zone = self.client.list_availability_zones()
self.assertTrue(len(availability_zone) > 0)
@test.attr(type='gate')
@test.idempotent_id('ef726c58-530f-44c2-968c-c7bed22d5b8c')
def test_get_availability_zone_list_detail(self):
# List of availability zones and available services
- availability_zone = self.client.get_availability_zone_list_detail()
+ availability_zone = self.client.list_availability_zones(detail=True)
self.assertTrue(len(availability_zone) > 0)
diff --git a/tempest/api/compute/admin/test_availability_zone_negative.py b/tempest/api/compute/admin/test_availability_zone_negative.py
index d6e577e..e9de628 100644
--- a/tempest/api/compute/admin/test_availability_zone_negative.py
+++ b/tempest/api/compute/admin/test_availability_zone_negative.py
@@ -36,4 +36,4 @@
# non-administrator user
self.assertRaises(
lib_exc.Forbidden,
- self.non_adm_client.get_availability_zone_list_detail)
+ self.non_adm_client.list_availability_zones, detail=True)
diff --git a/tempest/api/compute/admin/test_baremetal_nodes.py b/tempest/api/compute/admin/test_baremetal_nodes.py
index 64099c3..9b88938 100644
--- a/tempest/api/compute/admin/test_baremetal_nodes.py
+++ b/tempest/api/compute/admin/test_baremetal_nodes.py
@@ -52,5 +52,5 @@
# Test getting each individually
for node in test_nodes:
- baremetal_node = self.client.get_baremetal_node(node['uuid'])
+ baremetal_node = self.client.show_baremetal_node(node['uuid'])
self.assertEqual(node['uuid'], baremetal_node['id'])
diff --git a/tempest/api/compute/certificates/test_certificates.py b/tempest/api/compute/certificates/test_certificates.py
index 2be201a..4fe87ad 100644
--- a/tempest/api/compute/certificates/test_certificates.py
+++ b/tempest/api/compute/certificates/test_certificates.py
@@ -33,6 +33,6 @@
@test.idempotent_id('3ac273d0-92d2-4632-bdfc-afbc21d4606c')
def test_get_root_certificate(self):
# get the root certificate
- body = self.certificates_client.get_certificate('root')
+ body = self.certificates_client.show_certificate('root')
self.assertIn('data', body)
self.assertIn('private_key', body)
diff --git a/tempest/api/compute/security_groups/test_security_groups_negative.py b/tempest/api/compute/security_groups/test_security_groups_negative.py
index e069f6e..3a6b42d 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -156,7 +156,7 @@
@test.idempotent_id('00579617-fe04-4e1c-9d08-ca7467d2e34b')
@testtools.skipIf(CONF.service_available.neutron,
- "Neutron not check the security_group_id")
+ "Neutron does not check the security group ID")
@test.attr(type=['negative', 'smoke'])
@test.services('network')
def test_update_security_group_with_invalid_sg_id(self):
@@ -171,7 +171,7 @@
@test.idempotent_id('cda8d8b4-59f8-4087-821d-20cf5a03b3b1')
@testtools.skipIf(CONF.service_available.neutron,
- "Neutron not check the security_group_name")
+ "Neutron does not check the security group name")
@test.attr(type=['negative', 'smoke'])
@test.services('network')
def test_update_security_group_with_invalid_sg_name(self):
@@ -187,7 +187,7 @@
@test.idempotent_id('97d12b1c-a610-4194-93f1-ba859e718b45')
@testtools.skipIf(CONF.service_available.neutron,
- "Neutron not check the security_group_description")
+ "Neutron does not check the security group description")
@test.attr(type=['negative', 'smoke'])
@test.services('network')
def test_update_security_group_with_invalid_sg_des(self):
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index f3650ac..8d3f31c 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -32,5 +32,5 @@
@test.idempotent_id('a8333aa2-205c-449f-a828-d38c2489bf25')
def test_get_availability_zone_list_with_non_admin_user(self):
# List of availability zone with non-administrator user
- availability_zone = self.client.get_availability_zone_list()
+ availability_zone = self.client.list_availability_zones()
self.assertTrue(len(availability_zone) > 0)
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index 5b14071..09927fc 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -50,5 +50,5 @@
@test.attr(type='gate')
def test_get_extension(self):
# get the specified extensions
- extension = self.extensions_client.get_extension('os-consoles')
+ extension = self.extensions_client.show_extension('os-consoles')
self.assertEqual('os-consoles', extension['alias'])
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index d91fbaa..5a903b7 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -12,14 +12,216 @@
# License for the specific language governing permissions and limitations
# under the License.
+from collections import OrderedDict
+
+import six
from tempest_lib import exceptions as lib_exc
from tempest import config
+from tempest import exceptions
import tempest.test
CONF = config.CONF
+"""Default templates.
+There should always be at least a master1 and a worker1 node
+group template."""
+DEFAULT_TEMPLATES = {
+ 'vanilla': OrderedDict([
+ ('2.6.0', {
+ 'NODES': {
+ 'master1': {
+ 'count': 1,
+ 'node_processes': ['namenode', 'resourcemanager',
+ 'hiveserver']
+ },
+ 'master2': {
+ 'count': 1,
+ 'node_processes': ['oozie', 'historyserver',
+ 'secondarynamenode']
+ },
+ 'worker1': {
+ 'count': 1,
+ 'node_processes': ['datanode', 'nodemanager'],
+ 'node_configs': {
+ 'MapReduce': {
+ 'yarn.app.mapreduce.am.resource.mb': 256,
+ 'yarn.app.mapreduce.am.command-opts': '-Xmx256m'
+ },
+ 'YARN': {
+ 'yarn.scheduler.minimum-allocation-mb': 256,
+ 'yarn.scheduler.maximum-allocation-mb': 1024,
+ 'yarn.nodemanager.vmem-check-enabled': False
+ }
+ }
+ }
+ },
+ 'cluster_configs': {
+ 'HDFS': {
+ 'dfs.replication': 1
+ }
+ }
+ }),
+ ('1.2.1', {
+ 'NODES': {
+ 'master1': {
+ 'count': 1,
+ 'node_processes': ['namenode', 'jobtracker']
+ },
+ 'worker1': {
+ 'count': 1,
+ 'node_processes': ['datanode', 'tasktracker'],
+ 'node_configs': {
+ 'HDFS': {
+ 'Data Node Heap Size': 1024
+ },
+ 'MapReduce': {
+ 'Task Tracker Heap Size': 1024
+ }
+ }
+ }
+ },
+ 'cluster_configs': {
+ 'HDFS': {
+ 'dfs.replication': 1
+ },
+ 'MapReduce': {
+ 'mapred.map.tasks.speculative.execution': False,
+ 'mapred.child.java.opts': '-Xmx500m'
+ },
+ 'general': {
+ 'Enable Swift': False
+ }
+ }
+ })
+ ]),
+ 'hdp': OrderedDict([
+ ('2.0.6', {
+ 'NODES': {
+ 'master1': {
+ 'count': 1,
+ 'node_processes': ['NAMENODE', 'SECONDARY_NAMENODE',
+ 'ZOOKEEPER_SERVER', 'AMBARI_SERVER',
+ 'HISTORYSERVER', 'RESOURCEMANAGER',
+ 'GANGLIA_SERVER', 'NAGIOS_SERVER',
+ 'OOZIE_SERVER']
+ },
+ 'worker1': {
+ 'count': 1,
+ 'node_processes': ['HDFS_CLIENT', 'DATANODE',
+ 'YARN_CLIENT', 'ZOOKEEPER_CLIENT',
+ 'MAPREDUCE2_CLIENT', 'NODEMANAGER',
+ 'PIG', 'OOZIE_CLIENT']
+ }
+ },
+ 'cluster_configs': {
+ 'HDFS': {
+ 'dfs.replication': 1
+ }
+ }
+ })
+ ]),
+ 'spark': OrderedDict([
+ ('1.0.0', {
+ 'NODES': {
+ 'master1': {
+ 'count': 1,
+ 'node_processes': ['namenode', 'master']
+ },
+ 'worker1': {
+ 'count': 1,
+ 'node_processes': ['datanode', 'slave']
+ }
+ },
+ 'cluster_configs': {
+ 'HDFS': {
+ 'dfs.replication': 1
+ }
+ }
+ })
+ ]),
+ 'cdh': OrderedDict([
+ ('5.3.0', {
+ 'NODES': {
+ 'master1': {
+ 'count': 1,
+ 'node_processes': ['CLOUDERA_MANAGER']
+ },
+ 'master2': {
+ 'count': 1,
+ 'node_processes': ['HDFS_NAMENODE',
+ 'YARN_RESOURCEMANAGER']
+ },
+ 'master3': {
+ 'count': 1,
+ 'node_processes': ['OOZIE_SERVER', 'YARN_JOBHISTORY',
+ 'HDFS_SECONDARYNAMENODE',
+ 'HIVE_METASTORE', 'HIVE_SERVER2']
+ },
+ 'worker1': {
+ 'count': 1,
+ 'node_processes': ['YARN_NODEMANAGER', 'HDFS_DATANODE']
+ }
+ },
+ 'cluster_configs': {
+ 'HDFS': {
+ 'dfs_replication': 1
+ }
+ }
+ }),
+ ('5', {
+ 'NODES': {
+ 'master1': {
+ 'count': 1,
+ 'node_processes': ['CLOUDERA_MANAGER']
+ },
+ 'master2': {
+ 'count': 1,
+ 'node_processes': ['HDFS_NAMENODE',
+ 'YARN_RESOURCEMANAGER']
+ },
+ 'master3': {
+ 'count': 1,
+ 'node_processes': ['OOZIE_SERVER', 'YARN_JOBHISTORY',
+ 'HDFS_SECONDARYNAMENODE',
+ 'HIVE_METASTORE', 'HIVE_SERVER2']
+ },
+ 'worker1': {
+ 'count': 1,
+ 'node_processes': ['YARN_NODEMANAGER', 'HDFS_DATANODE']
+ }
+ },
+ 'cluster_configs': {
+ 'HDFS': {
+ 'dfs_replication': 1
+ }
+ }
+ })
+ ]),
+ 'mapr': OrderedDict([
+ ('4.0.1.mrv2', {
+ 'NODES': {
+ 'master1': {
+ 'count': 1,
+ 'node_processes': ['CLDB', 'FileServer', 'ZooKeeper',
+ 'NodeManager', 'ResourceManager',
+ 'HistoryServer', 'Oozie']
+ },
+ 'worker1': {
+ 'count': 1,
+ 'node_processes': ['FileServer', 'NodeManager', 'Pig']
+ }
+ },
+ 'cluster_configs': {
+ 'Hive': {
+ 'Hive Version': '0.13',
+ }
+ }
+ })
+ ]),
+}
+
class BaseDataProcessingTest(tempest.test.BaseTestCase):
@@ -28,6 +230,7 @@
super(BaseDataProcessingTest, cls).skip_checks()
if not CONF.service_available.sahara:
raise cls.skipException('Sahara support is required')
+ cls.default_plugin = cls._get_default_plugin()
@classmethod
def setup_credentials(cls):
@@ -43,6 +246,10 @@
def resource_setup(cls):
super(BaseDataProcessingTest, cls).resource_setup()
+ cls.default_version = cls._get_default_version()
+ if cls.default_plugin is not None and cls.default_version is None:
+ raise exceptions.InvalidConfiguration(
+ message="No known Sahara plugin version was found")
cls.flavor_ref = CONF.compute.flavor_ref
# add lists for watched resources
@@ -172,3 +379,100 @@
cls._jobs.append(resp_body['id'])
return resp_body
+
+ @classmethod
+ def _get_default_plugin(cls):
+ """Returns the default plugin used for testing."""
+ if len(CONF.data_processing_feature_enabled.plugins) == 0:
+ return None
+
+ for plugin in CONF.data_processing_feature_enabled.plugins:
+ if plugin in DEFAULT_TEMPLATES.keys():
+ break
+ else:
+ plugin = ''
+ return plugin
+
+ @classmethod
+ def _get_default_version(cls):
+ """Returns the default plugin version used for testing.
+ This is gathered separately from the plugin to allow
+ the usage of plugin name in skip_checks. This method is
+ rather invoked into resource_setup, which allows API calls
+ and exceptions.
+ """
+ if not cls.default_plugin:
+ return None
+ plugin = cls.client.get_plugin(cls.default_plugin)
+
+ for version in DEFAULT_TEMPLATES[cls.default_plugin].keys():
+ if version in plugin['versions']:
+ break
+ else:
+ version = None
+
+ return version
+
+ @classmethod
+ def get_node_group_template(cls, nodegroup='worker1'):
+ """Returns a node group template for the default plugin."""
+ try:
+ plugin_data = (
+ DEFAULT_TEMPLATES[cls.default_plugin][cls.default_version]
+ )
+ nodegroup_data = plugin_data['NODES'][nodegroup]
+ node_group_template = {
+ 'description': 'Test node group template',
+ 'plugin_name': cls.default_plugin,
+ 'hadoop_version': cls.default_version,
+ 'node_processes': nodegroup_data['node_processes'],
+ 'flavor_id': cls.flavor_ref,
+ 'node_configs': nodegroup_data.get('node_configs', {}),
+ }
+ return node_group_template
+ except (IndexError, KeyError):
+ return None
+
+ @classmethod
+ def get_cluster_template(cls, node_group_template_ids=None):
+ """Returns a cluster template for the default plugin.
+ node_group_template_defined contains the type and ID of pre-defined
+ node group templates that have to be used in the cluster template
+ (instead of dynamically defining them with 'node_processes').
+ """
+ if node_group_template_ids is None:
+ node_group_template_ids = {}
+ try:
+ plugin_data = (
+ DEFAULT_TEMPLATES[cls.default_plugin][cls.default_version]
+ )
+
+ all_node_groups = []
+ for ng_name, ng_data in six.iteritems(plugin_data['NODES']):
+ node_group = {
+ 'name': '%s-node' % (ng_name),
+ 'flavor_id': cls.flavor_ref,
+ 'count': ng_data['count']
+ }
+ if ng_name in node_group_template_ids.keys():
+ # node group already defined, use it
+ node_group['node_group_template_id'] = (
+ node_group_template_ids[ng_name]
+ )
+ else:
+ # node_processes list defined on-the-fly
+ node_group['node_processes'] = ng_data['node_processes']
+ if 'node_configs' in ng_data:
+ node_group['node_configs'] = ng_data['node_configs']
+ all_node_groups.append(node_group)
+
+ cluster_template = {
+ 'description': 'Test cluster template',
+ 'plugin_name': cls.default_plugin,
+ 'hadoop_version': cls.default_version,
+ 'cluster_configs': plugin_data.get('cluster_configs', {}),
+ 'node_groups': all_node_groups,
+ }
+ return cluster_template
+ except (IndexError, KeyError):
+ return None
diff --git a/tempest/api/data_processing/test_cluster_templates.py b/tempest/api/data_processing/test_cluster_templates.py
index 8a63c3f..cebf493 100644
--- a/tempest/api/data_processing/test_cluster_templates.py
+++ b/tempest/api/data_processing/test_cluster_templates.py
@@ -15,6 +15,7 @@
from tempest_lib.common.utils import data_utils
from tempest.api.data_processing import base as dp_base
+from tempest import exceptions
from tempest import test
@@ -23,55 +24,30 @@
sahara/restapi/rest_api_v1.0.html#cluster-templates
"""
@classmethod
+ def skip_checks(cls):
+ super(ClusterTemplateTest, cls).skip_checks()
+ if cls.default_plugin is None:
+ raise cls.skipException("No Sahara plugins configured")
+
+ @classmethod
def resource_setup(cls):
super(ClusterTemplateTest, cls).resource_setup()
- # create node group template
- node_group_template = {
- 'name': data_utils.rand_name('sahara-ng-template'),
- 'description': 'Test node group template',
- 'plugin_name': 'vanilla',
- 'hadoop_version': '1.2.1',
- 'node_processes': ['datanode'],
- 'flavor_id': cls.flavor_ref,
- 'node_configs': {
- 'HDFS': {
- 'Data Node Heap Size': 1024
- }
- }
- }
- resp_body = cls.create_node_group_template(**node_group_template)
- node_group_template_id = resp_body['id']
- cls.full_cluster_template = {
- 'description': 'Test cluster template',
- 'plugin_name': 'vanilla',
- 'hadoop_version': '1.2.1',
- 'cluster_configs': {
- 'HDFS': {
- 'dfs.replication': 2
- },
- 'MapReduce': {
- 'mapred.map.tasks.speculative.execution': False,
- 'mapred.child.java.opts': '-Xmx500m'
- },
- 'general': {
- 'Enable Swift': False
- }
- },
- 'node_groups': [
- {
- 'name': 'master-node',
- 'flavor_id': cls.flavor_ref,
- 'node_processes': ['namenode'],
- 'count': 1
- },
- {
- 'name': 'worker-node',
- 'node_group_template_id': node_group_template_id,
- 'count': 3
- }
- ]
- }
+ # pre-define a node group templates
+ node_group_template_w = cls.get_node_group_template('worker1')
+ if node_group_template_w is None:
+ raise exceptions.InvalidConfiguration(
+ message="No known Sahara plugin was found")
+
+ node_group_template_w['name'] = data_utils.rand_name(
+ 'sahara-ng-template')
+ resp_body = cls.create_node_group_template(**node_group_template_w)
+ node_group_template_id = resp_body['id']
+ configured_node_group_templates = {'worker1': node_group_template_id}
+
+ cls.full_cluster_template = cls.get_cluster_template(
+ configured_node_group_templates)
+
# create cls.cluster_template variable to use for comparison to cluster
# template response body. The 'node_groups' field in the response body
# has some extra info that post body does not have. The 'node_groups'
diff --git a/tempest/api/data_processing/test_node_group_templates.py b/tempest/api/data_processing/test_node_group_templates.py
index d7381f4..4068027 100644
--- a/tempest/api/data_processing/test_node_group_templates.py
+++ b/tempest/api/data_processing/test_node_group_templates.py
@@ -19,27 +19,16 @@
class NodeGroupTemplateTest(dp_base.BaseDataProcessingTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(NodeGroupTemplateTest, cls).skip_checks()
+ if cls.default_plugin is None:
+ raise cls.skipException("No Sahara plugins configured")
+
@classmethod
def resource_setup(cls):
super(NodeGroupTemplateTest, cls).resource_setup()
- cls.node_group_template = {
- 'description': 'Test node group template',
- 'plugin_name': 'vanilla',
- 'hadoop_version': '1.2.1',
- 'node_processes': [
- 'datanode',
- 'tasktracker'
- ],
- 'flavor_id': cls.flavor_ref,
- 'node_configs': {
- 'HDFS': {
- 'Data Node Heap Size': 1024
- },
- 'MapReduce': {
- 'Task Tracker Heap Size': 1024
- }
- }
- }
def _create_node_group_template(self, template_name=None):
"""Creates Node Group Template with optional name specified.
@@ -47,6 +36,10 @@
It creates template, ensures template name and response body.
Returns id and name of created template.
"""
+ self.node_group_template = self.get_node_group_template()
+ self.assertIsNotNone(self.node_group_template,
+ "No known Sahara plugin was found")
+
if not template_name:
# generate random name if it's not specified
template_name = data_utils.rand_name('sahara-ng-template')
diff --git a/tempest/api/telemetry/test_telemetry_alarming_api.py b/tempest/api/telemetry/test_telemetry_alarming_api.py
index 8bc97e8..d106b28 100644
--- a/tempest/api/telemetry/test_telemetry_alarming_api.py
+++ b/tempest/api/telemetry/test_telemetry_alarming_api.py
@@ -67,13 +67,13 @@
self.assertEqual(alarm_name, body['name'])
self.assertDictContainsSubset(new_rule, body['threshold_rule'])
# Get and verify details of an alarm after update
- body = self.telemetry_client.get_alarm(alarm_id)
+ body = self.telemetry_client.show_alarm(alarm_id)
self.assertEqual(alarm_name, body['name'])
self.assertDictContainsSubset(new_rule, body['threshold_rule'])
# Delete alarm and verify if deleted
self.telemetry_client.delete_alarm(alarm_id)
self.assertRaises(lib_exc.NotFound,
- self.telemetry_client.get_alarm, alarm_id)
+ self.telemetry_client.show_alarm, alarm_id)
@test.attr(type="gate")
@test.idempotent_id('aca49486-70bb-4016-87e0-f6131374f741')
@@ -87,7 +87,7 @@
new_state)
self.assertEqual(new_state, state.data)
# Get alarm state and verify
- state = self.telemetry_client.alarm_get_state(alarm['alarm_id'])
+ state = self.telemetry_client.show_alarm_state(alarm['alarm_id'])
self.assertEqual(new_state, state.data)
@test.attr(type="gate")
@@ -106,4 +106,4 @@
# Verify alarm delete
self.telemetry_client.delete_alarm(alarm_id)
self.assertRaises(lib_exc.NotFound,
- self.telemetry_client.get_alarm, alarm_id)
+ self.telemetry_client.show_alarm, alarm_id)
diff --git a/tempest/api_schema/response/compute/version.py b/tempest/api_schema/response/compute/version.py
index 32c6d96..6579c63 100644
--- a/tempest/api_schema/response/compute/version.py
+++ b/tempest/api_schema/response/compute/version.py
@@ -45,8 +45,12 @@
}
},
'status': {'type': 'string'},
- 'updated': {'type': 'string', 'format': 'date-time'}
+ 'updated': {'type': 'string', 'format': 'date-time'},
+ 'version': {'type': 'string'},
+ 'min_version': {'type': 'string'}
},
+ # NOTE: version and min_version have been added since Kilo,
+ # so they should not be required.
'required': ['id', 'links', 'media-types', 'status', 'updated']
}
},
diff --git a/tempest/cli/simple_read_only/object_storage/__init__.py b/tempest/cli/simple_read_only/object_storage/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/object_storage/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/object_storage/test_swift.py b/tempest/cli/simple_read_only/object_storage/test_swift.py
deleted file mode 100644
index 7201eab..0000000
--- a/tempest/cli/simple_read_only/object_storage/test_swift.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# Copyright 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 re
-
-from tempest_lib import exceptions
-
-from tempest import cli
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class SimpleReadOnlySwiftClientTest(cli.ClientTestBase):
- """Basic, read-only tests for Swift CLI client.
-
- Checks return values and output of read-only commands.
- These tests do not presume any content, nor do they create
- their own. They only verify the structure of output if present.
- """
-
- @classmethod
- def resource_setup(cls):
- if not CONF.service_available.swift:
- msg = ("%s skipped as Swift is not available" % cls.__name__)
- raise cls.skipException(msg)
- super(SimpleReadOnlySwiftClientTest, cls).resource_setup()
-
- def swift(self, *args, **kwargs):
- return self.clients.swift(
- *args, endpoint_type=CONF.object_storage.endpoint_type, **kwargs)
-
- @test.idempotent_id('74360cdc-e7ec-493f-8a87-2b65f4d54aa3')
- def test_swift_fake_action(self):
- self.assertRaises(exceptions.CommandFailed,
- self.swift,
- 'this-does-not-exist')
-
- @test.idempotent_id('809ec373-828e-4279-8df6-9d4db81c7909')
- def test_swift_list(self):
- self.swift('list')
-
- @test.idempotent_id('325d5fe4-e5ab-4f52-aec4-357533f24fa1')
- def test_swift_stat(self):
- output = self.swift('stat')
- entries = ['Account', 'Containers', 'Objects', 'Bytes', 'Content-Type',
- 'X-Timestamp', 'X-Trans-Id']
- for entry in entries:
- self.assertTrue(entry in output)
-
- @test.idempotent_id('af1483e1-dafd-4552-a39b-b9d337df808b')
- def test_swift_capabilities(self):
- output = self.swift('capabilities')
- entries = ['account_listing_limit', 'container_listing_limit',
- 'max_file_size', 'Additional middleware']
- for entry in entries:
- self.assertTrue(entry in output)
-
- @test.idempotent_id('29c83a64-8eb7-418c-a39b-c70cefa5b695')
- def test_swift_help(self):
- help_text = self.swift('', flags='--help')
- lines = help_text.split('\n')
- self.assertFirstLineStartsWith(lines, 'Usage: swift')
-
- commands = []
- cmds_start = lines.index('Positional arguments:')
- cmds_end = lines.index('Examples:')
- command_pattern = re.compile('^ {4}([a-z0-9\-\_]+)')
- for line in lines[cmds_start:cmds_end]:
- match = command_pattern.match(line)
- if match:
- commands.append(match.group(1))
- commands = set(commands)
- wanted_commands = set(('stat', 'list', 'delete',
- 'download', 'post', 'upload'))
- self.assertFalse(wanted_commands - commands)
-
- # Optional arguments:
-
- @test.idempotent_id('2026be82-4e53-4414-a828-f1c894b8cf0f')
- def test_swift_version(self):
- self.swift('', flags='--version')
-
- @test.idempotent_id('0ae6172e-3df7-42b8-a987-d42609ada6ed')
- def test_swift_debug_list(self):
- self.swift('list', flags='--debug')
-
- @test.idempotent_id('1bdf5dd0-7df5-446c-a124-2b0703a5d199')
- def test_swift_retries_list(self):
- self.swift('list', flags='--retries 3')
-
- @test.idempotent_id('64eae749-8fbd-4d85-bc7f-f706d3581c6f')
- def test_swift_region_list(self):
- region = CONF.object_storage.region
- if not region:
- region = CONF.identity.region
- self.swift('list', flags='--os-region-name ' + region)
diff --git a/tempest/common/accounts.py b/tempest/common/accounts.py
index acf6d4f..93c8bcf 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/accounts.py
@@ -180,12 +180,20 @@
useable_hashes = hashes
return useable_hashes
+ def _sanitize_creds(self, creds):
+ temp_creds = creds.copy()
+ temp_creds.pop('password')
+ return temp_creds
+
def _get_creds(self, roles=None):
if self.use_default_creds:
raise exceptions.InvalidConfiguration(
"Account file %s doesn't exist" % CONF.auth.test_accounts_file)
useable_hashes = self._get_match_hash_list(roles)
free_hash = self._get_free_hash(useable_hashes)
+ clean_creds = self._sanitize_creds(
+ self.hash_dict['creds'][free_hash])
+ LOG.info('%s allocated creds:\n%s' % (self.name, clean_creds))
return self._wrap_creds_with_network(free_hash)
@lockutils.synchronized('test_accounts_io', external=True)
@@ -216,7 +224,9 @@
def remove_credentials(self, creds):
_hash = self.get_hash(creds)
+ clean_creds = self._sanitize_creds(self.hash_dict['creds'][_hash])
self.remove_hash(_hash)
+ LOG.info("%s returned allocated creds:\n%s" % (self.name, clean_creds))
def get_primary_creds(self):
if self.isolated_creds.get('primary'):
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index d2c41f0..cc152d2 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -319,10 +319,18 @@
if username is None:
username = CONF.scenario.ssh_user
- if private_key is None:
- private_key = self.keypair['private_key']
+ # Set this with 'keypair' or others to log in with keypair or
+ # username/password.
+ if CONF.compute.ssh_auth_method == 'keypair':
+ password = None
+ if private_key is None:
+ private_key = self.keypair['private_key']
+ else:
+ password = CONF.compute.image_ssh_password
+ private_key = None
linux_client = remote_client.RemoteClient(ip, username,
- pkey=private_key)
+ pkey=private_key,
+ password=password)
try:
linux_client.validate_authentication()
except Exception:
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index c5e8012..b1d3418 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -80,7 +80,7 @@
def _check_aggregate_details(self, aggregate, aggregate_name, azone,
hosts, metadata):
- aggregate = self.aggregates_client.get_aggregate(aggregate['id'])
+ aggregate = self.aggregates_client.show_aggregate(aggregate['id'])
self.assertEqual(aggregate_name, aggregate['name'])
self.assertEqual(azone, aggregate['availability_zone'])
self.assertEqual(hosts, aggregate['hosts'])
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index 0d17048..8f37d74 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -185,7 +185,7 @@
# Start netcat
start_server = ('while true; do '
'sudo nc -ll -p %(port)s -e sh /tmp/%(script)s; '
- 'done &')
+ 'done > /dev/null &')
cmd = start_server % {'port': self.port1,
'script': 'script1'}
ssh_client.exec_command(cmd)
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index 36a347b..6c02b63 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -30,7 +30,7 @@
self.validate_response(schema.list_aggregates, resp, body)
return service_client.ResponseBodyList(resp, body['aggregates'])
- def get_aggregate(self, aggregate_id):
+ def show_aggregate(self, aggregate_id):
"""Get details of the given aggregate."""
resp, body = self.get("os-aggregates/%s" % str(aggregate_id))
body = json.loads(body)
@@ -67,7 +67,7 @@
def is_resource_deleted(self, id):
try:
- self.get_aggregate(id)
+ self.show_aggregate(id)
except lib_exc.NotFound:
return True
return False
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
index 6c50398..925d79f 100644
--- a/tempest/services/compute/json/availability_zone_client.py
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -22,17 +22,15 @@
class AvailabilityZoneClientJSON(service_client.ServiceClient):
- def get_availability_zone_list(self):
- resp, body = self.get('os-availability-zone')
- body = json.loads(body)
- self.validate_response(schema.list_availability_zone_list, resp, body)
- return service_client.ResponseBodyList(resp,
- body['availabilityZoneInfo'])
+ def list_availability_zones(self, detail=False):
+ url = 'os-availability-zone'
+ schema_list = schema.list_availability_zone_list
+ if detail:
+ url += '/detail'
+ schema_list = schema.list_availability_zone_list_detail
- def get_availability_zone_list_detail(self):
- resp, body = self.get('os-availability-zone/detail')
+ resp, body = self.get(url)
body = json.loads(body)
- self.validate_response(schema.list_availability_zone_list_detail, resp,
- body)
+ self.validate_response(schema_list, resp, body)
return service_client.ResponseBodyList(resp,
body['availabilityZoneInfo'])
diff --git a/tempest/services/compute/json/baremetal_nodes_client.py b/tempest/services/compute/json/baremetal_nodes_client.py
index d8bbadd..e4a4e88 100644
--- a/tempest/services/compute/json/baremetal_nodes_client.py
+++ b/tempest/services/compute/json/baremetal_nodes_client.py
@@ -34,7 +34,7 @@
self.validate_response(schema.list_baremetal_nodes, resp, body)
return service_client.ResponseBodyList(resp, body['nodes'])
- def get_baremetal_node(self, baremetal_node_id):
+ def show_baremetal_node(self, baremetal_node_id):
"""Returns the details of a single baremetal node."""
url = 'os-baremetal-nodes/%s' % baremetal_node_id
resp, body = self.get(url)
diff --git a/tempest/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index e6b72bb..752a48e 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -21,7 +21,7 @@
class CertificatesClientJSON(service_client.ServiceClient):
- def get_certificate(self, id):
+ def show_certificate(self, id):
url = "os-certificates/%s" % (id)
resp, body = self.get(url)
body = json.loads(body)
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index 5c69085..265b381 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -33,7 +33,7 @@
exts = extensions['extensions']
return any([e for e in exts if e['name'] == extension])
- def get_extension(self, extension_alias):
+ def show_extension(self, extension_alias):
resp, body = self.get('extensions/%s' % extension_alias)
body = json.loads(body)
return service_client.ResponseBody(resp, body['extension'])
diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py
index 36c123b..0c01908 100644
--- a/tempest/services/telemetry/json/telemetry_client.py
+++ b/tempest/services/telemetry/json/telemetry_client.py
@@ -50,7 +50,7 @@
body = self.deserialize(body)
return service_client.ResponseBody(resp, body)
- def helper_list(self, uri, query=None, period=None):
+ def _helper_list(self, uri, query=None, period=None):
uri_dict = {}
if query:
uri_dict = {'q.field': query[0],
@@ -67,32 +67,32 @@
def list_resources(self, query=None):
uri = '%s/resources' % self.uri_prefix
- return self.helper_list(uri, query)
+ return self._helper_list(uri, query)
def list_meters(self, query=None):
uri = '%s/meters' % self.uri_prefix
- return self.helper_list(uri, query)
+ return self._helper_list(uri, query)
def list_alarms(self, query=None):
uri = '%s/alarms' % self.uri_prefix
- return self.helper_list(uri, query)
+ return self._helper_list(uri, query)
def list_statistics(self, meter, period=None, query=None):
uri = "%s/meters/%s/statistics" % (self.uri_prefix, meter)
- return self.helper_list(uri, query, period)
+ return self._helper_list(uri, query, period)
def list_samples(self, meter_id, query=None):
uri = '%s/meters/%s' % (self.uri_prefix, meter_id)
- return self.helper_list(uri, query)
+ return self._helper_list(uri, query)
- def get_resource(self, resource_id):
+ def show_resource(self, resource_id):
uri = '%s/resources/%s' % (self.uri_prefix, resource_id)
resp, body = self.get(uri)
self.expected_success(200, resp.status)
body = self.deserialize(body)
return service_client.ResponseBody(resp, body)
- def get_alarm(self, alarm_id):
+ def show_alarm(self, alarm_id):
uri = '%s/alarms/%s' % (self.uri_prefix, alarm_id)
resp, body = self.get(uri)
self.expected_success(200, resp.status)
@@ -123,7 +123,7 @@
body = self.deserialize(body)
return service_client.ResponseBody(resp, body)
- def alarm_get_state(self, alarm_id):
+ def show_alarm_state(self, alarm_id):
uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
resp, body = self.get(uri)
self.expected_success(200, resp.status)