Files
nova-powervm/nova_powervm/tests/virt/powervm/test_vios.py
Matt Rabe 0b2125e64c Raise an exception if no active VIOSes in build_tx_feed_task
get_active_vioses returns an empty list if there aren't any
active VIOSes. If an empty list is used as the feed to a FeedTask
then we get a generic error explaining that the FeedTask can't have
an empty feed.

This change attempts to make the error more clear in the event
there aren't any active VIOSes when build_tx_feed_task is called
by raising an exception explaining that there aren't any active
VIOSes.

Change-Id: I3d67c653131952bfc13bbbda2e67486c0291c4cc
Closes-Bug: #1581652
2016-05-31 23:14:41 +02:00

204 lines
7.8 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
from pypowervm.tests import test_fixtures as pvm_fx
from pypowervm.tests.test_utils import pvmhttp
from pypowervm.wrappers import base_partition as pvm_bp
from pypowervm.wrappers import virtual_io_server as pvm_vios
from nova_powervm.virt.powervm import exception as nova_pvm_exc
from nova_powervm.virt.powervm import vios
VIOS_FEED = 'fake_vios_feed2.txt'
class TestVios(test.TestCase):
def setUp(self):
super(TestVios, self).setUp()
self.adpt = self.useFixture(pvm_fx.AdapterFx()).adpt
def resp(file_name):
return pvmhttp.load_pvm_resp(file_name).get_response()
self.vios_feed_resp = resp(VIOS_FEED)
def test_get_active_vioses(self):
self.adpt.read.return_value = self.vios_feed_resp
vioses = vios.get_active_vioses(self.adpt, 'host_uuid')
self.assertEqual(1, len(vioses))
vio = vioses[0]
self.assertEqual(pvm_bp.LPARState.RUNNING, vio.state)
self.assertEqual(pvm_bp.RMCState.ACTIVE, vio.rmc_state)
self.adpt.read.assert_called_with(pvm_vios.VIOS.schema_type, xag=None)
@mock.patch('pypowervm.wrappers.virtual_io_server.VIOS.get')
def test_get_active_vioses_w_vios_wraps(self, mock_get):
mock_vios1 = mock.Mock(state='running', rmc_state='active')
mock_vios2 = mock.Mock(state='running', rmc_state='inactive')
vios_wraps = [mock_vios1, mock_vios2]
vioses = vios.get_active_vioses(
self.adpt, 'host_uuid', vios_wraps=vios_wraps)
self.assertEqual(1, len(vioses))
vio = vioses[0]
self.assertEqual(pvm_bp.LPARState.RUNNING, vio.state)
self.assertEqual(pvm_bp.RMCState.ACTIVE, vio.rmc_state)
self.assertEqual(0, mock_get.call_count)
def test_get_inactive_running_vioses(self):
# No
mock_vios1 = mock.Mock(
state=pvm_bp.LPARState.NOT_ACTIVATED,
rmc_state=pvm_bp.RMCState.INACTIVE)
# No
mock_vios2 = mock.Mock(
state=pvm_bp.LPARState.RUNNING,
rmc_state=pvm_bp.RMCState.BUSY)
# Yes
mock_vios3 = mock.Mock(
state=pvm_bp.LPARState.RUNNING,
rmc_state=pvm_bp.RMCState.UNKNOWN)
# No
mock_vios4 = mock.Mock(
state=pvm_bp.LPARState.UNKNOWN,
rmc_state=pvm_bp.RMCState.ACTIVE)
# No
mock_vios5 = mock.Mock(
state=pvm_bp.LPARState.RUNNING,
rmc_state=pvm_bp.RMCState.ACTIVE)
# Yes
mock_vios6 = mock.Mock(
state=pvm_bp.LPARState.RUNNING,
rmc_state=pvm_bp.RMCState.INACTIVE)
self.assertEqual(
{mock_vios6, mock_vios3}, set(vios.get_inactive_running_vioses(
[mock_vios1, mock_vios2, mock_vios3, mock_vios4,
mock_vios5, mock_vios6])))
mock_vios2 = mock.Mock()
def test_get_physical_wwpns(self):
self.adpt.read.return_value = self.vios_feed_resp
expected = set(['21000024FF649104'])
result = set(vios.get_physical_wwpns(self.adpt, 'fake_uuid'))
self.assertSetEqual(expected, result)
@mock.patch('nova_powervm.virt.powervm.vios.get_active_vioses')
@mock.patch('pypowervm.utils.transaction.FeedTask')
def test_build_tx_feed_task(self, mock_feed_task, mock_get_active_vioses):
mock_get_active_vioses.return_value = ['vios1', 'vios2']
mock_feed_task.return_value = 'mock_feed'
self.assertEqual('mock_feed',
vios.build_tx_feed_task(mock.MagicMock(),
mock.MagicMock()))
@mock.patch('nova_powervm.virt.powervm.vios.get_active_vioses')
def test_build_tx_feed_task_w_empty_feed(self, mock_get_active_vioses):
mock_get_active_vioses.return_value = []
self.assertRaises(
nova_pvm_exc.NoActiveViosForFeedTask, vios.build_tx_feed_task,
mock.MagicMock(), mock.MagicMock())
@mock.patch('retrying.retry')
@mock.patch('nova_powervm.virt.powervm.vios.get_active_vioses')
@mock.patch('nova_powervm.virt.powervm.vios.get_inactive_running_vioses')
@mock.patch('pypowervm.wrappers.virtual_io_server.VIOS.get')
def test_is_vios_ready(self, mock_get, mock_get_inactive_vioses,
mock_get_active_vioses, mock_retry):
adpt = mock.MagicMock()
host_uuid = 'host_uuid'
# Validates the retry method itself.
def validate_retry(kwargs):
self.assertIn('retry_on_result', kwargs)
self.assertEqual(5000, kwargs['wait_fixed'])
self.assertEqual(300000, kwargs['stop_max_delay'])
# Used to simulate an eventual timeout.
def retry_timeout(**kwargs):
# First validate the retry.
validate_retry(kwargs)
def one_running_inactive_vio():
mock_vios1 = mock.Mock()
mock_vios1.configure_mock(name='vios1')
return [mock_vios1]
def wrapped(_poll_for_dev):
return one_running_inactive_vio
return wrapped
# Validate that we will eventually timeout.
mock_retry.side_effect = retry_timeout
mock_get_active_vioses.return_value = [mock.Mock()]
# Shouldn't raise an error because we have active vioses
vios.validate_vios_ready(adpt, host_uuid)
# Should raise an exception now because we timed out and there
# weren't any active VIOSes
mock_get_active_vioses.return_value = []
self.assertRaises(
nova_pvm_exc.ViosNotAvailable, vios.validate_vios_ready, adpt,
host_uuid)
# Now test where we pass through to the actual method in the retry.
def retry_passthrough(**kwargs):
validate_retry(kwargs)
def wrapped(_poll_for_dev):
return _poll_for_dev
return wrapped
def get_active_vioses_side_effect(*args, **kwargs):
return kwargs['vios_wraps']
mock_retry.side_effect = retry_passthrough
# First run should succeed because all VIOSes should be active and
# running
mock_get.return_value = ['vios1', 'vios2', 'vios3', 'vios4']
mock_get_inactive_vioses.return_value = []
mock_get_active_vioses.side_effect = get_active_vioses_side_effect
vios.validate_vios_ready(adpt, host_uuid)
# Second run should fail because we raise an exception (which retries,
# and then eventually times out with no active VIOSes)
mock_get.reset_mock()
mock_get.side_effect = Exception('testing error')
mock_get_active_vioses.reset_mock()
mock_get_active_vioses.return_value = []
self.assertRaises(
nova_pvm_exc.ViosNotAvailable, vios.validate_vios_ready, adpt,
host_uuid)
# Last run should succeed but raise a warning because there's
# still inactive running VIOSes
mock_vios1, mock_vios2 = mock.Mock(), mock.Mock()
mock_vios1.configure_mock(name='vios1')
mock_vios2.configure_mock(name='vios2')
mock_get_inactive_vioses.return_value = [mock_vios1, mock_vios2]
mock_get_active_vioses.reset_mock()
mock_get_active_vioses.side_effect = ['vios1', 'vios2']
vios.validate_vios_ready(adpt, host_uuid)