Merge "Add libvirt test to ensure metadata are working."
This commit is contained in:
Vendored
+35
@@ -914,6 +914,25 @@ def _parse_vcpu_info(element):
|
||||
return vcpu_info
|
||||
|
||||
|
||||
def _parse_filesystem_info(element):
|
||||
filesystem_info = {}
|
||||
filesystem_info['type'] = element.get('type', 'mount')
|
||||
|
||||
driver = element.find('./driver')
|
||||
if driver is not None:
|
||||
filesystem_info['driver_type'] = driver.get('type')
|
||||
|
||||
source = element.find('./source')
|
||||
if source is not None:
|
||||
filesystem_info['source'] = source.get('dir')
|
||||
|
||||
target = element.find('./target')
|
||||
if target is not None:
|
||||
filesystem_info['target'] = target.get('dir')
|
||||
|
||||
return filesystem_info
|
||||
|
||||
|
||||
def _parse_nic_info(element):
|
||||
nic_info = {}
|
||||
nic_info['type'] = element.get('type', 'bridge')
|
||||
@@ -1177,6 +1196,13 @@ class Domain(object):
|
||||
disks_info += [_parse_disk_info(disk)]
|
||||
devices['disks'] = disks_info
|
||||
|
||||
# Manage shares
|
||||
filesystems_info = []
|
||||
filesystems = device_nodes.findall('./filesystem')
|
||||
for filesystem in filesystems:
|
||||
filesystems_info += [_parse_filesystem_info(filesystem)]
|
||||
devices['filesystem'] = filesystems_info
|
||||
|
||||
nics_info = []
|
||||
nics = device_nodes.findall('./interface')
|
||||
for nic in nics:
|
||||
@@ -1458,6 +1484,13 @@ class Domain(object):
|
||||
<address type='drive' controller='0' bus='0' unit='0'/>
|
||||
</disk>"""
|
||||
disks += strformat % dict(source_attr=source_attr, **disk)
|
||||
filesystems = ''
|
||||
for filesystem in self._def['devices']['filesystem']:
|
||||
filesystems += '''<filesystem type='%(type)s'>
|
||||
<driver type='%(driver_type)s'/>
|
||||
<source dir='%(source)s'/>
|
||||
<target dir='%(target)s'/>
|
||||
</filesystem>''' % dict(source_attr=source_attr, **filesystem)
|
||||
nics = ''
|
||||
for func, nic in enumerate(self._def['devices']['nics']):
|
||||
if func > 7:
|
||||
@@ -1590,6 +1623,7 @@ class Domain(object):
|
||||
<devices>
|
||||
<emulator>/usr/bin/kvm</emulator>
|
||||
%(disks)s
|
||||
%(filesystems)s
|
||||
<controller type='ide' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01'
|
||||
function='0x1'/>
|
||||
@@ -1624,6 +1658,7 @@ class Domain(object):
|
||||
'arch': self._def['os']['arch'],
|
||||
'loader': loader,
|
||||
'disks': disks,
|
||||
'filesystems': filesystems,
|
||||
'nics': nics,
|
||||
'hostdevs': hostdevs,
|
||||
'vpmems': vpmems,
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
# 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 fixtures
|
||||
from lxml import etree
|
||||
from requests import request
|
||||
|
||||
from nova import context as nova_context
|
||||
from nova.objects import instance
|
||||
from nova.tests import fixtures as nova_fixtures
|
||||
from nova.tests.functional.libvirt import base
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from unittest import mock
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ServerSharesTestBase(base.ServersTestBase):
|
||||
api_major_version = 'v2.1'
|
||||
microversion = 'latest'
|
||||
ADMIN_API = True
|
||||
FAKE_LIBVIRT_VERSION = 7000000
|
||||
FAKE_QEMU_VERSION = 5002000
|
||||
|
||||
def setUp(self):
|
||||
super(ServerSharesTestBase, self).setUp()
|
||||
|
||||
self.context = nova_context.get_admin_context()
|
||||
self.manila_fixture = self.useFixture(nova_fixtures.ManilaFixture())
|
||||
self.flags(ram_allocation_ratio=1.0)
|
||||
self.flags(file_backed_memory=8192, group='libvirt')
|
||||
self.compute = self.start_compute(
|
||||
'host1',
|
||||
libvirt_version=self.FAKE_LIBVIRT_VERSION,
|
||||
qemu_version=self.FAKE_QEMU_VERSION
|
||||
)
|
||||
|
||||
self.api_fixture = self.useFixture(nova_fixtures.OSMetadataServer())
|
||||
self.md_url = self.api_fixture.md_url
|
||||
|
||||
self.host = self.computes[self.compute].driver._host
|
||||
|
||||
def _get_xml(self, server):
|
||||
self.instance = instance.Instance.get_by_uuid(
|
||||
self.context, server['id'])
|
||||
guest = self.host.get_guest(self.instance)
|
||||
xml = guest.get_xml_desc()
|
||||
return xml
|
||||
|
||||
def _get_filesystem_tag(self, xml, tag):
|
||||
tags = []
|
||||
tree = etree.fromstring(xml)
|
||||
device_nodes = tree.find('./devices')
|
||||
filesystems = device_nodes.findall('./filesystem')
|
||||
for filesystem in filesystems:
|
||||
target = filesystem.find('./target')
|
||||
tags.append(target.get('dir'))
|
||||
return tags
|
||||
|
||||
def _assert_filesystem_tag(self, xml, tag):
|
||||
tags = self._get_filesystem_tag(xml, tag)
|
||||
self.assertIn(tag, tags)
|
||||
|
||||
def _assert_filesystem_tag_not_present(self, xml, tag):
|
||||
tags = self._get_filesystem_tag(xml, tag)
|
||||
self.assertNotIn(tag, tags)
|
||||
|
||||
def _get_metadata_url(self, server):
|
||||
# make sure that the metadata service returns information about the
|
||||
# server we created above
|
||||
|
||||
def fake_get_fixed_ip_by_address(self, ctxt, address):
|
||||
return {'instance_uuid': server['id']}
|
||||
|
||||
self.useFixture(
|
||||
fixtures.MonkeyPatch(
|
||||
'nova.network.neutron.API.get_fixed_ip_by_address',
|
||||
fake_get_fixed_ip_by_address))
|
||||
url = '%sopenstack/latest/meta_data.json' % self.md_url
|
||||
return url
|
||||
|
||||
def _assert_share_in_metadata(self, metatdata_url, share_id, tag):
|
||||
device_share_and_tag = []
|
||||
res = request('GET', metatdata_url, timeout=5)
|
||||
self.assertEqual(200, res.status_code)
|
||||
metadata = jsonutils.loads(res.text)
|
||||
for device in metadata['devices']:
|
||||
device_share_and_tag.append((device['share_id'], device['tag']))
|
||||
self.assertIn((share_id, tag), device_share_and_tag)
|
||||
|
||||
|
||||
class ServerSharesTest(ServerSharesTestBase):
|
||||
|
||||
def test_server_share_metadata(self):
|
||||
"""Verify that share metadata are available"""
|
||||
with mock.patch(
|
||||
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
|
||||
'disconnect_volume'
|
||||
), mock.patch(
|
||||
'nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver.'
|
||||
'connect_volume'
|
||||
):
|
||||
traits = self._get_provider_traits(
|
||||
self.compute_rp_uuids[self.compute])
|
||||
for trait in (
|
||||
'COMPUTE_STORAGE_VIRTIO_FS', 'COMPUTE_MEM_BACKING_FILE'):
|
||||
self.assertIn(trait, traits)
|
||||
server = self._create_server(networks='auto')
|
||||
self._stop_server(server)
|
||||
|
||||
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
|
||||
self._attach_share(server, share_id)
|
||||
self._start_server(server)
|
||||
|
||||
# tag is the filesystem target directory.
|
||||
# if post /server/{server_id}/share was called without a specific
|
||||
# tag then the tag is the share id.
|
||||
self._assert_filesystem_tag(self._get_xml(server), share_id)
|
||||
|
||||
self._assert_share_in_metadata(
|
||||
self._get_metadata_url(server), share_id, share_id)
|
||||
return (server, share_id)
|
||||
|
||||
def test_server_cephfs_share_metadata(self):
|
||||
"""Verify that cephfs share metadata are available"""
|
||||
with mock.patch(
|
||||
'nova.virt.libvirt.volume.cephfs.LibvirtCEPHFSVolumeDriver.'
|
||||
'disconnect_volume'
|
||||
), mock.patch(
|
||||
'nova.virt.libvirt.volume.cephfs.LibvirtCEPHFSVolumeDriver.'
|
||||
'connect_volume'
|
||||
):
|
||||
# update the mock to call the cephfs fake values
|
||||
self.manila_fixture.mock_get.side_effect = (
|
||||
self.manila_fixture.fake_get_cephfs
|
||||
)
|
||||
self.manila_fixture.mock_get_access.side_effect = (
|
||||
self.manila_fixture.fake_get_access_cephfs
|
||||
)
|
||||
|
||||
traits = self._get_provider_traits(
|
||||
self.compute_rp_uuids[self.compute])
|
||||
for trait in (
|
||||
'COMPUTE_STORAGE_VIRTIO_FS', 'COMPUTE_MEM_BACKING_FILE'):
|
||||
self.assertIn(trait, traits)
|
||||
server = self._create_server(networks='auto')
|
||||
self._stop_server(server)
|
||||
|
||||
share_id = '4b021746-d0eb-4031-92aa-23c3bec182cd'
|
||||
self._attach_share(server, share_id)
|
||||
self._start_server(server)
|
||||
|
||||
# tag is the filesystem target directory.
|
||||
# if post /server/{server_id}/share was called without a specific
|
||||
# tag then the tag is the share id.
|
||||
self._assert_filesystem_tag(self._get_xml(server), share_id)
|
||||
|
||||
self._assert_share_in_metadata(
|
||||
self._get_metadata_url(server), share_id, share_id)
|
||||
return (server, share_id)
|
||||
Reference in New Issue
Block a user