
Added wrapper classes which are inherited from base data types str, list, tuple and dict. Each of these wrapper classes and the Resource class contain a 'request_ids' attribute which is populated with a 'x-compute-request-id' or a 'x-openstack-request-id' received in a header from a response body. This change is required to return 'request_id' from client to log request_id mappings of cross projects. This patch is one of a series of patches for implementing return-request-id-to-caller. Co-authored-by: Ankit Agrawal <ankit11.agrawal@nttdata.com> Change-Id: I422c4f4ee59991ca89a0a16f548b537c8b61bb97 Implements: blueprint return-request-id-to-caller
138 lines
5.0 KiB
Python
138 lines
5.0 KiB
Python
#
|
|
# 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.
|
|
|
|
"""
|
|
A fake server that "responds" to API methods with pre-canned responses.
|
|
|
|
All of these responses come from the spec, so if for some reason the spec's
|
|
wrong the tests might raise AssertionError. I've indicated in comments the
|
|
places where actual behavior differs from the spec.
|
|
"""
|
|
|
|
from novaclient import base
|
|
|
|
# fake request id
|
|
FAKE_REQUEST_ID = 'req-3fdea7c2-e3e3-48b5-a656-6b12504c49a1'
|
|
FAKE_REQUEST_ID_LIST = [FAKE_REQUEST_ID]
|
|
|
|
|
|
def assert_has_keys(dict, required=None, optional=None):
|
|
required = required or []
|
|
optional = optional or []
|
|
keys = dict.keys()
|
|
for k in required:
|
|
try:
|
|
assert k in keys
|
|
except AssertionError:
|
|
extra_keys = set(keys).difference(set(required + optional))
|
|
raise AssertionError("found unexpected keys: %s" %
|
|
list(extra_keys))
|
|
|
|
|
|
class FakeClient(object):
|
|
|
|
def assert_called(self, method, url, body=None, pos=-1):
|
|
"""Assert than an HTTP method was called at given order/position.
|
|
|
|
:param method: HTTP method name which is expected to be called
|
|
:param url: Expected request url to be called with given method
|
|
:param body: Expected request body to be called with given method
|
|
and url. Default is None.
|
|
:param pos: Order of the expected method call. If multiple methods
|
|
calls are made in single API request, then, order of each
|
|
method call can be checked by passing expected order to
|
|
this arg.
|
|
Default is -1 which means most recent call.
|
|
|
|
Usage::
|
|
1. self.run_command('flavor-list --extra-specs')
|
|
self.assert_called('GET', '/flavors/aa1/os-extra_specs')
|
|
|
|
2. self.run_command(["boot", "--image", "1",
|
|
"--flavor", "512 MB Server",
|
|
"--max-count", "3", "server"])
|
|
self.assert_called('GET', '/images/1', pos=0)
|
|
self.assert_called('GET', '/flavors/512 MB Server', pos=1)
|
|
self.assert_called('GET', '/flavors?is_public=None', pos=2)
|
|
self.assert_called('GET', '/flavors/2', pos=3)
|
|
self.assert_called(
|
|
'POST', '/servers',
|
|
{
|
|
'server': {
|
|
'flavorRef': '2',
|
|
'name': 'server',
|
|
'imageRef': '1',
|
|
'min_count': 1,
|
|
'max_count': 3,
|
|
}
|
|
}, pos=4)
|
|
"""
|
|
expected = (method, url)
|
|
called = self.client.callstack[pos][0:2]
|
|
|
|
assert self.client.callstack, \
|
|
"Expected %s %s but no calls were made." % expected
|
|
|
|
assert expected == called, \
|
|
'Expected %s %s; got %s %s' % (expected + called)
|
|
|
|
if body is not None:
|
|
if self.client.callstack[pos][2] != body:
|
|
raise AssertionError('%r != %r' %
|
|
(self.client.callstack[pos][2], body))
|
|
|
|
def assert_called_anytime(self, method, url, body=None):
|
|
"""Assert than an HTTP method was called anytime in the test.
|
|
|
|
:param method: HTTP method name which is expected to be called
|
|
:param url: Expected request url to be called with given method
|
|
:param body: Expected request body to be called with given method
|
|
and url. Default is None.
|
|
Usage::
|
|
self.run_command('flavor-list --extra-specs')
|
|
self.assert_called_anytime('GET', '/flavors/detail')
|
|
"""
|
|
expected = (method, url)
|
|
|
|
assert self.client.callstack, \
|
|
"Expected %s %s but no calls were made." % expected
|
|
|
|
found = False
|
|
for entry in self.client.callstack:
|
|
if expected == entry[0:2]:
|
|
found = True
|
|
break
|
|
|
|
assert found, 'Expected %s; got %s' % (expected, self.client.callstack)
|
|
if body is not None:
|
|
try:
|
|
assert entry[2] == body
|
|
except AssertionError:
|
|
print(entry[2])
|
|
print("!=")
|
|
print(body)
|
|
raise
|
|
|
|
self.client.callstack = []
|
|
|
|
def clear_callstack(self):
|
|
self.client.callstack = []
|
|
|
|
def authenticate(self):
|
|
pass
|
|
|
|
|
|
# Fake class that will be used as an extension
|
|
class FakeManager(base.Manager):
|
|
pass
|