Improve code coverage and API test cases for Views and Materialized Views. Fixes #5337
parent
29c3c0cf7f
commit
ce14696165
|
@ -13,6 +13,7 @@ New features
|
||||||
Housekeeping
|
Housekeeping
|
||||||
************
|
************
|
||||||
|
|
||||||
|
| `Issue #5337 <https://redmine.postgresql.org/issues/5337>`_ - Improve code coverage and API test cases for Views and Materialized Views.
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
*********
|
*********
|
||||||
|
|
|
@ -73,10 +73,11 @@ class CompoundTriggersAddTestCase(BaseTestGenerator):
|
||||||
"ALTER TABLE %s.%s OWNER TO %s"
|
"ALTER TABLE %s.%s OWNER TO %s"
|
||||||
self.view_name = \
|
self.view_name = \
|
||||||
"view_compound_trigger_%s" % (str(uuid.uuid4())[1:8])
|
"view_compound_trigger_%s" % (str(uuid.uuid4())[1:8])
|
||||||
self.view_id = view_utils.create_view(self.server, self.db_name,
|
self.view_id = compound_trigger_utils.create_view(self.server,
|
||||||
self.schema_name,
|
self.db_name,
|
||||||
view_sql,
|
self.schema_name,
|
||||||
self.view_name)
|
view_sql,
|
||||||
|
self.view_name)
|
||||||
|
|
||||||
def create_compound_trigger(self, object_id):
|
def create_compound_trigger(self, object_id):
|
||||||
return self.tester.post(
|
return self.tester.post(
|
||||||
|
|
|
@ -74,6 +74,49 @@ def create_compound_trigger(server, db_name, schema_name, table_name,
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def create_view(server, db_name, schema_name, sql_query, view_name):
|
||||||
|
"""
|
||||||
|
This function creates a table under provided schema.
|
||||||
|
:param server: server details
|
||||||
|
:type server: dict
|
||||||
|
:param db_name: database name
|
||||||
|
:type db_name: str
|
||||||
|
:param schema_name: schema name
|
||||||
|
:type schema_name: str
|
||||||
|
:param sql_query: sql query to create view
|
||||||
|
:type sql_query: str
|
||||||
|
:param view_name: view name
|
||||||
|
:type view_name: str
|
||||||
|
:return view_id: view id
|
||||||
|
:rtype: int
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
connection = utils.get_db_connection(db_name,
|
||||||
|
server['username'],
|
||||||
|
server['db_password'],
|
||||||
|
server['host'],
|
||||||
|
server['port'],
|
||||||
|
server['sslmode'])
|
||||||
|
old_isolation_level = connection.isolation_level
|
||||||
|
connection.set_isolation_level(0)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
query = sql_query % (schema_name, view_name, schema_name, view_name,
|
||||||
|
server['username'])
|
||||||
|
pg_cursor.execute(query)
|
||||||
|
connection.set_isolation_level(old_isolation_level)
|
||||||
|
connection.commit()
|
||||||
|
# Get 'oid' from newly created view
|
||||||
|
pg_cursor.execute("select oid from pg_class where relname='%s'" %
|
||||||
|
view_name)
|
||||||
|
view = pg_cursor.fetchone()
|
||||||
|
view_id = view[0]
|
||||||
|
connection.close()
|
||||||
|
return view_id
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
def verify_compound_trigger(server, db_name, trigger_name):
|
def verify_compound_trigger(server, db_name, trigger_name):
|
||||||
"""
|
"""
|
||||||
This function verifies table exist in database or not.
|
This function verifies table exist in database or not.
|
||||||
|
|
|
@ -1,188 +0,0 @@
|
||||||
##########################################################################
|
|
||||||
#
|
|
||||||
# pgAdmin 4 - PostgreSQL Tools
|
|
||||||
#
|
|
||||||
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
|
||||||
# This software is released under the PostgreSQL Licence
|
|
||||||
#
|
|
||||||
##########################################################################
|
|
||||||
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
|
||||||
utils as schema_utils
|
|
||||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
|
||||||
database_utils
|
|
||||||
from pgadmin.utils import server_utils as server_utils
|
|
||||||
from pgadmin.utils.route import BaseTestGenerator
|
|
||||||
from regression import parent_node_dict
|
|
||||||
from regression.python_test_utils import test_utils as utils
|
|
||||||
from . import utils as views_utils
|
|
||||||
|
|
||||||
|
|
||||||
class MViewsUpdateParameterTestCase(BaseTestGenerator):
|
|
||||||
"""This class will update the view/mview under schema node."""
|
|
||||||
scenarios = [
|
|
||||||
# Fetching default URL for table node.
|
|
||||||
('Enable custom auto vacuum and set the parameters for table '
|
|
||||||
'without autovacuum_enabled',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
api_data={
|
|
||||||
'autovacuum_custom': True,
|
|
||||||
'vacuum_table': {
|
|
||||||
'changed': [
|
|
||||||
{'name': 'autovacuum_vacuum_cost_delay',
|
|
||||||
'value': 20},
|
|
||||||
{'name': 'autovacuum_vacuum_threshold',
|
|
||||||
'value': 20}
|
|
||||||
]
|
|
||||||
}}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
('Change a parameter to zero value '
|
|
||||||
'without autovacuum_enabled',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
api_data={
|
|
||||||
'vacuum_table': {
|
|
||||||
'changed': [
|
|
||||||
{'name': 'autovacuum_vacuum_cost_delay',
|
|
||||||
'value': 0}
|
|
||||||
]
|
|
||||||
}}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
('Enable autovacuum_enabled',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
api_data={'autovacuum_enabled': 't'}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
('Reset individual parameters for table',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
api_data={
|
|
||||||
'autovacuum_enabled': 'x',
|
|
||||||
'vacuum_table': {
|
|
||||||
'changed': [
|
|
||||||
{'name': 'autovacuum_vacuum_cost_delay',
|
|
||||||
'value': None},
|
|
||||||
]
|
|
||||||
}}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
('Reset custom auto vacuum',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
api_data={'autovacuum_custom': False}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
('Enable toast custom auto vacuum and set the parameters for table '
|
|
||||||
'without autovacuum_enabled',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
api_data={
|
|
||||||
'toast_autovacuum': True,
|
|
||||||
'vacuum_toast': {
|
|
||||||
'changed': [
|
|
||||||
{'name': 'autovacuum_vacuum_cost_delay',
|
|
||||||
'value': 20},
|
|
||||||
{'name': 'autovacuum_vacuum_threshold',
|
|
||||||
'value': 20}
|
|
||||||
]
|
|
||||||
}}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
('Change a toast parameter to zero value '
|
|
||||||
'without autovacuum_enabled',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
api_data={
|
|
||||||
'vacuum_toast': {
|
|
||||||
'changed': [
|
|
||||||
{'name': 'autovacuum_vacuum_cost_delay',
|
|
||||||
'value': 0}
|
|
||||||
]
|
|
||||||
}}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
('Enable toast.autovacuum_enabled',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
api_data={'toast_autovacuum_enabled': 't'}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
('Reset individual toast parameters for table',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
api_data={
|
|
||||||
'toast_autovacuum_enabled': 'x',
|
|
||||||
'vacuum_toast': {
|
|
||||||
'changed': [
|
|
||||||
{'name': 'autovacuum_vacuum_cost_delay',
|
|
||||||
'value': None},
|
|
||||||
]
|
|
||||||
}}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
('Reset auto vacuum',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
api_data={'toast_autovacuum': False}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
m_view_name = "test_mview_put_%s" % (str(uuid.uuid4())[1:8])
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
|
||||||
schema_info = parent_node_dict["schema"][-1]
|
|
||||||
self.server_id = schema_info["server_id"]
|
|
||||||
self.db_id = schema_info["db_id"]
|
|
||||||
server_response = server_utils.connect_server(self, self.server_id)
|
|
||||||
|
|
||||||
if server_response["data"]["version"] < 90300 and "mview" in self.url:
|
|
||||||
message = "Materialized Views are not supported by PG9.2 " \
|
|
||||||
"and PPAS9.2 and below."
|
|
||||||
self.skipTest(message)
|
|
||||||
|
|
||||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
|
||||||
self.server_id, self.db_id)
|
|
||||||
if not db_con['data']["connected"]:
|
|
||||||
raise Exception("Could not connect to database to update a mview.")
|
|
||||||
self.schema_id = schema_info["schema_id"]
|
|
||||||
self.schema_name = schema_info["schema_name"]
|
|
||||||
schema_response = schema_utils.verify_schemas(self.server,
|
|
||||||
self.db_name,
|
|
||||||
self.schema_name)
|
|
||||||
if not schema_response:
|
|
||||||
raise Exception("Could not find the schema to update a mview.")
|
|
||||||
|
|
||||||
self.m_view_id = views_utils.get_view_id(self.server, self.db_name,
|
|
||||||
self.m_view_name)
|
|
||||||
|
|
||||||
if self.m_view_id is None:
|
|
||||||
m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE " \
|
|
||||||
"pg_default AS SELECT 'test_pgadmin' WITH NO " \
|
|
||||||
"DATA;ALTER TABLE %s.%s OWNER TO %s"
|
|
||||||
self.m_view_id = views_utils.create_view(self.server,
|
|
||||||
self.db_name,
|
|
||||||
self.schema_name,
|
|
||||||
m_view_sql,
|
|
||||||
self.m_view_name)
|
|
||||||
|
|
||||||
def runTest(self):
|
|
||||||
"""This function will update the view/mview under schema node."""
|
|
||||||
mview_response = views_utils.verify_view(self.server, self.db_name,
|
|
||||||
self.m_view_name)
|
|
||||||
if not mview_response:
|
|
||||||
raise Exception("Could not find the mview to update.")
|
|
||||||
|
|
||||||
data = self.api_data
|
|
||||||
data['oid'] = self.m_view_id
|
|
||||||
|
|
||||||
response = self.tester.put(self.url + str(utils.SERVER_GROUP) + '/' +
|
|
||||||
str(self.server_id) + '/' +
|
|
||||||
str(self.db_id) + '/' +
|
|
||||||
str(self.schema_id) + '/' +
|
|
||||||
str(self.m_view_id),
|
|
||||||
data=json.dumps(data),
|
|
||||||
follow_redirects=True)
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
# Disconnect the database
|
|
||||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
|
|
@ -20,50 +20,28 @@ from regression import parent_node_dict
|
||||||
from regression.python_test_utils import test_utils as utils
|
from regression.python_test_utils import test_utils as utils
|
||||||
from . import utils as views_utils
|
from . import utils as views_utils
|
||||||
|
|
||||||
MVIEW_CHECK_UTILITY_URL = 'browser/mview/check_utility_exists/'
|
|
||||||
MVIEW_REFRESH_URL = 'browser/mview/refresh_data/'
|
|
||||||
IS_UTILITY_EXISTS = True
|
|
||||||
|
|
||||||
|
|
||||||
class MViewsUpdateParameterTestCase(BaseTestGenerator):
|
class MViewsUpdateParameterTestCase(BaseTestGenerator):
|
||||||
"""This class will check materialized view refresh functionality."""
|
"""This class will check materialized view refresh functionality."""
|
||||||
scenarios = [
|
# Generates scenarios
|
||||||
('Check utility route',
|
scenarios = utils.generate_scenarios("mview_refresh",
|
||||||
dict(type='check_utility')
|
views_utils.test_cases)
|
||||||
),
|
|
||||||
('Refresh materialized view with invalid oid',
|
|
||||||
dict(type='invalid')
|
|
||||||
),
|
|
||||||
('Refresh materialized view with data',
|
|
||||||
dict(type='with_data')
|
|
||||||
),
|
|
||||||
('Refresh materialized view with no data',
|
|
||||||
dict(type='with_no_data')
|
|
||||||
),
|
|
||||||
('Refresh materialized view with data (concurrently)',
|
|
||||||
dict(type='with_data_concurrently')
|
|
||||||
),
|
|
||||||
('Refresh materialized view with no data (concurrently)',
|
|
||||||
dict(type='with_no_data_concurrently')
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
# Load test data
|
||||||
|
self.data = self.test_data
|
||||||
|
|
||||||
|
# Create db connection
|
||||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||||
schema_info = parent_node_dict["schema"][-1]
|
schema_info = parent_node_dict["schema"][-1]
|
||||||
self.server_id = schema_info["server_id"]
|
self.server_id = schema_info["server_id"]
|
||||||
self.db_id = schema_info["db_id"]
|
self.db_id = schema_info["db_id"]
|
||||||
server_response = server_utils.connect_server(self, self.server_id)
|
|
||||||
|
|
||||||
if server_response["data"]["version"] < 90300 and "mview" in self.url:
|
|
||||||
message = "Materialized Views are not supported by PG9.2 " \
|
|
||||||
"and PPAS9.2 and below."
|
|
||||||
self.skipTest(message)
|
|
||||||
|
|
||||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||||
self.server_id, self.db_id)
|
self.server_id, self.db_id)
|
||||||
if not db_con['data']["connected"]:
|
if not db_con['data']["connected"]:
|
||||||
raise Exception("Could not connect to database to update a mview.")
|
raise Exception("Could not connect to database to update a mview.")
|
||||||
|
|
||||||
|
# Create schema
|
||||||
self.schema_id = schema_info["schema_id"]
|
self.schema_id = schema_info["schema_id"]
|
||||||
self.schema_name = schema_info["schema_name"]
|
self.schema_name = schema_info["schema_name"]
|
||||||
schema_response = schema_utils.verify_schemas(self.server,
|
schema_response = schema_utils.verify_schemas(self.server,
|
||||||
|
@ -72,75 +50,55 @@ class MViewsUpdateParameterTestCase(BaseTestGenerator):
|
||||||
if not schema_response:
|
if not schema_response:
|
||||||
raise Exception("Could not find the schema to update a mview.")
|
raise Exception("Could not find the schema to update a mview.")
|
||||||
|
|
||||||
self.m_view_name = "test_mview_put_%s" % (str(uuid.uuid4())[1:8])
|
query = self.inventory_data['query']
|
||||||
m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default " \
|
|
||||||
"AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE " \
|
|
||||||
"%s.%s OWNER TO %s"
|
|
||||||
|
|
||||||
self.m_view_id = views_utils.create_view(self.server,
|
self.m_view_name = "test_mview_put_%s" % (str(uuid.uuid4())[1:8])
|
||||||
self.db_name,
|
|
||||||
self.schema_name,
|
self.view_id = views_utils.create_view(self.server,
|
||||||
m_view_sql,
|
self.db_name,
|
||||||
self.m_view_name)
|
self.schema_name,
|
||||||
|
self.m_view_name,
|
||||||
|
query)
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
"""This class will check materialized view refresh functionality"""
|
"""This class will check materialized view refresh functionality"""
|
||||||
|
|
||||||
mview_response = views_utils.verify_view(self.server, self.db_name,
|
mview_response = views_utils.verify_view(self.server, self.db_name,
|
||||||
self.m_view_name)
|
self.m_view_name)
|
||||||
if not mview_response:
|
if not mview_response:
|
||||||
raise Exception("Could not find the mview to update.")
|
raise Exception("Could not find the mview to update.")
|
||||||
|
|
||||||
data = None
|
if self.is_put_request:
|
||||||
is_put_request = True
|
# Check utility
|
||||||
|
url_from_test_data = self.url
|
||||||
|
self.url = 'browser/mview/check_utility_exists/'
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
if response.json['success'] == 0:
|
||||||
|
self.skipTest("Couldn't check materialized view refresh "
|
||||||
|
"functionality because utility/binary does "
|
||||||
|
"not exists.")
|
||||||
|
# reset self.url value
|
||||||
|
self.url = url_from_test_data
|
||||||
|
|
||||||
if self.type == 'check_utility':
|
if self.is_positive_test:
|
||||||
is_put_request = False
|
response = views_utils.api_put(self)
|
||||||
elif self.type == 'invalid':
|
|
||||||
data = dict({'concurrent': 'false', 'with_data': 'false'})
|
|
||||||
elif self.type == 'with_data':
|
|
||||||
data = dict({'concurrent': 'false', 'with_data': 'true'})
|
|
||||||
elif self.type == 'with_no_data':
|
|
||||||
data = dict({'concurrent': 'false', 'with_data': 'false'})
|
|
||||||
elif self.type == 'with_data_concurrently':
|
|
||||||
data = dict({'concurrent': 'true', 'with_data': 'true'})
|
|
||||||
elif self.type == 'with_no_data_concurrently':
|
|
||||||
data = dict({'concurrent': 'true', 'with_data': 'false'})
|
|
||||||
|
|
||||||
response = self.tester.get(
|
# Assert response
|
||||||
MVIEW_CHECK_UTILITY_URL + str(utils.SERVER_GROUP) + '/' +
|
utils.assert_status_code(self, response)
|
||||||
str(self.server_id) + '/' +
|
|
||||||
str(self.db_id) + '/' +
|
|
||||||
str(self.schema_id) + '/' +
|
|
||||||
str(self.m_view_id),
|
|
||||||
content_type='html/json'
|
|
||||||
)
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
if is_put_request and response.json['success'] == 0:
|
|
||||||
self.skipTest(
|
|
||||||
"Couldn't check materialized view refresh"
|
|
||||||
" functionality because utility/binary does not exists."
|
|
||||||
)
|
|
||||||
|
|
||||||
if is_put_request:
|
|
||||||
mvid = self.m_view_id
|
|
||||||
if self.type == 'invalid':
|
|
||||||
mvid = 99999
|
|
||||||
response = self.tester.put(
|
|
||||||
MVIEW_REFRESH_URL + str(utils.SERVER_GROUP) + '/' +
|
|
||||||
str(self.server_id) + '/' +
|
|
||||||
str(self.db_id) + '/' +
|
|
||||||
str(self.schema_id) + '/' +
|
|
||||||
str(mvid),
|
|
||||||
data=json.dumps(data),
|
|
||||||
follow_redirects=True
|
|
||||||
)
|
|
||||||
if self.type == 'invalid':
|
|
||||||
self.assertEqual(response.status_code, 410)
|
|
||||||
else:
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
# On success we get job_id from server
|
|
||||||
self.assertTrue('job_id' in response.json['data'])
|
self.assertTrue('job_id' in response.json['data'])
|
||||||
|
else:
|
||||||
|
if 'm_view_id' in self.data:
|
||||||
|
self.view_id = self.data['m_view_id']
|
||||||
|
response = views_utils.api_put(self)
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
utils.assert_error_message(self, response)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# only check utility
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
# Disconnect the database
|
# Disconnect the database
|
||||||
|
|
|
@ -6,9 +6,8 @@
|
||||||
# This software is released under the PostgreSQL Licence
|
# This software is released under the PostgreSQL Licence
|
||||||
#
|
#
|
||||||
##########################################################################
|
##########################################################################
|
||||||
import json
|
|
||||||
import uuid
|
import uuid
|
||||||
|
from unittest.mock import patch
|
||||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
utils as schema_utils
|
utils as schema_utils
|
||||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||||
|
@ -17,68 +16,31 @@ from pgadmin.utils import server_utils as server_utils
|
||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
from regression import parent_node_dict
|
from regression import parent_node_dict
|
||||||
from regression.python_test_utils import test_utils as utils
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from . import utils as views_utils
|
||||||
|
|
||||||
|
|
||||||
class ViewsAddTestCase(BaseTestGenerator):
|
class ViewsAddTestCase(BaseTestGenerator):
|
||||||
"""This class will add new view under schema node."""
|
"""This class will add new view under schema node."""
|
||||||
view_name = "test_view_add_%s" % (str(uuid.uuid4())[1:8])
|
|
||||||
v_data = {"schema": "",
|
# Generates scenarios
|
||||||
"owner": "",
|
scenarios = utils.generate_scenarios("view_create",
|
||||||
"datacl": [],
|
views_utils.test_cases)
|
||||||
"seclabels": [],
|
|
||||||
"name": view_name,
|
|
||||||
"definition": "SELECT 'Hello World';"
|
|
||||||
}
|
|
||||||
m_view_name = "test_mview_add_%s" % (str(uuid.uuid4())[1:8])
|
|
||||||
m_view_data = {"spcname": "pg_default",
|
|
||||||
"toast_autovacuum_enabled": False,
|
|
||||||
"autovacuum_enabled": False,
|
|
||||||
"schema": "",
|
|
||||||
"owner": "",
|
|
||||||
"vacuum_table": [
|
|
||||||
{"name": "autovacuum_analyze_scale_factor"},
|
|
||||||
{"name": "autovacuum_analyze_threshold"},
|
|
||||||
{"name": "autovacuum_freeze_max_age"},
|
|
||||||
{"name": "autovacuum_vacuum_cost_delay"},
|
|
||||||
{"name": "autovacuum_vacuum_cost_limit"},
|
|
||||||
{"name": "autovacuum_vacuum_scale_factor"},
|
|
||||||
{"name": "autovacuum_vacuum_threshold"},
|
|
||||||
{"name": "autovacuum_freeze_min_age"},
|
|
||||||
{"name": "autovacuum_freeze_table_age"}],
|
|
||||||
"vacuum_toast": [{"name": "autovacuum_freeze_max_age"},
|
|
||||||
{"name": "autovacuum_vacuum_cost_delay"},
|
|
||||||
{"name": "autovacuum_vacuum_cost_limit"},
|
|
||||||
{"name": "autovacuum_vacuum_scale_factor"},
|
|
||||||
{"name": "autovacuum_vacuum_threshold"},
|
|
||||||
{"name": "autovacuum_freeze_min_age"},
|
|
||||||
{"name": "autovacuum_freeze_table_age"}],
|
|
||||||
"datacl": [],
|
|
||||||
"seclabels": [],
|
|
||||||
"name": m_view_name,
|
|
||||||
"definition": "SELECT 'test_pgadmin';"}
|
|
||||||
scenarios = [
|
|
||||||
('Add view under schema node', dict(url='/browser/view/obj/',
|
|
||||||
data=v_data)),
|
|
||||||
('Add materialized view under schema node',
|
|
||||||
dict(url='/browser/mview/obj/', data=m_view_data))
|
|
||||||
]
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
# Load test data
|
||||||
|
self.data = self.test_data
|
||||||
|
|
||||||
|
# Create db connection
|
||||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||||
schema_info = parent_node_dict["schema"][-1]
|
schema_info = parent_node_dict["schema"][-1]
|
||||||
self.server_id = schema_info["server_id"]
|
self.server_id = schema_info["server_id"]
|
||||||
self.db_id = schema_info["db_id"]
|
self.db_id = schema_info["db_id"]
|
||||||
server_response = server_utils.connect_server(self, self.server_id)
|
|
||||||
|
|
||||||
if server_response["data"]["version"] < 90300 and "mview" in self.url:
|
|
||||||
message = "Materialized Views are not supported by PG9.2 " \
|
|
||||||
"and PPAS9.2 and below."
|
|
||||||
self.skipTest(message)
|
|
||||||
|
|
||||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||||
self.server_id, self.db_id)
|
self.server_id, self.db_id)
|
||||||
if not db_con['data']["connected"]:
|
if not db_con['data']["connected"]:
|
||||||
raise Exception("Could not connect to database to add view.")
|
raise Exception("Could not connect to database to add view.")
|
||||||
|
|
||||||
|
# Create schema
|
||||||
self.schema_id = schema_info["schema_id"]
|
self.schema_id = schema_info["schema_id"]
|
||||||
self.schema_name = schema_info["schema_name"]
|
self.schema_name = schema_info["schema_name"]
|
||||||
schema_response = schema_utils.verify_schemas(self.server,
|
schema_response = schema_utils.verify_schemas(self.server,
|
||||||
|
@ -90,13 +52,44 @@ class ViewsAddTestCase(BaseTestGenerator):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
"""This function will add view under schema node."""
|
"""This function will add view under schema node."""
|
||||||
db_user = self.server["username"]
|
db_user = self.server["username"]
|
||||||
self.data["schema"] = self.schema_name
|
self.data["schema"] = self.schema_id
|
||||||
self.data["owner"] = db_user
|
self.data["owner"] = db_user
|
||||||
response = self.tester.post(
|
|
||||||
self.url + str(utils.SERVER_GROUP) + '/' + str(self.server_id) +
|
if "name" in self.data:
|
||||||
'/' + str(self.db_id) + '/' + str(self.schema_id) + '/',
|
view_name = \
|
||||||
data=json.dumps(self.data), content_type='html/json')
|
self.data["name"] + (str(uuid.uuid4())[1:8])
|
||||||
self.assertEqual(response.status_code, 200)
|
self.data["name"] = view_name
|
||||||
|
|
||||||
|
if self.is_positive_test:
|
||||||
|
response = views_utils.api_create(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
|
||||||
|
# Verify in backend
|
||||||
|
cross_check_res = views_utils.verify_view(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.data["name"])
|
||||||
|
|
||||||
|
self.assertIsNotNone(cross_check_res, "Could not find the newly"
|
||||||
|
" created check view.")
|
||||||
|
else:
|
||||||
|
if self.mocking_required:
|
||||||
|
with patch(self.mock_data["function_name"],
|
||||||
|
side_effect=eval(self.mock_data["return_value"])):
|
||||||
|
response = views_utils.api_create(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
utils.assert_error_message(self, response)
|
||||||
|
else:
|
||||||
|
if 'table_id' in self.data:
|
||||||
|
self.table_id = self.data['table_id']
|
||||||
|
response = views_utils.api_create(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
utils.assert_error_message(self, response)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
# Disconnect the database
|
# Disconnect the database
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
utils as schema_utils
|
utils as schema_utils
|
||||||
|
@ -22,38 +23,26 @@ from . import utils as views_utils
|
||||||
|
|
||||||
class ViewsDeleteTestCase(BaseTestGenerator):
|
class ViewsDeleteTestCase(BaseTestGenerator):
|
||||||
"""This class will delete the view/mview under schema node."""
|
"""This class will delete the view/mview under schema node."""
|
||||||
view_sql = "CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; " \
|
|
||||||
"ALTER TABLE %s.%s OWNER TO %s"
|
# Generates scenarios
|
||||||
m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS " \
|
scenarios = utils.generate_scenarios("view_delete",
|
||||||
"SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER" \
|
views_utils.test_cases)
|
||||||
" TO %s"
|
|
||||||
scenarios = [
|
|
||||||
('Delete view under schema node', dict(
|
|
||||||
url='/browser/view/obj/',
|
|
||||||
view_name="test_view_delete_%s" % (str(uuid.uuid4())[1:8]),
|
|
||||||
sql_query=view_sql)),
|
|
||||||
('Delete materialized view under schema node',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
view_name="test_mview_delete_%s" % (str(uuid.uuid4())[1:8]),
|
|
||||||
sql_query=m_view_sql))
|
|
||||||
]
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
# Load test data
|
||||||
|
self.data = self.test_data
|
||||||
|
|
||||||
|
# Create db connection
|
||||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||||
schema_info = parent_node_dict["schema"][-1]
|
schema_info = parent_node_dict["schema"][-1]
|
||||||
self.server_id = schema_info["server_id"]
|
self.server_id = schema_info["server_id"]
|
||||||
self.db_id = schema_info["db_id"]
|
self.db_id = schema_info["db_id"]
|
||||||
server_response = server_utils.connect_server(self, self.server_id)
|
|
||||||
|
|
||||||
if server_response["data"]["version"] < 90300 and "mview" in self.url:
|
|
||||||
message = "Materialized Views are not supported by PG9.2 " \
|
|
||||||
"and PPAS9.2 and below."
|
|
||||||
self.skipTest(message)
|
|
||||||
|
|
||||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||||
self.server_id, self.db_id)
|
self.server_id, self.db_id)
|
||||||
if not db_con['data']["connected"]:
|
if not db_con['data']["connected"]:
|
||||||
raise Exception("Could not connect to database to delete view.")
|
raise Exception("Could not connect to database to delete view.")
|
||||||
|
|
||||||
|
# Create schema
|
||||||
self.schema_id = schema_info["schema_id"]
|
self.schema_id = schema_info["schema_id"]
|
||||||
self.schema_name = schema_info["schema_name"]
|
self.schema_name = schema_info["schema_name"]
|
||||||
schema_response = schema_utils.verify_schemas(self.server,
|
schema_response = schema_utils.verify_schemas(self.server,
|
||||||
|
@ -61,26 +50,69 @@ class ViewsDeleteTestCase(BaseTestGenerator):
|
||||||
self.schema_name)
|
self.schema_name)
|
||||||
if not schema_response:
|
if not schema_response:
|
||||||
raise Exception("Could not find the schema to delete the view.")
|
raise Exception("Could not find the schema to delete the view.")
|
||||||
|
|
||||||
|
# Create view
|
||||||
|
query = self.inventory_data['query']
|
||||||
|
|
||||||
|
self.view_name = "test_view_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||||
|
|
||||||
self.view_id = views_utils.create_view(self.server,
|
self.view_id = views_utils.create_view(self.server,
|
||||||
self.db_name,
|
self.db_name,
|
||||||
self.schema_name,
|
self.schema_name,
|
||||||
self.sql_query,
|
self.view_name,
|
||||||
self.view_name)
|
query)
|
||||||
|
|
||||||
def runTest(self):
|
|
||||||
"""This function will delete the view/mview under schema node."""
|
|
||||||
view_response = views_utils.verify_view(self.server, self.db_name,
|
view_response = views_utils.verify_view(self.server, self.db_name,
|
||||||
self.view_name)
|
self.view_name)
|
||||||
if not view_response:
|
if not view_response:
|
||||||
raise Exception("Could not find the view to delete.")
|
raise Exception("Could not find the view to delete.")
|
||||||
response = self.tester.delete(
|
|
||||||
"{0}{1}/{2}/{3}/{4}/{5}".format(self.url, utils.SERVER_GROUP,
|
if self.is_list:
|
||||||
self.server_id, self.db_id,
|
self.view_name_2 = "test_view_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||||
self.schema_id, self.view_id
|
|
||||||
),
|
self.view_id_2 = views_utils.create_view(self.server,
|
||||||
follow_redirects=True
|
self.db_name,
|
||||||
)
|
self.schema_name,
|
||||||
self.assertEqual(response.status_code, 200)
|
self.view_name_2,
|
||||||
|
query)
|
||||||
|
|
||||||
|
view_response = views_utils.verify_view(self.server, self.db_name,
|
||||||
|
self.view_name_2)
|
||||||
|
if not view_response:
|
||||||
|
raise Exception("Could not find the view to delete.")
|
||||||
|
|
||||||
|
# list to delete views
|
||||||
|
self.data['ids'] = [self.view_id, self.view_id_2]
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
"""This function will delete the view/mview under schema node."""
|
||||||
|
|
||||||
|
if self.is_positive_test:
|
||||||
|
|
||||||
|
if self.is_list:
|
||||||
|
response = views_utils.api_delete(self, '')
|
||||||
|
else:
|
||||||
|
response = views_utils.api_delete(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
|
||||||
|
# Verify in backend
|
||||||
|
view_response = views_utils.verify_view(self.server, self.db_name,
|
||||||
|
self.view_name)
|
||||||
|
self.assertIsNone(view_response, "Deleted view still present")
|
||||||
|
else:
|
||||||
|
if self.mocking_required:
|
||||||
|
with patch(self.mock_data["function_name"],
|
||||||
|
side_effect=[eval(self.mock_data["return_value"])]):
|
||||||
|
response = views_utils.api_delete(self)
|
||||||
|
elif 'view_id' in self.data:
|
||||||
|
self.view_id = self.data["view_id"]
|
||||||
|
response = views_utils.api_delete(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
utils.assert_error_message(self, response)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
# Disconnect the database
|
# Disconnect the database
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
##########################################################################
|
|
||||||
#
|
|
||||||
# pgAdmin 4 - PostgreSQL Tools
|
|
||||||
#
|
|
||||||
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
|
||||||
# This software is released under the PostgreSQL Licence
|
|
||||||
#
|
|
||||||
##########################################################################
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
import json
|
|
||||||
|
|
||||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
|
||||||
utils as schema_utils
|
|
||||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
|
||||||
database_utils
|
|
||||||
from pgadmin.utils import server_utils as server_utils
|
|
||||||
from pgadmin.utils.route import BaseTestGenerator
|
|
||||||
from regression import parent_node_dict
|
|
||||||
from regression.python_test_utils import test_utils as utils
|
|
||||||
from . import utils as views_utils
|
|
||||||
|
|
||||||
|
|
||||||
class ViewsDeleteMultipleTestCase(BaseTestGenerator):
|
|
||||||
"""This class will delete the view/mview under schema node."""
|
|
||||||
view_sql = "CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; " \
|
|
||||||
"ALTER TABLE %s.%s OWNER TO %s"
|
|
||||||
m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS " \
|
|
||||||
"SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER" \
|
|
||||||
" TO %s"
|
|
||||||
scenarios = [
|
|
||||||
('Delete multiple view under schema node', dict(
|
|
||||||
url='/browser/view/obj/',
|
|
||||||
view_name=["test_view_delete_%s" % (str(uuid.uuid4())[1:8]),
|
|
||||||
"test_view_delete_%s" % (str(uuid.uuid4())[1:8])],
|
|
||||||
sql_query=view_sql)),
|
|
||||||
('Delete multiple materialized view under schema node',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
view_name=["test_mview_delete_%s" % (str(uuid.uuid4())[1:8]),
|
|
||||||
"test_mview_delete_%s" % (str(uuid.uuid4())[1:8])],
|
|
||||||
sql_query=m_view_sql))
|
|
||||||
]
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
|
||||||
schema_info = parent_node_dict["schema"][-1]
|
|
||||||
self.server_id = schema_info["server_id"]
|
|
||||||
self.db_id = schema_info["db_id"]
|
|
||||||
server_response = server_utils.connect_server(self, self.server_id)
|
|
||||||
|
|
||||||
if server_response["data"]["version"] < 90300 and "mview" in self.url:
|
|
||||||
message = "Materialized Views are not supported by PG9.2 " \
|
|
||||||
"and PPAS9.2 and below."
|
|
||||||
self.skipTest(message)
|
|
||||||
|
|
||||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
|
||||||
self.server_id, self.db_id)
|
|
||||||
if not db_con['data']["connected"]:
|
|
||||||
raise Exception("Could not connect to database to delete view.")
|
|
||||||
self.schema_id = schema_info["schema_id"]
|
|
||||||
self.schema_name = schema_info["schema_name"]
|
|
||||||
schema_response = schema_utils.verify_schemas(self.server,
|
|
||||||
self.db_name,
|
|
||||||
self.schema_name)
|
|
||||||
if not schema_response:
|
|
||||||
raise Exception("Could not find the schema to delete the view.")
|
|
||||||
self.view_ids = [views_utils.create_view(self.server,
|
|
||||||
self.db_name,
|
|
||||||
self.schema_name,
|
|
||||||
self.sql_query,
|
|
||||||
self.view_name[0]),
|
|
||||||
views_utils.create_view(self.server,
|
|
||||||
self.db_name,
|
|
||||||
self.schema_name,
|
|
||||||
self.sql_query,
|
|
||||||
self.view_name[1])
|
|
||||||
]
|
|
||||||
|
|
||||||
def runTest(self):
|
|
||||||
"""This function will delete the view/mview under schema node."""
|
|
||||||
view_response = views_utils.verify_view(self.server, self.db_name,
|
|
||||||
self.view_name[0])
|
|
||||||
if not view_response:
|
|
||||||
raise Exception("Could not find the view to delete.")
|
|
||||||
view_response = views_utils.verify_view(self.server, self.db_name,
|
|
||||||
self.view_name[1])
|
|
||||||
if not view_response:
|
|
||||||
raise Exception("Could not find the view to delete.")
|
|
||||||
|
|
||||||
data = {'ids': self.view_ids}
|
|
||||||
response = self.tester.delete(
|
|
||||||
"{0}{1}/{2}/{3}/{4}/".format(self.url, utils.SERVER_GROUP,
|
|
||||||
self.server_id, self.db_id,
|
|
||||||
self.schema_id
|
|
||||||
),
|
|
||||||
follow_redirects=True,
|
|
||||||
data=json.dumps(data),
|
|
||||||
content_type='html/json'
|
|
||||||
)
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
# Disconnect the database
|
|
||||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
import json
|
import json
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
utils as schema_utils
|
utils as schema_utils
|
||||||
|
@ -23,52 +24,25 @@ from . import utils as views_utils
|
||||||
|
|
||||||
class ViewsGetTestCase(BaseTestGenerator):
|
class ViewsGetTestCase(BaseTestGenerator):
|
||||||
"""This class will fetch the view under schema node."""
|
"""This class will fetch the view under schema node."""
|
||||||
view_sql = "CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; " \
|
|
||||||
"ALTER TABLE %s.%s OWNER TO %s"
|
# Generates scenarios
|
||||||
m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS " \
|
scenarios = utils.generate_scenarios("view_get", views_utils.test_cases)
|
||||||
"SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER" \
|
|
||||||
" TO %s"
|
|
||||||
view_sql_with_bracket = "CREATE OR REPLACE VIEW %s.%s AS " \
|
|
||||||
"SELECT CASE WHEN (pg_db.datistemplate = false " \
|
|
||||||
"AND pg_db.datallowconn = true AND " \
|
|
||||||
"(pg_db.datconnlimit = -1 OR " \
|
|
||||||
"pg_db.datacl is null)) then true else false " \
|
|
||||||
"end as res FROM pg_database pg_db; " \
|
|
||||||
"ALTER TABLE %s.%s OWNER TO %s"
|
|
||||||
scenarios = [
|
|
||||||
('Get view under schema node', dict(
|
|
||||||
url='/browser/view/obj/',
|
|
||||||
view_name="test_view_get_%s" % (str(uuid.uuid4())[1:8]),
|
|
||||||
sql_query=view_sql,
|
|
||||||
type='view_without_conditions')),
|
|
||||||
('Get materialized view under schema node',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
view_name="test_mview_get_%s" % (str(uuid.uuid4())[1:8]),
|
|
||||||
sql_query=m_view_sql,
|
|
||||||
type='m_view_without_conditions')),
|
|
||||||
('Get view having brackets in script under schema node', dict(
|
|
||||||
url='/browser/view/obj/',
|
|
||||||
view_name="test_view_get_%s" % (str(uuid.uuid4())[1:8]),
|
|
||||||
sql_query=view_sql_with_bracket,
|
|
||||||
type='view_with_conditions'))
|
|
||||||
]
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
# Load test data
|
||||||
|
self.data = self.test_data
|
||||||
|
|
||||||
|
# Create db connection
|
||||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||||
schema_info = parent_node_dict["schema"][-1]
|
schema_info = parent_node_dict["schema"][-1]
|
||||||
self.server_id = schema_info["server_id"]
|
self.server_id = schema_info["server_id"]
|
||||||
self.db_id = schema_info["db_id"]
|
self.db_id = schema_info["db_id"]
|
||||||
server_response = server_utils.connect_server(self, self.server_id)
|
|
||||||
|
|
||||||
if server_response["data"]["version"] < 90300 and "mview" in self.url:
|
|
||||||
message = "Materialized Views are not supported by PG9.2 " \
|
|
||||||
"and PPAS9.2 and below."
|
|
||||||
self.skipTest(message)
|
|
||||||
|
|
||||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||||
self.server_id, self.db_id)
|
self.server_id, self.db_id)
|
||||||
if not db_con['data']["connected"]:
|
if not db_con['data']["connected"]:
|
||||||
raise Exception("Could not connect to database to fetch the view.")
|
raise Exception("Could not connect to database to fetch the view.")
|
||||||
|
|
||||||
|
# Create schema
|
||||||
self.schema_id = schema_info["schema_id"]
|
self.schema_id = schema_info["schema_id"]
|
||||||
self.schema_name = schema_info["schema_name"]
|
self.schema_name = schema_info["schema_name"]
|
||||||
schema_response = schema_utils.verify_schemas(self.server,
|
schema_response = schema_utils.verify_schemas(self.server,
|
||||||
|
@ -76,25 +50,56 @@ class ViewsGetTestCase(BaseTestGenerator):
|
||||||
self.schema_name)
|
self.schema_name)
|
||||||
if not schema_response:
|
if not schema_response:
|
||||||
raise Exception("Could not find the schema to fetch the view.")
|
raise Exception("Could not find the schema to fetch the view.")
|
||||||
|
|
||||||
|
# Create view
|
||||||
|
query = self.inventory_data['query']
|
||||||
|
|
||||||
|
self.view_name = "test_view_get_%s" % (str(uuid.uuid4())[1:8])
|
||||||
|
|
||||||
self.view_id = views_utils.create_view(self.server,
|
self.view_id = views_utils.create_view(self.server,
|
||||||
self.db_name,
|
self.db_name,
|
||||||
self.schema_name,
|
self.schema_name,
|
||||||
self.sql_query,
|
self.view_name,
|
||||||
self.view_name)
|
query)
|
||||||
|
# In case of multiple views
|
||||||
|
if self.is_list:
|
||||||
|
self.view_name_2 = "test_view_get_%s" % (str(uuid.uuid4())[1:8])
|
||||||
|
self.view_id_2 = views_utils.create_view(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.schema_name,
|
||||||
|
self.view_name_2,
|
||||||
|
query)
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
"""This function will fetch the view/mview under schema node."""
|
"""This function will fetch the view/mview under schema node."""
|
||||||
response = self.tester.get(
|
if self.is_positive_test:
|
||||||
"{0}{1}/{2}/{3}/{4}/{5}".format(self.url, utils.SERVER_GROUP,
|
if self.is_list:
|
||||||
self.server_id, self.db_id,
|
response = views_utils.api_get(self, '')
|
||||||
self.schema_id, self.view_id
|
else:
|
||||||
),
|
response = views_utils.api_get(self)
|
||||||
follow_redirects=True
|
|
||||||
)
|
# Assert response
|
||||||
self.assertEqual(response.status_code, 200)
|
utils.assert_status_code(self, response)
|
||||||
if self.type == 'view_with_conditions':
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
# Check definition data
|
||||||
self.assertIn('((pg_db.datistemplate', response_data['definition'])
|
test_result_data = self.expected_data["test_result_data"]
|
||||||
|
if bool(test_result_data):
|
||||||
|
response_data = json.loads(response.data.decode('utf-8'))
|
||||||
|
self.assertIn(test_result_data["definition"],
|
||||||
|
response_data['definition'])
|
||||||
|
else:
|
||||||
|
if self.mocking_required:
|
||||||
|
with patch(self.mock_data["function_name"],
|
||||||
|
side_effect=[eval(self.mock_data["return_value"])]):
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
elif 'view_id' in self.data:
|
||||||
|
# Non-existing view id
|
||||||
|
self.view_id = self.data["view_id"]
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
utils.assert_error_message(self, response)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
# Disconnect the database
|
# Disconnect the database
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
import json
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
|
utils as schema_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||||
|
database_utils
|
||||||
|
from pgadmin.utils import server_utils as server_utils
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression import parent_node_dict
|
||||||
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from . import utils as views_utils
|
||||||
|
|
||||||
|
|
||||||
|
class ViewsDependeciesDependentsGetTestCase(BaseTestGenerator):
|
||||||
|
"""This class will fetch dependenciey & dependents for
|
||||||
|
the view under schema node."""
|
||||||
|
|
||||||
|
# Generates scenarios
|
||||||
|
scenarios = utils.generate_scenarios("view_dependecies_dependents",
|
||||||
|
views_utils.test_cases)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
# Load test data
|
||||||
|
self.data = self.test_data
|
||||||
|
|
||||||
|
# Create db connection
|
||||||
|
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||||
|
schema_info = parent_node_dict["schema"][-1]
|
||||||
|
self.server_id = schema_info["server_id"]
|
||||||
|
self.db_id = schema_info["db_id"]
|
||||||
|
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||||
|
self.server_id, self.db_id)
|
||||||
|
if not db_con['data']["connected"]:
|
||||||
|
raise Exception("Could not connect to database to fetch the view.")
|
||||||
|
|
||||||
|
# Create schema
|
||||||
|
self.schema_id = schema_info["schema_id"]
|
||||||
|
self.schema_name = schema_info["schema_name"]
|
||||||
|
schema_response = schema_utils.verify_schemas(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.schema_name)
|
||||||
|
if not schema_response:
|
||||||
|
raise Exception("Could not find the schema to fetch the view.")
|
||||||
|
|
||||||
|
# Create view
|
||||||
|
query = self.inventory_data['query']
|
||||||
|
|
||||||
|
self.view_name = "test_view_get_%s" % (str(uuid.uuid4())[1:8])
|
||||||
|
|
||||||
|
self.view_id = views_utils.create_view(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.schema_name,
|
||||||
|
self.view_name,
|
||||||
|
query)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
"""This function will fetch dependenciey & dependents for
|
||||||
|
the view/mview under schema node."""
|
||||||
|
if self.is_positive_test:
|
||||||
|
if self.is_dependent:
|
||||||
|
self.url = self.url + 'dependent/'
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
else:
|
||||||
|
self.url = self.url + 'dependency/'
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# Disconnect the database
|
||||||
|
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
|
@ -0,0 +1,90 @@
|
||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
import json
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
|
utils as schema_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||||
|
database_utils
|
||||||
|
from pgadmin.utils import server_utils as server_utils
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression import parent_node_dict
|
||||||
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from . import utils as views_utils
|
||||||
|
|
||||||
|
|
||||||
|
class ViewsGetMsqlTestCase(BaseTestGenerator):
|
||||||
|
"""This class will fetch the modified view/mview sql under schema node."""
|
||||||
|
|
||||||
|
# Generates scenarios
|
||||||
|
scenarios = utils.generate_scenarios("view_get_msql",
|
||||||
|
views_utils.test_cases)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
# Load test data
|
||||||
|
self.data = self.test_data
|
||||||
|
|
||||||
|
# Create db connection
|
||||||
|
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||||
|
schema_info = parent_node_dict["schema"][-1]
|
||||||
|
self.server_id = schema_info["server_id"]
|
||||||
|
self.db_id = schema_info["db_id"]
|
||||||
|
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||||
|
self.server_id, self.db_id)
|
||||||
|
if not db_con['data']["connected"]:
|
||||||
|
raise Exception("Could not connect to database to fetch the view.")
|
||||||
|
|
||||||
|
# Create schema
|
||||||
|
self.schema_id = schema_info["schema_id"]
|
||||||
|
self.schema_name = schema_info["schema_name"]
|
||||||
|
schema_response = schema_utils.verify_schemas(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.schema_name)
|
||||||
|
if not schema_response:
|
||||||
|
raise Exception("Could not find the schema to fetch the view.")
|
||||||
|
|
||||||
|
# Create view
|
||||||
|
query = self.inventory_data['query']
|
||||||
|
|
||||||
|
self.view_name = "test_view_get_%s" % (str(uuid.uuid4())[1:8])
|
||||||
|
|
||||||
|
self.view_id = views_utils.create_view(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.schema_name,
|
||||||
|
self.view_name,
|
||||||
|
query)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
"""This function will fetch the modified view/mview sql under
|
||||||
|
schema node."""
|
||||||
|
|
||||||
|
if self.is_positive_test:
|
||||||
|
url_encode_data = {"oid": self.view_id,
|
||||||
|
"comment": self.data['comment']}
|
||||||
|
|
||||||
|
response = views_utils.api_get_msql(self, url_encode_data)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
else:
|
||||||
|
if 'view_id' in self.data:
|
||||||
|
# Non-existing view id
|
||||||
|
self.view_id = self.data["view_id"]
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
utils.assert_error_message(self, response)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# Disconnect the database
|
||||||
|
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
|
@ -0,0 +1,99 @@
|
||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
import json
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
|
utils as schema_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||||
|
database_utils
|
||||||
|
from pgadmin.utils import server_utils as server_utils
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression import parent_node_dict
|
||||||
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from . import utils as views_utils
|
||||||
|
|
||||||
|
|
||||||
|
class ViewsGetNodesTestCase(BaseTestGenerator):
|
||||||
|
"""This class will fetch the view nodes under schema node."""
|
||||||
|
|
||||||
|
# Generates scenarios
|
||||||
|
scenarios = utils.generate_scenarios("view_get_nodes",
|
||||||
|
views_utils.test_cases)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
# Load test data
|
||||||
|
self.data = self.test_data
|
||||||
|
|
||||||
|
# Create db connection
|
||||||
|
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||||
|
schema_info = parent_node_dict["schema"][-1]
|
||||||
|
self.server_id = schema_info["server_id"]
|
||||||
|
self.db_id = schema_info["db_id"]
|
||||||
|
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||||
|
self.server_id, self.db_id)
|
||||||
|
if not db_con['data']["connected"]:
|
||||||
|
raise Exception("Could not connect to database to fetch the view.")
|
||||||
|
|
||||||
|
# Create schema
|
||||||
|
self.schema_id = schema_info["schema_id"]
|
||||||
|
self.schema_name = schema_info["schema_name"]
|
||||||
|
schema_response = schema_utils.verify_schemas(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.schema_name)
|
||||||
|
if not schema_response:
|
||||||
|
raise Exception("Could not find the schema to fetch the view.")
|
||||||
|
|
||||||
|
# Create view
|
||||||
|
query = self.inventory_data['query']
|
||||||
|
|
||||||
|
self.view_name = "test_view_get_%s" % (str(uuid.uuid4())[1:8])
|
||||||
|
|
||||||
|
self.view_id = views_utils.create_view(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.schema_name,
|
||||||
|
self.view_name,
|
||||||
|
query)
|
||||||
|
# In case of multiple views
|
||||||
|
if self.is_list:
|
||||||
|
self.view_name_2 = "test_view_get_%s" % (str(uuid.uuid4())[1:8])
|
||||||
|
self.check_constraint_id_2 = views_utils.\
|
||||||
|
create_view(self.server, self.db_name, self.schema_name,
|
||||||
|
self.view_name_2, query)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
"""This function will fetch the view/mview nodes under schema node."""
|
||||||
|
if self.is_positive_test:
|
||||||
|
if self.is_list:
|
||||||
|
response = views_utils.api_get(self, '')
|
||||||
|
else:
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.mocking_required:
|
||||||
|
with patch(self.mock_data["function_name"],
|
||||||
|
side_effect=[eval(self.mock_data["return_value"])]):
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
elif 'view_id' in self.data:
|
||||||
|
# Non-existing view/mview id
|
||||||
|
self.view_id = self.data["view_id"]
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
utils.assert_error_message(self, response)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# Disconnect the database
|
||||||
|
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import uuid
|
import uuid
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
utils as schema_utils
|
utils as schema_utils
|
||||||
|
@ -23,38 +24,24 @@ from . import utils as views_utils
|
||||||
|
|
||||||
class ViewsUpdateTestCase(BaseTestGenerator):
|
class ViewsUpdateTestCase(BaseTestGenerator):
|
||||||
"""This class will update the view/mview under schema node."""
|
"""This class will update the view/mview under schema node."""
|
||||||
view_sql = "CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; " \
|
# Generates scenarios
|
||||||
"ALTER TABLE %s.%s OWNER TO %s"
|
scenarios = utils.generate_scenarios("view_put", views_utils.test_cases)
|
||||||
m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS " \
|
|
||||||
"SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER" \
|
|
||||||
" TO %s"
|
|
||||||
scenarios = [
|
|
||||||
('Update view under schema node', dict(
|
|
||||||
url='/browser/view/obj/',
|
|
||||||
view_name="test_view_put_%s" % (str(uuid.uuid4())[1:8]),
|
|
||||||
sql_query=view_sql)),
|
|
||||||
('Update materialized view under schema node',
|
|
||||||
dict(url='/browser/mview/obj/',
|
|
||||||
view_name="test_mview_put_%s" % (str(uuid.uuid4())[1:8]),
|
|
||||||
sql_query=m_view_sql))
|
|
||||||
]
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
# Load test data
|
||||||
|
self.data = self.test_data
|
||||||
|
|
||||||
|
# Create db connection
|
||||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||||
schema_info = parent_node_dict["schema"][-1]
|
schema_info = parent_node_dict["schema"][-1]
|
||||||
self.server_id = schema_info["server_id"]
|
self.server_id = schema_info["server_id"]
|
||||||
self.db_id = schema_info["db_id"]
|
self.db_id = schema_info["db_id"]
|
||||||
server_response = server_utils.connect_server(self, self.server_id)
|
|
||||||
|
|
||||||
if server_response["data"]["version"] < 90300 and "mview" in self.url:
|
|
||||||
message = "Materialized Views are not supported by PG9.2 " \
|
|
||||||
"and PPAS9.2 and below."
|
|
||||||
self.skipTest(message)
|
|
||||||
|
|
||||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||||
self.server_id, self.db_id)
|
self.server_id, self.db_id)
|
||||||
if not db_con['data']["connected"]:
|
if not db_con['data']["connected"]:
|
||||||
raise Exception("Could not connect to database to update a view.")
|
raise Exception("Could not connect to database to update a view.")
|
||||||
|
|
||||||
|
# Create schema
|
||||||
self.schema_id = schema_info["schema_id"]
|
self.schema_id = schema_info["schema_id"]
|
||||||
self.schema_name = schema_info["schema_name"]
|
self.schema_name = schema_info["schema_name"]
|
||||||
schema_response = schema_utils.verify_schemas(self.server,
|
schema_response = schema_utils.verify_schemas(self.server,
|
||||||
|
@ -62,11 +49,18 @@ class ViewsUpdateTestCase(BaseTestGenerator):
|
||||||
self.schema_name)
|
self.schema_name)
|
||||||
if not schema_response:
|
if not schema_response:
|
||||||
raise Exception("Could not find the schema to update a view.")
|
raise Exception("Could not find the schema to update a view.")
|
||||||
self.view_id = views_utils.create_view(self.server,
|
|
||||||
self.db_name,
|
query = self.inventory_data['query']
|
||||||
self.schema_name,
|
|
||||||
self.sql_query,
|
self.view_name = "test_view_update_%s" % (str(uuid.uuid4())[1:8])
|
||||||
|
|
||||||
|
self.view_id = views_utils.get_view_id(self.server, self.db_name,
|
||||||
self.view_name)
|
self.view_name)
|
||||||
|
if self.view_id is None:
|
||||||
|
self.view_id = views_utils.create_view(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.schema_name,
|
||||||
|
self.view_name, query)
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
"""This function will update the view/mview under schema node."""
|
"""This function will update the view/mview under schema node."""
|
||||||
|
@ -74,17 +68,23 @@ class ViewsUpdateTestCase(BaseTestGenerator):
|
||||||
self.view_name)
|
self.view_name)
|
||||||
if not view_response:
|
if not view_response:
|
||||||
raise Exception("Could not find the view to update.")
|
raise Exception("Could not find the view to update.")
|
||||||
data = {"id": self.view_id,
|
|
||||||
"comment": "This is test comment"
|
self.data["oid"] = self.view_id
|
||||||
}
|
|
||||||
response = self.tester.put(
|
if self.is_positive_test:
|
||||||
"{0}{1}/{2}/{3}/{4}/{5}".format(self.url, utils.SERVER_GROUP,
|
response = views_utils.api_put(self)
|
||||||
self.server_id, self.db_id,
|
|
||||||
self.schema_id, self.view_id
|
# Assert response
|
||||||
),
|
utils.assert_status_code(self, response)
|
||||||
data=json.dumps(data),
|
else:
|
||||||
follow_redirects=True)
|
if self.mocking_required:
|
||||||
self.assertEqual(response.status_code, 200)
|
with patch(self.mock_data["function_name"],
|
||||||
|
side_effect=[eval(self.mock_data["return_value"])]):
|
||||||
|
response = views_utils.api_put(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
utils.assert_error_message(self, response)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
# Disconnect the database
|
# Disconnect the database
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
import json
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
|
utils as schema_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||||
|
database_utils
|
||||||
|
from pgadmin.utils import server_utils as server_utils
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression import parent_node_dict
|
||||||
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from . import utils as views_utils
|
||||||
|
|
||||||
|
|
||||||
|
class ViewsSqlTestCase(BaseTestGenerator):
|
||||||
|
"""This class will fetch the view/mview sql under schema node."""
|
||||||
|
|
||||||
|
# Generates scenarios
|
||||||
|
scenarios = utils.generate_scenarios("view_sql", views_utils.test_cases)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
# Load test data
|
||||||
|
self.data = self.test_data
|
||||||
|
|
||||||
|
# Create db connection
|
||||||
|
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||||
|
schema_info = parent_node_dict["schema"][-1]
|
||||||
|
self.server_id = schema_info["server_id"]
|
||||||
|
self.db_id = schema_info["db_id"]
|
||||||
|
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||||
|
self.server_id, self.db_id)
|
||||||
|
|
||||||
|
# Check DB version
|
||||||
|
if "server_min_version" in self.data:
|
||||||
|
server_con = server_utils.connect_server(self, self.server_id)
|
||||||
|
if not server_con["info"] == "Server connected.":
|
||||||
|
raise Exception("Could not connect to server to check version")
|
||||||
|
if "type" in server_con["data"] and \
|
||||||
|
server_con["data"]["type"] == "pg":
|
||||||
|
self.skipTest("Compound Triggers are not supported by PG.")
|
||||||
|
elif server_con["data"]["type"] == "ppas" \
|
||||||
|
and server_con["data"]["version"] < self.data[
|
||||||
|
"server_min_version"]:
|
||||||
|
self.skipTest(self.data["skip_msg"])
|
||||||
|
|
||||||
|
if not db_con['data']["connected"]:
|
||||||
|
raise Exception("Could not connect to database to fetch the view.")
|
||||||
|
|
||||||
|
# Create schema
|
||||||
|
self.schema_id = schema_info["schema_id"]
|
||||||
|
self.schema_name = schema_info["schema_name"]
|
||||||
|
schema_response = schema_utils.verify_schemas(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.schema_name)
|
||||||
|
if not schema_response:
|
||||||
|
raise Exception("Could not find the schema to fetch the view.")
|
||||||
|
|
||||||
|
# Create view
|
||||||
|
query = self.inventory_data['query']
|
||||||
|
|
||||||
|
self.view_name = "test_view_sql_%s" % (str(uuid.uuid4())[1:8])
|
||||||
|
|
||||||
|
self.view_id = views_utils.create_view(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.schema_name,
|
||||||
|
self.view_name,
|
||||||
|
query)
|
||||||
|
|
||||||
|
if hasattr(self, "trigger_fun_required"):
|
||||||
|
self.func_name = "trigger_func_get_%s" % str(uuid.uuid4())[1:8]
|
||||||
|
self.function_info = views_utils.\
|
||||||
|
create_trigger_function_with_trigger(self.server, self.db_name,
|
||||||
|
self.schema_name,
|
||||||
|
self.func_name)
|
||||||
|
self.trigger_name = \
|
||||||
|
"test_trigger_get_%s" % (str(uuid.uuid4())[1:8])
|
||||||
|
self.trigger_id = views_utils.create_trigger(self.server,
|
||||||
|
self.db_name,
|
||||||
|
self.schema_name,
|
||||||
|
self.view_name,
|
||||||
|
self.trigger_name,
|
||||||
|
self.func_name,
|
||||||
|
"a")
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
"""This function will fetch the view/mview sql under schema node."""
|
||||||
|
if self.is_positive_test:
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.mocking_required:
|
||||||
|
with patch(self.mock_data["function_name"],
|
||||||
|
side_effect=[eval(self.mock_data["return_value"])]):
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
elif 'view_id' in self.data:
|
||||||
|
# Non-existing view id
|
||||||
|
self.view_id = self.data["view_id"]
|
||||||
|
response = views_utils.api_get(self)
|
||||||
|
|
||||||
|
# Assert response
|
||||||
|
utils.assert_status_code(self, response)
|
||||||
|
utils.assert_error_message(self, response)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# Disconnect the database
|
||||||
|
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
|
@ -10,11 +10,150 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
from regression.python_test_utils import test_utils as utils
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
|
# Load test data from json file.
|
||||||
|
CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
with open(CURRENT_PATH + "/view_test_data.json") as data_file:
|
||||||
|
test_cases = json.load(data_file)
|
||||||
|
|
||||||
|
|
||||||
def create_view(server, db_name, schema_name, sql_query, view_name):
|
# api call methods
|
||||||
|
def api_create(self):
|
||||||
|
return self.tester.post("{0}{1}/{2}/{3}/{4}/".
|
||||||
|
format(self.url, utils.SERVER_GROUP,
|
||||||
|
self.server_id, self.db_id,
|
||||||
|
self.schema_id
|
||||||
|
),
|
||||||
|
data=json.dumps(self.data),
|
||||||
|
content_type='html/json')
|
||||||
|
|
||||||
|
|
||||||
|
def api_get(self, view_id=None):
|
||||||
|
if view_id is None:
|
||||||
|
view_id = self.view_id
|
||||||
|
return self.tester.get("{0}{1}/{2}/{3}/{4}/{5}".
|
||||||
|
format(self.url, utils.SERVER_GROUP,
|
||||||
|
self.server_id, self.db_id,
|
||||||
|
self.schema_id, view_id),
|
||||||
|
follow_redirects=True)
|
||||||
|
|
||||||
|
|
||||||
|
def api_get_msql(self, url_encode_data):
|
||||||
|
return self.tester.get("{0}{1}/{2}/{3}/{4}/{5}?{6}".
|
||||||
|
format(self.url, utils.SERVER_GROUP,
|
||||||
|
self.server_id, self.db_id,
|
||||||
|
self.schema_id, self.view_id,
|
||||||
|
urlencode(url_encode_data)),
|
||||||
|
follow_redirects=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def api_delete(self, view_id=None):
|
||||||
|
if view_id is None:
|
||||||
|
view_id = self.view_id
|
||||||
|
return self.tester.delete("{0}{1}/{2}/{3}/{4}/{5}".
|
||||||
|
format(self.url, utils.SERVER_GROUP,
|
||||||
|
self.server_id, self.db_id,
|
||||||
|
self.schema_id, view_id),
|
||||||
|
data=json.dumps(self.data),
|
||||||
|
follow_redirects=True)
|
||||||
|
|
||||||
|
|
||||||
|
def api_put(self):
|
||||||
|
return self.tester.put("{0}{1}/{2}/{3}/{4}/{5}".
|
||||||
|
format(self.url, utils.SERVER_GROUP,
|
||||||
|
self.server_id, self.db_id,
|
||||||
|
self.schema_id, self.view_id),
|
||||||
|
data=json.dumps(self.data),
|
||||||
|
follow_redirects=True)
|
||||||
|
|
||||||
|
|
||||||
|
def create_trigger_function_with_trigger(server, db_name, schema_name,
|
||||||
|
func_name):
|
||||||
|
"""This function add the trigger function to schema"""
|
||||||
|
try:
|
||||||
|
connection = utils.get_db_connection(db_name,
|
||||||
|
server['username'],
|
||||||
|
server['db_password'],
|
||||||
|
server['host'],
|
||||||
|
server['port'],
|
||||||
|
server['sslmode'])
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
query = "CREATE FUNCTION " + schema_name + "." + func_name + \
|
||||||
|
"()" \
|
||||||
|
" RETURNS trigger LANGUAGE 'plpgsql' STABLE LEAKPROOF" \
|
||||||
|
" SECURITY DEFINER SET enable_sort=true AS $BODY$ BEGIN" \
|
||||||
|
" NULL; END; $BODY$"
|
||||||
|
pg_cursor.execute(query)
|
||||||
|
connection.commit()
|
||||||
|
# Get 'oid' from newly created function
|
||||||
|
pg_cursor.execute("SELECT pro.oid, pro.proname FROM"
|
||||||
|
" pg_proc pro WHERE pro.proname='%s'" %
|
||||||
|
func_name)
|
||||||
|
functions = pg_cursor.fetchone()
|
||||||
|
connection.close()
|
||||||
|
return functions
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def create_trigger(server, db_name, schema_name, table_name, trigger_name,
|
||||||
|
trigger_func_name, trigger_func_arg=None):
|
||||||
|
"""
|
||||||
|
This function creates a column under provided table.
|
||||||
|
:param server: server details
|
||||||
|
:type server: dict
|
||||||
|
:param db_name: database name
|
||||||
|
:type db_name: str
|
||||||
|
:param schema_name: schema name
|
||||||
|
:type schema_name: str
|
||||||
|
:param table_name: table name
|
||||||
|
:type table_name: str
|
||||||
|
:param trigger_name: trigger name
|
||||||
|
:type trigger_name: str
|
||||||
|
:param trigger_func_name: trigger function name
|
||||||
|
:type trigger_func_name: str
|
||||||
|
:return trigger_id: trigger id
|
||||||
|
:rtype: int
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
connection = utils.get_db_connection(db_name,
|
||||||
|
server['username'],
|
||||||
|
server['db_password'],
|
||||||
|
server['host'],
|
||||||
|
server['port'],
|
||||||
|
server['sslmode'])
|
||||||
|
old_isolation_level = connection.isolation_level
|
||||||
|
connection.set_isolation_level(0)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
query = "CREATE TRIGGER %s INSTEAD OF DELETE ON %s.%s FOR EACH ROW " \
|
||||||
|
"EXECUTE PROCEDURE %s.%s(%s)" % (trigger_name, schema_name,
|
||||||
|
table_name, schema_name,
|
||||||
|
trigger_func_name,
|
||||||
|
trigger_func_arg)
|
||||||
|
pg_cursor.execute(query)
|
||||||
|
connection.set_isolation_level(old_isolation_level)
|
||||||
|
connection.commit()
|
||||||
|
pg_cursor.execute("SELECT oid FROM pg_trigger where tgname='%s'" %
|
||||||
|
trigger_name)
|
||||||
|
trigger = pg_cursor.fetchone()
|
||||||
|
trigger_id = ''
|
||||||
|
if trigger:
|
||||||
|
trigger_id = trigger[0]
|
||||||
|
connection.close()
|
||||||
|
return trigger_id
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def create_view(server, db_name, schema_name, view_name, sql_query=None,
|
||||||
|
mview_index=None):
|
||||||
"""
|
"""
|
||||||
This function creates a table under provided schema.
|
This function creates a table under provided schema.
|
||||||
:param server: server details
|
:param server: server details
|
||||||
|
@ -40,8 +179,7 @@ def create_view(server, db_name, schema_name, sql_query, view_name):
|
||||||
old_isolation_level = connection.isolation_level
|
old_isolation_level = connection.isolation_level
|
||||||
connection.set_isolation_level(0)
|
connection.set_isolation_level(0)
|
||||||
pg_cursor = connection.cursor()
|
pg_cursor = connection.cursor()
|
||||||
query = sql_query % (schema_name, view_name, schema_name, view_name,
|
query = eval(sql_query)
|
||||||
server['username'])
|
|
||||||
pg_cursor.execute(query)
|
pg_cursor.execute(query)
|
||||||
connection.set_isolation_level(old_isolation_level)
|
connection.set_isolation_level(old_isolation_level)
|
||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue