nova-powervm/nova_powervm/tests/virt/powervm/test_media.py
Drew Thorstensen 02dbf675a6 Swap to mgmt VIF being 'static link local'
In order to support the management VIF for RMC connections, the link
local address needs to be defined on the management VIF.  For legacy
versions of cloud-init as well as broad distribution support, this
change set switches to a 'static' definition of the link local address.
This applies to a broader set of cloud init revisions.

Change-Id: I2f072b697b858cb0ee5bc7189c5f593f77fede89
2015-07-27 15:12:04 -04:00

198 lines
8.2 KiB
Python

# Copyright 2015 IBM Corp.
#
# 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 mock
from nova import test
import os
from pypowervm.tests.wrappers.util import pvmhttp
from pypowervm.wrappers import storage as pvm_stor
from nova_powervm.tests.virt.powervm import fixtures as fx
from nova_powervm.virt.powervm import exception as npvmex
from nova_powervm.virt.powervm import media as m
VOL_GRP_DATA = 'fake_volume_group.txt'
VOL_GRP_NOVG_DATA = 'fake_volume_group_no_vg.txt'
VOL_GRP_WITH_VIOS = 'fake_volume_group_with_vio_data.txt'
VIOS_WITH_VOL_GRP = 'fake_vios_with_volume_group_data.txt'
VIOS_NO_VG = 'fake_vios_feed_no_vg.txt'
VIOS_FEED = 'fake_vios_feed.txt'
class TestConfigDrivePowerVM(test.TestCase):
"""Unit Tests for the ConfigDrivePowerVM class."""
def setUp(self):
super(TestConfigDrivePowerVM, self).setUp()
# Find directory for response file(s)
data_dir = os.path.dirname(os.path.abspath(__file__))
data_dir = os.path.join(data_dir, 'data')
self.pypvm = self.useFixture(fx.PyPowerVM())
self.apt = self.pypvm.apt
def resp(file_name):
file_path = os.path.join(data_dir, file_name)
return pvmhttp.load_pvm_resp(
file_path, adapter=self.apt).get_response()
self.vol_grp_resp = resp(VOL_GRP_DATA)
self.vol_grp_novg_resp = resp(VOL_GRP_NOVG_DATA)
self.vg_to_vio = resp(VOL_GRP_WITH_VIOS)
self.vio_to_vg = resp(VIOS_WITH_VOL_GRP)
self.vio_feed_no_vg = resp(VIOS_NO_VG)
self.vio_feed = resp(VIOS_FEED)
# Wipe out the static variables, so that the revalidate is called
m.ConfigDrivePowerVM._cur_vios_uuid = None
m.ConfigDrivePowerVM._cur_vios_name = None
m.ConfigDrivePowerVM._cur_vg_uuid = None
@mock.patch('nova_powervm.virt.powervm.media.ConfigDrivePowerVM.'
'_validate_vopt_vg')
@mock.patch('nova.api.metadata.base.InstanceMetadata')
@mock.patch('nova.virt.configdrive.ConfigDriveBuilder.make_drive')
def test_crt_cfg_dr_iso(self, mock_mkdrv, mock_meta, mock_vopt_valid):
"""Validates that the image creation method works."""
cfg_dr_builder = m.ConfigDrivePowerVM(self.apt, 'host_uuid')
mock_instance = mock.MagicMock()
mock_instance.name = 'fake-instance'
mock_instance.uuid = '1e46bbfd-73b6-3c2a-aeab-a1d3f065e92f'
mock_files = mock.MagicMock()
mock_net = mock.MagicMock()
iso_path, file_name = cfg_dr_builder._create_cfg_dr_iso(mock_instance,
mock_files,
mock_net)
self.assertEqual('cfg_fake_instance.iso', file_name)
self.assertEqual('/tmp/cfgdrv/cfg_fake_instance.iso', iso_path)
# Make sure the length is limited properly
mock_instance.name = 'fake-instance-with-name-that-is-too-long'
iso_path, file_name = cfg_dr_builder._create_cfg_dr_iso(mock_instance,
mock_files,
mock_net)
self.assertEqual('cfg_fake_instance_with_name_that_.iso', file_name)
self.assertEqual('/tmp/cfgdrv/cfg_fake_instance_with_name_that_.iso',
iso_path)
@mock.patch('nova_powervm.virt.powervm.media.ConfigDrivePowerVM.'
'_create_cfg_dr_iso')
@mock.patch('nova_powervm.virt.powervm.media.ConfigDrivePowerVM.'
'_validate_vopt_vg')
@mock.patch('os.path.getsize')
@mock.patch('os.remove')
@mock.patch('nova_powervm.virt.powervm.media.ConfigDrivePowerVM.'
'_upload_vopt')
@mock.patch('pypowervm.tasks.scsi_mapper.add_vscsi_mapping')
def test_crt_cfg_drv_vopt(self, mock_add_map, mock_upld,
mock_rm, mock_size, mock_validate, mock_cfg_iso):
# Mock Returns
mock_cfg_iso.return_value = '/tmp/cfgdrv/fake.iso', 'fake.iso'
mock_size.return_value = 10000
mock_upld.return_value = (mock.Mock(), None)
# Run
cfg_dr_builder = m.ConfigDrivePowerVM(self.apt, 'fake_host')
cfg_dr_builder.create_cfg_drv_vopt(mock.MagicMock(), mock.MagicMock(),
mock.MagicMock(), 'fake_lpar')
self.assertTrue(mock_upld.called)
self.assertTrue(mock_add_map.called)
@mock.patch('nova_powervm.virt.powervm.media.ConfigDrivePowerVM.'
'_validate_vopt_vg')
def test_mgmt_cna_to_vif(self, mock_validate):
mock_cna = mock.MagicMock()
mock_cna.mac = "FAD4433ED120"
# Run
cfg_dr_builder = m.ConfigDrivePowerVM(self.apt, 'fake_host')
vif = cfg_dr_builder._mgmt_cna_to_vif(mock_cna)
# Validate
self.assertEqual(vif.get('address'), "fa:d4:43:3e:d1:20")
self.assertEqual(vif.get('id'), 'mgmt_vif')
self.assertIsNotNone(vif.get('network'))
self.assertEqual(1, len(vif.get('network').get('subnets')))
subnet = vif.get('network').get('subnets')[0]
self.assertEqual(6, subnet.get('version'))
self.assertEqual('fe80::/64', subnet.get('cidr'))
ip = subnet.get('ips')[0]
self.assertEqual('fe80::f8d4:43ff:fe3e:d120', ip.get('address'))
def test_mac_to_link_local(self):
mac = 'fa:d4:43:3e:d1:20'
self.assertEqual('fe80::f8d4:43ff:fe3e:d120',
m.ConfigDrivePowerVM._mac_to_link_local(mac))
mac = '00:00:00:00:00:00'
self.assertEqual('fe80::0200:00ff:fe00:0000',
m.ConfigDrivePowerVM._mac_to_link_local(mac))
mac = 'ff:ff:ff:ff:ff:ff'
self.assertEqual('fe80::fdff:ffff:feff:ffff',
m.ConfigDrivePowerVM._mac_to_link_local(mac))
def test_validate_opt_vg(self):
self.apt.read.side_effect = [self.vio_feed, self.vol_grp_resp]
vg_update = self.vol_grp_resp.feed.entries[0]
self.apt.update_by_path.return_value = vg_update
cfg_dr_builder = m.ConfigDrivePowerVM(self.apt, 'fake_host')
self.assertEqual('1e46bbfd-73b6-3c2a-aeab-a1d3f065e92f',
cfg_dr_builder.vg_uuid)
def test_validate_opt_vg_fail(self):
self.apt.read.side_effect = [self.vio_feed_no_vg,
self.vol_grp_novg_resp]
self.assertRaises(npvmex.NoMediaRepoVolumeGroupFound,
m.ConfigDrivePowerVM, self.apt, 'fake_host')
@mock.patch('pypowervm.tasks.scsi_mapper.remove_vopt_mapping')
@mock.patch('nova_powervm.virt.powervm.media.ConfigDrivePowerVM.'
'_validate_vopt_vg')
def test_dlt_vopt(self, mock_vop_valid, mock_remove_map):
# Set up the mock data.
resp = mock.MagicMock(name='resp')
type(resp).body = mock.PropertyMock(return_value='2')
self.apt.read.side_effect = [resp, self.vg_to_vio]
# We tell it to remove all the optical medias.
vg = pvm_stor.VG.wrap(self.vg_to_vio)
mock_remove_map.return_value = ('fake_vios',
vg.vmedia_repos[0].optical_media)
# Make sure that the first update is a VIO and doesn't have the vopt
# mapping
def validate_update(*kargs, **kwargs):
vol_grp = kargs[0]
# This is the VG update. Make sure there are no optical medias
# anymore.
self.assertEqual(0, len(vol_grp.vmedia_repos[0].optical_media))
return vol_grp.entry
self.apt.update_by_path.side_effect = validate_update
# Invoke the operation
cfg_dr = m.ConfigDrivePowerVM(self.apt, 'fake_host')
cfg_dr.dlt_vopt('fake_lpar_uuid')
self.assertEqual(1, self.apt.update_by_path.call_count)