An exception's message can be a translatable message. If it is, the message can contain unicode characters which will cause str to fail. In cases where the message is explicity needed, the use of str is replaced with the use of six.text_type. When an exception is used as a replacement string in a format string, the logger correctly handles it without the need for str, so it is removed. In addition to the case where a translatable message contains unicode, enabling lazy translation in the oslo.i18n library causes translatable messages to be replaced with an object that does not support str, this causes all calls to str on a translatable message to fail. Thus this patch is also needed to support blueprint: i18n-enablement. This patch includes a hacking check for use of str() on exceptions identified in except statements. Change-Id: Idb426d7f710ea69b835f70d0e883e93e9b9111d2 Partially-Implements: blueprint i18n-enablement
		
			
				
	
	
		
			262 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			262 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Copyright (c) 2012 OpenStack Foundation
 | 
						|
# 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 resource tracker claims."""
 | 
						|
 | 
						|
import re
 | 
						|
import uuid
 | 
						|
 | 
						|
import six
 | 
						|
 | 
						|
from nova.compute import claims
 | 
						|
from nova import exception
 | 
						|
from nova.openstack.common import jsonutils
 | 
						|
from nova.pci import pci_manager
 | 
						|
from nova import test
 | 
						|
 | 
						|
 | 
						|
class FakeResourceHandler(object):
 | 
						|
    test_called = False
 | 
						|
    usage_is_instance = False
 | 
						|
 | 
						|
    def test_resources(self, usage, limits):
 | 
						|
        self.test_called = True
 | 
						|
        self.usage_is_itype = usage.get('name') is 'fakeitype'
 | 
						|
        return []
 | 
						|
 | 
						|
 | 
						|
class DummyTracker(object):
 | 
						|
    icalled = False
 | 
						|
    rcalled = False
 | 
						|
    pci_tracker = pci_manager.PciDevTracker()
 | 
						|
    ext_resources_handler = FakeResourceHandler()
 | 
						|
 | 
						|
    def abort_instance_claim(self, *args, **kwargs):
 | 
						|
        self.icalled = True
 | 
						|
 | 
						|
    def drop_resize_claim(self, *args, **kwargs):
 | 
						|
        self.rcalled = True
 | 
						|
 | 
						|
    def new_pci_tracker(self):
 | 
						|
        self.pci_tracker = pci_manager.PciDevTracker()
 | 
						|
 | 
						|
 | 
						|
class ClaimTestCase(test.NoDBTestCase):
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(ClaimTestCase, self).setUp()
 | 
						|
        self.resources = self._fake_resources()
 | 
						|
        self.tracker = DummyTracker()
 | 
						|
 | 
						|
    def _claim(self, limits=None, overhead=None, **kwargs):
 | 
						|
        instance = self._fake_instance(**kwargs)
 | 
						|
        if overhead is None:
 | 
						|
            overhead = {'memory_mb': 0}
 | 
						|
        return claims.Claim(instance, self.tracker, self.resources,
 | 
						|
                            overhead=overhead, limits=limits)
 | 
						|
 | 
						|
    def _fake_instance(self, **kwargs):
 | 
						|
        instance = {
 | 
						|
            'uuid': str(uuid.uuid1()),
 | 
						|
            'memory_mb': 1024,
 | 
						|
            'root_gb': 10,
 | 
						|
            'ephemeral_gb': 5,
 | 
						|
            'vcpus': 1,
 | 
						|
            'system_metadata': {}
 | 
						|
        }
 | 
						|
        instance.update(**kwargs)
 | 
						|
        return instance
 | 
						|
 | 
						|
    def _fake_instance_type(self, **kwargs):
 | 
						|
        instance_type = {
 | 
						|
            'id': 1,
 | 
						|
            'name': 'fakeitype',
 | 
						|
            'memory_mb': 1,
 | 
						|
            'vcpus': 1,
 | 
						|
            'root_gb': 1,
 | 
						|
            'ephemeral_gb': 2
 | 
						|
        }
 | 
						|
        instance_type.update(**kwargs)
 | 
						|
        return instance_type
 | 
						|
 | 
						|
    def _fake_resources(self, values=None):
 | 
						|
        resources = {
 | 
						|
            'memory_mb': 2048,
 | 
						|
            'memory_mb_used': 0,
 | 
						|
            'free_ram_mb': 2048,
 | 
						|
            'local_gb': 20,
 | 
						|
            'local_gb_used': 0,
 | 
						|
            'free_disk_gb': 20,
 | 
						|
            'vcpus': 2,
 | 
						|
            'vcpus_used': 0
 | 
						|
        }
 | 
						|
        if values:
 | 
						|
            resources.update(values)
 | 
						|
        return resources
 | 
						|
 | 
						|
    # TODO(lxsli): Remove once Py2.6 is deprecated
 | 
						|
    def assertRaisesRegexp(self, re_obj, e, fn, *a, **kw):
 | 
						|
        try:
 | 
						|
            fn(*a, **kw)
 | 
						|
            self.fail("Expected exception not raised")
 | 
						|
        except e as ee:
 | 
						|
            self.assertTrue(re.search(re_obj, six.text_type(ee)))
 | 
						|
 | 
						|
    def test_memory_unlimited(self):
 | 
						|
        self._claim(memory_mb=99999999)
 | 
						|
 | 
						|
    def test_disk_unlimited_root(self):
 | 
						|
        self._claim(root_gb=999999)
 | 
						|
 | 
						|
    def test_disk_unlimited_ephemeral(self):
 | 
						|
        self._claim(ephemeral_gb=999999)
 | 
						|
 | 
						|
    def test_memory_with_overhead(self):
 | 
						|
        overhead = {'memory_mb': 8}
 | 
						|
        limits = {'memory_mb': 2048}
 | 
						|
        self._claim(memory_mb=2040, limits=limits,
 | 
						|
                    overhead=overhead)
 | 
						|
 | 
						|
    def test_memory_with_overhead_insufficient(self):
 | 
						|
        overhead = {'memory_mb': 9}
 | 
						|
        limits = {'memory_mb': 2048}
 | 
						|
 | 
						|
        self.assertRaises(exception.ComputeResourcesUnavailable,
 | 
						|
                          self._claim, limits=limits, overhead=overhead,
 | 
						|
                          memory_mb=2040)
 | 
						|
 | 
						|
    def test_memory_oversubscription(self):
 | 
						|
        self._claim(memory_mb=4096)
 | 
						|
 | 
						|
    def test_memory_insufficient(self):
 | 
						|
        limits = {'memory_mb': 8192}
 | 
						|
        self.assertRaises(exception.ComputeResourcesUnavailable,
 | 
						|
                          self._claim, limits=limits, memory_mb=16384)
 | 
						|
 | 
						|
    def test_disk_oversubscription(self):
 | 
						|
        limits = {'disk_gb': 60}
 | 
						|
        self._claim(root_gb=10, ephemeral_gb=40,
 | 
						|
                    limits=limits)
 | 
						|
 | 
						|
    def test_disk_insufficient(self):
 | 
						|
        limits = {'disk_gb': 45}
 | 
						|
        self.assertRaisesRegexp(re.compile("disk", re.IGNORECASE),
 | 
						|
                exception.ComputeResourcesUnavailable,
 | 
						|
                self._claim, limits=limits, root_gb=10, ephemeral_gb=40)
 | 
						|
 | 
						|
    def test_disk_and_memory_insufficient(self):
 | 
						|
        limits = {'disk_gb': 45, 'memory_mb': 8192}
 | 
						|
        self.assertRaisesRegexp(re.compile("memory.*disk", re.IGNORECASE),
 | 
						|
                exception.ComputeResourcesUnavailable,
 | 
						|
                self._claim, limits=limits, root_gb=10, ephemeral_gb=40,
 | 
						|
                memory_mb=16384)
 | 
						|
 | 
						|
    def test_pci_pass(self):
 | 
						|
        dev_dict = {
 | 
						|
            'compute_node_id': 1,
 | 
						|
            'address': 'a',
 | 
						|
            'product_id': 'p',
 | 
						|
            'vendor_id': 'v',
 | 
						|
            'status': 'available'}
 | 
						|
        self.tracker.new_pci_tracker()
 | 
						|
        self.tracker.pci_tracker.set_hvdevs([dev_dict])
 | 
						|
        claim = self._claim()
 | 
						|
        self._set_pci_request(claim)
 | 
						|
        claim._test_pci()
 | 
						|
 | 
						|
    def _set_pci_request(self, claim):
 | 
						|
        request = [{'count': 1,
 | 
						|
                       'spec': [{'vendor_id': 'v', 'product_id': 'p'}],
 | 
						|
                      }]
 | 
						|
 | 
						|
        claim.instance.update(
 | 
						|
            system_metadata={'pci_requests': jsonutils.dumps(request)})
 | 
						|
 | 
						|
    def test_pci_fail(self):
 | 
						|
        dev_dict = {
 | 
						|
            'compute_node_id': 1,
 | 
						|
            'address': 'a',
 | 
						|
            'product_id': 'p',
 | 
						|
            'vendor_id': 'v1',
 | 
						|
            'status': 'available'}
 | 
						|
        self.tracker.new_pci_tracker()
 | 
						|
        self.tracker.pci_tracker.set_hvdevs([dev_dict])
 | 
						|
        claim = self._claim()
 | 
						|
        self._set_pci_request(claim)
 | 
						|
        self.assertEqual("Claim pci failed.", claim._test_pci())
 | 
						|
 | 
						|
    def test_pci_pass_no_requests(self):
 | 
						|
        dev_dict = {
 | 
						|
            'compute_node_id': 1,
 | 
						|
            'address': 'a',
 | 
						|
            'product_id': 'p',
 | 
						|
            'vendor_id': 'v',
 | 
						|
            'status': 'available'}
 | 
						|
        self.tracker.new_pci_tracker()
 | 
						|
        self.tracker.pci_tracker.set_hvdevs([dev_dict])
 | 
						|
        claim = self._claim()
 | 
						|
        self._set_pci_request(claim)
 | 
						|
        claim._test_pci()
 | 
						|
 | 
						|
    def test_ext_resources(self):
 | 
						|
        self._claim()
 | 
						|
        self.assertTrue(self.tracker.ext_resources_handler.test_called)
 | 
						|
        self.assertFalse(self.tracker.ext_resources_handler.usage_is_itype)
 | 
						|
 | 
						|
    def test_abort(self):
 | 
						|
        claim = self._abort()
 | 
						|
        self.assertTrue(claim.tracker.icalled)
 | 
						|
 | 
						|
    def _abort(self):
 | 
						|
        claim = None
 | 
						|
        try:
 | 
						|
            with self._claim(memory_mb=4096) as claim:
 | 
						|
                raise test.TestingException("abort")
 | 
						|
        except test.TestingException:
 | 
						|
            pass
 | 
						|
 | 
						|
        return claim
 | 
						|
 | 
						|
 | 
						|
class ResizeClaimTestCase(ClaimTestCase):
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(ResizeClaimTestCase, self).setUp()
 | 
						|
        self.instance = self._fake_instance()
 | 
						|
 | 
						|
    def _claim(self, limits=None, overhead=None, **kwargs):
 | 
						|
        instance_type = self._fake_instance_type(**kwargs)
 | 
						|
        if overhead is None:
 | 
						|
            overhead = {'memory_mb': 0}
 | 
						|
        return claims.ResizeClaim(self.instance, instance_type, self.tracker,
 | 
						|
                                  self.resources, overhead=overhead,
 | 
						|
                                  limits=limits)
 | 
						|
 | 
						|
    def _set_pci_request(self, claim):
 | 
						|
        request = [{'count': 1,
 | 
						|
                       'spec': [{'vendor_id': 'v', 'product_id': 'p'}],
 | 
						|
                      }]
 | 
						|
        claim.instance.update(
 | 
						|
            system_metadata={'new_pci_requests': jsonutils.dumps(request)})
 | 
						|
 | 
						|
    def test_ext_resources(self):
 | 
						|
        self._claim()
 | 
						|
        self.assertTrue(self.tracker.ext_resources_handler.test_called)
 | 
						|
        self.assertTrue(self.tracker.ext_resources_handler.usage_is_itype)
 | 
						|
 | 
						|
    def test_abort(self):
 | 
						|
        claim = self._abort()
 | 
						|
        self.assertTrue(claim.tracker.rcalled)
 |