tests: Centralize configuration of default flavor, image

Different tests were doing this in different ways. Centralize it all in
the base test class for functional tests. For both flavor and image, the
order of precedence is:

- Environment variables
- clouds.yaml configuration
- Guesswork (pick a cirros, Ubuntu or CentOS image for images, or the
  flavor with the lowest RAM for flavors)

Change-Id: I90fda8ef48008c7fa634edc295c0e83e5f29387f
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane 2021-12-22 14:57:19 +00:00
parent 11d89450c1
commit 3244abd020
10 changed files with 163 additions and 164 deletions

View File

@ -68,8 +68,9 @@ configured for the one cloud. These accounts are:
configurable via the ``OPENSTACKSDK_DEMO_CLOUD_ALT`` environment variable configurable via the ``OPENSTACKSDK_DEMO_CLOUD_ALT`` environment variable
In addition, you must indicate the names of the flavor and image that should be In addition, you must indicate the names of the flavor and image that should be
used for tests. These can be configured via ``functional.flavor_name`` and used for tests. These can be configured via ``OPENSTACKSDK_FLAVOR`` and
``functional.image_name`` settings in the ``clouds.yaml`` file. ``OPENSTACKSDK_IMAGE`` environment variables or ``functional.flavor_name`` and
``functional.image_name`` settings in the ``clouds.yaml`` file, respectively.
Finally, you can configure the timeout for tests using the Finally, you can configure the timeout for tests using the
``OPENSTACKSDK_FUNC_TEST_TIMEOUT`` environment variable (defaults to 300 ``OPENSTACKSDK_FUNC_TEST_TIMEOUT`` environment variable (defaults to 300

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import operator
import os import os
from keystoneauth1 import discover from keystoneauth1 import discover
@ -28,9 +29,8 @@ TEST_CLOUD_NAME = os.getenv('OS_CLOUD', 'devstack-admin')
TEST_CLOUD_REGION = openstack.config.get_cloud_region(cloud=TEST_CLOUD_NAME) TEST_CLOUD_REGION = openstack.config.get_cloud_region(cloud=TEST_CLOUD_NAME)
def _get_resource_value(resource_key, default): def _get_resource_value(resource_key):
return TEST_CONFIG.get_extra_config( return TEST_CONFIG.get_extra_config('functional').get(resource_key)
'functional').get(resource_key, default)
def _disable_keep_alive(conn): def _disable_keep_alive(conn):
@ -38,10 +38,6 @@ def _disable_keep_alive(conn):
sess.keep_alive = False sess.keep_alive = False
IMAGE_NAME = _get_resource_value('image_name', 'cirros-0.4.0-x86_64-disk')
FLAVOR_NAME = _get_resource_value('flavor_name', 'm1.small')
class BaseFunctionalTest(base.TestCase): class BaseFunctionalTest(base.TestCase):
_wait_for_timeout_key = '' _wait_for_timeout_key = ''
@ -52,10 +48,12 @@ class BaseFunctionalTest(base.TestCase):
_disable_keep_alive(self.conn) _disable_keep_alive(self.conn)
self._demo_name = os.environ.get('OPENSTACKSDK_DEMO_CLOUD', 'devstack') self._demo_name = os.environ.get('OPENSTACKSDK_DEMO_CLOUD', 'devstack')
self._demo_name_alt = os.environ.get('OPENSTACKSDK_DEMO_CLOUD_ALT', self._demo_name_alt = os.environ.get(
'devstack-alt') 'OPENSTACKSDK_DEMO_CLOUD_ALT', 'devstack-alt',
)
self._op_name = os.environ.get( self._op_name = os.environ.get(
'OPENSTACKSDK_OPERATOR_CLOUD', 'devstack-admin') 'OPENSTACKSDK_OPERATOR_CLOUD', 'devstack-admin',
)
self.config = openstack.config.OpenStackConfig() self.config = openstack.config.OpenStackConfig()
self._set_user_cloud() self._set_user_cloud()
@ -64,6 +62,9 @@ class BaseFunctionalTest(base.TestCase):
self.identity_version = \ self.identity_version = \
self.operator_cloud.config.get_api_version('identity') self.operator_cloud.config.get_api_version('identity')
self.flavor = self._pick_flavor()
self.image = self._pick_image()
# Defines default timeout for wait_for methods used # Defines default timeout for wait_for methods used
# in the functional tests # in the functional tests
self._wait_for_timeout = int( self._wait_for_timeout = int(
@ -71,8 +72,7 @@ class BaseFunctionalTest(base.TestCase):
'OPENSTACKSDK_FUNC_TEST_TIMEOUT', 300))) 'OPENSTACKSDK_FUNC_TEST_TIMEOUT', 300)))
def _set_user_cloud(self, **kwargs): def _set_user_cloud(self, **kwargs):
user_config = self.config.get_one( user_config = self.config.get_one(cloud=self._demo_name, **kwargs)
cloud=self._demo_name, **kwargs)
self.user_cloud = connection.Connection(config=user_config) self.user_cloud = connection.Connection(config=user_config)
_disable_keep_alive(self.user_cloud) _disable_keep_alive(self.user_cloud)
@ -84,37 +84,95 @@ class BaseFunctionalTest(base.TestCase):
_disable_keep_alive(self.user_cloud_alt) _disable_keep_alive(self.user_cloud_alt)
def _set_operator_cloud(self, **kwargs): def _set_operator_cloud(self, **kwargs):
operator_config = self.config.get_one( operator_config = self.config.get_one(cloud=self._op_name, **kwargs)
cloud=self._op_name, **kwargs)
self.operator_cloud = connection.Connection(config=operator_config) self.operator_cloud = connection.Connection(config=operator_config)
_disable_keep_alive(self.operator_cloud) _disable_keep_alive(self.operator_cloud)
def pick_image(self): def _pick_flavor(self):
"""Pick a sensible flavor to run tests with.
This returns None if the compute service is not present (e.g.
ironic-only deployments).
"""
if not self.user_cloud.has_service('compute'):
return None
flavors = self.user_cloud.list_flavors(get_extra=False)
self.add_info_on_exception('flavors', flavors)
flavor_name = os.environ.get('OPENSTACKSDK_FLAVOR')
if not flavor_name:
flavor_name = _get_resource_value('flavor_name')
if flavor_name:
for flavor in flavors:
if flavor.name == flavor_name:
return flavor
raise self.failureException(
"Cloud does not have flavor '%s'", flavor_name,
)
# Enable running functional tests against RAX, which requires
# performance flavors be used for boot from volume
for flavor in sorted(flavors, key=operator.attrgetter('ram')):
if 'performance' in flavor.name:
return flavor
# Otherwise, pick the smallest flavor with a ephemeral disk configured
for flavor in sorted(flavors, key=operator.attrgetter('ram')):
if flavor.disk:
return flavor
raise self.failureException('No sensible flavor found')
def _pick_image(self):
"""Pick a sensible image to run tests with.
This returns None if the image service is not present.
"""
if not self.user_cloud.has_service('image'):
return None
images = self.user_cloud.list_images() images = self.user_cloud.list_images()
self.add_info_on_exception('images', images) self.add_info_on_exception('images', images)
image_name = os.environ.get('OPENSTACKSDK_IMAGE') image_name = os.environ.get('OPENSTACKSDK_IMAGE')
if not image_name:
image_name = _get_resource_value('image_name')
if image_name: if image_name:
for image in images: for image in images:
if image.name == image_name: if image.name == image_name:
return image return image
self.assertFalse(
"Cloud does not have {image}".format(image=image_name)) raise self.failureException(
"Cloud does not have image '%s'", image_name,
)
for image in images: for image in images:
if image.name.startswith('cirros') and image.name.endswith('-uec'): if image.name.startswith('cirros') and image.name.endswith('-uec'):
return image return image
for image in images: for image in images:
if (image.name.startswith('cirros') if (
and image.disk_format == 'qcow2'): image.name.startswith('cirros')
and image.disk_format == 'qcow2'
):
return image return image
for image in images: for image in images:
if image.name.lower().startswith('ubuntu'): if image.name.lower().startswith('ubuntu'):
return image return image
for image in images: for image in images:
if image.name.lower().startswith('centos'): if image.name.lower().startswith('centos'):
return image return image
self.assertFalse('no sensible image available')
raise self.failureException('No sensible image found')
def addEmptyCleanup(self, func, *args, **kwargs): def addEmptyCleanup(self, func, *args, **kwargs):
def cleanup(): def cleanup():
@ -125,9 +183,9 @@ class BaseFunctionalTest(base.TestCase):
def require_service(self, service_type, min_microversion=None, **kwargs): def require_service(self, service_type, min_microversion=None, **kwargs):
"""Method to check whether a service exists """Method to check whether a service exists
Usage: Usage::
class TestMeter(base.BaseFunctionalTest): class TestMeter(base.BaseFunctionalTest):
...
def setUp(self): def setUp(self):
super(TestMeter, self).setUp() super(TestMeter, self).setUp()
self.require_service('metering') self.require_service('metering')
@ -144,16 +202,19 @@ class BaseFunctionalTest(base.TestCase):
data = self.conn.session.get_endpoint_data( data = self.conn.session.get_endpoint_data(
service_type=service_type, **kwargs) service_type=service_type, **kwargs)
if not (data.min_microversion if not (
data.min_microversion
and data.max_microversion and data.max_microversion
and discover.version_between( and discover.version_between(
data.min_microversion, data.min_microversion,
data.max_microversion, data.max_microversion,
min_microversion)): min_microversion,
self.skipTest('Service {service_type} does not provide ' )
'microversion {ver}'.format( ):
service_type=service_type, self.skipTest(
ver=min_microversion)) f'Service {service_type} does not provide microversion '
f'{min_microversion}'
)
class KeystoneBaseFunctionalTest(BaseFunctionalTest): class KeystoneBaseFunctionalTest(BaseFunctionalTest):

View File

@ -115,8 +115,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -145,8 +145,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -189,8 +189,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -232,8 +232,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -318,8 +318,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -392,8 +392,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -474,8 +474,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -567,8 +567,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -656,8 +656,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -713,8 +713,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -775,8 +775,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -863,8 +863,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -914,8 +914,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -1018,8 +1018,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -1056,8 +1056,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -1094,8 +1094,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -1130,8 +1130,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -1297,8 +1297,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"
@ -1356,8 +1356,8 @@ class TestClustering(base.BaseFunctionalTest):
profile_name = "test_profile" profile_name = "test_profile"
spec = { spec = {
"properties": { "properties": {
"flavor": "m1.tiny", "flavor": self.flavor.name,
"image": base.IMAGE_NAME, "image": self.image.name,
"networks": [ "networks": [
{ {
"network": "private" "network": "private"

View File

@ -23,7 +23,6 @@ from fixtures import TimeoutException
from openstack.cloud import exc from openstack.cloud import exc
from openstack.tests.functional import base from openstack.tests.functional import base
from openstack.tests.functional.cloud.util import pick_flavor
from openstack import utils from openstack import utils
@ -34,11 +33,6 @@ class TestCompute(base.BaseFunctionalTest):
self.TIMEOUT_SCALING_FACTOR = 1.5 self.TIMEOUT_SCALING_FACTOR = 1.5
super(TestCompute, self).setUp() super(TestCompute, self).setUp()
self.flavor = pick_flavor(
self.user_cloud.list_flavors(get_extra=False))
if self.flavor is None:
self.assertFalse('no sensible flavor available')
self.image = self.pick_image()
self.server_name = self.getUniqueString() self.server_name = self.getUniqueString()
def _cleanup_servers_and_volumes(self, server_name): def _cleanup_servers_and_volumes(self, server_name):

View File

@ -28,7 +28,6 @@ from openstack.cloud.exc import OpenStackCloudException
from openstack.cloud import meta from openstack.cloud import meta
from openstack import proxy from openstack import proxy
from openstack.tests.functional import base from openstack.tests.functional import base
from openstack.tests.functional.cloud.util import pick_flavor
from openstack import utils from openstack import utils
@ -36,12 +35,7 @@ class TestFloatingIP(base.BaseFunctionalTest):
timeout = 60 timeout = 60
def setUp(self): def setUp(self):
super(TestFloatingIP, self).setUp() super().setUp()
self.flavor = pick_flavor(
self.user_cloud.list_flavors(get_extra=False))
if self.flavor is None:
self.assertFalse('no sensible flavor available')
self.image = self.pick_image()
# Generate a random name for these tests # Generate a random name for these tests
self.new_item_name = self.getUniqueString() self.new_item_name = self.getUniqueString()

View File

@ -25,9 +25,6 @@ from openstack.tests.functional import base
class TestImage(base.BaseFunctionalTest): class TestImage(base.BaseFunctionalTest):
def setUp(self):
super(TestImage, self).setUp()
self.image = self.pick_image()
def test_create_image(self): def test_create_image(self):
test_image = tempfile.NamedTemporaryFile(delete=False) test_image = tempfile.NamedTemporaryFile(delete=False)

View File

@ -21,21 +21,15 @@ Functional tests for `shade` inventory methods.
from openstack.cloud import inventory from openstack.cloud import inventory
from openstack.tests.functional import base from openstack.tests.functional import base
from openstack.tests.functional.cloud.util import pick_flavor
class TestInventory(base.BaseFunctionalTest): class TestInventory(base.BaseFunctionalTest):
def setUp(self): def setUp(self):
super(TestInventory, self).setUp() super().setUp()
# This needs to use an admin account, otherwise a public IP # This needs to use an admin account, otherwise a public IP
# is not allocated from devstack. # is not allocated from devstack.
self.inventory = inventory.OpenStackInventory(cloud='devstack-admin') self.inventory = inventory.OpenStackInventory(cloud='devstack-admin')
self.server_name = self.getUniqueString('inventory') self.server_name = self.getUniqueString('inventory')
self.flavor = pick_flavor(
self.user_cloud.list_flavors(get_extra=False))
if self.flavor is None:
self.assertTrue(False, 'no sensible flavor available')
self.image = self.pick_image()
self.addCleanup(self._cleanup_server) self.addCleanup(self._cleanup_server)
server = self.operator_cloud.create_server( server = self.operator_cloud.create_server(
name=self.server_name, image=self.image, flavor=self.flavor, name=self.server_name, image=self.image, flavor=self.flavor,

View File

@ -1,43 +0,0 @@
# 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.
"""
util
--------------------------------
Util methods for functional tests
"""
import operator
import os
def pick_flavor(flavors):
"""Given a flavor list pick the smallest one."""
# Enable running functional tests against rax - which requires
# performance flavors be used for boot from volume
flavor_name = os.environ.get('OPENSTACKSDK_FLAVOR')
if flavor_name:
for flavor in flavors:
if flavor.name == flavor_name:
return flavor
return None
for flavor in sorted(
flavors,
key=operator.attrgetter('ram')):
if 'performance' in flavor.name:
return flavor
for flavor in sorted(
flavors,
key=operator.attrgetter('ram')):
if flavor.disk:
return flavor

View File

@ -40,8 +40,8 @@ class TestCluster(base.BaseFunctionalTest):
'version': 1.0, 'version': 1.0,
'properties': { 'properties': {
'name': self.getUniqueString(), 'name': self.getUniqueString(),
'flavor': base.FLAVOR_NAME, 'flavor': self.flavor.name,
'image': base.IMAGE_NAME, 'image': self.image.name,
'networks': [{'network': self.network.id}] 'networks': [{'network': self.network.id}]
}}} }}}

View File

@ -11,7 +11,6 @@
# under the License. # under the License.
from openstack.compute.v2 import server from openstack.compute.v2 import server
from openstack.tests.functional import base
from openstack.tests.functional.compute import base as ft_base from openstack.tests.functional.compute import base as ft_base
from openstack.tests.functional.network.v2 import test_network from openstack.tests.functional.network.v2 import test_network
@ -23,21 +22,24 @@ class TestServerAdmin(ft_base.BaseComputeTest):
self._set_operator_cloud(interface='admin') self._set_operator_cloud(interface='admin')
self.NAME = 'needstobeshortandlowercase' self.NAME = 'needstobeshortandlowercase'
self.USERDATA = 'SSdtIGFjdHVhbGx5IGEgZ29hdC4=' self.USERDATA = 'SSdtIGFjdHVhbGx5IGEgZ29hdC4='
flavor = self.conn.compute.find_flavor(base.FLAVOR_NAME,
ignore_missing=False)
image = self.conn.compute.find_image(base.IMAGE_NAME,
ignore_missing=False)
volume = self.conn.create_volume(1) volume = self.conn.create_volume(1)
sot = self.conn.compute.create_server( sot = self.conn.compute.create_server(
name=self.NAME, flavor_id=flavor.id, image_id=image.id, name=self.NAME,
networks='none', user_data=self.USERDATA, flavor_id=self.flavor.id,
block_device_mapping=[{ image_id=self.image.id,
networks='none',
user_data=self.USERDATA,
block_device_mapping=[
{
'uuid': volume.id, 'uuid': volume.id,
'source_type': 'volume', 'source_type': 'volume',
'boot_index': 0, 'boot_index': 0,
'destination_type': 'volume', 'destination_type': 'volume',
'delete_on_termination': True, 'delete_on_termination': True,
'volume_size': 1}]) 'volume_size': 1,
},
],
)
self.conn.compute.wait_for_server(sot, wait=self._wait_for_timeout) self.conn.compute.wait_for_server(sot, wait=self._wait_for_timeout)
assert isinstance(sot, server.Server) assert isinstance(sot, server.Server)
self.assertEqual(self.NAME, sot.name) self.assertEqual(self.NAME, sot.name)
@ -72,10 +74,6 @@ class TestServer(ft_base.BaseComputeTest):
self.subnet = None self.subnet = None
self.cidr = '10.99.99.0/16' self.cidr = '10.99.99.0/16'
flavor = self.conn.compute.find_flavor(base.FLAVOR_NAME,
ignore_missing=False)
image = self.conn.compute.find_image(base.IMAGE_NAME,
ignore_missing=False)
self.network, self.subnet = test_network.create_network( self.network, self.subnet = test_network.create_network(
self.conn, self.conn,
self.NAME, self.NAME,
@ -83,8 +81,11 @@ class TestServer(ft_base.BaseComputeTest):
self.assertIsNotNone(self.network) self.assertIsNotNone(self.network)
sot = self.conn.compute.create_server( sot = self.conn.compute.create_server(
name=self.NAME, flavor_id=flavor.id, image_id=image.id, name=self.NAME,
networks=[{"uuid": self.network.id}]) flavor_id=self.flavor.id,
image_id=self.image.id,
networks=[{"uuid": self.network.id}],
)
self.conn.compute.wait_for_server(sot, wait=self._wait_for_timeout) self.conn.compute.wait_for_server(sot, wait=self._wait_for_timeout)
assert isinstance(sot, server.Server) assert isinstance(sot, server.Server)
self.assertEqual(self.NAME, sot.name) self.assertEqual(self.NAME, sot.name)