deb-heat/heat/tests/test_nova_client.py
huangtianhua 9ed0d2729c Remove KeypairConstraint and FlavorConstraint to nova.py
All nova custom constraints should be defined in
nova.py as neutron custom constraints.
And this change also remove the corresponding tests
to test_nova_client.py

Change-Id: Ie40192b5d53d60d2d4e152801cbd8583e6c45dac
Implements: blueprint nova-custom-constraints
2014-11-17 15:23:54 +08:00

341 lines
13 KiB
Python

#
# 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.
"""Tests for :module:'heat.engine.resources.nova_utls'."""
import collections
import mock
from novaclient import exceptions as nova_exceptions
from oslo.config import cfg
import six
import uuid
from heat.common import exception
from heat.engine.clients.os import nova
from heat.tests import common
from heat.tests import utils
from heat.tests.v1_1 import fakes as fakes_v1_1
class NovaClientPluginTestCase(common.HeatTestCase):
def setUp(self):
super(NovaClientPluginTestCase, self).setUp()
self.nova_client = self.m.CreateMockAnything()
con = utils.dummy_context()
c = con.clients
self.nova_plugin = c.client_plugin('nova')
self.nova_plugin._client = self.nova_client
class NovaClientPluginTests(NovaClientPluginTestCase):
"""
Basic tests for the helper methods in
:module:'heat.engine.resources.nova_utils'.
"""
def test_get_ip(self):
my_image = self.m.CreateMockAnything()
my_image.addresses = {
'public': [{'version': 4,
'addr': '4.5.6.7'},
{'version': 6,
'addr': '2401:1801:7800:0101:c058:dd33:ff18:04e6'}],
'private': [{'version': 4,
'addr': '10.13.12.13'}]}
expected = '4.5.6.7'
observed = self.nova_plugin.get_ip(my_image, 'public', 4)
self.assertEqual(expected, observed)
expected = '10.13.12.13'
observed = self.nova_plugin.get_ip(my_image, 'private', 4)
self.assertEqual(expected, observed)
expected = '2401:1801:7800:0101:c058:dd33:ff18:04e6'
observed = self.nova_plugin.get_ip(my_image, 'public', 6)
self.assertEqual(expected, observed)
def test_get_flavor_id(self):
"""Tests the get_flavor_id function."""
flav_id = str(uuid.uuid4())
flav_name = 'X-Large'
my_flavor = self.m.CreateMockAnything()
my_flavor.name = flav_name
my_flavor.id = flav_id
self.nova_client.flavors = self.m.CreateMockAnything()
self.nova_client.flavors.list().MultipleTimes().AndReturn([my_flavor])
self.m.ReplayAll()
self.assertEqual(flav_id, self.nova_plugin.get_flavor_id(flav_name))
self.assertEqual(flav_id, self.nova_plugin.get_flavor_id(flav_id))
self.assertRaises(exception.FlavorMissing,
self.nova_plugin.get_flavor_id, 'noflavor')
self.m.VerifyAll()
def test_get_keypair(self):
"""Tests the get_keypair function."""
my_pub_key = 'a cool public key string'
my_key_name = 'mykey'
my_key = self.m.CreateMockAnything()
my_key.public_key = my_pub_key
my_key.name = my_key_name
self.nova_client.keypairs = self.m.CreateMockAnything()
self.nova_client.keypairs.get(
my_key_name).AndReturn(my_key)
self.nova_client.keypairs.get(
'notakey').AndRaise(nova_exceptions.NotFound(404))
self.m.ReplayAll()
self.assertEqual(my_key, self.nova_plugin.get_keypair(my_key_name))
self.assertRaises(exception.UserKeyPairMissing,
self.nova_plugin.get_keypair, 'notakey')
self.m.VerifyAll()
def test_get_server(self):
"""Tests the get_server function."""
my_server = self.m.CreateMockAnything()
self.nova_client.servers = self.m.CreateMockAnything()
self.nova_client.servers.get('my_server').AndReturn(my_server)
self.nova_client.servers.get('idontexist').AndRaise(
nova_exceptions.NotFound(404))
self.m.ReplayAll()
self.assertEqual(my_server, self.nova_plugin.get_server('my_server'))
self.assertRaises(exception.ServerNotFound,
self.nova_plugin.get_server, 'idontexist')
self.m.VerifyAll()
def test_get_status(self):
server = self.m.CreateMockAnything()
server.status = 'ACTIVE'
observed = self.nova_plugin.get_status(server)
self.assertEqual('ACTIVE', observed)
server.status = 'ACTIVE(STATUS)'
observed = self.nova_plugin.get_status(server)
self.assertEqual('ACTIVE', observed)
class NovaUtilsRefreshServerTests(NovaClientPluginTestCase):
def test_successful_refresh(self):
server = self.m.CreateMockAnything()
server.get().AndReturn(None)
self.m.ReplayAll()
self.assertIsNone(self.nova_plugin.refresh_server(server))
self.m.VerifyAll()
def test_overlimit_error(self):
server = mock.Mock()
server.get.side_effect = nova_exceptions.OverLimit(
413, "limit reached")
self.assertIsNone(self.nova_plugin.refresh_server(server))
def test_500_error(self):
server = self.m.CreateMockAnything()
msg = ("ClientException: The server has either erred or is "
"incapable of performing the requested operation.")
server.get().AndRaise(
nova_exceptions.ClientException(500, msg))
self.m.ReplayAll()
self.assertIsNone(self.nova_plugin.refresh_server(server))
self.m.VerifyAll()
def test_503_error(self):
server = self.m.CreateMockAnything()
msg = ("ClientException: The server has either erred or is "
"incapable of performing the requested operation.")
server.get().AndRaise(
nova_exceptions.ClientException(503, msg))
self.m.ReplayAll()
self.assertIsNone(self.nova_plugin.refresh_server(server))
self.m.VerifyAll()
def test_unhandled_exception(self):
server = self.m.CreateMockAnything()
msg = ("ClientException: The server has either erred or is "
"incapable of performing the requested operation.")
server.get().AndRaise(
nova_exceptions.ClientException(501, msg))
self.m.ReplayAll()
self.assertRaises(nova_exceptions.ClientException,
self.nova_plugin.refresh_server, server)
self.m.VerifyAll()
class NovaUtilsUserdataTests(NovaClientPluginTestCase):
def test_build_userdata(self):
"""Tests the build_userdata function."""
cfg.CONF.set_override('heat_metadata_server_url',
'http://server.test:123')
cfg.CONF.set_override('heat_watch_server_url',
'http://server.test:345')
cfg.CONF.set_override('instance_connection_is_secure',
False)
cfg.CONF.set_override(
'instance_connection_https_validate_certificates', False)
data = self.nova_plugin.build_userdata({})
self.assertIn("Content-Type: text/cloud-config;", data)
self.assertIn("Content-Type: text/cloud-boothook;", data)
self.assertIn("Content-Type: text/part-handler;", data)
self.assertIn("Content-Type: text/x-cfninitdata;", data)
self.assertIn("Content-Type: text/x-shellscript;", data)
self.assertIn("http://server.test:345", data)
self.assertIn("http://server.test:123", data)
self.assertIn("[Boto]", data)
def test_build_userdata_without_instance_user(self):
"""Don't add a custom instance user when not requested."""
cfg.CONF.set_override('instance_user',
'config_instance_user')
cfg.CONF.set_override('heat_metadata_server_url',
'http://server.test:123')
cfg.CONF.set_override('heat_watch_server_url',
'http://server.test:345')
data = self.nova_plugin.build_userdata({}, instance_user=None)
self.assertNotIn('user: ', data)
self.assertNotIn('useradd', data)
self.assertNotIn('config_instance_user', data)
def test_build_userdata_with_instance_user(self):
"""Add the custom instance user when requested."""
self.m.StubOutWithMock(nova.cfg, 'CONF')
cnf = nova.cfg.CONF
cnf.instance_user = 'config_instance_user'
cnf.heat_metadata_server_url = 'http://server.test:123'
cnf.heat_watch_server_url = 'http://server.test:345'
data = self.nova_plugin.build_userdata(
None, instance_user="custominstanceuser")
self.assertNotIn('config_instance_user', data)
self.assertIn("custominstanceuser", data)
class NovaUtilsMetadataTests(NovaClientPluginTestCase):
def test_serialize_string(self):
original = {'test_key': 'simple string value'}
self.assertEqual(original, self.nova_plugin.meta_serialize(original))
def test_serialize_int(self):
original = {'test_key': 123}
expected = {'test_key': '123'}
self.assertEqual(expected, self.nova_plugin.meta_serialize(original))
def test_serialize_list(self):
original = {'test_key': [1, 2, 3]}
expected = {'test_key': '[1, 2, 3]'}
self.assertEqual(expected, self.nova_plugin.meta_serialize(original))
def test_serialize_dict(self):
original = {'test_key': {'a': 'b', 'c': 'd'}}
expected = {'test_key': '{"a": "b", "c": "d"}'}
self.assertEqual(expected, self.nova_plugin.meta_serialize(original))
def test_serialize_none(self):
original = {'test_key': None}
expected = {'test_key': 'null'}
self.assertEqual(expected, self.nova_plugin.meta_serialize(original))
def test_serialize_no_value(self):
"""This test is to prove that the user can only pass in a dict to nova
metadata.
"""
excp = self.assertRaises(exception.StackValidationFailed,
self.nova_plugin.meta_serialize, "foo")
self.assertIn('metadata needs to be a Map', six.text_type(excp))
def test_serialize_combined(self):
original = {
'test_key_1': 123,
'test_key_2': 'a string',
'test_key_3': {'a': 'b'},
'test_key_4': None,
}
expected = {
'test_key_1': '123',
'test_key_2': 'a string',
'test_key_3': '{"a": "b"}',
'test_key_4': 'null',
}
self.assertEqual(expected, self.nova_plugin.meta_serialize(original))
class ServerConstraintTest(NovaClientPluginTestCase):
def setUp(self):
super(ServerConstraintTest, self).setUp()
self.ctx = utils.dummy_context()
self.mock_get_server = mock.Mock()
self.ctx.clients.client_plugin(
'nova').get_server = self.mock_get_server
self.constraint = nova.ServerConstraint()
def test_validation(self):
self.mock_get_server.return_value = mock.MagicMock()
self.assertTrue(self.constraint.validate("foo", self.ctx))
def test_validation_error(self):
self.mock_get_server.side_effect = exception.ServerNotFound(
server='bar')
self.assertFalse(self.constraint.validate("bar", self.ctx))
class FlavorConstraintTest(common.HeatTestCase):
def test_validate(self):
client = fakes_v1_1.FakeClient()
self.stub_keystoneclient()
self.m.StubOutWithMock(nova.NovaClientPlugin, '_create')
nova.NovaClientPlugin._create().AndReturn(client)
client.flavors = self.m.CreateMockAnything()
flavor = collections.namedtuple("Flavor", ["id", "name"])
flavor.id = "1234"
flavor.name = "foo"
client.flavors.list().MultipleTimes().AndReturn([flavor])
self.m.ReplayAll()
constraint = nova.FlavorConstraint()
ctx = utils.dummy_context()
self.assertFalse(constraint.validate("bar", ctx))
self.assertTrue(constraint.validate("foo", ctx))
self.assertTrue(constraint.validate("1234", ctx))
self.m.VerifyAll()
class KeypairConstraintTest(common.HeatTestCase):
def test_validation(self):
client = fakes_v1_1.FakeClient()
self.m.StubOutWithMock(nova.NovaClientPlugin, '_create')
nova.NovaClientPlugin._create().AndReturn(client)
client.keypairs = self.m.CreateMockAnything()
key = collections.namedtuple("Key", ["name"])
key.name = "foo"
client.keypairs.get('bar').AndRaise(fakes_v1_1.fake_exception())
client.keypairs.get(key.name).AndReturn(key)
self.m.ReplayAll()
constraint = nova.KeypairConstraint()
ctx = utils.dummy_context()
self.assertFalse(constraint.validate("bar", ctx))
self.assertTrue(constraint.validate("foo", ctx))
self.assertTrue(constraint.validate("", ctx))
self.m.VerifyAll()