Files
deb-python-tempest-lib/tempest_lib/common/utils/misc.py
Ken'ichi Ohmichi 84dee6b781 Migrate rest_client to tempest-lib from tempest
This patch migrates rest_client module to tempest-lib from tempest.

The latest Change-Ids of each file are the following when this migration:
 * common/http.py             : I43703e2289212389c7841f44691ae7849ed1f505
 * common/rest_client.py      : Ie9105b5d01e7883213c1d3398cc5fe56782920d9
 * common/utils/misc.py       : I9a591eaa1cf4dabba58f06a64814611a05a51365
 * exceptions.py              : Ic8fc216377942619f11a2462b79d0597071ac294
 * tests/base.py              : I8f14cd2ca6afc38d3fe8ee758272071111022896
 * tests/fake_auth_provider.py: Id12341de52204e2c428e10b4b758b700b0fbab09
 * tests/fake_http.py         : I8f14cd2ca6afc38d3fe8ee758272071111022896
 * tests/test_rest_client.py  : Ie9105b5d01e7883213c1d3398cc5fe56782920d9

NOTE: Some docstrings are changed to avoid H404 and H405.

Change-Id: I879a02681c99376ae57458a0f7a04c8032dfebb2
2015-01-16 04:40:00 +00:00

88 lines
3.0 KiB
Python

# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# 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 inspect
import re
from tempest_lib.openstack.common import log as logging
LOG = logging.getLogger(__name__)
def singleton(cls):
"""Simple wrapper for classes that should only have a single instance."""
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
def find_test_caller():
"""Find the caller class and test name.
Because we know that the interesting things that call us are
test_* methods, and various kinds of setUp / tearDown, we
can look through the call stack to find appropriate methods,
and the class we were in when those were called.
"""
caller_name = None
names = []
frame = inspect.currentframe()
is_cleanup = False
# Start climbing the ladder until we hit a good method
while True:
try:
frame = frame.f_back
name = frame.f_code.co_name
names.append(name)
if re.search("^(test_|setUp|tearDown)", name):
cname = ""
if 'self' in frame.f_locals:
cname = frame.f_locals['self'].__class__.__name__
if 'cls' in frame.f_locals:
cname = frame.f_locals['cls'].__name__
caller_name = cname + ":" + name
break
elif re.search("^_run_cleanup", name):
is_cleanup = True
elif name == 'main':
caller_name = 'main'
break
else:
cname = ""
if 'self' in frame.f_locals:
cname = frame.f_locals['self'].__class__.__name__
if 'cls' in frame.f_locals:
cname = frame.f_locals['cls'].__name__
# the fact that we are running cleanups is indicated pretty
# deep in the stack, so if we see that we want to just
# start looking for a real class name, and declare victory
# once we do.
if is_cleanup and cname:
if not re.search("^RunTest", cname):
caller_name = cname + ":_run_cleanups"
break
except Exception:
break
# prevents frame leaks
del frame
if caller_name is None:
LOG.debug("Sane call name not found in %s" % names)
return caller_name