From 30159de5cd60d804e9f7792845e1bf01053e6359 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 25 May 2015 13:51:41 +0200 Subject: [PATCH] Enable more tests on Python 3 * Trait.convert_value() now explicitly decodes byte strings from UTF-8: it fixes a BytesWarning error when Python 3 is run using -bb command line option * Replace types.NoneType with type(None) * fileutils.write_to_tempfile() expects content as bytes: encode the content on Python 3 * subprocess.Popen.communicate() returns stdout and stderr as bytes: check for pattern using byte strings * Fix verify_signature() on Python 3: encode new signature to ASCII * Replace "with contextlib.nested(...):" with two nested with, contextlib.nested() was removed in Python 3 * Fix import in test_messaging * tox -e py34 now runs much more tests Change-Id: If2a16c3b8ca64ca86d8172b36ecbf6298044ec87 --- ceilometer/event/storage/models.py | 2 ++ ceilometer/publisher/utils.py | 2 ++ ceilometer/storage/sqlalchemy/utils.py | 3 +-- ceilometer/tests/test_bin.py | 36 +++++++++++++++++++------- ceilometer/tests/test_collector.py | 8 +++--- ceilometer/tests/test_messaging.py | 2 +- tox.ini | 30 ++++++++++++++++++++- 7 files changed, 65 insertions(+), 18 deletions(-) diff --git a/ceilometer/event/storage/models.py b/ceilometer/event/storage/models.py index 4995c6513..1bddda0a3 100644 --- a/ceilometer/event/storage/models.py +++ b/ceilometer/event/storage/models.py @@ -121,4 +121,6 @@ class Trait(base.Model): return float(value) if trait_type is cls.DATETIME_TYPE: return timeutils.normalize_time(timeutils.parse_isotime(value)) + if isinstance(value, six.binary_type): + return value.decode('utf-8') return six.text_type(value) diff --git a/ceilometer/publisher/utils.py b/ceilometer/publisher/utils.py index 6f89eae8f..6f377312e 100644 --- a/ceilometer/publisher/utils.py +++ b/ceilometer/publisher/utils.py @@ -105,6 +105,8 @@ def verify_signature(message, secret): old_sig = old_sig.encode('ascii') except UnicodeDecodeError: return False + if six.PY3: + new_sig = new_sig.encode('ascii') return compare_digest(new_sig, old_sig) diff --git a/ceilometer/storage/sqlalchemy/utils.py b/ceilometer/storage/sqlalchemy/utils.py index 5409ce3a0..c4cac9d9c 100644 --- a/ceilometer/storage/sqlalchemy/utils.py +++ b/ceilometer/storage/sqlalchemy/utils.py @@ -12,7 +12,6 @@ # import operator -import types import six from sqlalchemy import and_ @@ -29,7 +28,7 @@ from ceilometer.storage.sqlalchemy import models META_TYPE_MAP = {bool: models.MetaBool, str: models.MetaText, six.text_type: models.MetaText, - types.NoneType: models.MetaText, + type(None): models.MetaText, int: models.MetaBigInt, float: models.MetaFloat} if six.PY2: diff --git a/ceilometer/tests/test_bin.py b/ceilometer/tests/test_bin.py index 4ec3d6bbd..7a09fd5d1 100644 --- a/ceilometer/tests/test_bin.py +++ b/ceilometer/tests/test_bin.py @@ -22,6 +22,7 @@ import subprocess import time import httplib2 +import six from ceilometer.openstack.common import fileutils from ceilometer.tests import base @@ -34,6 +35,8 @@ class BinTestCase(base.BaseTestCase): "rpc_backend=fake\n" "[database]\n" "connection=log://localhost\n") + if six.PY3: + content = content.encode('utf-8') self.tempfile = fileutils.write_to_tempfile(content=content, prefix='ceilometer', suffix='.conf') @@ -54,12 +57,12 @@ class BinTestCase(base.BaseTestCase): stderr=subprocess.PIPE) __, err = subp.communicate() self.assertEqual(0, subp.poll()) - self.assertIn("Nothing to clean, database metering " - "time to live is disabled", err) - self.assertIn("Nothing to clean, database event " - "time to live is disabled", err) - self.assertIn("Nothing to clean, database alarm history " - "time to live is disabled", err) + self.assertIn(b"Nothing to clean, database metering " + b"time to live is disabled", err) + self.assertIn(b"Nothing to clean, database event " + b"time to live is disabled", err) + self.assertIn(b"Nothing to clean, database alarm history " + b"time to live is disabled", err) def _test_run_expirer_ttl_enabled(self, ttl_name, data_name): content = ("[DEFAULT]\n" @@ -67,6 +70,8 @@ class BinTestCase(base.BaseTestCase): "[database]\n" "%s=1\n" "connection=log://localhost\n" % ttl_name) + if six.PY3: + content = content.encode('utf-8') self.tempfile = fileutils.write_to_tempfile(content=content, prefix='ceilometer', suffix='.conf') @@ -76,7 +81,10 @@ class BinTestCase(base.BaseTestCase): stderr=subprocess.PIPE) __, err = subp.communicate() self.assertEqual(0, subp.poll()) - self.assertIn("Dropping %s data with TTL 1" % data_name, err) + msg = "Dropping %s data with TTL 1" % data_name + if six.PY3: + msg = msg.encode('utf-8') + self.assertIn(msg, err) def test_run_expirer_ttl_enabled(self): self._test_run_expirer_ttl_enabled('metering_time_to_live', @@ -94,6 +102,8 @@ class BinSendSampleTestCase(base.BaseTestCase): content = ("[DEFAULT]\n" "rpc_backend=fake\n" "pipeline_cfg_file={0}\n".format(pipeline_cfg_file)) + if six.PY3: + content = content.encode('utf-8') self.tempfile = fileutils.write_to_tempfile(content=content, prefix='ceilometer', @@ -120,6 +130,8 @@ class BinApiTestCase(base.BaseTestCase): "pipeline = api-server\n" "[app:api-server]\n" "paste.app_factory = ceilometer.api.app:app_factory\n") + if six.PY3: + content = content.encode('utf-8') self.paste = fileutils.write_to_tempfile(content=content, prefix='api_paste', suffix='.ini') @@ -143,6 +155,8 @@ class BinApiTestCase(base.BaseTestCase): policy_file, self.paste, self.api_port)) + if six.PY3: + content = content.encode('utf-8') self.tempfile = fileutils.write_to_tempfile(content=content, prefix='ceilometer', @@ -172,6 +186,8 @@ class BinApiTestCase(base.BaseTestCase): def test_v2(self): response, content = self.get_response('v2/meters') self.assertEqual(200, response.status) + if six.PY3: + content = content.decode('utf-8') self.assertEqual([], json.loads(content)) @@ -182,6 +198,8 @@ class BinCeilometerPollingServiceTestCase(base.BaseTestCase): "rpc_backend=fake\n" "[database]\n" "connection=log://localhost\n") + if six.PY3: + content = content.encode('utf-8') self.tempfile = fileutils.write_to_tempfile(content=content, prefix='ceilometer', suffix='.conf') @@ -201,5 +219,5 @@ class BinCeilometerPollingServiceTestCase(base.BaseTestCase): "compute"], stderr=subprocess.PIPE) out = self.subp.stderr.read(1024) - self.assertIn('Duplicated values: [\'compute\', \'compute\'] ' - 'found in CLI options, auto de-duplidated', out) + self.assertIn(b'Duplicated values: [\'compute\', \'compute\'] ' + b'found in CLI options, auto de-duplidated', out) diff --git a/ceilometer/tests/test_collector.py b/ceilometer/tests/test_collector.py index 27e990772..46899e962 100644 --- a/ceilometer/tests/test_collector.py +++ b/ceilometer/tests/test_collector.py @@ -12,7 +12,6 @@ # 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 contextlib import socket import mock @@ -189,10 +188,9 @@ class TestCollector(tests_base.BaseTestCase): def test_udp_receive_bad_decoding(self): self._setup_messaging(False) udp_socket = self._make_fake_socket(self.counter) - with contextlib.nested( - mock.patch('socket.socket', return_value=udp_socket), - mock.patch('msgpack.loads', self._raise_error)): - self.srv.start() + with mock.patch('socket.socket', return_value=udp_socket): + with mock.patch('msgpack.loads', self._raise_error): + self.srv.start() self._verify_udp_socket(udp_socket) diff --git a/ceilometer/tests/test_messaging.py b/ceilometer/tests/test_messaging.py index 15f7dfe30..785957626 100644 --- a/ceilometer/tests/test_messaging.py +++ b/ceilometer/tests/test_messaging.py @@ -13,7 +13,7 @@ # under the License. from oslo_config import fixture as fixture_config -import oslo_messaging +import oslo_messaging.conffixture from oslotest import base from ceilometer import messaging diff --git a/tox.ini b/tox.ini index 0a1b72594..75a13d5f3 100644 --- a/tox.ini +++ b/tox.ini @@ -31,7 +31,35 @@ commands = deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements-py3.txt commands = python -m testtools.run \ - ceilometer.tests.test_utils + ceilometer.tests.data_processing.test_notifications \ + ceilometer.tests.energy.test_kwapi \ + ceilometer.tests.network.services.test_fwaas \ + ceilometer.tests.network.services.test_lbaas \ + ceilometer.tests.network.services.test_vpnaas \ + ceilometer.tests.network.test_floatingip \ + ceilometer.tests.network.test_notifications \ + ceilometer.tests.orchestration.test_notifications \ + ceilometer.tests.profiler.test_notifications \ + ceilometer.tests.publisher.test_direct \ + ceilometer.tests.publisher.test_file \ + ceilometer.tests.publisher.test_kafka_broker_publisher \ + ceilometer.tests.publisher.test_messaging_publisher \ + ceilometer.tests.publisher.test_utils \ + ceilometer.tests.test_bin \ + ceilometer.tests.test_collector \ + ceilometer.tests.test_coordination \ + ceilometer.tests.test_event_pipeline \ + ceilometer.tests.test_hacking \ + ceilometer.tests.test_messaging \ + ceilometer.tests.test_middleware \ + ceilometer.tests.test_neutronclient \ + ceilometer.tests.test_notification \ + ceilometer.tests.test_notifier \ + ceilometer.tests.test_novaclient \ + ceilometer.tests.test_sample \ + ceilometer.tests.test_utils \ + ceilometer.tests.volume.test_notifications + # NOTE(chdent): The gabbi tests are also run under the primary tox # targets. This target simply provides a target to directly run just