python-troveclient/troveclient/tests/fakes.py

628 lines
22 KiB
Python

# Copyright [2015] Hewlett-Packard Development Company, L.P.
#
# 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.
from six.moves.urllib import parse
from troveclient import client as base_client
from troveclient.tests import utils
from troveclient.v1 import client
def get_version_map():
return {
'1.0': 'troveclient.tests.fakes.FakeClient',
}
def assert_has_keys(dict, required=[], optional=[]):
keys = dict.keys()
for k in required:
try:
assert k in keys
except AssertionError:
raise AssertionError("key: %s not found." % k)
class FakeClient(client.Client):
URL_QUERY_SEPARATOR = '&'
URL_SEPARATOR = '?'
def __init__(self, *args, **kwargs):
client.Client.__init__(self, 'username', 'password',
'project_id', 'auth_url',
extensions=kwargs.get('extensions'))
self.client = FakeHTTPClient(**kwargs)
def _order_url_query_str(self, url):
"""Returns the url with the query strings ordered, if they exist and
there's more than one. Otherwise the url is returned unaltered.
"""
if self.URL_QUERY_SEPARATOR in url:
parts = url.split(self.URL_SEPARATOR)
if len(parts) == 2:
queries = sorted(parts[1].split(self.URL_QUERY_SEPARATOR))
url = self.URL_SEPARATOR.join(
[parts[0], self.URL_QUERY_SEPARATOR.join(queries)])
return url
def assert_called(self, method, url, body=None, pos=-1):
"""Assert than an API method was just called."""
expected = (method, utils.order_url(url))
called = (self.client.callstack[pos][0],
utils.order_url(self.client.callstack[pos][1]))
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 API method was called anytime in the test."""
expected = (method, utils.order_url(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], utils.order_url(entry[1])):
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 = []
class FakeHTTPClient(base_client.HTTPClient):
def __init__(self, **kwargs):
self.username = 'username'
self.password = 'password'
self.auth_url = 'auth_url'
self.management_url = (
'http://trove-api:8779/v1.0/14630bc0e9ef4e248c9753eaf57b0f6e')
self.tenant_id = 'tenant_id'
self.callstack = []
self.projectid = 'projectid'
self.user = 'user'
self.region_name = 'region_name'
self.endpoint_type = 'endpoint_type'
self.service_type = 'service_type'
self.service_name = 'service_name'
self.volume_service_name = 'volume_service_name'
self.timings = 'timings'
self.bypass_url = 'bypass_url'
self.os_cache = 'os_cache'
self.http_log_debug = 'http_log_debug'
def _cs_request(self, url, method, **kwargs):
# Check that certain things are called correctly
if method in ['GET', 'DELETE']:
assert 'body' not in kwargs
elif method == 'PUT':
assert 'body' in kwargs
if url is not None:
# Call the method
args = parse.parse_qsl(parse.urlparse(url)[4])
kwargs.update(args)
munged_url = url.rsplit('?', 1)[0]
munged_url = munged_url.strip('/').replace('/', '_')
munged_url = munged_url.replace('.', '_')
munged_url = munged_url.replace('-', '_')
munged_url = munged_url.replace(' ', '_')
callback = "%s_%s" % (method.lower(), munged_url)
if not hasattr(self, callback):
raise AssertionError('Called unknown API method: %s %s, '
'expected fakes method name: %s' %
(method, url, callback))
# Note the call
self.callstack.append((method, url, kwargs.get('body')))
status, headers, body = getattr(self, callback)(**kwargs)
r = utils.TestResponse({
"status_code": status,
"text": body,
"headers": headers,
})
return r, body
def get_instances(self, **kw):
return (200, {}, {"instances": [
{
"id": "1234",
"name": "test-member-1",
"status": "ACTIVE",
"ip": ["10.0.0.13"],
"volume": {"size": 2},
"flavor": {"id": "2"},
"datastore": {"version": "5.6", "type": "mysql"}},
{
"id": "5678",
"name": "test-member-2",
"status": "ACTIVE",
"ip": ["10.0.0.14"],
"volume": {"size": 2},
"flavor": {"id": "2"},
"datastore": {"version": "5.6", "type": "mysql"}}]})
def get_instances_1234(self, **kw):
r = {'instance': self.get_instances()[2]['instances'][0]}
return (200, {}, r)
def post_instances(self, body, **kw):
assert_has_keys(
body['instance'],
required=['name', 'flavorRef'],
optional=['volume'])
if 'volume' in body['instance']:
assert_has_keys(body['instance']['volume'], required=['size'])
return (202, {}, self.get_instances_1234()[2])
def get_flavors(self, **kw):
return (200, {}, {"flavors": [
{
"str_id": "1",
"ram": 512,
"id": 1,
"name": "m1.tiny"},
{
"str_id": "10",
"ram": 768,
"id": 10,
"name": "eph.rd-smaller"},
{
"str_id": "2",
"ram": 2048,
"id": 2,
"name": "m1.small"},
{
"str_id": "3",
"ram": 4096,
"id": 3,
"name": "m1.medium"},
{
"str_id": "7d0d16e5-875f-4198-b6da-90ab2d3e899e",
"ram": 8192,
"id": None,
"name": "m1.uuid"}]})
def get_datastores_mysql_versions_some_version_id_flavors(self, **kw):
return self.get_flavors()
def get_flavors_1(self, **kw):
r = {'flavor': self.get_flavors()[2]['flavors'][0]}
return (200, {}, r)
def get_flavors_2(self, **kw):
r = {'flavor': self.get_flavors()[2]['flavors'][2]}
return (200, {}, r)
def get_flavors_m1_tiny(self, **kw):
r = {'flavor': self.get_flavors()[2]['flavors'][0]}
return (200, {}, r)
def get_flavors_m1_small(self, **kw):
r = {'flavor': self.get_flavors()[2]['flavors'][2]}
return (200, {}, r)
def get_flavors_m1_uuid(self, **kw):
r = {'flavor': self.get_flavors()[2]['flavors'][4]}
return (200, {}, r)
def get_clusters(self, **kw):
return (200, {}, {"clusters": [
{
"instances": [
{
"type": "member",
"id": "member-1",
"ip": ["10.0.0.3"],
"flavor": {"id": "2"},
"name": "test-clstr-member-1"
},
{
"type": "member",
"id": "member-2",
"ip": ["10.0.0.4"],
"flavor": {"id": "2"},
"name": "test-clstr-member-2"
}],
"updated": "2015-05-02T11:06:19",
"task": {"description": "No tasks for the cluster.", "id": 1,
"name": "NONE"},
"name": "test-clstr",
"created": "2015-05-02T10:37:04",
"datastore": {"version": "7.1", "type": "vertica"},
"id": "cls-1234"}]})
def get_clusters_cls_1234(self, **kw):
r = {'cluster': self.get_clusters()[2]['clusters'][0]}
return (200, {}, r)
def delete_instances_1234(self, **kw):
return (202, {}, None)
def delete_clusters_cls_1234(self, **kw):
return (202, {}, None)
def patch_instances_1234(self, **kw):
return (202, {}, None)
def post_clusters(self, body, **kw):
assert_has_keys(
body['cluster'],
required=['instances', 'datastore', 'name'])
if 'instances' in body['cluster']:
for instance in body['cluster']['instances']:
assert_has_keys(instance, required=['volume', 'flavorRef'])
return (202, {}, self.get_clusters_cls_1234()[2])
def post_clusters_cls_1234(self, body, **kw):
return (202, {}, None)
def post_instances_1234_action(self, **kw):
return (202, {}, None)
def get_datastores(self, **kw):
return (200, {}, {"datastores": [
{
"default_version": "v-56",
"versions": [{"id": "v-56", "name": "5.6"}],
"id": "d-123",
"name": "mysql"},
{
"default_version": "v-71",
"versions": [{"id": "v-71", "name": "7.1"}],
"id": "d-456",
"name": "vertica"
}]})
def get_datastores_d_123(self, **kw):
r = {'datastore': self.get_datastores()[2]['datastores'][0]}
return (200, {}, r)
def get_datastores_d_123_versions(self, **kw):
return (200, {}, {"versions": [
{
"datastore": "d-123",
"id": "v-56",
"name": "5.6"}]})
def get_datastores_d_123_versions_v_56(self, **kw):
r = {'version': self.get_datastores_d_123_versions()[2]['versions'][0]}
return (200, {}, r)
def get_configurations(self, **kw):
return (200, {}, {"configurations": [
{
"datastore_name": "mysql",
"updated": "2015-05-16T10:24:29",
"name": "test_config",
"created": "2015-05-16T10:24:28",
"datastore_version_name": "5.6",
"id": "c-123",
"values": {"max_connections": 5},
"datastore_version_id": "d-123", "description": ''}]})
def get_configurations_c_123(self, **kw):
r = {'configuration': self.get_configurations()[2]['configurations'][0]
}
return (200, {}, r)
def get_datastores_d_123_versions_v_156_parameters(self, **kw):
return (200, {}, {"configuration-parameters": [
{
"type": "string",
"name": "character_set_results",
"datastore_version_id": "d-123",
"restart_required": "false"},
{
"name": "connect_timeout",
"min": 2,
"max": 31536000,
"restart_required": "false",
"type": "integer",
"datastore_version_id": "d-123"},
{
"type": "string",
"name": "character_set_client",
"datastore_version_id": "d-123",
"restart_required": "false"},
{
"name": "max_connections",
"min": 1,
"max": 100000,
"restart_required": "false",
"type": "integer",
"datastore_version_id": "d-123"}]})
def get_datastores_d_123_versions_v_56_parameters_max_connections(self,
**kw):
r = self.get_datastores_d_123_versions_v_156_parameters()[
2]['configuration-parameters'][3]
return (200, {}, r)
def get_configurations_c_123_instances(self, **kw):
return (200, {}, {"instances": []})
def delete_configurations_c_123(self, **kw):
return (202, {}, None)
def get_instances_1234_configuration(self, **kw):
return (200, {}, {"instance": {"configuration": {
"tmp_table_size": "15M",
"innodb_log_files_in_group": "2",
"skip-external-locking": "1",
"max_user_connections": "98"}}})
def put_instances_1234(self, **kw):
return (202, {}, None)
def patch_instances_1234_metadata_key_123(self, **kw):
return (202, {}, None)
def put_instances_1234_metadata_key_123(self, **kw):
return (202, {}, None)
def delete_instances_1234_metadata_key_123(self, **kw):
return (202, {}, None)
def post_instances_1234_metadata_key123(self, body, **kw):
return (202, {}, {'metadata': {}})
def get_instances_1234_metadata(self, **kw):
return (200, {}, {"metadata": {}})
def get_instances_1234_metadata_key123(self, **kw):
return (200, {}, {"metadata": {}})
def get_modules(self, **kw):
return (200, {}, {"modules": [
{
"id": "4321",
"name": "mod1",
"type": "ping",
"datastore": 'all',
"datastore_version": 'all',
"tenant": 'all',
"auto_apply": 0,
"visible": 1},
{
"id": "8765",
"name": "mod2",
"type": "ping",
"datastore": 'all',
"datastore_version": 'all',
"tenant": 'all',
"auto_apply": 0,
"visible": 1}]})
def get_modules_4321(self, **kw):
r = {'module': self.get_modules()[2]['modules'][0]}
return (200, {}, r)
def get_modules_8765(self, **kw):
r = {'module': self.get_modules()[2]['modules'][1]}
return (200, {}, r)
def post_modules(self, **kw):
r = {'module': self.get_modules()[2]['modules'][0]}
return (200, {}, r)
def put_modules_4321(self, **kw):
return (200, {}, {"module": {'name': 'mod3'}})
def delete_modules_4321(self, **kw):
return (200, {}, None)
def get_instances_1234_modules(self, **kw):
return (200, {}, {"modules": [{"module": {}}]})
def get_modules_4321_instances(self, **kw):
return self.get_instances()
def get_instances_modules(self, **kw):
return (200, {}, None)
def get_instances_member_1_modules(self, **kw):
return self.get_modules()
def get_instances_member_2_modules(self, **kw):
return self.get_modules()
def post_instances_1234_modules(self, **kw):
r = {'modules': [self.get_modules()[2]['modules'][0]]}
return (200, {}, r)
def delete_instances_1234_modules_4321(self, **kw):
return (200, {}, None)
def get_limits(self, **kw):
return (200, {}, {"limits": [
{
"max_backups": 50,
"verb": "ABSOLUTE",
"max_volumes": 20,
"max_instances": 5}]})
def get_backups(self, **kw):
return (200, {}, {"backups": [
{
"status": "COMPLETED",
"updated": "2015-05-16T14:23:08",
"description": None,
"datastore": {"version": "5.6", "type": "mysql",
"version_id": "v-56"},
"id": "bk-1234",
"size": 0.11,
"name": "bkp_1",
"created": "2015-05-16T14:22:28",
"instance_id": "1234",
"parent_id": None,
"locationRef": ("http://backup_srvr/database_backups/"
"bk-1234.xbstream.gz.enc")},
{
"status": "COMPLETED",
"updated": "2015-05-16T14:22:12",
"description": None,
"datastore": {"version": "5.6", "type": "mysql",
"version_id": "v-56"},
"id": "bk-5678",
"size": 0.11,
"name": "test_bkp",
"created": "2015-05-16T14:21:27",
"instance_id": "5678",
"parent_id": None,
"locationRef": ("http://backup_srvr/database_backups/"
"bk-5678.xbstream.gz.enc")}]})
def get_backups_bk_1234(self, **kw):
r = {'backup': self.get_backups()[2]['backups'][0]}
return (200, {}, r)
def get_instances_1234_backups(self, **kw):
r = {'backups': [self.get_backups()[2]['backups'][0]]}
return (200, {}, r)
def delete_backups_bk_1234(self, **kw):
return (202, {}, None)
def post_backups(self, body, **kw):
assert_has_keys(
body['backup'],
required=['name'],
optional=['description', 'parent'])
return (202, {}, self.get_backups_bk_1234()[2])
def get_instances_1234_databases(self, **kw):
return (200, {}, {"databases": [
{"name": "db_1"},
{"name": "db_2"},
{"name": "performance_schema"}]})
def delete_instances_1234_databases_db_1(self, **kw):
return (202, {}, None)
def post_instances_1234_databases(self, body, **kw):
assert_has_keys(
body,
required=['databases'])
for database in body['databases']:
assert_has_keys(database, required=['name'],
optional=['character_set', 'collate'])
return (202, {},
self.get_instances_1234_databases()[2]['databases'][0])
def get_instances_1234_users(self, **kw):
return (200, {}, {"users": [
{"host": "%", "name": "jacob", "databases": []},
{"host": "%", "name": "rocky", "databases": []},
{"host": "%", "name": "harry", "databases": [{"name": "db1"}]}]})
def get_instances_1234_users_jacob(self, **kw):
r = {'user': self.get_instances_1234_users()[2]['users'][0]}
return (200, {}, r)
def delete_instances_1234_users_jacob(self, **kw):
return (202, {}, None)
def post_instances_1234_users(self, body, **kw):
assert_has_keys(
body,
required=['users'])
for database in body['users']:
assert_has_keys(database, required=['name', 'password'],
optional=['databases'])
return (202, {}, self.get_instances_1234_users()[2]['users'][0])
def get_instances_1234_users_jacob_databases(self, **kw):
r = {'databases': [
self.get_instances_1234_databases()[2]['databases'][0],
self.get_instances_1234_databases()[2]['databases'][1]]}
return (200, {}, r)
def put_instances_1234_users_jacob(self, **kw):
return (202, {}, None)
def put_instances_1234_users_jacob_databases(self, **kw):
return (202, {}, None)
def delete_instances_1234_users_jacob_databases_db1(self, **kw):
return (202, {}, None)
def post_instances_1234_root(self, **kw):
return (202, {}, {"user": {"password": "password", "name": "root"}})
def post_clusters_cls_1234_root(self, **kw):
return (202, {}, {"user": {"password": "password", "name": "root"}})
def delete_instances_1234_root(self, **kw):
return (202, {}, None)
def get_instances_1234_root(self, **kw):
return (200, {}, {"rootEnabled": 'True'})
def get_clusters_cls_1234_root(self, **kw):
return (200, {}, {"rootEnabled": 'True'})
def get_security_groups(self, **kw):
return (200, {}, {"security_groups": [
{
"instance_id": "1234",
"updated": "2015-05-16T17:29:45",
"name": "SecGroup_1234",
"created": "2015-05-16T17:29:45",
"rules": [{"to_port": 3306, "cidr": "0.0.0.0/0",
"from_port": 3306,
"protocol": "tcp", "id": "1"}],
"id": "2",
"description": "Security Group for 1234"}]})
def get_security_groups_2(self, **kw):
r = {'security_group': self.get_security_groups()[
2]['security_groups'][0]}
return (200, {}, r)
def delete_security_group_rules_2(self, **kw):
return (202, {}, None)
def post_security_group_rules(self, body, **kw):
assert_has_keys(body['security_group_rule'], required=['cidr', 'cidr'])
return (202, {}, {"security_group_rule": [
{
"from_port": 3306,
"protocol": "tcp",
"created": "2015-05-16T17:55:05",
"to_port": 3306,
"security_group_id": "2",
"cidr": "15.0.0.0/24", "id": 3}]})