Add ComputePort object
This is a general compute port object, where we will save bare metal ports for scheduling. Change-Id: I9dd599830aedebb70c75846803e89a6fc0a421ae
This commit is contained in:
parent
a1b960fc92
commit
1b8cfe717e
|
@ -173,6 +173,14 @@ class ComputeNodeNotFound(NotFound):
|
|||
msg_fmt = _("ComputeNode %(node)s could not be found.")
|
||||
|
||||
|
||||
class ComputePortAlreadyExists(MoganException):
|
||||
_msg_fmt = _("ComputePort with port_uuid %(port)s already exists.")
|
||||
|
||||
|
||||
class ComputePortNotFound(NotFound):
|
||||
msg_fmt = _("ComputePort %(port)s could not be found.")
|
||||
|
||||
|
||||
class NodeNotFound(NotFound):
|
||||
msg_fmt = _("Node associated with instance %(instance)s "
|
||||
"could not be found.")
|
||||
|
|
|
@ -103,6 +103,31 @@ class Connection(object):
|
|||
def compute_node_update(self, context, node_uuid, values):
|
||||
"""Update a compute node."""
|
||||
|
||||
# Compute ports
|
||||
@abc.abstractmethod
|
||||
def compute_port_create(self, context, values):
|
||||
"""Create a new compute port."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def compute_port_get(self, context, port_uuid):
|
||||
"""Get compute port by port uuid."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def compute_port_get_all(self, context):
|
||||
"""Get all compute ports."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def compute_port_get_by_node_uuid(self, context, node_uuid):
|
||||
"""Get compute ports by node_uuid."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def compute_port_destroy(self, context, port_uuid):
|
||||
"""Delete a compute port."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def compute_port_update(self, context, port_uuid, values):
|
||||
"""Update a compute port."""
|
||||
|
||||
# Instance Type extra specs
|
||||
@abc.abstractmethod
|
||||
def extra_specs_update_or_create(self, context,
|
||||
|
|
|
@ -111,6 +111,21 @@ def upgrade():
|
|||
mysql_ENGINE='InnoDB',
|
||||
mysql_DEFAULT_CHARSET='UTF8'
|
||||
)
|
||||
op.create_table(
|
||||
'compute_ports',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('port_type', sa.String(length=255), nullable=False),
|
||||
sa.Column('port_uuid', sa.String(length=36), nullable=False),
|
||||
sa.Column('node_uuid', sa.String(length=36), nullable=False),
|
||||
sa.Column('extra_specs', sa.Text(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('port_uuid', name='uniq_compute_ports0port_uuid'),
|
||||
sa.ForeignKeyConstraint(['node_uuid'], ['compute_nodes.node_uuid'], ),
|
||||
mysql_ENGINE='InnoDB',
|
||||
mysql_DEFAULT_CHARSET='UTF8'
|
||||
)
|
||||
op.create_table(
|
||||
'instance_nics',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
|
|
|
@ -278,6 +278,10 @@ class Connection(api.Connection):
|
|||
context,
|
||||
models.ComputeNode).filter_by(node_uuid=node_uuid)
|
||||
|
||||
port_query = model_query(context, models.ComputePort).filter_by(
|
||||
node_uuid=node_uuid)
|
||||
port_query.delete()
|
||||
|
||||
count = query.delete()
|
||||
if count != 1:
|
||||
raise exception.ComputeNodeNotFound(node=node_uuid)
|
||||
|
@ -295,6 +299,57 @@ class Connection(api.Connection):
|
|||
ref.update(values)
|
||||
return ref
|
||||
|
||||
def compute_port_create(self, context, values):
|
||||
compute_port = models.ComputePort()
|
||||
compute_port.update(values)
|
||||
with _session_for_write() as session:
|
||||
try:
|
||||
session.add(compute_port)
|
||||
session.flush()
|
||||
except db_exc.DBDuplicateEntry:
|
||||
raise exception.ComputePortAlreadyExists(
|
||||
port=values['port_uuid'])
|
||||
return compute_port
|
||||
|
||||
def compute_port_get(self, context, port_uuid):
|
||||
query = model_query(
|
||||
context,
|
||||
models.ComputePort).filter_by(port_uuid=port_uuid)
|
||||
try:
|
||||
return query.one()
|
||||
except NoResultFound:
|
||||
raise exception.ComputePortNotFound(port=port_uuid)
|
||||
|
||||
def compute_port_get_all(self, context):
|
||||
return model_query(context, models.ComputePort)
|
||||
|
||||
def compute_port_get_by_node_uuid(self, context, node_uuid):
|
||||
return model_query(context, models.ComputePort).filter_by(
|
||||
node_uuid=node_uuid).all()
|
||||
|
||||
def compute_port_destroy(self, context, port_uuid):
|
||||
with _session_for_write():
|
||||
query = model_query(
|
||||
context,
|
||||
models.ComputePort).filter_by(port_uuid=port_uuid)
|
||||
|
||||
count = query.delete()
|
||||
if count != 1:
|
||||
raise exception.ComputePortNotFound(port=port_uuid)
|
||||
|
||||
def compute_port_update(self, context, port_uuid, values):
|
||||
with _session_for_write():
|
||||
query = model_query(
|
||||
context,
|
||||
models.ComputePort).filter_by(port_uuid=port_uuid)
|
||||
try:
|
||||
ref = query.with_lockmode('update').one()
|
||||
except NoResultFound:
|
||||
raise exception.ComputePortNotFound(port=port_uuid)
|
||||
|
||||
ref.update(values)
|
||||
return ref
|
||||
|
||||
def extra_specs_update_or_create(self, context,
|
||||
instance_type_uuid, specs,
|
||||
max_retries=10):
|
||||
|
|
|
@ -93,7 +93,7 @@ class Instance(Base):
|
|||
|
||||
|
||||
class ComputeNode(Base):
|
||||
"""Represents possible types for compute_nodes."""
|
||||
"""Represents the compute nodes."""
|
||||
|
||||
__tablename__ = 'compute_nodes'
|
||||
__table_args__ = (
|
||||
|
@ -111,6 +111,27 @@ class ComputeNode(Base):
|
|||
extra_specs = Column(db_types.JsonEncodedDict)
|
||||
|
||||
|
||||
class ComputePort(Base):
|
||||
"""Represents the compute ports."""
|
||||
|
||||
__tablename__ = 'compute_ports'
|
||||
__table_args__ = (
|
||||
schema.UniqueConstraint('port_uuid',
|
||||
name='uniq_compute_ports0port_uuid'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
port_type = Column(String(255), nullable=False)
|
||||
port_uuid = Column(String(36), nullable=False)
|
||||
node_uuid = Column(String(36), nullable=False)
|
||||
extra_specs = Column(db_types.JsonEncodedDict)
|
||||
_node = orm.relationship(
|
||||
ComputeNode,
|
||||
backref=orm.backref('compute_ports', uselist=False),
|
||||
foreign_keys=node_uuid,
|
||||
primaryjoin='ComputeNode.node_uuid == ComputePort.node_uuid')
|
||||
|
||||
|
||||
class InstanceNic(Base):
|
||||
"""Represents the NIC info for instances."""
|
||||
|
||||
|
|
|
@ -159,6 +159,17 @@ class IronicDriver(base_driver.BaseEngineDriver):
|
|||
}
|
||||
return dic
|
||||
|
||||
def _port_resource(self, port):
|
||||
"""Helper method to create resource dict from port stats."""
|
||||
port_type = port.extra.get('port_type')
|
||||
|
||||
dic = {
|
||||
'port_type': str(port_type),
|
||||
'node_uuid': str(port.node_uuid),
|
||||
'port_uuid': str(port.uuid),
|
||||
}
|
||||
return dic
|
||||
|
||||
def _add_instance_info_to_node(self, node, instance):
|
||||
|
||||
patch = list()
|
||||
|
@ -447,7 +458,7 @@ class IronicDriver(base_driver.BaseEngineDriver):
|
|||
node_resources = {}
|
||||
for node in node_list:
|
||||
# Add ports to the associated node
|
||||
node.ports = [port for port in port_list
|
||||
node.ports = [self._port_resource(port) for port in port_list
|
||||
if node.uuid == port.node_uuid]
|
||||
node_resources[node.uuid] = self._node_resource(node)
|
||||
return node_resources
|
||||
|
|
|
@ -51,6 +51,14 @@ class EngineManager(base_manager.BaseEngineManager):
|
|||
with self._lock:
|
||||
self.node_cache = nodes
|
||||
|
||||
def _get_compute_port(self, context, port_uuid):
|
||||
"""Gets compute port by the uuid."""
|
||||
try:
|
||||
return objects.ComputePort.get(context, port_uuid)
|
||||
except exception.NotFound:
|
||||
LOG.warning(_LW("No compute port record for %(port)s"),
|
||||
{'port': port_uuid})
|
||||
|
||||
def _get_compute_node(self, context, node_uuid):
|
||||
"""Gets compute node by the uuid."""
|
||||
try:
|
||||
|
@ -59,6 +67,27 @@ class EngineManager(base_manager.BaseEngineManager):
|
|||
LOG.warning(_LW("No compute node record for %(node)s"),
|
||||
{'node': node_uuid})
|
||||
|
||||
def _init_compute_port(self, context, port):
|
||||
"""Initialize the compute port if it does not already exist.
|
||||
|
||||
:param context: security context
|
||||
:param port: initial values
|
||||
"""
|
||||
|
||||
# now try to get the compute port record from the
|
||||
# database. If we get one we use resources to initialize
|
||||
cp = self._get_compute_port(context, port['port_uuid'])
|
||||
if cp:
|
||||
cp.update_from_driver(port)
|
||||
cp.save()
|
||||
return
|
||||
|
||||
# there was no compute port in the database so we need to create
|
||||
# a new compute port. This needs to be initialized with node values.
|
||||
cp = objects.ComputePort(context)
|
||||
cp.update_from_driver(port)
|
||||
cp.create()
|
||||
|
||||
def _init_compute_node(self, context, node):
|
||||
"""Initialize the compute node if it does not already exist.
|
||||
|
||||
|
@ -72,13 +101,19 @@ class EngineManager(base_manager.BaseEngineManager):
|
|||
if cn:
|
||||
cn.update_from_driver(node)
|
||||
cn.save()
|
||||
return
|
||||
else:
|
||||
# there was no compute node in the database so we need to
|
||||
# create a new compute node. This needs to be initialized
|
||||
# with node values.
|
||||
cn = objects.ComputeNode(context)
|
||||
cn.update_from_driver(node)
|
||||
cn.create()
|
||||
|
||||
# there was no compute node in the database so we need to create
|
||||
# a new compute node. This needs to be initialized with node values.
|
||||
cn = objects.ComputeNode(context)
|
||||
cn.update_from_driver(node)
|
||||
cn.create()
|
||||
# Record compute ports to db
|
||||
for port in node['ports']:
|
||||
# initialize the compute port object, creating it
|
||||
# if it does not already exist.
|
||||
self._init_compute_port(context, port)
|
||||
|
||||
@periodic_task.periodic_task(
|
||||
spacing=CONF.engine.update_resources_interval,
|
||||
|
|
|
@ -27,7 +27,7 @@ class PortsFilter(filters.BaseNodeFilter):
|
|||
"""Check if ports has the specified port type."""
|
||||
|
||||
for port in ports:
|
||||
if port_type == port.extra.get('port_type'):
|
||||
if port_type == port['port_type']:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
|
|
@ -30,3 +30,4 @@ def register_all():
|
|||
__import__('mogan.objects.instance_nics')
|
||||
__import__('mogan.objects.instance_fault')
|
||||
__import__('mogan.objects.compute_node')
|
||||
__import__('mogan.objects.compute_port')
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
# Copyright 2017 Huawei Technologies Co.,LTD.
|
||||
# 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.
|
||||
|
||||
from oslo_versionedobjects import base as object_base
|
||||
|
||||
from mogan.db import api as dbapi
|
||||
from mogan.objects import base
|
||||
from mogan.objects import fields as object_fields
|
||||
|
||||
|
||||
@base.MoganObjectRegistry.register
|
||||
class ComputePort(base.MoganObject, object_base.VersionedObjectDictCompat):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
dbapi = dbapi.get_instance()
|
||||
|
||||
fields = {
|
||||
'id': object_fields.IntegerField(read_only=True),
|
||||
'port_type': object_fields.StringField(),
|
||||
'port_uuid': object_fields.UUIDField(read_only=True),
|
||||
'node_uuid': object_fields.UUIDField(read_only=True),
|
||||
'extra_specs': object_fields.FlexibleDictField(nullable=True),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def list(cls, context):
|
||||
"""Return a list of ComputePort objects."""
|
||||
db_compute_ports = cls.dbapi.compute_port_get_all(context)
|
||||
return cls._from_db_object_list(context, db_compute_ports)
|
||||
|
||||
@classmethod
|
||||
def get(cls, context, port_uuid):
|
||||
"""Find a compute port and return a ComputePort object."""
|
||||
db_compute_port = cls.dbapi.compute_port_get(context, port_uuid)
|
||||
compute_port = cls._from_db_object(cls(context), db_compute_port)
|
||||
return compute_port
|
||||
|
||||
def create(self, context=None):
|
||||
"""Create a ComputePort record in the DB."""
|
||||
values = self.obj_get_changes()
|
||||
db_compute_port = self.dbapi.compute_port_create(context, values)
|
||||
self._from_db_object(self, db_compute_port)
|
||||
|
||||
def destroy(self, context=None):
|
||||
"""Delete the ComputePort from the DB."""
|
||||
self.dbapi.compute_port_destroy(context, self.port_uuid)
|
||||
self.obj_reset_changes()
|
||||
|
||||
def save(self, context=None):
|
||||
"""Save updates to this ComputePort."""
|
||||
updates = self.obj_get_changes()
|
||||
self.dbapi.compute_port_update(context, self.port_uuid, updates)
|
||||
self.obj_reset_changes()
|
||||
|
||||
def refresh(self, context=None):
|
||||
"""Refresh the object by re-fetching from the DB."""
|
||||
current = self.__class__.get(context, self.port_uuid)
|
||||
self.obj_refresh(current)
|
||||
|
||||
def update_from_driver(self, port):
|
||||
keys = ["port_type", "port_uuid", "node_uuid", "extra_specs"]
|
||||
for key in keys:
|
||||
if key in port:
|
||||
setattr(self, key, port[key])
|
||||
|
||||
|
||||
@base.MoganObjectRegistry.register
|
||||
class ComputePortList(object_base.ObjectListBase, base.MoganObject,
|
||||
object_base.VersionedObjectDictCompat):
|
||||
# Version 1.0: Initial version
|
||||
|
||||
VERSION = '1.0'
|
||||
|
||||
dbapi = dbapi.get_instance()
|
||||
|
||||
fields = {
|
||||
'objects': object_fields.ListOfObjectsField('ComputePort')
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_by_node_uuid(cls, context, node_uuid):
|
||||
db_ports = cls.dbapi.compute_port_get_by_node_uuid(
|
||||
context, node_uuid)
|
||||
return object_base.obj_make_list(context, cls(context),
|
||||
ComputePort, db_ports)
|
|
@ -0,0 +1,78 @@
|
|||
# Copyright 2017 Huawei Technologies Co.,LTD.
|
||||
# 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.
|
||||
|
||||
"""Tests for manipulating ComputePorts via the DB API"""
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
import six
|
||||
|
||||
from mogan.common import exception
|
||||
from mogan.tests.unit.db import base
|
||||
from mogan.tests.unit.db import utils
|
||||
|
||||
|
||||
class DbComputePortTestCase(base.DbTestCase):
|
||||
|
||||
def test_compute_port_create(self):
|
||||
utils.create_test_compute_port()
|
||||
|
||||
def test_compute_port_create_with_same_uuid(self):
|
||||
utils.create_test_compute_port(port_uuid='uuid')
|
||||
self.assertRaises(exception.ComputePortAlreadyExists,
|
||||
utils.create_test_compute_port,
|
||||
port_uuid='uuid')
|
||||
|
||||
def test_compute_port_get_by_uuid(self):
|
||||
port = utils.create_test_compute_port()
|
||||
res = self.dbapi.compute_port_get(self.context, port.port_uuid)
|
||||
self.assertEqual(port.port_uuid, res.port_uuid)
|
||||
|
||||
def test_compute_port_get_not_exist(self):
|
||||
self.assertRaises(exception.ComputePortNotFound,
|
||||
self.dbapi.compute_port_get,
|
||||
self.context,
|
||||
'12345678-9999-0000-aaaa-123456789012')
|
||||
|
||||
def test_compute_port_get_all(self):
|
||||
port_uuids = []
|
||||
for i in range(0, 3):
|
||||
port = utils.create_test_compute_port(
|
||||
port_uuid=uuidutils.generate_uuid())
|
||||
port_uuids.append(six.text_type(port['port_uuid']))
|
||||
|
||||
res = self.dbapi.compute_port_get_all(self.context)
|
||||
res_uuids = [r.port_uuid for r in res]
|
||||
self.assertItemsEqual(port_uuids, res_uuids)
|
||||
|
||||
def test_compute_port_destroy(self):
|
||||
port = utils.create_test_compute_port()
|
||||
self.dbapi.compute_port_destroy(self.context, port.port_uuid)
|
||||
self.assertRaises(exception.ComputePortNotFound,
|
||||
self.dbapi.compute_port_get,
|
||||
self.context,
|
||||
port.port_uuid)
|
||||
|
||||
def test_compute_port_destroy_not_exist(self):
|
||||
self.assertRaises(exception.ComputePortNotFound,
|
||||
self.dbapi.compute_port_destroy,
|
||||
self.context,
|
||||
'12345678-9999-0000-aaaa-123456789012')
|
||||
|
||||
def test_compute_port_update(self):
|
||||
port = utils.create_test_compute_port()
|
||||
res = self.dbapi.compute_port_update(self.context,
|
||||
port.port_uuid,
|
||||
{'port_type': 'foo'})
|
||||
self.assertEqual('foo', res.port_type)
|
|
@ -109,7 +109,7 @@ def create_test_compute_node(context={}, **kw):
|
|||
Function to be used to create test ComputeNode objects in the database.
|
||||
|
||||
:param context: The request context, for access checks.
|
||||
:param kw: kwargs with overriding values for instance's attributes.
|
||||
:param kw: kwargs with overriding values for node's attributes.
|
||||
:returns: Test ComputeNode DB object.
|
||||
|
||||
"""
|
||||
|
@ -122,6 +122,39 @@ def create_test_compute_node(context={}, **kw):
|
|||
return dbapi.compute_node_create(context, node)
|
||||
|
||||
|
||||
def get_test_compute_port(**kw):
|
||||
return {
|
||||
'id': kw.get('id', 123),
|
||||
'port_type': kw.get('port_type', '1GE'),
|
||||
'port_uuid': kw.get('port_uuid',
|
||||
'f978ef48-d4af-4dad-beec-e6174309bc72'),
|
||||
'node_uuid': kw.get('node_uuid',
|
||||
'f978ef48-d4af-4dad-beec-e6174309bc71'),
|
||||
'extra_specs': kw.get('extra_specs', {}),
|
||||
'updated_at': kw.get('updated_at'),
|
||||
'created_at': kw.get('created_at'),
|
||||
}
|
||||
|
||||
|
||||
def create_test_compute_port(context={}, **kw):
|
||||
"""Create test compute port entry in DB and return ComputePort DB object.
|
||||
|
||||
Function to be used to create test ComputePort objects in the database.
|
||||
|
||||
:param context: The request context, for access checks.
|
||||
:param kw: kwargs with overriding values for port's attributes.
|
||||
:returns: Test ComputePort DB object.
|
||||
|
||||
"""
|
||||
port = get_test_compute_port(**kw)
|
||||
# Let DB generate ID if it isn't specified explicitly
|
||||
if 'id' not in kw:
|
||||
del port['id']
|
||||
dbapi = db_api.get_instance()
|
||||
|
||||
return dbapi.compute_port_create(context, port)
|
||||
|
||||
|
||||
def get_test_instance_type(**kw):
|
||||
return {
|
||||
'uuid': kw.get('uuid', uuidutils.generate_uuid()),
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
# Copyright 2017 Huawei Technologies Co.,LTD.
|
||||
# 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 copy
|
||||
|
||||
import mock
|
||||
from oslo_context import context
|
||||
|
||||
from mogan import objects
|
||||
from mogan.tests.unit.db import base
|
||||
from mogan.tests.unit.db import utils
|
||||
from mogan.tests.unit.objects import utils as obj_utils
|
||||
|
||||
|
||||
class TestComputePortObject(base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestComputePortObject, self).setUp()
|
||||
self.ctxt = context.get_admin_context()
|
||||
self.fake_port = utils.get_test_compute_port(context=self.ctxt)
|
||||
self.port = obj_utils.get_test_compute_port(
|
||||
self.ctxt, **self.fake_port)
|
||||
|
||||
def test_get(self):
|
||||
port_uuid = self.fake_port['port_uuid']
|
||||
with mock.patch.object(self.dbapi, 'compute_port_get',
|
||||
autospec=True) as mock_port_get:
|
||||
mock_port_get.return_value = self.fake_port
|
||||
|
||||
port = objects.ComputePort.get(self.context, port_uuid)
|
||||
|
||||
mock_port_get.assert_called_once_with(self.context, port_uuid)
|
||||
self.assertEqual(self.context, port._context)
|
||||
|
||||
def test_list(self):
|
||||
with mock.patch.object(self.dbapi, 'compute_port_get_all',
|
||||
autospec=True) as mock_port_get_all:
|
||||
mock_port_get_all.return_value = [self.fake_port]
|
||||
|
||||
ports = objects.ComputePort.list(self.context)
|
||||
|
||||
mock_port_get_all.assert_called_once_with(self.context)
|
||||
self.assertIsInstance(ports[0], objects.ComputePort)
|
||||
self.assertEqual(self.context, ports[0]._context)
|
||||
|
||||
def test_create(self):
|
||||
with mock.patch.object(self.dbapi, 'compute_port_create',
|
||||
autospec=True) as mock_port_create:
|
||||
mock_port_create.return_value = self.fake_port
|
||||
port = objects.ComputePort(self.context, **self.fake_port)
|
||||
port.obj_get_changes()
|
||||
port.create(self.context)
|
||||
expected_called = copy.deepcopy(self.fake_port)
|
||||
mock_port_create.assert_called_once_with(self.context,
|
||||
expected_called)
|
||||
self.assertEqual(self.fake_port['port_uuid'], port['port_uuid'])
|
||||
|
||||
def test_destroy(self):
|
||||
uuid = self.fake_port['port_uuid']
|
||||
with mock.patch.object(self.dbapi, 'compute_port_destroy',
|
||||
autospec=True) as mock_port_destroy:
|
||||
port = objects.ComputePort(self.context, **self.fake_port)
|
||||
port.destroy(self.context)
|
||||
mock_port_destroy.assert_called_once_with(self.context, uuid)
|
||||
|
||||
def test_save(self):
|
||||
uuid = self.fake_port['port_uuid']
|
||||
with mock.patch.object(self.dbapi, 'compute_port_update',
|
||||
autospec=True) as mock_port_update:
|
||||
mock_port_update.return_value = self.fake_port
|
||||
port = objects.ComputePort(self.context, **self.fake_port)
|
||||
updates = port.obj_get_changes()
|
||||
port.save(self.context)
|
||||
mock_port_update.assert_called_once_with(
|
||||
self.context, uuid, updates)
|
||||
|
||||
def test_save_after_refresh(self):
|
||||
db_port = utils.create_test_compute_port(context=self.ctxt)
|
||||
port = objects.ComputePort.get(self.context, db_port.port_uuid)
|
||||
port.refresh(self.context)
|
||||
port.port_type = 'refresh'
|
||||
port.save(self.context)
|
|
@ -384,6 +384,8 @@ class _TestObject(object):
|
|||
expected_object_fingerprints = {
|
||||
'Instance': '1.0-18d0ffc894a0f6b52df73a29919c035b',
|
||||
'ComputeNode': '1.0-9dd029c83e37adc7e01ff759e76cdda1',
|
||||
'ComputePort': '1.0-bdba0f3ece31260c4deea37d39618c1a',
|
||||
'ComputePortList': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
|
||||
'InstanceFault': '1.0-6b5b01b2cc7b6b547837acb168ec6eb9',
|
||||
'InstanceFaultList': '1.0-43e8aad0258652921f929934e9e048fd',
|
||||
'InstanceType': '1.0-589b096651fcdb30898ff50f748dd948',
|
||||
|
|
|
@ -96,3 +96,32 @@ def create_test_compute_node(ctxt, **kw):
|
|||
node = get_test_compute_node(ctxt, **kw)
|
||||
node.create()
|
||||
return node
|
||||
|
||||
|
||||
def get_test_compute_port(ctxt, **kw):
|
||||
"""Return a ComputePort object with appropriate attributes.
|
||||
|
||||
NOTE: The object leaves the attributes marked as changed, such
|
||||
that a create() could be used to commit it to the DB.
|
||||
"""
|
||||
kw['object_type'] = 'compute_port'
|
||||
get_db_compute_port_checked = check_keyword_arguments(
|
||||
db_utils.get_test_compute_port)
|
||||
db_port = get_db_compute_port_checked(**kw)
|
||||
|
||||
# Let DB generate ID if it isn't specified explicitly
|
||||
if 'id' not in kw:
|
||||
del db_port['id']
|
||||
port = objects.ComputePort(ctxt, **db_port)
|
||||
return port
|
||||
|
||||
|
||||
def create_test_compute_port(ctxt, **kw):
|
||||
"""Create and return a test compute port object.
|
||||
|
||||
Create a compute port in the DB and return a ComputePort object with
|
||||
appropriate attributes.
|
||||
"""
|
||||
port = get_test_compute_port(ctxt, **kw)
|
||||
port.create()
|
||||
return port
|
||||
|
|
Loading…
Reference in New Issue