Changes the namespace from storm to tempest, as well as adding addition tests and improvements

* Changed namespace from storm to tempest
* Added absolute limits service and server personality file tests
* Optimized run time for image metadata tests
* Added additional assertions for create server and rebuild server tests
* Removed any SSH verification until further decisions are made

Change-Id: I5bebd29be382c9404914c7314302670ae09627fc
changes/94/2094/2
Daryl Walleck 11 years ago
parent 7f75763f54
commit ed8bef3a03
  1. 4
      etc/TEMPEST_README.txt
  2. 0
      etc/tempest.conf.sample
  3. 158
      storm/tests/test_image_metadata.py
  4. 98
      storm/tests/test_server_actions.py
  5. 0
      tempest/__init__.py
  6. 0
      tempest/common/__init__.py
  7. 12
      tempest/common/rest_client.py
  8. 0
      tempest/common/ssh.py
  9. 0
      tempest/common/utils/__init__.py
  10. 0
      tempest/common/utils/data_utils.py
  11. 3
      tempest/config.py
  12. 12
      tempest/exceptions.py
  13. 22
      tempest/openstack.py
  14. 0
      tempest/services/__init__.py
  15. 0
      tempest/services/nova/__init__.py
  16. 0
      tempest/services/nova/json/__init__.py
  17. 2
      tempest/services/nova/json/flavors_client.py
  18. 6
      tempest/services/nova/json/images_client.py
  19. 26
      tempest/services/nova/json/limits_client.py
  20. 7
      tempest/services/nova/json/servers_client.py
  21. 0
      tempest/services/nova/xml/__init__.py
  22. 0
      tempest/tests/__init__.py
  23. 4
      tempest/tests/test_flavors.py
  24. 107
      tempest/tests/test_image_metadata.py
  25. 38
      tempest/tests/test_images.py
  26. 37
      tempest/tests/test_list_images.py
  27. 6
      tempest/tests/test_list_servers.py
  28. 113
      tempest/tests/test_server_actions.py
  29. 6
      tempest/tests/test_server_metadata.py
  30. 67
      tempest/tests/test_server_personality.py
  31. 35
      tempest/tests/test_servers.py
  32. 10
      tempest/tests/test_servers_negative.py

@ -1,8 +1,8 @@
To run:
-rename the /etc/storm.conf.sample file to storm.conf
-rename the /etc/tempest.conf.sample file to tempest.conf
-Set the fields in the file to values relevant to your system
-Set the "authentication" value (basic or keystone_v2 currently supported)
-from the root directory of the project, run "nosetests storm/tests" to
-from the root directory of the project, run "nosetests tempest/tests" to
run all tests
TODO:

@ -1,158 +0,0 @@
from nose.plugins.attrib import attr
from storm import openstack
from storm.common.utils.data_utils import rand_name
import storm.config
import unittest2 as unittest
class ImagesMetadataTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.os = openstack.Manager()
cls.servers_client = cls.os.servers_client
cls.client = cls.os.images_client
cls.config = cls.os.config
cls.image_ref = cls.config.env.image_ref
cls.flavor_ref = cls.config.env.flavor_ref
cls.ssh_timeout = cls.config.nova.ssh_timeout
name = rand_name('server')
resp, cls.server = cls.servers_client.create_server(name,
cls.image_ref,
cls.flavor_ref)
#Wait for the server to become active
cls.servers_client.wait_for_server_status(cls.server['id'], 'ACTIVE')
#Create an image from the server
name = rand_name('image')
cls.meta = {'key1': 'value1', 'key2': 'value2'}
resp, body = cls.client.create_image(cls.server['id'], name, cls.meta)
image_ref = resp['location']
temp = image_ref.rsplit('/')
image_id = temp[len(temp) - 1]
cls.client.wait_for_image_resp_code(image_id, 200)
cls.client.wait_for_image_status(image_id, 'ACTIVE')
resp, cls.image = cls.client.get_image(image_id)
@classmethod
def tearDownClass(cls):
cls.servers_client.delete_server(cls.server['id'])
cls.client.delete_image(cls.image['id'])
def _parse_image_id(self, image_ref):
temp = image_ref.rsplit('/')
return len(temp) - 1
def test_list_image_metadata(self):
"""All metadata key/value pairs for an image should be returned"""
resp, metadata = self.client.list_image_metadata(self.image['id'])
self.assertEqual('value1', metadata['key1'])
self.assertEqual('value2', metadata['key2'])
def test_set_image_metadata(self):
"""The metadata for the image should match the new values"""
meta = {'meta1': 'data1'}
name = rand_name('server')
resp, server = self.servers_client.create_server(name, self.image_ref,
self.flavor_ref)
self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
name = rand_name('image')
resp, body = self.client.create_image(server['id'], name, meta)
image_id = self._parse_image_id(resp['location'])
self.client.wait_for_image_resp_code(image_id, 200)
self.client.wait_for_image_status(image_id, 'ACTIVE')
resp, image = self.client.get_image(image_id)
meta = {'meta2': 'data2', 'meta3': 'data3'}
resp, body = self.client.set_image_metadata(image['id'], meta)
resp, metadata = self.client.list_image_metadata(image['id'])
self.assertEqual('data2', metadata['meta2'])
self.assertEqual('data3', metadata['meta3'])
self.assertTrue('meta1' not in metadata)
self.servers_client.delete_server(server['id'])
self.client.delete_image(image['id'])
def test_update_image_metadata(self):
"""The metadata for the image should match the updated values"""
meta = {'key1': 'value1', 'key2': 'value2'}
name = rand_name('server')
resp, server = self.servers_client.create_server(name, self.image_ref,
self.flavor_ref)
self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
name = rand_name('image')
resp, body = self.client.create_image(server['id'], name, meta)
image_id = self._parse_image_id(resp['location'])
self.client.wait_for_image_resp_code(image_id, 200)
self.client.wait_for_image_status(image_id, 'ACTIVE')
resp, image = self.client.get_image(image_id)
meta = {'key1': 'alt1', 'key2': 'alt2'}
resp, metadata = self.client.update_image_metadata(image['id'], meta)
resp, metadata = self.client.list_image_metadata(image['id'])
self.assertEqual('alt1', metadata['key1'])
self.assertEqual('alt2', metadata['key2'])
self.servers_client.delete_server(server['id'])
self.client.delete_image(image['id'])
def test_get_image_metadata_item(self):
"""The value for a specic metadata key should be returned"""
resp, meta = self.client.get_image_metadata_item(self.image['id'],
'key2')
self.assertTrue('value2', meta['key2'])
def test_set_image_metadata_item(self):
"""
The value provided for the given meta item should be set for the image
"""
meta = {'nova': 'server'}
name = rand_name('server')
resp, server = self.servers_client.create_server(name, self.image_ref,
self.flavor_ref)
self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
name = rand_name('image')
resp, body = self.client.create_image(server['id'], name, meta)
image_id = self._parse_image_id(resp['location'])
self.client.wait_for_image_resp_code(image_id, 200)
self.client.wait_for_image_status(image_id, 'ACTIVE')
resp, image = self.client.get_image(image_id)
meta = {'nova': 'alt'}
resp, body = self.client.set_image_metadata_item(image['id'],
'nova', meta)
resp, metadata = self.client.list_image_metadata(image['id'])
self.assertEqual('alt', metadata['nova'])
self.servers_client.delete_server(server['id'])
self.client.delete_image(image['id'])
def test_delete_image_metadata_item(self):
"""The metadata value/key pair should be deleted from the image"""
meta = {'delkey': 'delvalue'}
name = rand_name('server')
resp, server = self.servers_client.create_server(name, self.image_ref,
self.flavor_ref)
self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
name = rand_name('image')
resp, body = self.client.create_image(server['id'], name, meta)
image_id = self._parse_image_id(resp['location'])
self.client.wait_for_image_resp_code(image_id, 200)
self.client.wait_for_image_status(image_id, 'ACTIVE')
resp, image = self.client.get_image(image_id)
resp, body = self.client.delete_image_metadata_item(image['id'],
'delkey')
resp, metadata = self.client.list_image_metadata(image['id'])
self.assertTrue('delkey' not in metadata)
self.servers_client.delete_server(server['id'])
self.client.delete_image(image['id'])

@ -1,98 +0,0 @@
from nose.plugins.attrib import attr
from storm import openstack
import unittest2 as unittest
import storm.config
from storm.common.utils.data_utils import rand_name
# Some module-level skip conditions
resize_available = False
class ServerActionsTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.os = openstack.Manager()
cls.client = cls.os.servers_client
cls.config = cls.os.config
cls.image_ref = cls.config.env.image_ref
cls.image_ref_alt = cls.config.env.image_ref_alt
cls.flavor_ref = cls.config.env.flavor_ref
cls.flavor_ref_alt = cls.config.env.flavor_ref_alt
resize_available = cls.config.env.resize_available
def setUp(self):
self.name = rand_name('server')
resp, server = self.client.create_server(self.name, self.image_ref,
self.flavor_ref)
self.id = server['id']
self.client.wait_for_server_status(self.id, 'ACTIVE')
def tearDown(self):
self.client.delete_server(self.id)
@attr(type='smoke')
def test_change_server_password(self):
"""The server's password should be set to the provided password"""
resp, body = self.client.change_password(self.id, 'newpass')
self.client.wait_for_server_status(self.id, 'ACTIVE')
#TODO: SSH in to verify the new password works
@attr(type='smoke')
def test_reboot_server_hard(self):
""" The server should be power cycled """
#TODO: Add validation the server has been rebooted
resp, body = self.client.reboot(self.id, 'HARD')
self.client.wait_for_server_status(self.id, 'ACTIVE')
@attr(type='smoke')
def test_reboot_server_soft(self):
"""The server should be signaled to reboot gracefully"""
#TODO: Add validation the server has been rebooted
resp, body = self.client.reboot(self.id, 'SOFT')
self.client.wait_for_server_status(self.id, 'ACTIVE')
@attr(type='smoke')
def test_rebuild_server(self):
"""The server should be rebuilt using the provided image"""
self.client.rebuild(self.id, self.image_ref_alt, name='rebuiltserver')
self.client.wait_for_server_status(self.id, 'ACTIVE')
resp, server = self.client.get_server(self.id)
self.assertEqual(self.image_ref_alt, server['image']['id'])
self.assertEqual('rebuiltserver', server['name'])
@attr(type='smoke')
@unittest.skipIf(not resize_available, 'Resize not available.')
def test_resize_server_confirm(self):
"""
The server's RAM and disk space should be modified to that of
the provided flavor
"""
self.client.resize(self.id, self.flavor_ref_alt)
self.client.wait_for_server_status(self.id, 'VERIFY_RESIZE')
self.client.confirm_resize(self.id)
self.client.wait_for_server_status(self.id, 'ACTIVE')
resp, server = self.client.get_server(self.id)
self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
@attr(type='smoke')
@unittest.skipIf(not resize_available, 'Resize not available.')
def test_resize_server_revert(self):
"""
The server's RAM and disk space should return to its original
values after a resize is reverted
"""
self.client.resize(self.id, self.flavor_ref_alt)
self.client.wait_for_server_status(id, 'VERIFY_RESIZE')
self.client.revert_resize(self.id)
self.client.wait_for_server_status(id, 'ACTIVE')
resp, server = self.client.get_server(id)
self.assertEqual(self.flavor_ref, server['flavor']['id'])

@ -2,8 +2,8 @@ import json
import httplib2
from storm import exceptions
import storm.config
from tempest import exceptions
import tempest.config
class RestClient(object):
@ -102,4 +102,12 @@ class RestClient(object):
body = json.loads(body)
raise exceptions.BadRequest(body['badRequest']['message'])
if resp.status == 413:
body = json.loads(body)
raise exceptions.OverLimit(body['overLimit']['message'])
if resp.status in (500, 501):
body = json.loads(body)
raise exceptions.ComputeFault(body['computeFault']['message'])
return resp, body

@ -120,9 +120,10 @@ class EnvironmentConfig(object):
return self.get("authentication", 'keystone')
class StormConfig(object):
class TempestConfig(object):
"""Provides OpenStack configuration information."""
def __init__(self, conf_dir, conf_file):
"""
Initialize a configuration from a conf directory and conf file.

@ -16,10 +16,18 @@ class BadRequest(Exception):
def __str__(self):
return repr(self.message)
class AuthenticationFailure(Exception):
msg = ("Authentication with user %(user)s and password "
"%(password)s failed.")
def __init__(self, **kwargs):
self.message = self.msg % kwargs
class OverLimit(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return repr(self.message)

@ -1,10 +1,11 @@
import os
from storm.services.nova.json.images_client import ImagesClient
from storm.services.nova.json.flavors_client import FlavorsClient
from storm.services.nova.json.servers_client import ServersClient
from storm.common.utils import data_utils
import storm.config
from tempest.services.nova.json.images_client import ImagesClient
from tempest.services.nova.json.flavors_client import FlavorsClient
from tempest.services.nova.json.servers_client import ServersClient
from tempest.services.nova.json.limits_client import LimitsClient
from tempest.common.utils import data_utils
import tempest.config
class Manager(object):
@ -48,6 +49,12 @@ class Manager(object):
self.config.nova.api_key,
self.auth_url,
self.config.nova.tenant_name)
self.limits_client = LimitsClient(self.config,
self.config.nova.username,
self.config.nova.api_key,
self.auth_url,
self.config.nova.tenant_name)
else:
#Assuming basic/native authentication
self.servers_client = ServersClient(self.config,
@ -63,3 +70,8 @@ class Manager(object):
self.config.nova.auth_url,
self.config.nova.api_key,
self.auth_url)
self.limits_client = LimitsClient(self.config,
self.config.nova.username,
self.config.nova.auth_url,
self.config.nova.api_key,
self.auth_url)

@ -1,4 +1,4 @@
from storm.common import rest_client
from tempest.common import rest_client
import json
import time

@ -1,6 +1,7 @@
from storm.common import rest_client
from tempest.common import rest_client
from tempest import exceptions
import json
import storm.config
import tempest.config
import time
@ -10,6 +11,7 @@ class ImagesClient(object):
self.config = config
self.client = rest_client.RestClient(config, username, key,
auth_url, tenant_name)
self.build_interval = self.config.nova.build_interval
self.build_timeout = self.config.nova.build_timeout
self.headers = {'Content-Type': 'application/json',

@ -0,0 +1,26 @@
import json
from tempest.common import rest_client
class LimitsClient(object):
def __init__(self, username, key, auth_url, tenant_name=None):
self.client = rest_client.RestClient(config, username, key,
auth_url, tenant_name)
def get_limits(self):
resp, body = self.client.get("limits")
body = json.loads(body)
return resp, body['limits']
def get_max_server_meta(self):
resp, limits_dict = self.get_limits()
return resp, limits_dict['absolute']['maxServerMeta']
def get_personality_file_limit(self):
resp, limits_dict = self.get_limits()
return resp, limits_dict['absolute']['maxPersonality']
def get_personality_size_limit(self):
resp, limits_dict = self.get_limits()
return resp, limits_dict['absolute']['maxPersonalitySize']

@ -1,7 +1,7 @@
from storm import exceptions
from storm.common import rest_client
from tempest import exceptions
from tempest.common import rest_client
import json
import storm.config
import tempest.config
import time
@ -11,6 +11,7 @@ class ServersClient(object):
self.config = config
self.client = rest_client.RestClient(config, username, key,
auth_url, tenant_name)
self.build_interval = self.config.nova.build_interval
self.build_timeout = self.config.nova.build_timeout
self.headers = {'Content-Type': 'application/json',

@ -1,6 +1,6 @@
from nose.plugins.attrib import attr
from storm import openstack
import storm.config
from tempest import openstack
import tempest.config
import unittest2 as unittest

@ -0,0 +1,107 @@
from nose.plugins.attrib import attr
from tempest import openstack
from tempest.common.utils.data_utils import rand_name
import tempest.config
import unittest2 as unittest
class ImagesMetadataTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.os = openstack.Manager()
cls.servers_client = cls.os.servers_client
cls.client = cls.os.images_client
cls.config = cls.os.config
cls.image_ref = cls.config.env.image_ref
cls.flavor_ref = cls.config.env.flavor_ref
cls.ssh_timeout = cls.config.nova.ssh_timeout
name = rand_name('server')
resp, cls.server = cls.servers_client.create_server(name,
cls.image_ref,
cls.flavor_ref)
#Wait for the server to become active
cls.servers_client.wait_for_server_status(cls.server['id'], 'ACTIVE')
@classmethod
def tearDownClass(cls):
cls.servers_client.delete_server(cls.server['id'])
def setUp(self):
meta = {'key1': 'value1', 'key2': 'value2'}
name = rand_name('image')
resp, body = self.client.create_image(self.server['id'], name, meta)
image_ref = resp['location']
temp = image_ref.rsplit('/')
image_id = temp[6]
self.client.wait_for_image_resp_code(image_id, 200)
self.client.wait_for_image_status(image_id, 'ACTIVE')
resp, self.image = self.client.get_image(image_id)
def tearDown(self):
self.client.delete_image(self.image['id'])
def _parse_image_id(self, image_ref):
temp = image_ref.rsplit('/')
return len(temp) - 1
def test_list_image_metadata(self):
"""All metadata key/value pairs for an image should be returned"""
resp, metadata = self.client.list_image_metadata(self.image['id'])
self.assertEqual('value1', metadata['key1'])
self.assertEqual('value2', metadata['key2'])
def test_set_image_metadata(self):
"""The metadata for the image should match the new values"""
meta = {'meta1': 'data1'}
name = rand_name('image')
resp, body = self.client.create_image(self.server['id'], name, meta)
image_id = self._parse_image_id(resp['location'])
self.client.wait_for_image_resp_code(image_id, 200)
self.client.wait_for_image_status(image_id, 'ACTIVE')
resp, image = self.client.get_image(image_id)
meta = {'meta2': 'data2', 'meta3': 'data3'}
resp, body = self.client.set_image_metadata(image['id'], meta)
resp, metadata = self.client.list_image_metadata(image['id'])
self.assertEqual('data2', metadata['meta2'])
self.assertEqual('data3', metadata['meta3'])
self.assertTrue('key1' not in metadata)
self.servers_client.delete_server(server['id'])
self.client.delete_image(image['id'])
def test_update_image_metadata(self):
"""The metadata for the image should match the updated values"""
meta = {'key1': 'alt1', 'key2': 'alt2'}
resp, metadata = self.client.update_image_metadata(self.image['id'], meta)
resp, metadata = self.client.list_image_metadata(self.image['id'])
self.assertEqual('alt1', metadata['key1'])
self.assertEqual('alt2', metadata['key2'])
def test_get_image_metadata_item(self):
"""The value for a specic metadata key should be returned"""
resp, meta = self.client.get_image_metadata_item(self.image['id'],
'key2')
self.assertTrue('value2', meta['key2'])
def test_set_image_metadata_item(self):
"""
The value provided for the given meta item should be set for the image
"""
meta = {'key1': 'alt'}
resp, body = self.client.set_image_metadata_item(self.image['id'],
'key1', meta)
resp, metadata = self.client.list_image_metadata(self.image['id'])
self.assertEqual('alt', metadata['key1'])
def test_delete_image_metadata_item(self):
"""The metadata value/key pair should be deleted from the image"""
resp, body = self.client.delete_image_metadata_item(self.image['id'],
'key1')
resp, metadata = self.client.list_image_metadata(self.image['id'])
self.assertTrue('key1' not in metadata)

@ -1,8 +1,8 @@
from nose.plugins.attrib import attr
from storm import openstack
from storm.common.utils.data_utils import rand_name
from tempest import openstack
from tempest.common.utils.data_utils import rand_name
import unittest2 as unittest
import storm.config
import tempest.config
# Some module-level skip conditions
create_image_enabled = False
@ -24,8 +24,9 @@ class ImagesTest(unittest.TestCase):
temp = image_ref.rsplit('/')
return temp[6]
@unittest.skipIf(not create_image_enabled,
@unittest.skipIf(not imaging_enabled,
'Environment unable to create images.')
@attr(type='smoke')
def test_create_delete_image(self):
"""An image for the provided server should be created"""
server_name = rand_name('server')
@ -36,7 +37,8 @@ class ImagesTest(unittest.TestCase):
#Create a new image
name = rand_name('image')
resp, body = self.client.create_image(server['id'], name)
meta = {'image_type': 'test'}
resp, body = self.client.create_image(server['id'], name, meta)
image_id = self._parse_image_id(resp['location'])
self.client.wait_for_image_resp_code(image_id, 200)
self.client.wait_for_image_status(image_id, 'ACTIVE')
@ -44,27 +46,13 @@ class ImagesTest(unittest.TestCase):
#Verify the image was created correctly
resp, image = self.client.get_image(image_id)
self.assertEqual(name, image['name'])
self.assertEqual('test', image['metadata']['image_type'])
#Verify minRAM and minDisk values are the same as the original image
resp, original_image = self.client.get_image(self.image_ref)
self.assertEqual(original_image['minRam'], image['minRam'])
self.assertEqual(original_image['minDisk'], image['minDisk'])
#Teardown
self.client.delete_image(image['id'])
self.servers_client.delete_server(server['id'])
@attr(type='smoke')
def test_get_image(self):
"""Returns the correct details for a single image"""
resp, image = self.client.get_image(self.image_ref)
self.assertEqual(self.image_ref, image['id'])
@attr(type='smoke')
def test_list_images(self):
"""The list of all images should contain the image flavor"""
resp, images = self.client.list_images()
found = any([i for i in images if i['id'] == self.image_ref])
self.assertTrue(found)
@attr(type='smoke')
def test_list_images_with_detail(self):
"""Detailed list of all images should contain the expected image"""
resp, images = self.client.list_images_with_detail()
found = any([i for i in images if i['id'] == self.image_ref])
self.assertTrue(found)

@ -0,0 +1,37 @@
from nose.plugins.attrib import attr
from tempest import openstack
from tempest.common.utils.data_utils import rand_name
import unittest2 as unittest
import tempest.config
class ListImagesTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.os = openstack.Manager()
cls.client = cls.os.images_client
cls.servers_client = cls.os.servers_client
cls.config = cls.os.config
cls.image_ref = cls.config.env.image_ref
cls.flavor_ref = cls.config.env.flavor_ref
@attr(type='smoke')
def test_get_image(self):
"""Returns the correct details for a single image"""
resp, image = self.client.get_image(self.image_ref)
self.assertEqual(self.image_ref, image['id'])
@attr(type='smoke')
def test_list_images(self):
"""The list of all images should contain the image"""
resp, images = self.client.list_images()
found = any([i for i in images if i['id'] == self.image_ref])
self.assertTrue(found)
@attr(type='smoke')
def test_list_images_with_detail(self):
"""Detailed list of all images should contain the expected image"""
resp, images = self.client.list_images_with_detail()
found = any([i for i in images if i['id'] == self.image_ref])
self.assertTrue(found)

@ -1,8 +1,8 @@
from nose.plugins.attrib import attr
from storm import openstack
from storm.common.utils.data_utils import rand_name
from tempest import openstack
from tempest.common.utils.data_utils import rand_name
import unittest2 as unittest
import storm.config
import tempest.config
class ServerDetailsTest(unittest.TestCase):

@ -0,0 +1,113 @@
from nose.plugins.attrib import attr
from tempest import openstack
from tempest.common.utils.data_utils import rand_name
import unittest2 as unittest
import tempest.config
import base64
class ServerActionsTest(unittest.TestCase):
resize_available = tempest.config.TempestConfig().env.resize_available
@classmethod
def setUpClass(cls):
cls.os = openstack.Manager()
cls.client = cls.os.servers_client
cls.config = cls.os.config
cls.image_ref = cls.config.env.image_ref
cls.image_ref_alt = cls.config.env.image_ref_alt
cls.flavor_ref = cls.config.env.flavor_ref
cls.flavor_ref_alt = cls.config.env.flavor_ref_alt
def setUp(self):
self.name = rand_name('server')
resp, self.server = self.client.create_server(self.name,
self.image_ref,
self.flavor_ref)
self.client.wait_for_server_status(self.server['id'], 'ACTIVE')
def tearDown(self):
self.client.delete_server(self.id)
@attr(type='smoke')
def test_change_server_password(self):
"""The server's password should be set to the provided password"""
resp, body = self.client.change_password(self.server['id'], 'newpass')
self.assertEqual(202, resp.status)
self.client.wait_for_server_status(self.server['id'], 'ACTIVE')
@attr(type='smoke')
def test_reboot_server_hard(self):
""" The server should be power cycled """
resp, body = self.client.reboot(self.server['id'], 'HARD')
self.assertEqual(202, resp.status)
self.client.wait_for_server_status(self.server['id'], 'ACTIVE')
@attr(type='smoke')
def test_reboot_server_soft(self):
"""The server should be signaled to reboot gracefully"""
resp, body = self.client.reboot(self.server['id'], 'SOFT')
self.assertEqual(202, resp.status)
self.client.wait_for_server_status(self.server['id'], 'ACTIVE')
@attr(type='smoke')
def test_rebuild_server(self):
""" The server should be rebuilt using the provided image and data """
meta = {'rebuild': 'server'}
name = rand_name('server')
file_contents = 'Test server rebuild.'
personality = [{'path': '/etc/rebuild.txt',
'contents': base64.b64encode(file_contents)}]
resp, rebuilt_server = self.client.rebuild(self.server['id'],
self.image_ref_alt,
name=name, meta=meta,
personality=personality,
adminPass='rebuild')
#Verify the properties in the initial response are correct
self.assertEqual(self.server['id'], rebuilt_server['id'])
self.assertEqual(self.image_ref_alt, rebuilt_server['image']['id'])
self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id'])
#Verify the server properties after the rebuild completes
self.client.wait_for_server_status(rebuilt_server['id'], 'ACTIVE')
resp, server = self.client.get_server(rebuilt_server['id'])
self.assertEqual(self.image_ref_alt, rebuilt_server['image']['id'])
self.assertEqual('rebuiltserver', rebuilt_server['name'])
@attr(type='smoke')
@unittest.skipIf(not resize_available, 'Resize not available.')
def test_resize_server_confirm(self):
"""
The server's RAM and disk space should be modified to that of
the provided flavor
"""
resp, server = self.client.resize(self.id, self.flavor_ref_alt)
self.assertEqual(202, resp.status)
self.client.wait_for_server_status(self.id, 'VERIFY_RESIZE')
self.client.confirm_resize(self.id)
self.client.wait_for_server_status(self.id, 'ACTIVE')
resp, server = self.client.get_server(self.id)
self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
@attr(type='smoke')
@unittest.skipIf(not resize_available, 'Resize not available.')
def test_resize_server_revert(self):
"""
The server's RAM and disk space should return to its original
values after a resize is reverted
"""
resp, server = self.client.resize(self.id, self.flavor_ref_alt)
self.assertEqual(202, resp.status)
self.client.wait_for_server_status(id, 'VERIFY_RESIZE')
self.client.revert_resize(self.id)
self.client.wait_for_server_status(id, 'ACTIVE')
resp, server = self.client.get_server(id)
self.assertEqual(self.flavor_ref, server['flavor']['id'])

@ -1,8 +1,8 @@
from nose.plugins.attrib import attr
from storm import openstack
from storm.common.utils.data_utils import rand_name
from tempest import openstack
from tempest.common.utils.data_utils import rand_name
import unittest2 as unittest
import storm.config
import tempest.config
class ServerMetadataTest(unittest.TestCase):

@ -0,0 +1,67 @@
from nose.plugins.attrib import attr
from tempest import openstack
from tempest import exceptions
from tempest.common.utils.data_utils import rand_name
import base64
import tempest.config
import unittest2 as unittest
class ServerPersonalityTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.os = openstack.Manager()
cls.client = cls.os.servers_client
cls.config = cls.config = cls.os.config
cls.image_ref = cls.config.env.image_ref
cls.flavor_ref = cls.config.env.flavor_ref
cls.user_client = cls.os.limits_client
def test_personality_files_exceed_limit(self):
"""
Server creation should fail if greater than the maximum allowed
number of files are injected into the server.
"""
name = rand_name('server')
file_contents = 'This is a test file.'
personality = []
resp, max_file_limit = self.user_client.get_personality_file_limit()
for i in range(0, max_file_limit + 1):
path = 'etc/test' + str(i) + '.txt'
personality.append({'path': path,
'contents': base64.b64encode(file_contents)})
try:
resp, resp_body = self.client.create_server(name, self.image_ref,
self.flavor_ref,
personality=personality)
except exceptions.OverLimit:
pass
else:
self.fail('This request did not fail as expected')
@attr(type='positive')
def test_can_create_server_with_max_number_personality_files(self):
"""
Server should be created successfully if maximum allowed number of
files is injected into the server during creation.
"""
name = rand_name('server')
file_contents = 'This is a test file.'
resp, max_file_limit = self.user_client.get_personality_file_limit()
self.assertEqual(200, resp.status)
personality = []
for i in range(0, max_file_limit):
path = 'etc/test' + str(i) + '.txt'
personality.append({'path': path,
'contents': base64.b64encode(file_contents)})
resp, server = self.client.create_server(name, self.image_ref,
self.flavor_ref,
personality=personality)
self.assertEqual('202', resp['status'])
#Teardown
self.client.delete_server(server['id'])

@ -1,9 +1,9 @@
from storm.common import ssh
from tempest.common import ssh
from nose.plugins.attrib import attr
from storm import openstack
from storm.common.utils.data_utils import rand_name
from tempest import openstack
from tempest.common.utils.data_utils import rand_name
import base64
import storm.config
import tempest.config
import unittest2 as unittest
@ -16,7 +16,6 @@ class ServersTest(unittest.TestCase):
cls.config = cls.os.config
cls.image_ref = cls.config.env.image_ref
cls.flavor_ref = cls.config.env.flavor_ref
cls.ssh_timeout = cls.config.nova.ssh_timeout
@attr(type='smoke')
def test_create_delete_server(self):
@ -34,6 +33,10 @@ class ServersTest(unittest.TestCase):
accessIPv4=accessIPv4,
accessIPv6=accessIPv6,
personality=personality)
#Check the initial response
self.assertEqual(202, resp.status)
self.assertTrue(server['id'] is not None)
self.assertTrue(server['adminPass'] is not None)
#Wait for the server to become active
self.client.wait_for_server_status(server['id'], 'ACTIVE')
@ -46,8 +49,9 @@ class ServersTest(unittest.TestCase):
self.assertEqual(self.image_ref, server['image']['id'])
self.assertEqual(str(self.flavor_ref), server['flavor']['id'])
#Teardown
self.client.delete_server(self.id)
#Delete the server
resp, body = self.client.delete_server(server['id'])
self.assertEqual(204, resp.status)
@attr(type='smoke')
def test_create_server_with_admin_password(self):
@ -64,14 +68,6 @@ class ServersTest(unittest.TestCase):
#Verify the password is set correctly in the response
self.assertEqual('testpassword', server['adminPass'])
#SSH into the server using the set password
self.client.wait_for_server_status(server['id'], 'ACTIVE')
resp, addresses = self.client.list_addresses(server['id'])
ip = addresses['public'][0]['addr']
client = ssh.Client(ip, 'root', 'testpassword', self.ssh_timeout)
self.assertTrue(client.test_connection_auth())
#Teardown
self.client.delete_server(server['id'])
@ -84,7 +80,8 @@ class ServersTest(unittest.TestCase):
self.client.wait_for_server_status(server['id'], 'ACTIVE')
#Update the server with a new name
self.client.update_server(server['id'], name='newname')
resp, server = self.client.update_server(server['id'], name='newname')
self.assertEquals(200, resp.status)
self.client.wait_for_server_status(server['id'], 'ACTIVE')
#Verify the name of the server has changed
@ -105,8 +102,10 @@ class ServersTest(unittest.TestCase):
self.client.wait_for_server_status(server['id'], 'ACTIVE')
#Update the IPv4 and IPv6 access addresses
self.client.update_server(server['id'], accessIPv4='1.1.1.1',
accessIPv6='::babe:2.2.2.2')
resp, body = self.client.update_server(server['id'],
accessIPv4='1.1.1.1',
accessIPv6='::babe:2.2.2.2')
self.assertEqual(200, resp.status)
self.client.wait_for_server_status(server['id'], 'ACTIVE')
#Verify the access addresses have been updated

@ -1,11 +1,11 @@
import unittest2 as unittest
import storm.config
import tempest.config
import base64
from nose.plugins.attrib import attr
from storm import openstack
from storm.common.utils.data_utils import rand_name
from storm.common import ssh
from storm import exceptions
from tempest import openstack
from tempest.common.utils.data_utils import rand_name
from tempest.common import ssh
from tempest import exceptions
class ServersNegativeTest(unittest.TestCase):
Loading…
Cancel
Save