From 21faa7f82fa7f3be0dfadc6f5f5735b79bb778fd Mon Sep 17 00:00:00 2001 From: Bill Brinzer Date: Mon, 19 Dec 2016 18:00:04 -0500 Subject: [PATCH] Update Netronome Agilio SmartNIC Python code for Mitaka compatibility 1. Replace the urllib3 library with Requests. There appears to be a tug-of-war going on between the Requests library authors and Linux distribution vendors regarding urllib3. Requests has its own vendor-branched copy of urllib3, but Debian et al. disagree with this doing this (possibly for security reasons) so they "unbundle" it: i.e., they replace the local Requests copy of urllib3 with a stub that loads the global version of urllib3. The Requests authors, in turn, disagree with the Debian "unbundling," so they implement countermeasures to it. (See [ `requests/packages/__init__.py`]( https://github.com/kennethreitz/requests/blob/v2.9.1/requests/packages/__init__.py), which on Ubuntu 14.04 is installed to `/usr/lib/python2.7/dist-packages/requests/packages/__init__.py`.) **Problem** On Ubuntu 14.04 Contrail 3.1 OpenStack Mitaka compute nodes, somehow between all the competing ideas about where urllib3 should live we end up with a situation where the global urllib3 is unusable. In particular, the name `urllib3` turns into a reference to `requests.packages.urllib3` in `except` exception lists, but otherwise refers to the global `urllib3`. In other words, with an `import urllib3` at the top level, errors being raised by HTTP requests have the type: (Pdb) type(e) but `except` blocks are unable to catch these because the type name that they need to use has been hijacked and turned into an alias for a type in Requests: (Pdb) urllib3.exceptions.MaxRetryError **Solution** Since the Netronome Python code is not using the "retries" feature of urllib3, simply replace urllib3 with Requests. This causes an additional complication due to the test code checking log messages, since we need to maintain Kilo compatibility. Workaround is to set the log level of urllib3-related loggers to WARNING while the affected unit tests are running. 2. Use `NovaObjectSerializer` when passing Nova objects to Netronome Python code. The original Netronome code inadvertently had a Kilo dependency when receiving flavor and image metadata, because it used an unofficial method of serializing Nova objects. Rewrite to use a supported serialization method which is compatible with both Kilo and Mitaka. Add unit tests. 3. Support multiqueue TAP interface creation. Change-Id: Ic21aad32cca37775fbbc1726df63163990604c0a Closes-Bug: #1651266 Related-Bug: #1644348 --- .../netronome/vrouter/apps/port_control.py | 144 +++- .../netronome/vrouter/plug.py | 47 +- .../netronome/vrouter/tests/helpers/plug.py | 10 + .../netronome/vrouter/tests/unit/__init__.py | 33 + .../tests/unit/apps/test_port_control.py | 779 +++++++++++++++++- .../netronome/vrouter/tests/unit/test_plug.py | 84 +- 6 files changed, 963 insertions(+), 134 deletions(-) diff --git a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/apps/port_control.py b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/apps/port_control.py index 15785325d52..2bc99603f59 100644 --- a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/apps/port_control.py +++ b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/apps/port_control.py @@ -102,16 +102,136 @@ def _init_Session(conf, logger): return sessionmaker(bind=engine) +def _get_nova_object_data(v, namespace, name): + """ + Check for an acceptable value of nova_object.namespace and + nova_object.name (i.e., the type name sent over from Nova). If the check + passes, return nova_object.data, else None. + + For now, we only allow one expected type (namespace.name) at a time (unlike + config_editor.deserialize()). + """ + + if 'nova_object.version' not in v: + # Note that we currently check only check that nova_object.version is + # present; we don't check its value. + return + + ns, n = v['nova_object.namespace'], v['nova_object.name'] + if ns != namespace or n != name: + raise ValueError( + 'nova_object type {}.{} is not allowed; expected type {}.{}'. + format(ns, n, namespace, name) + ) + + return v['nova_object.data'] + + +def _decode_nova_object(value, decoders, error_msg): + """ + Attempt to decode `value` using each of a sequence of `decoders`. + Raise ValueError(error_msg) if no decoder succeeds. + """ + + for d in decoders: + decoded = d(value) + if decoded is not None: + return decoded + + raise ValueError(error_msg) + + +def _decode_image_metadata_mitaka(v): + try: + d = _get_nova_object_data(v, 'nova', 'ImageMeta') + if d is None: + return + + # All of name, id, properties are optional. Let's attempt to sanity + # check # the data by making sure that it has a disk_format and + # container_format. + if 'disk_format' not in d or 'container_format' not in d: + return + + if 'properties' in d: + props = _get_nova_object_data( + d['properties'], 'nova', 'ImageMetaProps' + ) + else: + props = {} + + return { + 'name': d.get('name'), + 'id': d.get('id'), + 'properties': props, + } + + except KeyError: + pass # decode failed + + +def _decode_image_metadata_kilo(v): + # All of name, id, properties are optional. Let's attempt to sanity check + # the data by making sure that it has a disk_format and container_format. + if 'disk_format' not in v or 'container_format' not in v: + return + + return { + 'name': v.get('name'), + 'id': v.get('id'), + 'properties': v.get('properties', {}), + } + + +def _decode_image_metadata(v): + return _decode_nova_object( + value=v, + decoders=( + _decode_image_metadata_mitaka, + _decode_image_metadata_kilo, + ), + error_msg='unable to decode image metadata', + ) + + def _image_metadata_to_allowed_modes(image_metadata, logger): if image_metadata is None: return logger.debug('image metadata: %s', image_metadata) t, v = config_editor.deserialize(image_metadata, allowed_types=('dict',)) + decoded = _decode_image_metadata(v) return glance.allowed_hw_acceleration_modes( - image_properties=v.get('properties', '{}'), name=v.get('name'), - id=v.get('id') + name=decoded['name'], + id=decoded['id'], + image_properties=decoded['properties'], + ) + + +def _decode_flavor_metadata_kilo(v): + if 'nova_object.version' not in v: + return + + try: + d = _get_nova_object_data(v, 'nova', 'Flavor') + + return { + 'name': d['name'], + 'extra_specs': d['extra_specs'], + } + + except KeyError: + pass # decode failed + + +def _decode_flavor_metadata(v): + return _decode_nova_object( + value=v, + decoders=( + _decode_flavor_metadata_kilo, + ), + error_msg='unable to decode flavor metadata', ) @@ -121,10 +241,12 @@ def _flavor_metadata_to_allowed_modes(flavor_metadata, logger): logger.debug('flavor information: %s', flavor_metadata) t, v = config_editor.deserialize( - flavor_metadata, allowed_types=('Flavor',) + flavor_metadata, allowed_types=('dict',) ) + decoded = _decode_flavor_metadata(v) + return flavor.allowed_hw_acceleration_modes( - extra_specs=v.get('_extra_specs', {}), name=v.get('_name') + extra_specs=decoded['extra_specs'], name=decoded['name'] ) @@ -134,10 +256,12 @@ def _assert_flavor_supports_mode(flavor_metadata, mode): if mode == PM.VirtIO: t, v = config_editor.deserialize( - flavor_metadata, allowed_types=('Flavor',) + flavor_metadata, allowed_types=('dict',) ) + decoded = _decode_flavor_metadata(v) + flavor.assert_flavor_supports_virtio( - extra_specs=v.get('_extra_specs', {}), name=v.get('_name') + extra_specs=decoded['extra_specs'], name=decoded['name'] ) @@ -650,6 +774,13 @@ class AddCmd(OsloConfigSubcmd): help='System name of TAP device for this Neutron port', ) + MultiqueueOpt = cfg.Opt( + 'multiqueue', + type=types.Boolean(), + default=False, + help=default_help('Configure TAP devices in multiqueue mode', False) + ) + PortTypeOpt_choices = ('NovaVMPort', 'NameSpacePort') PortTypeOpt = cfg.Opt( 'port_type', @@ -722,6 +853,7 @@ def HwAccelerationModeOpt(): VmNameOpt, MacOpt, TapNameOpt, + MultiqueueOpt, PortTypeOpt, TxVlanIdOpt, RxVlanIdOpt, diff --git a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/plug.py b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/plug.py index ead6aff5175..e86d161de68 100644 --- a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/plug.py +++ b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/plug.py @@ -23,11 +23,11 @@ import logging import os import re +import requests import six import stat import sys import time -import urllib3 import urlparse import zmq @@ -197,16 +197,21 @@ def apply_root_dir(o, root_dir): class _CreateTAP(_Step): @config_section('linux_net') - def configure(self, dry_run=False): + def configure(self, dry_run=False, multiqueue=False): self._dry_run = dry_run + self._multiqueue = multiqueue @staticmethod def translate_conf(conf): ans = _Step.translate_conf(conf) + section = ans.setdefault('linux_net', {}) + g = getattr(conf, 'iproute2', None) if g is not None and g.dry_run: - ans.update({'linux_net': {'dry_run': True}}) + section['dry_run'] = True + if getattr(conf, 'multiqueue', False): + section['multiqueue'] = True return ans @@ -215,9 +220,13 @@ def forward_action(self, session, port, journal): # VRT-604 garbage collection return _NullAction + if self._multiqueue: + fmt = 'Create multiqueue TAP interface: {}' + else: + fmt = 'Create standard TAP interface: {}' + return _Action( - lambda: self._do(session, port, journal), - 'Create TAP interface: {}'.format(port.tap_name) + lambda: self._do(session, port, journal), fmt.format(port.tap_name) ) def reverse_action(self, session, port, journal): @@ -231,8 +240,9 @@ def reverse_action(self, session, port, journal): ) def _do(self, session, port, journal): + kwds = {'multiqueue': True} if self._multiqueue else {} if not self._dry_run: - linux_net.create_tap_dev(port.tap_name) + linux_net.create_tap_dev(port.tap_name, **kwds) return _StepStatus.OK @@ -365,7 +375,6 @@ def __init__(self, get_vif_devname=lambda p: None, vif_sync=None, **kwds): self.get_vif_devname = get_vif_devname self.vif_sync = vif_sync - self.http = urllib3.PoolManager(timeout=5, retries=1) @config_section('contrail-vrouter-agent') def configure(self, base_url=DEFAULT_AGENT_API_EP, vif_sync=None): @@ -423,20 +432,19 @@ def _do(self, session, port, journal, tap_name): body = json.dumps(port.dump(tap_name=tap_name)) try: - r = self.http.urlopen( - 'POST', ep, body=body, + r = requests.post( + ep, data=body, headers={'Content-Type': 'application/json'}, - retries=None ) - except urllib3.exceptions.HTTPError as e: + except requests.exceptions.RequestException as e: logger.error('POST error: %s', _exception_msg(e)) return _StepStatus.ERROR try: log_content_type = True tc = vrouter_rest.HTTPSuccessTc() - tc.assert_valid(r.status) + tc.assert_valid(r.status_code) log_content_type = False tc = vrouter_rest.ContentTypeTc('application/json') @@ -444,7 +452,8 @@ def _do(self, session, port, journal, tap_name): except ValueError as e: _log_error_response( - 'POST', e, r.headers, r.data, log_content_type=log_content_type + 'POST', e, r.headers, r.content, + log_content_type=log_content_type ) # vrouter-port-control also masks this error. Since it represents @@ -461,18 +470,18 @@ def _undo(self, session, port, journal): ep = urlparse.urljoin(self.base_url, 'port/{}'.format(port.uuid)) try: - r = self.http.urlopen('DELETE', ep, retries=None) + r = requests.delete(ep) - except urllib3.exceptions.HTTPError as e: + except requests.exceptions.RequestException as e: logger.error('DELETE error: %s', _exception_msg(e)) return _StepStatus.ERROR try: tc = vrouter_rest.HTTPSuccessTc() - tc.assert_valid(r.status) + tc.assert_valid(r.status_code) except ValueError as e: - if port.tap_name is None and r.status == 404: + if port.tap_name is None and r.status_code == 404: # VRT-604 garbage collection pass @@ -482,9 +491,9 @@ def _undo(self, session, port, journal): # original vrouter-port-control script from Contrail masked all # HTTP DELETE errors. - _log_error_response('DELETE', e, r.headers, r.data) + _log_error_response('DELETE', e, r.headers, r.content) - if r.status == 404: + if r.status_code == 404: return _StepStatus.ERROR else: raise diff --git a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/helpers/plug.py b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/helpers/plug.py index afd7616563c..6472d336fde 100644 --- a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/helpers/plug.py +++ b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/helpers/plug.py @@ -43,6 +43,16 @@ from netronome.vrouter.tests.unit import * from netronome.vrouter.tests.helpers.config import _random_pci_address +# urllib3 log messages can appear under various names depending on the versions +# of the requests and/or urllib3 libraries (e.g., as they may change between +# different releases of Ubuntu OpenStack). +URLLIB3_LOGGERS = frozenset(( + 'urllib3.connectionpool', + 'urllib3.util.retry', + 'requests.packages.urllib3.connectionpool', + 'requests.packages.urllib3.util.retry', +)) + def _enable_fake_intel_iommu(root_dir, pt=False): """Fakes out netronome.iommu_check to believe that the IOMMU is on.""" diff --git a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/__init__.py b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/__init__.py index d59f265d492..35d3dfd7eee 100644 --- a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/__init__.py +++ b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/__init__.py @@ -25,6 +25,7 @@ __all__ = ( 'LogMessageCounter', + 'SetLogLevel', 'attachLogHandler', 'make_vfset', 'make_getLogger', @@ -62,6 +63,38 @@ def __str__(self): return json.dumps(self.logs, indent=4) +class SetLogLevel(object): + """ + Sets the log level for a set of loggers, typically at file scope. + + This is originally intended for urllib3 and/or "requests" library logging. + The DEBUG and INFO messages for these loggers are radically different + between different releases of OpenStack Kilo and OpenStack Mitaka (the + loggers have different names, etc). We have no interest in checking these. + + We do leave warnings, errors, etc. enabled however, as we aren't expecting + any of these. + """ + + def __init__(self, loggers, level, **kwds): + super(SetLogLevel, self).__init__(**kwds) + self.loggers = loggers + self.level = level + self.old = {} + + def setUp(self): + assert not self.old, 'setUp called multiple times' + for k in self.loggers: + logger = logging.getLogger(k) + self.old[k] = logger.level + logger.setLevel(self.level) + + def tearDown(self): + old, self.old = self.old, {} + for k, v in old.iteritems(): + logging.getLogger(k).setLevel(v) + + @contextlib.contextmanager def attachLogHandler(logger, handler=None, level=logging.DEBUG): if handler is None: diff --git a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/apps/test_port_control.py b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/apps/test_port_control.py index 26d69bf89dc..54436a28627 100644 --- a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/apps/test_port_control.py +++ b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/apps/test_port_control.py @@ -18,6 +18,7 @@ import argparse import contextlib +import copy import json import logging import os @@ -35,7 +36,7 @@ from netronome.vrouter.apps import port_control from netronome.vrouter.tests.helpers.config import FakeSysfs from netronome.vrouter.tests.helpers.plug import ( - _DisableGC, _enable_fake_intel_iommu, FakeAgent + _DisableGC, _enable_fake_intel_iommu, FakeAgent, URLLIB3_LOGGERS ) from netronome.vrouter.tests.randmac import RandMac from netronome.vrouter.tests.unit import * @@ -69,12 +70,681 @@ def _ROOT_LMC(cls=LogMessageCounter): else: _TMP_PREFIX = 'netronome.vrouter.tests.unit.apps.test_port_control.' +urllib3_logging = SetLogLevel(loggers=URLLIB3_LOGGERS, level=logging.WARNING) + def setUpModule(): e = re.split(r'\s+', os.environ.get('NS_VROUTER_TESTS_ENABLE_LOGGING', '')) if 'port_control' in e: logging.basicConfig(level=logging.DEBUG) + urllib3_logging.setUp() + + +def tearDownModule(): + urllib3_logging.tearDown() + + +_IMAGE_METADATA_JSON_KILO_1 = r''' +{ + "type": "dict", + "vars": { + "status": "active", + "created_at": "2016-12-05T19:22:22.270042", + "name": "UbuntuCloudVF-virtio", + "deleted": false, + "container_format": "bare", + "min_ram": 0, + "disk_format": "qcow2", + "updated_at": "2016-12-05T19:22:41.704354", + "properties": { + "architecture": "x86_64" + }, + "owner": "52ad9bf691e046abb9628008ede2bc7a", + "checksum": "2122e9d388ba080cf3a2bb5f98868a48", + "min_disk": 0, + "is_public": true, + "deleted_at": null, + "id": "5f38cce2-dcb5-4843-908a-a2a0e6a114db", + "size": 2973171712 + } +}''' + +# Missing properties +_IMAGE_METADATA_JSON_KILO_2 = r''' +{ + "type": "dict", + "vars": { + "status": "active", + "created_at": "2016-12-05T19:22:22.270042", + "name": "UbuntuCloudVF-virtio", + "deleted": false, + "container_format": "bare", + "min_ram": 0, + "disk_format": "qcow2", + "updated_at": "2016-12-05T19:22:41.704354", + "owner": "52ad9bf691e046abb9628008ede2bc7a", + "checksum": "2122e9d388ba080cf3a2bb5f98868a48", + "min_disk": 0, + "is_public": true, + "deleted_at": null, + "id": "5f38cce2-dcb5-4843-908a-a2a0e6a114db", + "size": 2973171712 + } +}''' + +# Missing disk_format, decode should fail +_IMAGE_METADATA_JSON_KILO_3 = r''' +{ + "type": "dict", + "vars": { + "status": "active", + "created_at": "2016-12-05T19:22:22.270042", + "deleted": false, + "container_format": "bare", + "min_ram": 0, + "updated_at": "2016-12-05T19:22:41.704354", + "properties": { + "architecture": "x86_64" + }, + "owner": "52ad9bf691e046abb9628008ede2bc7a", + "checksum": "2122e9d388ba080cf3a2bb5f98868a48", + "min_disk": 0, + "is_public": true, + "deleted_at": null, + "id": "5f38cce2-dcb5-4843-908a-a2a0e6a114db", + "size": 2973171712 + } +}''' + +# Enable SR-IOV +_IMAGE_METADATA_JSON_KILO_4 = r''' +{ + "type": "dict", + "vars": { + "status": "active", + "created_at": "2016-12-05T19:22:22.270042", + "name": "UbuntuCloudVF-virtio", + "deleted": false, + "container_format": "bare", + "min_ram": 0, + "disk_format": "qcow2", + "updated_at": "2016-12-05T19:22:41.704354", + "properties": { + "architecture": "x86_64", + "agilio.hw_acceleration_features": "SR-IOV" + }, + "owner": "52ad9bf691e046abb9628008ede2bc7a", + "checksum": "2122e9d388ba080cf3a2bb5f98868a48", + "min_disk": 0, + "is_public": true, + "deleted_at": null, + "id": "5f38cce2-dcb5-4843-908a-a2a0e6a114db", + "size": 2973171712 + } +}''' + +# Case from Jon Hickman, 2016-12-15 +_IMAGE_METADATA_JSON_KILO_5 = r''' +{ + "type": "dict", + "vars": { + "min_disk": "40", + "container_format": "bare", + "min_ram": "0", + "disk_format": "qcow2", + "properties": { + "base_image_ref": "e40c60a1-ff62-4428-8745-b644d62d76ac" + } + } +}''' + +_IMAGE_METADATA_JSON_MITAKA_1 = r''' +{ + "type": "dict", + "vars": { + "nova_object.version": "1.8", + "nova_object.namespace": "nova", + "nova_object.name": "ImageMeta", + "nova_object.data": { + "status": "active", + "properties": { + "nova_object.version": "1.12", + "nova_object.name": "ImageMetaProps", + "nova_object.namespace": "nova", + "nova_object.data": {} + }, + "name": "ubuntu", + "container_format": "bare", + "created_at": "2016-12-08T16:41:10Z", + "disk_format": "vmdk", + "updated_at": "2016-12-08T16:41:35Z", + "id": "d09d4ae2-2718-46dc-b953-4e924d0543ae", + "owner": "admin", + "checksum": "5067be9171570fb0f587ca018e1c43b6", + "min_disk": 0, + "min_ram": 0, + "size": 913637376 + }, + "nova_object.changes": [ + "status", + "name", + "container_format", + "created_at", + "disk_format", + "updated_at", + "properties", + "min_disk", + "min_ram", + "checksum", + "owner", + "id", + "size" + ] + } +}''' + +# Missing name and id (like _IMAGE_METADATA_JSON_KILO_5). +_IMAGE_METADATA_JSON_MITAKA_2 = r''' +{ + "type": "dict", + "vars": { + "nova_object.version": "1.8", + "nova_object.namespace": "nova", + "nova_object.name": "ImageMeta", + "nova_object.data": { + "status": "active", + "properties": { + "nova_object.version": "1.12", + "nova_object.name": "ImageMetaProps", + "nova_object.namespace": "nova", + "nova_object.data": {} + }, + "container_format": "bare", + "created_at": "2016-12-08T16:41:10Z", + "disk_format": "vmdk", + "updated_at": "2016-12-08T16:41:35Z", + "owner": "admin", + "checksum": "5067be9171570fb0f587ca018e1c43b6", + "min_disk": 0, + "min_ram": 0, + "size": 913637376 + }, + "nova_object.changes": [ + "status", + "name", + "container_format", + "created_at", + "disk_format", + "updated_at", + "properties", + "min_disk", + "min_ram", + "checksum", + "owner", + "id", + "size" + ] + } +}''' + +# Missing properties +_IMAGE_METADATA_JSON_MITAKA_3 = r''' +{ + "type": "dict", + "vars": { + "nova_object.version": "1.8", + "nova_object.namespace": "nova", + "nova_object.name": "ImageMeta", + "nova_object.data": { + "status": "active", + "name": "ubuntu", + "container_format": "bare", + "created_at": "2016-12-08T16:41:10Z", + "disk_format": "vmdk", + "updated_at": "2016-12-08T16:41:35Z", + "id": "d09d4ae2-2718-46dc-b953-4e924d0543ae", + "owner": "admin", + "checksum": "5067be9171570fb0f587ca018e1c43b6", + "min_disk": 0, + "min_ram": 0, + "size": 913637376 + }, + "nova_object.changes": [ + "status", + "name", + "container_format", + "created_at", + "disk_format", + "updated_at", + "properties", + "min_disk", + "min_ram", + "checksum", + "owner", + "id", + "size" + ] + } +}''' + +# Properties wrong type +_IMAGE_METADATA_JSON_MITAKA_4 = r''' +{ + "type": "dict", + "vars": { + "nova_object.version": "1.8", + "nova_object.namespace": "nova", + "nova_object.name": "ImageMeta", + "nova_object.data": { + "status": "active", + "properties": { + "nova_object.version": "1.12", + "nova_object.name": "MageMetaProps", + "nova_object.namespace": "nova", + "nova_object.data": {} + }, + "name": "ubuntu", + "container_format": "bare", + "created_at": "2016-12-08T16:41:10Z", + "disk_format": "vmdk", + "updated_at": "2016-12-08T16:41:35Z", + "id": "d09d4ae2-2718-46dc-b953-4e924d0543ae", + "owner": "admin", + "checksum": "5067be9171570fb0f587ca018e1c43b6", + "min_disk": 0, + "min_ram": 0, + "size": 913637376 + }, + "nova_object.changes": [ + "status", + "name", + "container_format", + "created_at", + "disk_format", + "updated_at", + "properties", + "min_disk", + "min_ram", + "checksum", + "owner", + "id", + "size" + ] + } +}''' + +# Enable SR-IOV +_IMAGE_METADATA_JSON_MITAKA_5 = r''' +{ + "type": "dict", + "vars": { + "nova_object.version": "1.8", + "nova_object.namespace": "nova", + "nova_object.name": "ImageMeta", + "nova_object.data": { + "status": "active", + "properties": { + "nova_object.version": "1.12", + "nova_object.name": "ImageMetaProps", + "nova_object.namespace": "nova", + "nova_object.data": { + "agilio.hw_acceleration_features": "SR-IOV" + } + }, + "name": "ubuntu", + "container_format": "bare", + "created_at": "2016-12-08T16:41:10Z", + "disk_format": "vmdk", + "updated_at": "2016-12-08T16:41:35Z", + "id": "d09d4ae2-2718-46dc-b953-4e924d0543ae", + "owner": "admin", + "checksum": "5067be9171570fb0f587ca018e1c43b6", + "min_disk": 0, + "min_ram": 0, + "size": 913637376 + }, + "nova_object.changes": [ + "status", + "name", + "container_format", + "created_at", + "disk_format", + "updated_at", + "properties", + "min_disk", + "min_ram", + "checksum", + "owner", + "id", + "size" + ] + } +}''' + +# Missing container_format. +_IMAGE_METADATA_JSON_MITAKA_6 = r''' +{ + "type": "dict", + "vars": { + "nova_object.version": "1.8", + "nova_object.namespace": "nova", + "nova_object.name": "ImageMeta", + "nova_object.data": { + "status": "active", + "properties": { + "nova_object.version": "1.12", + "nova_object.name": "ImageMetaProps", + "nova_object.namespace": "nova", + "nova_object.data": { + "agilio.hw_acceleration_features": "SR-IOV" + } + }, + "name": "ubuntu", + "created_at": "2016-12-08T16:41:10Z", + "disk_format": "vmdk", + "updated_at": "2016-12-08T16:41:35Z", + "id": "d09d4ae2-2718-46dc-b953-4e924d0543ae", + "owner": "admin", + "checksum": "5067be9171570fb0f587ca018e1c43b6", + "min_disk": 0, + "min_ram": 0, + "size": 913637376 + }, + "nova_object.changes": [ + "status", + "name", + "container_format", + "created_at", + "disk_format", + "updated_at", + "properties", + "min_disk", + "min_ram", + "checksum", + "owner", + "id", + "size" + ] + } +}''' + + +class TestImageMetadataToAllowedModes(unittest.TestCase): + def test_kilo(self): + logger = logging.getLogger('29fd9be2-f0b8-4d33-a514-fb5bed544227') + logger.disabled = True + + UV = (PM.unaccelerated, PM.VirtIO) + SUV = (PM.SRIOV, PM.unaccelerated, PM.VirtIO) + + good = ( + (_IMAGE_METADATA_JSON_KILO_1, UV), + (_IMAGE_METADATA_JSON_KILO_2, UV), + (_IMAGE_METADATA_JSON_KILO_4, SUV), + (_IMAGE_METADATA_JSON_KILO_5, UV), + ) + for g in good: + allowed_modes = port_control._image_metadata_to_allowed_modes( + logger=logger, image_metadata=g[0] + ) + self.assertEqual(frozenset(allowed_modes), frozenset(g[1])) + + bad = ( + _IMAGE_METADATA_JSON_KILO_3, + ) + for b in bad: + with self.assertRaises(ValueError): + port_control._image_metadata_to_allowed_modes( + logger=logger, image_metadata=b + ) + + def test_mitaka(self): + logger = logging.getLogger('ee1c8395-0620-4332-8fc7-3933b9b1297a') + logger.disabled = True + + UV = (PM.unaccelerated, PM.VirtIO) + SUV = (PM.SRIOV, PM.unaccelerated, PM.VirtIO) + + good = ( + (_IMAGE_METADATA_JSON_MITAKA_1, UV), + (_IMAGE_METADATA_JSON_MITAKA_5, SUV), + (_IMAGE_METADATA_JSON_MITAKA_2, UV), + (_IMAGE_METADATA_JSON_MITAKA_3, UV), + ) + for g in good: + allowed_modes = port_control._image_metadata_to_allowed_modes( + logger=logger, image_metadata=g[0] + ) + self.assertEqual(frozenset(allowed_modes), frozenset(g[1])) + + bad = ( + _IMAGE_METADATA_JSON_MITAKA_4, + _IMAGE_METADATA_JSON_MITAKA_6, + ) + for b in bad: + with self.assertRaises(ValueError): + port_control._image_metadata_to_allowed_modes( + logger=logger, image_metadata=b + ) + +_FLAVOR_METADATA_JSON_KILO_1 = r''' +{ + "type": "dict", + "vars": { + "nova_object.version": "1.1", + "nova_object.namespace": "nova", + "nova_object.name": "Flavor", + "nova_object.data": { + "memory_mb": 4096, + "root_gb": 40, + "deleted_at": null, + "name": "m1.medium.virtio_1G", + "deleted": false, + "created_at": "2016-12-01T20:48:10Z", + "ephemeral_gb": 0, + "updated_at": null, + "disabled": false, + "vcpus": 2, + "extra_specs": { + "hw:mem_page_size": "1048576" + }, + "swap": 0, + "rxtx_factor": 1.0, + "is_public": true, + "flavorid": "2aaabc78-4db1-11e6-9721-b083fed41633", + "vcpu_weight": 0, + "id": 12 + }, + "nova_object.changes": [ + "extra_specs" + ] + } +}''' + +# Allowed modes fixed to SR-IOV. +_FLAVOR_METADATA_JSON_KILO_2 = r''' +{ + "type": "dict", + "vars": { + "nova_object.version": "1.1", + "nova_object.namespace": "nova", + "nova_object.name": "Flavor", + "nova_object.data": { + "memory_mb": 4096, + "root_gb": 40, + "deleted_at": null, + "name": "m1.medium.virtio_1G", + "deleted": false, + "created_at": "2016-12-01T20:48:10Z", + "ephemeral_gb": 0, + "updated_at": null, + "disabled": false, + "vcpus": 2, + "extra_specs": { + "agilio:hw_acceleration": "SR-IOV" + }, + "swap": 0, + "rxtx_factor": 1.0, + "is_public": true, + "flavorid": "2aaabc78-4db1-11e6-9721-b083fed41633", + "vcpu_weight": 0, + "id": 12 + }, + "nova_object.changes": [ + "extra_specs" + ] + } +}''' + +# Missing extra_specs +_FLAVOR_METADATA_JSON_KILO_3 = r''' +{ + "type": "dict", + "vars": { + "nova_object.version": "1.1", + "nova_object.namespace": "nova", + "nova_object.name": "Flavor", + "nova_object.data": { + "memory_mb": 4096, + "root_gb": 40, + "deleted_at": null, + "name": "m1.medium.virtio_1G", + "deleted": false, + "created_at": "2016-12-01T20:48:10Z", + "ephemeral_gb": 0, + "updated_at": null, + "disabled": false, + "vcpus": 2, + "swap": 0, + "rxtx_factor": 1.0, + "is_public": true, + "flavorid": "2aaabc78-4db1-11e6-9721-b083fed41633", + "vcpu_weight": 0, + "id": 12 + }, + "nova_object.changes": [ + "extra_specs" + ] + } +}''' + +# extra_specs wrong type +_FLAVOR_METADATA_JSON_KILO_4 = r''' +{ + "type": "dict", + "vars": { + "nova_object.version": "1.1", + "nova_object.namespace": "nova", + "nova_object.name": "Flavor", + "nova_object.data": { + "memory_mb": 4096, + "root_gb": 40, + "deleted_at": null, + "name": "m1.medium.virtio_1G", + "deleted": false, + "created_at": "2016-12-01T20:48:10Z", + "extra_specs": [ + "agilio:hw_acceleration", "SR-IOV" + ], + "ephemeral_gb": 0, + "updated_at": null, + "disabled": false, + "vcpus": 2, + "swap": 0, + "rxtx_factor": 1.0, + "is_public": true, + "flavorid": "2aaabc78-4db1-11e6-9721-b083fed41633", + "vcpu_weight": 0, + "id": 12 + }, + "nova_object.changes": [ + "extra_specs" + ] + } +}''' + +_FLAVOR_METADATA_JSON_MITAKA_1 = r''' +{ + "type": "dict", + "vars": { + "nova_object.version": "1.1", + "nova_object.namespace": "nova", + "nova_object.name": "Flavor", + "nova_object.data": { + "memory_mb": 4096, + "root_gb": 40, + "deleted_at": null, + "name": "m1.medium.virtio_1G", + "deleted": false, + "created_at": "2016-12-08T16:44:41Z", + "ephemeral_gb": 0, + "updated_at": null, + "disabled": false, + "vcpus": 2, + "extra_specs": { + "hw:mem_page_size": "1048576" + }, + "swap": 0, + "rxtx_factor": 1.0, + "is_public": true, + "flavorid": "2aaabc78-4db1-11e6-9721-b083fed41633", + "vcpu_weight": 0, + "id": 12 + }, + "nova_object.changes": [ + "extra_specs" + ] + } +}''' + + +class TestFlavorMetadataToAllowedModes(unittest.TestCase): + def test_kilo(self): + logger = logging.getLogger('c1732b72-db81-4614-9f65-5864b12891e7') + logger.disabled = True + + SUV = (PM.SRIOV, PM.unaccelerated, PM.VirtIO) + + good = ( + (_FLAVOR_METADATA_JSON_KILO_1, SUV), + (_FLAVOR_METADATA_JSON_KILO_2, (PM.SRIOV,)), + ) + for g in good: + allowed_modes = port_control._flavor_metadata_to_allowed_modes( + logger=logger, flavor_metadata=g[0] + ) + self.assertEqual(frozenset(allowed_modes), frozenset(g[1])) + + bad = ( + _FLAVOR_METADATA_JSON_KILO_3, + _FLAVOR_METADATA_JSON_KILO_4, + ) + for b in bad: + with self.assertRaises(ValueError): + port_control._image_metadata_to_allowed_modes( + logger=logger, image_metadata=b + ) + + def test_mitaka(self): + logger = logging.getLogger('149960ef-f8ec-49c7-9119-629745ff9ba7') + logger.disabled = True + + SUV = (PM.SRIOV, PM.unaccelerated, PM.VirtIO) + + good = ( + (_FLAVOR_METADATA_JSON_MITAKA_1, SUV), + ) + for g in good: + allowed_modes = port_control._flavor_metadata_to_allowed_modes( + logger=logger, flavor_metadata=g[0] + ) + self.assertEqual(frozenset(allowed_modes), frozenset(g[1])) + + # Kilo and Mitaka use the same decoder function and the flavor data has + # the same format so this test is really just a sanity check, hence + # only one test case for Mitaka. + class TestApp(unittest.TestCase): """Basic tests of the vRouterPortControl application.""" @@ -147,31 +817,35 @@ def _make_config_file(**kwds): def _make_flavor(tweak=None): + # Based on a Mitaka flavor. ans = { - 'type': 'Flavor', - 'vars': { - '_changed_fields': None, - '_deleted_at': None, - '_vcpus': 1, - '_context': None, - '_deleted': False, - '_created_at': None, - '_flavorid': '1', - '_disabled': False, - '_orig_extra_specs': {}, - '_vcpu_weight': 0, - '_updated_at': None, - '_memory_mb': 512, - 'VERSION': '1.1', - '_root_gb': 1, - '_is_public': True, - '_rxtx_factor': 1.0, - '_extra_specs': {}, - '_orig_projects': [], - '_name': 'm1.tiny', - '_swap': 0, - '_id': 2, - '_ephemeral_gb': 0 + "type": "dict", + "vars": { + "nova_object.version": "1.1", + "nova_object.namespace": "nova", + "nova_object.name": "Flavor", + "nova_object.data": { + "memory_mb": 4096, + "root_gb": 40, + "deleted_at": None, + "name": "m1.medium.virtio_1G", + "deleted": False, + "created_at": None, + "ephemeral_gb": 0, + "updated_at": None, + "disabled": False, + "vcpus": 2, + "extra_specs": {}, + "swap": 0, + "rxtx_factor": 1.0, + "is_public": True, + "flavorid": "2aaabc78-4db1-11e6-9721-b083fed41633", + "vcpu_weight": 0, + "id": 12 + }, + "nova_object.changes": [ + "extra_specs" + ] } } @@ -379,7 +1053,7 @@ def test_config_VirtIO_good_flavor(self): """ good_flavor = _make_flavor() - good_flavor['vars']['_extra_specs'].setdefault( + good_flavor['vars']['nova_object.data']['extra_specs'].setdefault( 'hw:mem_page_size', '1G' ) @@ -1086,6 +1760,51 @@ def test_translate_conf(self): # driver's constructor. d = t[0](config=c, **t[1]) + def test_translate_conf_multiqueue(self): + cmd = port_control.AddCmd(logger=subcmd._LOGGER) + self.assertIsNone(cmd.conf) + + port_uuid = uuid.uuid1() + instance_uuid = uuid.uuid1() + vm_project_uuid = uuid.uuid1() + vn_uuid = uuid.uuid1() + mac1 = RandMac().generate() + + standard_args = ( + '--uuid', str(port_uuid), + '--instance_uuid', str(instance_uuid), + '--vm_project_uuid', str(vm_project_uuid), + '--vif_type', 'Vrouter', + '--mac', mac1, + '--port_type', 'NovaVMPort', + '--tap_name', config.default_devname('tap', port_uuid), + '--vn_uuid', str(vn_uuid), + ) + + m = lambda s: ('--multiqueue={}'.format(s),) + test_data = ( + ((), False), + (m('false'), False), + (m('False'), False), + (m('true'), True), + (m('True'), True), + ) + + for td in test_data: + rc = cmd.parse_args( + prog=subcmd._PROG, command='xx', args=standard_args + td[0], + default_config_files=() + ) + self.assertIsNone(rc) + self.assertIsInstance(cmd.conf, cfg.ConfigOpts) + + step = plug._CreateTAP() + c = step.translate_conf(copy.copy(cmd.conf)) + self.assertIsInstance(c, dict) + step.configure(**c[step.configure.section]) + + self.assertEqual(step._multiqueue, td[1]) + def randip4(): addr = ((1, 223), (0, 255), (0, 255), (0, 254)) @@ -1233,8 +1952,6 @@ def test_configure_then_plug(self): _PLUG_LOGGER.name: {'DEBUG': 7 + have_iommu_check, 'INFO': 2}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) def test_configure_then_multiplug(self): @@ -1255,8 +1972,6 @@ def test_configure_then_multiplug(self): }, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 2}, - 'urllib3.connectionpool': {'DEBUG': 2, 'INFO': 2}, - 'urllib3.util.retry': {'DEBUG': 2}, }) def test_configure_then_plug_mandatory(self): @@ -1273,8 +1988,6 @@ def test_configure_then_plug_mandatory(self): _PLUG_LOGGER.name: {'DEBUG': 7 + have_iommu_check, 'INFO': 2}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) def test_configure_then_plug_mandatory_with_conflict(self): @@ -1303,8 +2016,6 @@ def test_plug_straightaway(self): _PLUG_LOGGER.name: {'DEBUG': 7 + have_iommu_check, 'INFO': 2}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) def test_plug_straightaway_without_mandatory(self): diff --git a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/test_plug.py b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/test_plug.py index 734b7444731..351694988b1 100644 --- a/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/test_plug.py +++ b/src/vnsw/opencontrail-vrouter-netronome/netronome/vrouter/tests/unit/test_plug.py @@ -58,7 +58,7 @@ ) from netronome.vrouter.tests.helpers.plug import ( _enable_fake_intel_iommu, _make_fake_sysfs_fallback_map, _DisableGC, - FakeAgent, FakeVirtIOServer + FakeAgent, FakeVirtIOServer, URLLIB3_LOGGERS ) from netronome.vrouter.tests.helpers.vf import (fake_FallbackMap) from netronome.vrouter.tests.unit.rest import test_rest @@ -83,12 +83,20 @@ # FreeBSD (regardless of target port). _UNREACHABLE_AGENT_URL = 'http://127.255.255.255:49151' +urllib3_logging = SetLogLevel(loggers=URLLIB3_LOGGERS, level=logging.WARNING) + def setUpModule(): e = re.split(r'\s+', os.environ.get('NS_VROUTER_TESTS_ENABLE_LOGGING', '')) if 'plug' in e: logging.basicConfig(level=logging.DEBUG) + urllib3_logging.setUp() + + +def tearDownModule(): + urllib3_logging.tearDown() + def _test_data(tweak=None): u = str(uuid.uuid1()) @@ -231,8 +239,6 @@ def test_PlugUnaccelerated(self): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 3}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) with attachLogHandler(logging.root, LogMessageCounter()) as lmc: @@ -251,8 +257,6 @@ def test_PlugUnaccelerated(self): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 3}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) agent.stop() @@ -334,8 +338,6 @@ def test_PlugUnaccelerated_agent_POST_fail_just_warns(self): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 3, 'ERROR': 1}, - 'urllib3.connectionpool': {'INFO': 2, 'WARNING': 1}, - 'urllib3.util.retry': {'DEBUG': 2}, }) with attachLogHandler(logging.root, LogMessageCounter()) as lmc: @@ -365,8 +367,6 @@ def test_PlugUnaccelerated_agent_POST_fail_just_warns(self): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 3, 'ERROR': 1}, - 'urllib3.connectionpool': {'INFO': 2, 'WARNING': 1}, - 'urllib3.util.retry': {'DEBUG': 2}, }) s.commit() @@ -439,8 +439,6 @@ def test_PlugUnaccelerated_agent_file_write_fail_just_warns(self): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 3, 'ERROR': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) # need to get rid of the obstruction since _AgentFileWrite.undo() @@ -464,8 +462,6 @@ def test_PlugUnaccelerated_agent_file_write_fail_just_warns(self): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 3}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) agent.stop() @@ -545,8 +541,6 @@ def test_PlugUnaccelerated_agent_file_write_has_no_persist_option(self): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 2}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) with attachLogHandler(logging.root, LogMessageCounter()) as lmc: @@ -573,8 +567,6 @@ def test_PlugUnaccelerated_agent_file_write_has_no_persist_option(self): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 2}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) agent.stop() @@ -632,8 +624,6 @@ def test_PlugUnaccelerated_agent_file_write_and_POST_both_fail_raises( # check log messages self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'CRITICAL': 2, 'DEBUG': 6, 'ERROR': 3}, - 'urllib3.connectionpool': {'INFO': 4, 'WARNING': 2}, - 'urllib3.util.retry': {'DEBUG': 4}, }) # no need to unplug, plug exception handler already unwound for us @@ -672,8 +662,6 @@ def test_PlugUnaccelerated_agent_post_fail_and_no_persist_raises(self): # check log messages self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'CRITICAL': 1, 'DEBUG': 4, 'ERROR': 2}, - 'urllib3.connectionpool': {'INFO': 4, 'WARNING': 2}, - 'urllib3.util.retry': {'DEBUG': 4}, }) # no need to unplug, plug exception handler already unwound for us @@ -730,8 +718,6 @@ def _tweak(ans): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 5}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) with attachLogHandler(logging.root, LogMessageCounter()) as lmc: @@ -748,8 +734,6 @@ def _tweak(ans): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 3}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) agent.stop() @@ -824,8 +808,6 @@ def test_PlugUnaccelerated_DPDK_wrong_socket_type(self): expected_log_messages={ _PLUG_LOGGER.name: {'DEBUG': 7, 'CRITICAL': 1}, 'tornado.access': {'INFO': 2}, - 'urllib3.connectionpool': {'DEBUG': 2, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 2} } ) @@ -840,8 +822,6 @@ def test_PlugUnaccelerated_DPDK_socket_timeout(self): expected_log_messages={ _PLUG_LOGGER.name: {'DEBUG': 7, 'CRITICAL': 1}, 'tornado.access': {'INFO': 2}, - 'urllib3.connectionpool': {'DEBUG': 2, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 2} } ) @@ -919,8 +899,6 @@ def _tweak(ans): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 3, 'ERROR': 1}, - 'urllib3.connectionpool': {'INFO': 2, 'WARNING': 1}, - 'urllib3.util.retry': {'DEBUG': 2} }) with attachLogHandler(logging.root, LogMessageCounter()) as lmc: @@ -947,8 +925,6 @@ def _tweak(ans): self.assertEqual(lmc.count, { _PLUG_LOGGER.name: {'DEBUG': 3, 'ERROR': 1}, - 'urllib3.connectionpool': {'INFO': 2, 'WARNING': 1}, - 'urllib3.util.retry': {'DEBUG': 2} }) s.commit() @@ -1349,8 +1325,6 @@ def test_AgentPost_connection_error(self): self.assertTrue(do_ok.is_negative()) self.assertEqual(log_message_counter.count, { _PLUG_LOGGER.name: {'ERROR': 1}, - 'urllib3.connectionpool': {'INFO': 2, 'WARNING': 1}, - 'urllib3.util.retry': {'DEBUG': 2}, }) log_message_counter = LogMessageCounter() @@ -1364,8 +1338,6 @@ def test_AgentPost_connection_error(self): self.assertTrue(undo_ok.is_negative()) self.assertEqual(log_message_counter.count, { _PLUG_LOGGER.name: {'ERROR': 1}, - 'urllib3.connectionpool': {'INFO': 2, 'WARNING': 1}, - 'urllib3.util.retry': {'DEBUG': 2}, }) s.commit() @@ -1823,8 +1795,6 @@ def _test_PlugSRIOV(self, customize_port, expected_plug_logs): _PLUG_LOGGER.name: {'DEBUG': 6}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) agent.stop() @@ -1849,8 +1819,6 @@ def test_PlugSRIOV(self): _PLUG_LOGGER.name: {'DEBUG': 6 + have_iommu_check}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, } ) @@ -1862,8 +1830,6 @@ def test_PlugSRIOV_with_VF_already_allocated(self): _PLUG_LOGGER.name: {'DEBUG': 6 + have_iommu_check}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, } ) @@ -1937,8 +1903,6 @@ def test_plug_timeout(self): }, _VF_LOGGER.name: {'INFO': 2}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) agent.stop() @@ -2023,8 +1987,6 @@ def test_unplug_timeout(self): _PLUG_LOGGER.name: {'DEBUG': 6 + have_iommu_check}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) # Now do the actual unplug. This should log a timeout error, but NOT @@ -2047,8 +2009,6 @@ def test_unplug_timeout(self): _PLUG_LOGGER.name: {'DEBUG': 5, 'ERROR': 1}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) agent.stop() @@ -2705,8 +2665,6 @@ def h(request): _PLUG_LOGGER.name: {'DEBUG': 11, 'INFO': 3, 'WARNING': 1}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }) JOIN_TIMEOUT_SEC = 9 @@ -2742,8 +2700,6 @@ def test_PlugVirtIO(self): _PLUG_LOGGER.name: {'DEBUG': 12, 'INFO': 3, 'WARNING': 1}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, } ) @@ -2754,8 +2710,6 @@ def test_PlugVirtIO_with_VF_already_allocated(self): _PLUG_LOGGER.name: {'DEBUG': 12, 'INFO': 3, 'WARNING': 1}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }, ) @@ -2777,8 +2731,6 @@ def _enable_fake_ksm(root_dir): }, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }, ) @@ -2884,8 +2836,6 @@ def test_plug_new_port(self): _PLUG_LOGGER.name: {'DEBUG': 4, 'INFO': 2}, _VF_LOGGER.name: {'WARNING': 2}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }, ) @@ -2909,8 +2859,6 @@ def chmod_0(d): }, _VF_LOGGER.name: {'WARNING': 2}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }, _d_customize=chmod_0, ) @@ -2928,8 +2876,6 @@ def precreate_unaccel_pm(session, uuid): _PLUG_LOGGER.name: {'DEBUG': 4, 'INFO': 2}, _VF_LOGGER.name: {'WARNING': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }, _pm_customize=precreate_unaccel_pm, ) @@ -3068,8 +3014,6 @@ def test_unaccelerated_unplug(self): expected_logs={ _PLUG_LOGGER.name: {'DEBUG': 3, 'INFO': 4}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }, nfp_status=1, physical_vif_count=1, @@ -3084,8 +3028,6 @@ def test_SRIOV_unplug(self): _PLUG_LOGGER.name: {'DEBUG': 6, 'INFO': 5}, _VF_LOGGER.name: {'INFO': 1}, 'tornado.access': {'INFO': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }, nfp_status=1, physical_vif_count=1, @@ -3159,8 +3101,6 @@ def test_only_configured_unplug_unaccelerated(self): expected_logs={ _PLUG_LOGGER.name: {'INFO': 3, 'WARNING': 1, 'DEBUG': 2}, 'tornado.access': {'WARNING': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, } ) @@ -3175,8 +3115,6 @@ def enable_acceleration(d): expected_logs={ _PLUG_LOGGER.name: {'INFO': 4, 'WARNING': 1, 'DEBUG': 2}, 'tornado.access': {'WARNING': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, }, _d_customize=enable_acceleration, ) @@ -3271,8 +3209,6 @@ def test_unplugged_port_unplug(self): expected_logs={ _PLUG_LOGGER.name: {'INFO': 3, 'WARNING': 1, 'DEBUG': 2}, 'tornado.access': {'WARNING': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, } ) @@ -3285,8 +3221,6 @@ def test_nonexistent_port_unplug(self): expected_logs={ _PLUG_LOGGER.name: {'DEBUG': 3, 'INFO': 2}, 'tornado.access': {'WARNING': 1}, - 'urllib3.connectionpool': {'DEBUG': 1, 'INFO': 1}, - 'urllib3.util.retry': {'DEBUG': 1}, } )