add _find_caller to the request log
inspect the call stack to find the part of the test class that
called this rest request. This makes it easier to start from
the tempest log and figure out what rest calls were being made
over the various services, and how the succeeded or not.
Change-Id: Icfd08d5b35a4fd3fdde93042e158ee42424899bf
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 7d90d69..4cc7338 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -15,6 +15,7 @@
# under the License.
import collections
+import inspect
import json
from lxml import etree
import re
@@ -223,6 +224,57 @@
versions = map(lambda x: x['id'], body)
return resp, versions
+ def _find_caller(self):
+ """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
+ 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:
+ self.LOG.debug("Sane call name not found in %s" % names)
+ return caller_name
+
def _get_request_id(self, resp):
for i in ('x-openstack-request-id', 'x-compute-request-id'):
if i in resp:
@@ -232,7 +284,8 @@
def _log_request(self, method, req_url, resp):
extra = dict(request_id=self._get_request_id(resp))
self.LOG.info(
- 'Request: %s %s %s' % (
+ 'Request (%s): %s %s %s' % (
+ self._find_caller(),
resp['status'],
method,
req_url),