Tempest学习笔记 006:Tempest源码阅读—tearDownClass()

1 tearDownClass()流程

在这里插入图片描述

@classmethod
def tearDownClass(cls):
    # insert pdb breakpoint when pause_teardown is enabled
    if CONF.pause_teardown:
        cls.insert_pdb_breakpoint()
    at_exit_set.discard(cls)
    # It should never be overridden by descendants
    if hasattr(super(BaseTestCase, cls), 'tearDownClass'):
        super(BaseTestCase, cls).tearDownClass()
    # Save any existing exception, we always want to re-raise the original
    # exception only
    etype, value, trace = sys.exc_info()
    # If there was no exception during setup we shall re-raise the first
    # exception in teardown
    re_raise = (etype is None)
    while cls._teardowns:
        name, teardown = cls._teardowns.pop()
        # Catch any exception in tearDown so we can re-raise the original
        # exception at the end
        try:
            teardown()
            if name == 'resources':
                if not cls.__resource_cleanup_called:
                    raise RuntimeError(
                        "resource_cleanup for %s did not call the "
                        "super's resource_cleanup" % cls.__name__)
        except Exception as te:
            sys_exec_info = sys.exc_info()
            tetype = sys_exec_info[0]
            # TODO(andreaf): Resource cleanup is often implemented by
            # storing an array of resources at class level, and cleaning
            # them up during `resource_cleanup`.
            # In case of failure during setup, some resource arrays might
            # not be defined at all, in which case the cleanup code might
            # trigger an AttributeError. In such cases we log
            # AttributeError as info instead of exception. Once all
            # cleanups are migrated to addClassResourceCleanup we can
            # remove this.
            if tetype is AttributeError and name == 'resources':
                LOG.info("tearDownClass of %s failed: %s", name, te)
            else:
                LOG.exception("teardown of %s failed: %s", name, te)
            if not etype:
                etype, value, trace = sys_exec_info
    # If exceptions were raised during teardown, and not before, re-raise
    # the first one
    if re_raise and etype is not None:
        try:
            six.reraise(etype, value, trace)
        finally:
            del trace  # to avoid circular refs

tearDownClass()首先根据配置文件的设置插入pdb断点,在这里加入断点方便资源清理前对结果的分析。
清空at_exit_set,at_exit_set结合validate_tearDownClass函数和atexit,确保即使测试过程中发生异常也能够执行tearDownClass函数来完成资源清理。
cls._teardowns可以理解为栈,其中保存了两个函数cls.resource_cleanup()和cls.clear_credentials()。这两个函数分别用于清理测试资源和凭证资源(如:租户、用户等)。

2 resource_cleanup

@classmethod
def resource_cleanup(cls):        
    cls.__resource_cleanup_called = True
    cleanup_errors = []
    while cls._class_cleanups:
        try:
            fn, args, kwargs = cls._class_cleanups.pop()
            fn(*args, **kwargs)
        except Exception:
            cleanup_errors.append(sys.exc_info())
    if cleanup_errors:
        raise testtools.MultipleExceptions(*cleanup_errors)

cls._class_cleanups中保存了待执行的资源删除函数,如删除虚机、删除卷等,以函数名,位置参数,关键字参数的三元组形式保存。测试用例的编写过程中创建资源完成后会立即调用cls.addClassResourceCleanup(),将删除资源的信息写入cls._class_cleanups。
整个cls.resource_cleanup()主要是循环执行cls._class_cleanups中的删除操作,执行资源删除前从cls._class_cleanups弹出相关元组。

3 clear_credentials

def clear_creds(self):
    if not self._creds:
        return
    self._clear_isolated_net_resources()
    for creds in six.itervalues(self._creds):
        try:
            self.creds_client.delete_user(creds.user_id)
        except lib_exc.NotFound:
            LOG.warning("user with name: %s not found for delete",
                        creds.username)
        # NOTE(zhufl): Only when neutron's security_group ext is
        # enabled, _cleanup_default_secgroup will not raise error. But
        # here cannot use test_utils.is_extension_enabled for it will cause
        # "circular dependency". So here just use try...except to
        # ensure tenant deletion without big changes.
        try:
            if self.neutron_available:
                self._cleanup_default_secgroup(creds.tenant_id)
        except lib_exc.NotFound:
            LOG.warning("failed to cleanup tenant %s's secgroup",
                        creds.tenant_name)
        try:
            self.creds_client.delete_project(creds.tenant_id)
        except lib_exc.NotFound:
            LOG.warning("tenant with name: %s not found for delete",
                        creds.tenant_name)
    self._creds = {}

self._creds中保存有凭证信息,self.clear_creds函数删除每个租户的默认安全组和凭证信息。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值