229 lines
9.3 KiB
Python
229 lines
9.3 KiB
Python
# Copyright 2015 Tesora Inc.
|
|
# 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.
|
|
|
|
from proboscis import SkipTest
|
|
|
|
from trove.common import exception
|
|
from trove.common.utils import poll_until
|
|
from trove.tests.scenario import runners
|
|
from trove.tests.scenario.runners.test_runners import SkipKnownBug
|
|
from trove.tests.scenario.runners.test_runners import TestRunner
|
|
from troveclient.compat import exceptions
|
|
|
|
|
|
class DatabaseActionsRunner(TestRunner):
|
|
|
|
def __init__(self):
|
|
super(DatabaseActionsRunner, self).__init__()
|
|
self.db_defs = []
|
|
|
|
@property
|
|
def first_db_def(self):
|
|
if self.db_defs:
|
|
return self.db_defs[0]
|
|
raise SkipTest("No valid database definitions provided.")
|
|
|
|
@property
|
|
def non_existing_db_def(self):
|
|
db_def = self.test_helper.get_non_existing_database_definition()
|
|
if db_def:
|
|
return db_def
|
|
raise SkipTest("No valid database definitions provided.")
|
|
|
|
def run_databases_create(self, expected_http_code=202):
|
|
databases = self.test_helper.get_valid_database_definitions()
|
|
if databases:
|
|
self.db_defs = self.assert_databases_create(
|
|
self.instance_info.id, databases, expected_http_code)
|
|
else:
|
|
raise SkipTest("No valid database definitions provided.")
|
|
|
|
def assert_databases_create(self, instance_id, serial_databases_def,
|
|
expected_http_code):
|
|
client = self.auth_client
|
|
client.databases.create(instance_id, serial_databases_def)
|
|
self.assert_client_code(client, expected_http_code)
|
|
self.wait_for_database_create(client,
|
|
instance_id, serial_databases_def)
|
|
return serial_databases_def
|
|
|
|
def run_databases_list(self, expected_http_code=200):
|
|
self.assert_databases_list(
|
|
self.instance_info.id, self.db_defs, expected_http_code)
|
|
|
|
def assert_databases_list(self, instance_id, expected_database_defs,
|
|
expected_http_code, limit=2):
|
|
client = self.auth_client
|
|
full_list = client.databases.list(instance_id)
|
|
self.assert_client_code(client, expected_http_code)
|
|
listed_databases = {database.name: database for database in full_list}
|
|
self.assert_is_none(full_list.next,
|
|
"Unexpected pagination in the list.")
|
|
|
|
for database_def in expected_database_defs:
|
|
database_name = database_def['name']
|
|
self.assert_true(
|
|
database_name in listed_databases,
|
|
"Database not included in the 'database-list' output: %s" %
|
|
database_name)
|
|
|
|
# Check that the system (ignored) databases are not included in the
|
|
# output.
|
|
system_databases = self.get_system_databases()
|
|
self.assert_false(
|
|
any(name in listed_databases for name in system_databases),
|
|
"System databases should not be included in the 'database-list' "
|
|
"output.")
|
|
|
|
# Test list pagination.
|
|
list_page = client.databases.list(instance_id, limit=limit)
|
|
self.assert_client_code(client, expected_http_code)
|
|
|
|
self.assert_true(len(list_page) <= limit)
|
|
if len(full_list) > limit:
|
|
self.assert_is_not_none(list_page.next, "List page is missing.")
|
|
else:
|
|
self.assert_is_none(list_page.next, "An extra page in the list.")
|
|
marker = list_page.next
|
|
|
|
self.assert_pagination_match(list_page, full_list, 0, limit)
|
|
if marker:
|
|
last_database = list_page[-1]
|
|
expected_marker = last_database.name
|
|
self.assert_equal(expected_marker, marker,
|
|
"Pagination marker should be the last element "
|
|
"in the page.")
|
|
list_page = client.databases.list(
|
|
instance_id, marker=marker)
|
|
self.assert_client_code(client, expected_http_code)
|
|
self.assert_pagination_match(
|
|
list_page, full_list, limit, len(full_list))
|
|
|
|
def run_database_create_with_no_attributes(
|
|
self, expected_exception=exceptions.BadRequest,
|
|
expected_http_code=400):
|
|
self.assert_databases_create_failure(
|
|
self.instance_info.id, {}, expected_exception, expected_http_code)
|
|
|
|
def run_database_create_with_blank_name(
|
|
self, expected_exception=exceptions.BadRequest,
|
|
expected_http_code=400):
|
|
self.assert_databases_create_failure(
|
|
self.instance_info.id, {'name': ''},
|
|
expected_exception, expected_http_code)
|
|
|
|
def run_existing_database_create(
|
|
self, expected_exception=exceptions.BadRequest,
|
|
expected_http_code=400):
|
|
self.assert_databases_create_failure(
|
|
self.instance_info.id, self.first_db_def,
|
|
expected_exception, expected_http_code)
|
|
|
|
def assert_databases_create_failure(
|
|
self, instance_id, serial_databases_def,
|
|
expected_exception, expected_http_code):
|
|
client = self.auth_client
|
|
self.assert_raises(
|
|
expected_exception,
|
|
expected_http_code,
|
|
client, client.databases.create,
|
|
instance_id,
|
|
serial_databases_def)
|
|
|
|
def run_system_database_create(
|
|
self, expected_exception=exceptions.BadRequest,
|
|
expected_http_code=400):
|
|
# TODO(pmalik): Actions on system users and databases should probably
|
|
# return Forbidden 403 instead. The current error messages are
|
|
# confusing (talking about a malformed request).
|
|
system_databases = self.get_system_databases()
|
|
database_defs = [{'name': name} for name in system_databases]
|
|
if system_databases:
|
|
self.assert_databases_create_failure(
|
|
self.instance_info.id, database_defs,
|
|
expected_exception, expected_http_code)
|
|
|
|
def run_database_delete(self, expected_http_code=202):
|
|
for database_def in self.db_defs:
|
|
self.assert_database_delete(
|
|
self.instance_info.id, database_def['name'],
|
|
expected_http_code)
|
|
|
|
def assert_database_delete(
|
|
self,
|
|
instance_id,
|
|
database_name,
|
|
expected_http_code):
|
|
client = self.auth_client
|
|
client.databases.delete(instance_id, database_name)
|
|
self.assert_client_code(client, expected_http_code)
|
|
self._wait_for_database_delete(client, instance_id, database_name)
|
|
|
|
def _wait_for_database_delete(self, client,
|
|
instance_id, deleted_database_name):
|
|
self.report.log("Waiting for deleted database to disappear from the "
|
|
"listing: %s" % deleted_database_name)
|
|
|
|
def _db_is_gone():
|
|
all_dbs = self.get_db_names(client, instance_id)
|
|
return deleted_database_name not in all_dbs
|
|
|
|
try:
|
|
poll_until(_db_is_gone, time_out=self.GUEST_CAST_WAIT_TIMEOUT_SEC)
|
|
self.report.log("Database is now gone from the instance.")
|
|
except exception.PollTimeOut:
|
|
self.fail("Database still listed after the poll timeout: %ds" %
|
|
self.GUEST_CAST_WAIT_TIMEOUT_SEC)
|
|
|
|
def run_nonexisting_database_delete(
|
|
self, expected_exception=exceptions.NotFound,
|
|
expected_http_code=404):
|
|
self.assert_database_delete_failure(
|
|
self.instance_info.id, self.non_existing_db_def['name'],
|
|
expected_exception, expected_http_code)
|
|
|
|
def run_system_database_delete(
|
|
self, expected_exception=exceptions.BadRequest,
|
|
expected_http_code=400):
|
|
# TODO(pmalik): Actions on system users and databases should probably
|
|
# return Forbidden 403 instead. The current error messages are
|
|
# confusing (talking about a malformed request).
|
|
system_databases = self.get_system_databases()
|
|
if system_databases:
|
|
for name in system_databases:
|
|
self.assert_database_delete_failure(
|
|
self.instance_info.id, name,
|
|
expected_exception, expected_http_code)
|
|
|
|
def assert_database_delete_failure(
|
|
self, instance_id, database_name,
|
|
expected_exception, expected_http_code):
|
|
client = self.auth_client
|
|
self.assert_raises(expected_exception, expected_http_code,
|
|
client, client.databases.delete,
|
|
instance_id, database_name)
|
|
|
|
def get_system_databases(self):
|
|
return self.get_datastore_config_property('ignore_dbs')
|
|
|
|
|
|
class PostgresqlDatabaseActionsRunner(DatabaseActionsRunner):
|
|
|
|
def run_system_database_create(self):
|
|
raise SkipKnownBug(runners.BUG_WRONG_API_VALIDATION)
|
|
|
|
def run_system_database_delete(self):
|
|
raise SkipKnownBug(runners.BUG_WRONG_API_VALIDATION)
|