Fix cleanup NotImplemented error

tempest cleanup doesn't check if the APIs it uses are
implemented or not. Therefore the patch adds a try
except block preventing tempest cleanup to fail when
some of the APIs are not implemented.

Closes-bug: #1832566

Change-Id: I9ced4af40eb0c2a22e3557caded56045a397d539
This commit is contained in:
Martin Kopec 2019-06-12 15:23:21 +00:00
parent bba7ad6b2c
commit 97857948d9
4 changed files with 79 additions and 10 deletions

View File

@ -94,6 +94,8 @@ CONF = config.CONF
class TempestCleanup(command.Command):
GOT_EXCEPTIONS = []
def take_action(self, parsed_args):
try:
self.init(parsed_args)
@ -103,6 +105,8 @@ class TempestCleanup(command.Command):
LOG.exception("Failure during cleanup")
traceback.print_exc()
raise
if self.GOT_EXCEPTIONS:
raise Exception(self.GOT_EXCEPTIONS)
def init(self, parsed_args):
cleanup_service.init_conf()
@ -159,7 +163,8 @@ class TempestCleanup(command.Command):
'is_dry_run': is_dry_run,
'saved_state_json': self.json_data,
'is_preserve': is_preserve,
'is_save_state': is_save_state}
'is_save_state': is_save_state,
'got_exceptions': self.GOT_EXCEPTIONS}
for service in self.global_services:
svc = service(admin_mgr, **kwargs)
svc.run()
@ -200,7 +205,8 @@ class TempestCleanup(command.Command):
'saved_state_json': self.json_data,
'is_preserve': is_preserve,
'is_save_state': False,
'project_id': project_id}
'project_id': project_id,
'got_exceptions': self.GOT_EXCEPTIONS}
for service in self.project_services:
svc = service(mgr, **kwargs)
svc.run()
@ -300,7 +306,8 @@ class TempestCleanup(command.Command):
'is_dry_run': False,
'saved_state_json': data,
'is_preserve': False,
'is_save_state': True}
'is_save_state': True,
'got_exceptions': self.GOT_EXCEPTIONS}
for service in self.global_services:
svc = service(admin_mgr, **kwargs)
svc.run()

View File

@ -22,6 +22,7 @@ from tempest.common import identity
from tempest.common import utils
from tempest.common.utils import net_info
from tempest import config
from tempest.lib import exceptions
LOG = logging.getLogger(__name__)
CONF = config.CONF
@ -127,12 +128,23 @@ class BaseService(object):
pass
def run(self):
if self.is_dry_run:
self.dry_run()
elif self.is_save_state:
self.save_state()
else:
self.delete()
try:
if self.is_dry_run:
self.dry_run()
elif self.is_save_state:
self.save_state()
else:
self.delete()
except exceptions.NotImplemented as exc:
# Many OpenStack services use extensions logic to implement the
# features or resources. Tempest cleanup tries to clean up the test
# resources without having much logic of extensions checks etc.
# If any of the extension is missing then, service will return
# NotImplemented error.
msg = ("Got NotImplemented error in %s, full exception: %s" %
(str(self.__class__), str(exc)))
LOG.exception(msg)
self.got_exceptions.append(msg)
class SnapshotService(BaseService):

View File

@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import mock
from tempest.cmd import cleanup
from tempest.tests import base
@ -24,3 +26,17 @@ class TestTempestCleanup(base.TestCase):
test_saved_json = 'tempest/tests/cmd/test_saved_state_json.json'
# test if the file is loaded without any issues/exceptions
c._load_json(test_saved_json)
@mock.patch('tempest.cmd.cleanup.TempestCleanup.init')
@mock.patch('tempest.cmd.cleanup.TempestCleanup._cleanup')
def test_take_action_got_exception(self, mock_cleanup, mock_init):
c = cleanup.TempestCleanup(None, None, 'test')
c.GOT_EXCEPTIONS.append('exception')
mock_cleanup.return_value = True
mock_init.return_value = True
try:
c.take_action(mock.Mock())
except Exception as exc:
self.assertEqual(str(exc), '[\'exception\']')
return
assert False

View File

@ -19,6 +19,7 @@ from oslo_serialization import jsonutils as json
from tempest import clients
from tempest.cmd import cleanup_service
from tempest import config
from tempest.lib import exceptions
from tempest.tests import base
from tempest.tests import fake_config
from tempest.tests.lib import fake_credentials
@ -27,13 +28,24 @@ from tempest.tests.lib import fake_http
class TestBaseService(base.TestCase):
class TestException(cleanup_service.BaseService):
def delete(self):
raise exceptions.NotImplemented
def dry_run(self):
raise exceptions.NotImplemented
def save_state(self):
raise exceptions.NotImplemented
def test_base_service_init(self):
kwargs = {'data': {'data': 'test'},
'is_dry_run': False,
'saved_state_json': {'saved': 'data'},
'is_preserve': False,
'is_save_state': True,
'tenant_id': 'project_id'}
'tenant_id': 'project_id',
'got_exceptions': []}
base = cleanup_service.BaseService(kwargs)
self.assertEqual(base.data, kwargs['data'])
self.assertFalse(base.is_dry_run)
@ -41,6 +53,28 @@ class TestBaseService(base.TestCase):
self.assertFalse(base.is_preserve)
self.assertTrue(base.is_save_state)
self.assertEqual(base.tenant_filter['project_id'], kwargs['tenant_id'])
self.assertEqual(base.got_exceptions, kwargs['got_exceptions'])
def test_not_implemented_ex(self):
kwargs = {'data': {'data': 'test'},
'is_dry_run': False,
'saved_state_json': {'saved': 'data'},
'is_preserve': False,
'is_save_state': False,
'tenant_id': 'project_id',
'got_exceptions': []}
base = self.TestException(kwargs)
# delete
base.run()
self.assertEqual(len(base.got_exceptions), 1)
# save_state
base.save_state = True
base.run()
self.assertEqual(len(base.got_exceptions), 2)
# dry_run
base.is_dry_run = True
base.run()
self.assertEqual(len(base.got_exceptions), 3)
class MockFunctionsBase(base.TestCase):