From d4f982449ed1a5110896fe92187daeb3ca18161f Mon Sep 17 00:00:00 2001 From: Dinesh Bhor Date: Tue, 4 Jul 2017 19:26:12 +0530 Subject: [PATCH] Use os-testr instead of testr Masakari should use ostestr instead of testr. ostestr is more powerful and provide much prettier output than testr. Other projects like cinder, nova, glance, neutron etc already uses the ostestr wrapper. Using ostestr shows each tests execution separately because of which it has shown errors related to "KeyError" in existing test cases. The error looks like below: "Exception in string format operation: KeyError: u'id'" This happens if we don't pass keyword argument like "id" to exception which we expect to be raised from test through side_effect [1]. This doesn't lead to test failure but it appears in test logs. This patch fixes such issues by passing expected keyword arguments to exceptions. [1] https://github.com/openstack/masakari/blob/master/masakari/tests/unit/api/openstack/ha/test_hosts.py#L364 Change-Id: I91603ea3dcf35fd20a00dcf477b93d612edca362 --- .../tests/unit/api/openstack/ha/test_hosts.py | 19 ++++++------ .../api/openstack/ha/test_notifications.py | 14 +++++---- .../unit/api/openstack/ha/test_segments.py | 14 +++++---- masakari/tests/unit/ha/test_api.py | 21 ++++++++------ masakari/tests/unit/objects/test_hosts.py | 2 +- masakari/tests/unit/objects/test_segments.py | 3 +- test-requirements.txt | 1 + tox.ini | 29 +++++++++++++++++-- 8 files changed, 70 insertions(+), 33 deletions(-) diff --git a/masakari/tests/unit/api/openstack/ha/test_hosts.py b/masakari/tests/unit/api/openstack/ha/test_hosts.py index dde9dcc8..bedf48ad 100644 --- a/masakari/tests/unit/api/openstack/ha/test_hosts.py +++ b/masakari/tests/unit/api/openstack/ha/test_hosts.py @@ -190,7 +190,7 @@ class HostTestCase(test.TestCase): req = fakes.HTTPRequest.blank('/v1/segments/%s/hosts?marker=123456' % ( uuidsentinel.fake_segment1), use_admin_context=True) mock_segment.return_value = mock.Mock() - mock_get_all.side_effect = exception.MarkerNotFound + mock_get_all.side_effect = exception.MarkerNotFound(marker="123456") self.assertRaises(exc.HTTPBadRequest, self.controller.index, req, uuidsentinel.fake_segment1) @@ -210,10 +210,11 @@ class HostTestCase(test.TestCase): self.assertRaises(exc.HTTPBadRequest, self.controller.index, req, uuidsentinel.fake_segment1) - @ddt.data([exception.MarkerNotFound, "/v1/segments/%s/hosts?marker=123456", - exc.HTTPBadRequest], - [exception.FailoverSegmentNotFound, "/v1/segments/%s/hosts", - exc.HTTPNotFound]) + @ddt.data([exception.MarkerNotFound(marker="123456"), + "/v1/segments/%s/hosts?marker=123456", exc.HTTPBadRequest], + [exception.FailoverSegmentNotFound( + id=uuidsentinel.fake_segment1), "/v1/segments/%s/hosts", + exc.HTTPNotFound]) @ddt.unpack @mock.patch.object(segment_obj.FailoverSegment, 'get_by_uuid') @mock.patch.object(ha_api.HostAPI, 'get_all') @@ -361,7 +362,7 @@ class HostTestCase(test.TestCase): @mock.patch.object(ha_api.HostAPI, 'get_host') def test_show_with_non_existing_id(self, mock_get_host): - mock_get_host.side_effect = exception.HostNotFound + mock_get_host.side_effect = exception.HostNotFound(id="2") self.assertRaises(exc.HTTPNotFound, self.controller.show, self.req, uuidsentinel.fake_segment1, "2") @@ -420,14 +421,14 @@ class HostTestCase(test.TestCase): def test_update_with_non_exising_host(self, mock_update_host): test_data = {"host": {"name": "host11"}} - mock_update_host.side_effect = exception.HostNotFound + mock_update_host.side_effect = exception.HostNotFound(id="2") self.assertRaises(exc.HTTPNotFound, self.controller.update, self.req, uuidsentinel.fake_segment1, "2", body=test_data) @mock.patch.object(ha_api.HostAPI, 'update_host') def test_update_with_duplicated_name(self, mock_update_host): test_data = {"host": {"name": "host-1"}} - mock_update_host.side_effect = exception.HostExists + mock_update_host.side_effect = exception.HostExists(name="host-1") self.assertRaises(exc.HTTPConflict, self.controller.update, self.req, uuidsentinel.fake_segment1, uuidsentinel.fake_host_1, body=test_data) @@ -455,7 +456,7 @@ class HostTestCase(test.TestCase): @mock.patch.object(ha_api.HostAPI, 'delete_host') def test_delete_host_not_found(self, mock_delete): - mock_delete.side_effect = exception.HostNotFound + mock_delete.side_effect = exception.HostNotFound(id="2") self.assertRaises(exc.HTTPNotFound, self.controller.delete, self.req, uuidsentinel.fake_segment1, uuidsentinel.fake_host_3) diff --git a/masakari/tests/unit/api/openstack/ha/test_notifications.py b/masakari/tests/unit/api/openstack/ha/test_notifications.py index 4b21460e..263b480a 100644 --- a/masakari/tests/unit/api/openstack/ha/test_notifications.py +++ b/masakari/tests/unit/api/openstack/ha/test_notifications.py @@ -129,7 +129,7 @@ class NotificationTestCase(test.TestCase): def test_index_marker_not_found(self, mock_get_all): fake_request = fakes.HTTPRequest.blank('/v1/notifications?marker=1234', use_admin_context=True) - mock_get_all.side_effect = exception.MarkerNotFound + mock_get_all.side_effect = exception.MarkerNotFound(marker="1234") self.assertRaises(exc.HTTPBadRequest, self.controller.index, fake_request) @@ -195,7 +195,8 @@ class NotificationTestCase(test.TestCase): "cluster_status": "ONLINE"}, "type": "VM", "generated_time": "2016-09-13T09:11:21.656788"}} - mock_create.side_effect = exception.HostNotFoundByName + mock_create.side_effect = exception.HostNotFoundByName( + host_name="fake_host") self.assertRaises(exc.HTTPBadRequest, self.controller.create, self.req, body=body) @@ -273,7 +274,8 @@ class NotificationTestCase(test.TestCase): @mock.patch.object(ha_api.NotificationAPI, 'create_notification') def test_create_duplicate_notification(self, mock_create_notification): - mock_create_notification.side_effect = exception.DuplicateNotification + mock_create_notification.side_effect = exception.DuplicateNotification( + type="COMPUTE_HOST") body = { "notification": {"hostname": "fake_host", "payload": {"event": "STOPPED", @@ -286,7 +288,8 @@ class NotificationTestCase(test.TestCase): @mock.patch.object(ha_api.NotificationAPI, 'create_notification') def test_create_host_on_maintenance(self, mock_create_notification): - mock_create_notification.side_effect = exception.HostOnMaintenanceError + mock_create_notification.side_effect = ( + exception.HostOnMaintenanceError(host_name="fake_host")) body = { "notification": {"hostname": "fake_host", "payload": {"event": "STOPPED", @@ -310,7 +313,8 @@ class NotificationTestCase(test.TestCase): @mock.patch.object(ha_api.NotificationAPI, 'get_notification') def test_show_with_non_existing_uuid(self, mock_get_notification): - mock_get_notification.side_effect = exception.NotificationNotFound + mock_get_notification.side_effect = exception.NotificationNotFound( + id="2") self.assertRaises(exc.HTTPNotFound, self.controller.show, self.req, "2") diff --git a/masakari/tests/unit/api/openstack/ha/test_segments.py b/masakari/tests/unit/api/openstack/ha/test_segments.py index 55f5d0ce..76fad9f4 100644 --- a/masakari/tests/unit/api/openstack/ha/test_segments.py +++ b/masakari/tests/unit/api/openstack/ha/test_segments.py @@ -94,7 +94,7 @@ class FailoverSegmentTestCase(test.TestCase): def test_index_marker_not_found(self, mock_get_all): fake_request = fakes.HTTPRequest.blank('/v1/segments?marker=12345', use_admin_context=True) - mock_get_all.side_effect = exception.MarkerNotFound + mock_get_all.side_effect = exception.MarkerNotFound(marker="12345") self.assertRaises(exc.HTTPBadRequest, self.controller.index, fake_request) @@ -227,7 +227,8 @@ class FailoverSegmentTestCase(test.TestCase): @mock.patch.object(ha_api.FailoverSegmentAPI, 'get_segment') def test_show_with_non_existing_id(self, mock_get_segment): - mock_get_segment.side_effect = exception.FailoverSegmentNotFound + mock_get_segment.side_effect = exception.FailoverSegmentNotFound( + id="2") self.assertRaises(exc.HTTPNotFound, self.controller.show, self.req, "2") @@ -275,14 +276,16 @@ class FailoverSegmentTestCase(test.TestCase): def test_update_with_non_exising_segment(self, mock_update_segment): test_data = {"segment": {"name": "segment11"}} - mock_update_segment.side_effect = exception.FailoverSegmentNotFound + mock_update_segment.side_effect = exception.FailoverSegmentNotFound( + id="2") self.assertRaises(exc.HTTPNotFound, self.controller.update, self.req, "2", body=test_data) @mock.patch.object(ha_api.FailoverSegmentAPI, 'update_segment') def test_update_with_duplicated_name(self, mock_update_segment): test_data = {"segment": {"name": "segment1"}} - mock_update_segment.side_effect = exception.FailoverSegmentExists + mock_update_segment.side_effect = exception.FailoverSegmentExists( + name="segment1") self.assertRaises(exc.HTTPConflict, self.controller.update, self.req, uuidsentinel.fake_segment, body=test_data) @@ -295,7 +298,8 @@ class FailoverSegmentTestCase(test.TestCase): @mock.patch.object(ha_api.FailoverSegmentAPI, 'delete_segment') def test_delete_segment_not_found(self, mock_delete): - mock_delete.side_effect = exception.FailoverSegmentNotFound + mock_delete.side_effect = exception.FailoverSegmentNotFound( + id=uuidsentinel.fake_segment) self.assertRaises(exc.HTTPNotFound, self.controller.delete, self.req, uuidsentinel.fake_segment) diff --git a/masakari/tests/unit/ha/test_api.py b/masakari/tests/unit/ha/test_api.py index bed538f1..36629ea3 100644 --- a/masakari/tests/unit/ha/test_api.py +++ b/masakari/tests/unit/ha/test_api.py @@ -86,11 +86,11 @@ class FailoverSegmentAPITestCase(test.NoDBTestCase): @mock.patch.object(segment_obj.FailoverSegmentList, 'get_all') def test_get_all_marker_not_found(self, mock_get_all): - mock_get_all.side_effect = exception.MarkerNotFound + mock_get_all.side_effect = exception.MarkerNotFound(marker='123') self.assertRaises(exception.MarkerNotFound, self.segment_api.get_all, self.context, filters=None, sort_keys=None, - sort_dirs=None, limit=None, marker=None) + sort_dirs=None, limit=None, marker='123') @mock.patch.object(segment_obj.FailoverSegmentList, 'get_all') def test_get_all_by_recovery_method(self, mock_get_all): @@ -105,7 +105,8 @@ class FailoverSegmentAPITestCase(test.NoDBTestCase): @mock.patch.object(segment_obj.FailoverSegmentList, 'get_all') def test_get_all_invalid_sort_dir(self, mock_get_all): - mock_get_all.side_effect = exception.InvalidInput + mock_get_all.side_effect = exception.InvalidInput( + reason="Unknown sort direction, must be 'asc' or 'desc'") self.assertRaises(exception.InvalidInput, self.segment_api.get_all, self.context, filters=None, sort_keys=None, sort_dirs=['abcd'], limit=None, marker=None) @@ -222,12 +223,12 @@ class HostAPITestCase(test.NoDBTestCase): @mock.patch.object(segment_obj.FailoverSegment, 'get_by_uuid') def test_get_all_marker_not_found(self, mock_get, mock_get_all): mock_get.return_value = self.failover_segment - mock_get_all.side_effect = exception.MarkerNotFound + mock_get_all.side_effect = exception.MarkerNotFound(marker="1234") self.assertRaises(exception.MarkerNotFound, self.host_api.get_all, self.context, filters=None, sort_keys=['created_at'], sort_dirs=['desc'], limit=None, - marker=None) + marker="1234") @mock.patch.object(host_obj.HostList, 'get_all') def test_get_all_by_type(self, mock_get): @@ -243,7 +244,8 @@ class HostAPITestCase(test.NoDBTestCase): @mock.patch.object(host_obj.HostList, 'get_all') def test_get_all_invalid_sort_dir(self, mock_get): - mock_get.side_effect = exception.InvalidInput + mock_get.side_effect = exception.InvalidInput( + reason="Unknown sort direction, must be 'asc' or 'desc'") self.assertRaises(exception.InvalidInput, self.host_api.get_all, self.context, filters=None, sort_keys=None, @@ -554,8 +556,8 @@ class NotificationAPITestCase(test.NoDBTestCase): @mock.patch.object(notification_obj.NotificationList, 'get_all') def test_get_all_marker_not_found(self, mock_get_all): - mock_get_all.side_effect = exception.MarkerNotFound - self.req = fakes.HTTPRequest.blank('/v1/notifications?limit=100', + mock_get_all.side_effect = exception.MarkerNotFound(marker="100") + self.req = fakes.HTTPRequest.blank('/v1/notifications?marker=100', use_admin_context=True) self.assertRaises(exception.MarkerNotFound, self.notification_api.get_all, @@ -575,7 +577,8 @@ class NotificationAPITestCase(test.NoDBTestCase): @mock.patch.object(notification_obj.NotificationList, 'get_all') def test_get_all_invalid_sort_dir(self, mock_get_all): - mock_get_all.side_effect = exception.InvalidInput + mock_get_all.side_effect = exception.InvalidInput( + reason="Unknown sort direction, must be 'asc' or 'desc'") self.req = fakes.HTTPRequest.blank('/v1/notifications?sort_dir=abcd', use_admin_context=True) self.assertRaises(exception.InvalidInput, diff --git a/masakari/tests/unit/objects/test_hosts.py b/masakari/tests/unit/objects/test_hosts.py index 48472e2a..9f146aa6 100644 --- a/masakari/tests/unit/objects/test_hosts.py +++ b/masakari/tests/unit/objects/test_hosts.py @@ -154,7 +154,7 @@ class TestHostObject(test_objects._LocalTest): @mock.patch.object(db, 'host_delete') def test_destroy_host_not_found(self, mock_host_destroy): - mock_host_destroy.side_effect = exception.HostNotFound + mock_host_destroy.side_effect = exception.HostNotFound(id=123) host_obj = self._host_create_attributes() host_obj.id = 123 self.assertRaises(exception.HostNotFound, host_obj.destroy) diff --git a/masakari/tests/unit/objects/test_segments.py b/masakari/tests/unit/objects/test_segments.py index 3e914268..64a2b83a 100644 --- a/masakari/tests/unit/objects/test_segments.py +++ b/masakari/tests/unit/objects/test_segments.py @@ -124,7 +124,8 @@ class TestFailoverSegmentObject(test_objects._LocalTest): @mock.patch('masakari.db.failover_segment_delete') def test_destroy_failover_segment_found(self, mock_segment_destroy): - mock_segment_destroy.side_effect = exception.FailoverSegmentNotFound + mock_segment_destroy.side_effect = exception.FailoverSegmentNotFound( + id=123) segment_obj = self._segment_create_attribute() segment_obj.id = 123 self.assertRaises(exception.FailoverSegmentNotFound, diff --git a/test-requirements.txt b/test-requirements.txt index 4c607ca3..fc53fa3d 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -12,6 +12,7 @@ python-subunit>=0.0.18 # Apache-2.0/BSD sphinx!=1.6.1,>=1.5.1 # BSD oslosphinx>=4.7.0 # Apache-2.0 oslotest>=1.10.0 # Apache-2.0 +os-testr>=0.8.0 # Apache-2.0 requests-mock>=1.1 # Apache-2.0 testrepository>=0.0.18 # Apache-2.0/BSD testresources>=0.2.4 # Apache-2.0/BSD diff --git a/tox.ini b/tox.ini index 6199812d..a5725a91 100644 --- a/tox.ini +++ b/tox.ini @@ -6,10 +6,33 @@ skipsdist = True [testenv] usedevelop = True install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages} -setenv = - VIRTUAL_ENV={envdir} +setenv = VIRTUAL_ENV={envdir} + OS_TEST_PATH=./masakari/tests/unit + LANGUAGE=en_US + LC_ALL=en_US.utf-8 deps = -r{toxinidir}/test-requirements.txt -commands = python setup.py test --slowest --testr-args='{posargs}' +whitelist_externals = bash + find + rm + env +# By default ostestr will set concurrency +# to ncpu, to specify something else use +# the concurrency= option. +# call ie: 'tox -epy27 -- --concurrency=4' +commands = + find . -type f -name "*.pyc" -delete + rm -Rf .testrepository/times.dbm +passenv = http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY OS_DEBUG GENERATE_HASHES + +[testenv:py27] +commands = + {[testenv]commands} + ostestr '{posargs}' + +[testenv:py34] +commands = + {[testenv]commands} + ostestr '{posargs}' [testenv:genconfig] commands = oslo-config-generator --config-file=etc/masakari/masakari-config-generator.conf