Introduce a test config database for the regression tests, and track/remove objects that are created during testing.
parent
3807ba047b
commit
d3d8836f61
|
@ -266,6 +266,15 @@ STORAGE_DIR = os.path.join(
|
||||||
'storage'
|
'storage'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# Test settings - used primarily by the regression suite, not for users
|
||||||
|
##########################################################################
|
||||||
|
# Set default testing mode
|
||||||
|
TESTING_MODE = False
|
||||||
|
|
||||||
|
# The default path for SQLite database for testing
|
||||||
|
TEST_SQLITE_PATH = os.path.join(DATA_DIR, 'test_pgadmin4.db')
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# Allows flask application to response to the each request asynchronously
|
# Allows flask application to response to the each request asynchronously
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
|
@ -7,57 +7,52 @@
|
||||||
#
|
#
|
||||||
# ##################################################################
|
# ##################################################################
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
from regression import test_utils as utils
|
from regression import test_utils as utils
|
||||||
|
from regression import test_server_dict
|
||||||
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
||||||
from . import utils as database_utils
|
from . import utils as database_utils
|
||||||
|
|
||||||
|
|
||||||
class DatabaseAddTestCase(BaseTestGenerator):
|
class DatabaseAddTestCase(BaseTestGenerator):
|
||||||
"""
|
"""This class will test the ADD database API"""
|
||||||
This class will check server group node present on the object browser's
|
|
||||||
tree node by response code.
|
|
||||||
"""
|
|
||||||
|
|
||||||
scenarios = [
|
scenarios = [
|
||||||
# Fetching default URL for database node.
|
# Fetching default URL for database node.
|
||||||
('Check Databases Node URL', dict(url='/browser/database/obj/'))
|
('Check Databases Node URL', dict(url='/browser/database/obj/'))
|
||||||
]
|
]
|
||||||
|
|
||||||
@classmethod
|
def setUp(self):
|
||||||
def setUpClass(cls):
|
pass
|
||||||
"""
|
|
||||||
This function used to add the sever
|
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Add the server
|
|
||||||
server_utils.add_server(cls.tester)
|
|
||||||
|
|
||||||
# Connect to server
|
|
||||||
cls.server_connect_response, cls.server_group, cls.server_ids = \
|
|
||||||
server_utils.connect_server(cls.tester)
|
|
||||||
|
|
||||||
if len(cls.server_connect_response) == 0:
|
|
||||||
raise Exception("No Server(s) connected to add the database!!!")
|
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
""" This function will add database under 1st server of tree node. """
|
""" This function will add database under 1st server of tree node. """
|
||||||
|
server_id = test_server_dict["server"][0]["server_id"]
|
||||||
|
server_utils.connect_server(self, server_id)
|
||||||
|
|
||||||
database_utils.add_database(self.tester, self.server_connect_response,
|
data = database_utils.get_db_data()
|
||||||
self.server_ids)
|
self.db_name = data['name']
|
||||||
|
response = self.tester.post(self.url + str(utils.SERVER_GROUP) +
|
||||||
|
"/" + str(server_id) + "/",
|
||||||
|
data=json.dumps(data),
|
||||||
|
content_type='html/json')
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
response_data = json.loads(response.data.decode('utf-8'))
|
||||||
|
db_id = response_data['node']['_id']
|
||||||
|
db_dict = {"db_id": db_id, "db_name": self.db_name}
|
||||||
|
utils.write_node_info(int(server_id), "did", db_dict)
|
||||||
|
|
||||||
@classmethod
|
def tearDown(self):
|
||||||
def tearDownClass(cls):
|
|
||||||
"""
|
"""
|
||||||
This function deletes the added database, added server and the
|
This function delete the database from server added in SQLite and
|
||||||
'parent_id.pkl' file which is created in setup()
|
clears the node_info_dict
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
"""
|
||||||
|
connection = utils.get_db_connection(self.server['db'],
|
||||||
database_utils.delete_database(cls.tester)
|
self.server['username'],
|
||||||
server_utils.delete_server(cls.tester)
|
self.server['db_password'],
|
||||||
utils.delete_parent_id_file()
|
self.server['host'],
|
||||||
|
self.server['port'])
|
||||||
|
utils.drop_database(connection, self.db_name)
|
||||||
|
utils.clear_node_info_dict()
|
||||||
|
|
|
@ -6,16 +6,14 @@
|
||||||
# This software is released under the PostgreSQL Licence
|
# This software is released under the PostgreSQL Licence
|
||||||
#
|
#
|
||||||
# ##################################################################
|
# ##################################################################
|
||||||
|
|
||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
from regression import test_utils as utils
|
from regression import test_utils as utils
|
||||||
|
from regression import test_server_dict
|
||||||
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
||||||
from . import utils as database_utils
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseDeleteTestCase(BaseTestGenerator):
|
class DatabaseDeleteTestCase(BaseTestGenerator):
|
||||||
""" This class will delete the database under last added server. """
|
""" This class will delete the database under last added server. """
|
||||||
|
|
||||||
scenarios = [
|
scenarios = [
|
||||||
# Fetching default URL for database node.
|
# Fetching default URL for database node.
|
||||||
('Check Databases Node URL', dict(url='/browser/database/obj/'))
|
('Check Databases Node URL', dict(url='/browser/database/obj/'))
|
||||||
|
@ -23,42 +21,23 @@ class DatabaseDeleteTestCase(BaseTestGenerator):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
"""
|
cls.db_id = utils.create_database(cls.server, "test_db_delete")
|
||||||
This function perform the three tasks
|
|
||||||
1. Add the test server
|
|
||||||
2. Connect to server
|
|
||||||
3. Add the databases
|
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Firstly, add the server
|
|
||||||
server_utils.add_server(cls.tester)
|
|
||||||
|
|
||||||
# Connect to server
|
|
||||||
cls.server_connect_response, cls.server_group, cls.server_ids = \
|
|
||||||
server_utils.connect_server(cls.tester)
|
|
||||||
|
|
||||||
if len(cls.server_connect_response) == 0:
|
|
||||||
raise Exception("No Server(s) connected to add the database!!!")
|
|
||||||
|
|
||||||
# Add database
|
|
||||||
database_utils.add_database(cls.tester, cls.server_connect_response,
|
|
||||||
cls.server_ids)
|
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
""" This function will delete the database."""
|
""" This function will delete the database."""
|
||||||
|
server_id = test_server_dict["server"][0]["server_id"]
|
||||||
database_utils.delete_database(self.tester)
|
server_response = server_utils.connect_server(self, server_id)
|
||||||
|
if server_response["data"]["connected"]:
|
||||||
|
db_id = self.db_id
|
||||||
|
response = self.tester.delete(
|
||||||
|
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||||
|
str(server_id) + '/' + str(db_id),
|
||||||
|
follow_redirects=True)
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
else:
|
||||||
|
raise Exception("Could not connect to server to delete the "
|
||||||
|
"database.")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
"""
|
pass
|
||||||
This function deletes the added server and the 'parent_id.pkl' file
|
|
||||||
which is created in setup() function.
|
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
server_utils.delete_server(cls.tester)
|
|
||||||
utils.delete_parent_id_file()
|
|
||||||
|
|
|
@ -9,9 +9,7 @@
|
||||||
|
|
||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
from regression import test_utils as utils
|
from regression import test_utils as utils
|
||||||
from regression.test_setup import config_data
|
from regression import test_server_dict
|
||||||
from regression.test_utils import get_ids
|
|
||||||
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
|
||||||
from . import utils as database_utils
|
from . import utils as database_utils
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,66 +17,32 @@ class DatabasesGetTestCase(BaseTestGenerator):
|
||||||
"""
|
"""
|
||||||
This class will fetch database added under last added server.
|
This class will fetch database added under last added server.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
scenarios = [
|
scenarios = [
|
||||||
# Fetching default URL for database node.
|
# Fetching default URL for database node.
|
||||||
('Check Dat abases Node URL', dict(url='/browser/database/obj/'))
|
('Check Dat abases Node URL', dict(url='/browser/database/obj/'))
|
||||||
]
|
]
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
"""
|
|
||||||
This function perform the three tasks
|
|
||||||
1. Add the test server
|
|
||||||
2. Connect to server
|
|
||||||
3. Add the databases
|
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Firstly, add the server
|
|
||||||
server_utils.add_server(cls.tester)
|
|
||||||
|
|
||||||
# Connect to server
|
|
||||||
cls.server_connect_response, cls.server_group, cls.server_ids = \
|
|
||||||
server_utils.connect_server(cls.tester)
|
|
||||||
|
|
||||||
if len(cls.server_connect_response) == 0:
|
|
||||||
raise Exception("No Server(s) connected to add the database!!!")
|
|
||||||
|
|
||||||
# Add database
|
|
||||||
database_utils.add_database(cls.tester, cls.server_connect_response,
|
|
||||||
cls.server_ids)
|
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
""" This function will fetch added database. """
|
""" This function will fetch added database. """
|
||||||
|
server_data = test_server_dict["database"][0]
|
||||||
all_id = get_ids()
|
server_id = server_data["server_id"]
|
||||||
server_ids = all_id["sid"]
|
db_id = server_data['db_id']
|
||||||
|
db_con = database_utils.verify_database(self,
|
||||||
db_ids_dict = all_id["did"][0]
|
utils.SERVER_GROUP,
|
||||||
srv_grp = config_data['server_group']
|
server_id,
|
||||||
|
db_id)
|
||||||
for server_id in server_ids:
|
if db_con["info"] == "Database connected.":
|
||||||
db_id = db_ids_dict[int(server_id)]
|
try:
|
||||||
db_con = database_utils.verify_database(self.tester, srv_grp,
|
|
||||||
server_id,
|
|
||||||
db_id)
|
|
||||||
if db_con["info"] == "Database connected.":
|
|
||||||
response = self.tester.get(
|
response = self.tester.get(
|
||||||
self.url + str(srv_grp) + '/' + str(server_id) + '/' +
|
self.url + str(utils.SERVER_GROUP) + '/' + str(
|
||||||
|
server_id) + '/' +
|
||||||
str(db_id), follow_redirects=True)
|
str(db_id), follow_redirects=True)
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
except Exception as exception:
|
||||||
|
raise Exception("Error while getting database. %s" % exception)
|
||||||
|
finally:
|
||||||
|
# Disconnect database to delete it
|
||||||
|
database_utils.disconnect_database(self, server_id, db_id)
|
||||||
|
|
||||||
@classmethod
|
else:
|
||||||
def tearDownClass(cls):
|
raise Exception("Could not connect to database.")
|
||||||
"""
|
|
||||||
This function deletes the added database, added server
|
|
||||||
and the 'parent_id.pkl' file which is created in setup() function.
|
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
database_utils.delete_database(cls.tester)
|
|
||||||
server_utils.delete_server(cls.tester)
|
|
||||||
utils.delete_parent_id_file()
|
|
||||||
|
|
|
@ -11,17 +11,13 @@ import json
|
||||||
|
|
||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
from regression import test_utils as utils
|
from regression import test_utils as utils
|
||||||
|
from regression import test_server_dict
|
||||||
from regression.test_setup import advanced_config_data
|
from regression.test_setup import advanced_config_data
|
||||||
from regression.test_utils import get_ids
|
|
||||||
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
|
||||||
from . import utils as database_utils
|
from . import utils as database_utils
|
||||||
|
|
||||||
|
|
||||||
class DatabasesUpdateTestCase(BaseTestGenerator):
|
class DatabasesUpdateTestCase(BaseTestGenerator):
|
||||||
"""
|
"""This class will update the database under last added server."""
|
||||||
This class will update the database under last added server.
|
|
||||||
"""
|
|
||||||
|
|
||||||
scenarios = [
|
scenarios = [
|
||||||
# Fetching default URL for database node.
|
# Fetching default URL for database node.
|
||||||
('Check Databases Node', dict(url='/browser/database/obj/'))
|
('Check Databases Node', dict(url='/browser/database/obj/'))
|
||||||
|
@ -29,63 +25,46 @@ class DatabasesUpdateTestCase(BaseTestGenerator):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
"""
|
cls.db_name = "test_db_put"
|
||||||
This function perform the three tasks
|
cls.db_id = utils.create_database(cls.server, cls.db_name)
|
||||||
1. Add the test server
|
|
||||||
2. Connect to server
|
|
||||||
3. Add the databases
|
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Firstly, add the server
|
|
||||||
server_utils.add_server(cls.tester)
|
|
||||||
|
|
||||||
# Connect to server
|
|
||||||
cls.server_connect_response, cls.server_group, cls.server_ids = \
|
|
||||||
server_utils.connect_server(cls.tester)
|
|
||||||
|
|
||||||
if len(cls.server_connect_response) == 0:
|
|
||||||
raise Exception("No Server(s) connected to add the database!!!")
|
|
||||||
|
|
||||||
# Add database
|
|
||||||
database_utils.add_database(cls.tester, cls.server_connect_response,
|
|
||||||
cls.server_ids)
|
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
""" This function will update the comments field of database."""
|
""" This function will update the comments field of database."""
|
||||||
|
server_id = test_server_dict["server"][0]["server_id"]
|
||||||
all_id = get_ids()
|
db_id = self.db_id
|
||||||
server_ids = all_id["sid"]
|
db_con = database_utils.verify_database(self,
|
||||||
db_ids_dict = all_id["did"][0]
|
utils.SERVER_GROUP,
|
||||||
|
server_id,
|
||||||
for server_id in server_ids:
|
db_id)
|
||||||
db_id = db_ids_dict[int(server_id)]
|
if db_con["info"] == "Database connected.":
|
||||||
db_con = database_utils.verify_database(self.tester,
|
try:
|
||||||
utils.SERVER_GROUP,
|
|
||||||
server_id,
|
|
||||||
db_id)
|
|
||||||
if db_con["info"] == "Database connected.":
|
|
||||||
data = {
|
data = {
|
||||||
"comments": advanced_config_data["db_update_data"][0]
|
"comments": advanced_config_data["db_update_data"]["comment"],
|
||||||
["comment"],
|
|
||||||
"id": db_id
|
"id": db_id
|
||||||
}
|
}
|
||||||
put_response = self.tester.put(
|
response = self.tester.put(self.url + str(utils.SERVER_GROUP) + '/' + str(
|
||||||
self.url + str(utils.SERVER_GROUP) + '/' + str(
|
|
||||||
server_id) + '/' +
|
server_id) + '/' +
|
||||||
str(db_id), data=json.dumps(data), follow_redirects=True)
|
str(db_id), data=json.dumps(data), follow_redirects=True)
|
||||||
self.assertEquals(put_response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
except Exception as exception:
|
||||||
|
raise Exception("Error while updating database details. %s" %
|
||||||
|
exception)
|
||||||
|
finally:
|
||||||
|
# Disconnect database to delete it
|
||||||
|
database_utils.disconnect_database(self, server_id, db_id)
|
||||||
|
else:
|
||||||
|
raise Exception("Error while updating database details.")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(self):
|
def tearDownClass(cls):
|
||||||
"""
|
"""
|
||||||
This function deletes the added server and 'parent_id.pkl' file
|
This function delete the database from server added in SQLite and
|
||||||
which is created in setup() function.
|
clears the node_info_dict
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
"""
|
||||||
|
connection = utils.get_db_connection(cls.server['db'],
|
||||||
database_utils.delete_database(self.tester)
|
cls.server['username'],
|
||||||
server_utils.delete_server(self.tester)
|
cls.server['db_password'],
|
||||||
utils.delete_parent_id_file()
|
cls.server['host'],
|
||||||
|
cls.server['port'])
|
||||||
|
utils.drop_database(connection, cls.db_name)
|
||||||
|
utils.clear_node_info_dict()
|
||||||
|
|
|
@ -8,11 +8,9 @@
|
||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import pickle
|
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from regression.test_setup import pickle_path, advanced_config_data
|
from regression.test_setup import advanced_config_data
|
||||||
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
||||||
from regression import test_utils as utils
|
from regression import test_utils as utils
|
||||||
|
|
||||||
|
@ -21,26 +19,11 @@ DATABASE_URL = '/browser/database/obj/'
|
||||||
DATABASE_CONNECT_URL = 'browser/database/connect/'
|
DATABASE_CONNECT_URL = 'browser/database/connect/'
|
||||||
|
|
||||||
|
|
||||||
def get_db_data(server_connect_data):
|
def get_db_data():
|
||||||
"""
|
"""This function returns the database details from json file"""
|
||||||
This function is used to get advance config test data for appropriate
|
|
||||||
server
|
|
||||||
|
|
||||||
:param server_connect_data: list of server details
|
|
||||||
:return data: database details
|
|
||||||
:rtype: dict
|
|
||||||
"""
|
|
||||||
|
|
||||||
adv_config_data = None
|
|
||||||
data = None
|
data = None
|
||||||
db_user = server_connect_data['data']['user']['name']
|
if advanced_config_data['add_database_data'] is not None:
|
||||||
|
adv_config_data = advanced_config_data['add_database_data']
|
||||||
# Get the config data of appropriate db user
|
|
||||||
for config_test_data in advanced_config_data['add_database_data']:
|
|
||||||
if db_user == config_test_data['owner']:
|
|
||||||
adv_config_data = config_test_data
|
|
||||||
|
|
||||||
if adv_config_data is not None:
|
|
||||||
data = {
|
data = {
|
||||||
"datacl": adv_config_data['privileges_acl'],
|
"datacl": adv_config_data['privileges_acl'],
|
||||||
"datconnlimit": adv_config_data['conn_limit'],
|
"datconnlimit": adv_config_data['conn_limit'],
|
||||||
|
@ -58,67 +41,13 @@ def get_db_data(server_connect_data):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def write_db_id(response_data):
|
def verify_database(self, server_group, server_id, db_id):
|
||||||
"""
|
|
||||||
This function writes the server and database related data like server
|
|
||||||
name, server id , database name, database id etc.
|
|
||||||
|
|
||||||
:param response_data: server and databases details
|
|
||||||
:type response_data: dict
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
db_id = response_data['node']['_id']
|
|
||||||
server_id = response_data['node']['_pid']
|
|
||||||
pickle_id_dict = utils.get_pickle_id_dict()
|
|
||||||
if os.path.isfile(pickle_path):
|
|
||||||
existing_server_id = open(pickle_path, 'rb')
|
|
||||||
tol_server_id = pickle.load(existing_server_id)
|
|
||||||
pickle_id_dict = tol_server_id
|
|
||||||
if 'did' in pickle_id_dict:
|
|
||||||
if pickle_id_dict['did']:
|
|
||||||
# Add the db_id as value in dict
|
|
||||||
pickle_id_dict["did"][0].update({server_id: db_id})
|
|
||||||
else:
|
|
||||||
# Create new dict with server_id and db_id
|
|
||||||
pickle_id_dict["did"].append({server_id: db_id})
|
|
||||||
db_output = open(pickle_path, 'wb')
|
|
||||||
pickle.dump(pickle_id_dict, db_output)
|
|
||||||
db_output.close()
|
|
||||||
|
|
||||||
|
|
||||||
def add_database(tester, server_connect_response, server_ids):
|
|
||||||
"""
|
|
||||||
This function add the database into servers
|
|
||||||
|
|
||||||
:param tester: flask test client
|
|
||||||
:type tester: flask test object
|
|
||||||
:param server_connect_response: server response
|
|
||||||
:type server_connect_response: dict
|
|
||||||
:param server_ids: server ids
|
|
||||||
:type server_ids: list
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
for server_connect, server_id in zip(server_connect_response, server_ids):
|
|
||||||
if server_connect['data']['connected']:
|
|
||||||
data = get_db_data(server_connect)
|
|
||||||
db_response = tester.post(DATABASE_URL + str(utils.SERVER_GROUP) +
|
|
||||||
"/" + server_id + "/",
|
|
||||||
data=json.dumps(data),
|
|
||||||
content_type='html/json')
|
|
||||||
assert db_response.status_code == 200
|
|
||||||
response_data = json.loads(db_response.data.decode('utf-8'))
|
|
||||||
write_db_id(response_data)
|
|
||||||
|
|
||||||
|
|
||||||
def verify_database(tester, server_group, server_id, db_id):
|
|
||||||
"""
|
"""
|
||||||
This function verifies that database is exists and whether it connect
|
This function verifies that database is exists and whether it connect
|
||||||
successfully or not
|
successfully or not
|
||||||
|
|
||||||
:param tester: test client
|
:param self: class object of test case class
|
||||||
:type tester: flask test client object
|
:type self: class
|
||||||
:param server_group: server group id
|
:param server_group: server group id
|
||||||
:type server_group: int
|
:type server_group: int
|
||||||
:param server_id: server id
|
:param server_id: server id
|
||||||
|
@ -130,15 +59,23 @@ def verify_database(tester, server_group, server_id, db_id):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Verify servers
|
# Verify servers
|
||||||
server_utils.verify_server(tester, server_group, server_id)
|
server_utils.connect_server(self, server_id)
|
||||||
|
|
||||||
# Connect to database
|
# Connect to database
|
||||||
con_response = tester.post('{0}{1}/{2}/{3}'.format(
|
db_con = self.tester.post('{0}{1}/{2}/{3}'.format(
|
||||||
DATABASE_CONNECT_URL, server_group, server_id, db_id),
|
DATABASE_CONNECT_URL, server_group, server_id, db_id),
|
||||||
follow_redirects=True)
|
follow_redirects=True)
|
||||||
temp_db_con = json.loads(con_response.data.decode('utf-8'))
|
self.assertEquals(db_con.status_code, 200)
|
||||||
|
db_con = json.loads(db_con.data.decode('utf-8'))
|
||||||
|
return db_con
|
||||||
|
|
||||||
return temp_db_con
|
|
||||||
|
def disconnect_database(self, server_id, db_id):
|
||||||
|
"""This function disconnect the db"""
|
||||||
|
db_con = self.tester.delete('{0}{1}/{2}/{3}'.format(
|
||||||
|
'browser/database/connect/', utils.SERVER_GROUP, server_id, db_id),
|
||||||
|
follow_redirects=True)
|
||||||
|
self.assertEquals(db_con.status_code, 200)
|
||||||
|
|
||||||
|
|
||||||
def delete_database(tester):
|
def delete_database(tester):
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#
|
#
|
||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
from regression import test_utils as utils
|
from regression import test_utils as utils
|
||||||
from . import utils as server_utils
|
from . import utils as server_utils
|
||||||
|
@ -26,17 +28,19 @@ class ServersAddTestCase(BaseTestGenerator):
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
""" This function will add the server under default server group."""
|
""" This function will add the server under default server group."""
|
||||||
|
url = "{0}{1}/".format(self.url, utils.SERVER_GROUP)
|
||||||
server_utils.add_server(self.tester)
|
response = self.tester.post(url, data=json.dumps(self.server),
|
||||||
|
content_type='html/json')
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
response_data = json.loads(response.data.decode('utf-8'))
|
||||||
|
server_id = response_data['node']['_id']
|
||||||
|
utils.write_node_info(int(server_id), "sid", self.server)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
"""
|
"""
|
||||||
This function deletes the added server and the 'parent_id.pkl' file
|
This function delete the server from SQLite & clears the node_info_dict
|
||||||
which is created in setup() function.
|
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
"""
|
||||||
|
server_id = server_utils.get_server_id()
|
||||||
server_utils.delete_server(cls.tester)
|
utils.delete_server(server_id)
|
||||||
utils.delete_parent_id_file()
|
utils.clear_node_info_dict()
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
#
|
#
|
||||||
# ##################################################################
|
# ##################################################################
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
from regression import test_utils as utils
|
from regression import test_utils as utils
|
||||||
|
|
||||||
from . import utils as server_utils
|
from . import utils as server_utils
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,28 +24,27 @@ class ServerDeleteTestCase(BaseTestGenerator):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
"""
|
"""This function add the server to test the DELETE API"""
|
||||||
This function is used to add the server
|
server_utils.add_server(cls.server)
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Firstly, add the server
|
|
||||||
server_utils.add_server(cls.tester)
|
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
""" This function will get all available servers under object browser
|
"""This function deletes the added server"""
|
||||||
and delete the last server using server id."""
|
all_id = utils.get_node_info_dict()
|
||||||
|
servers_info = all_id["sid"]
|
||||||
|
url = self.url + str(utils.SERVER_GROUP) + "/"
|
||||||
|
|
||||||
server_utils.delete_server(self.tester)
|
if len(servers_info) == 0:
|
||||||
|
raise Exception("No server to delete!!!")
|
||||||
|
|
||||||
|
# Call API to delete the servers
|
||||||
|
server_id = list(servers_info[0].keys())[0]
|
||||||
|
response = self.tester.delete(url + str(server_id))
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
response_data = json.loads(response.data.decode('utf-8'))
|
||||||
|
self.assertEquals(response_data['success'], 1)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
"""
|
"""This function calls the clear_node_info_dict() function to clears
|
||||||
This function deletes the 'parent_id.pkl' file which is created in
|
the node_info_dict"""
|
||||||
setup() function.
|
utils.clear_node_info_dict()
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
utils.delete_parent_id_file()
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
from regression import test_utils as utils
|
from regression import test_utils as utils
|
||||||
from . import utils as server_utils
|
from regression import test_server_dict
|
||||||
|
|
||||||
|
|
||||||
class ServersGetTestCase(BaseTestGenerator):
|
class ServersGetTestCase(BaseTestGenerator):
|
||||||
|
@ -23,29 +23,13 @@ class ServersGetTestCase(BaseTestGenerator):
|
||||||
('Default Server Node url', dict(url='/browser/server/obj/'))
|
('Default Server Node url', dict(url='/browser/server/obj/'))
|
||||||
]
|
]
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
"""
|
|
||||||
This function is used to add the server
|
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
server_utils.add_server(cls.tester)
|
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
""" This function will fetch the added servers to object browser. """
|
""" This function will fetch the added servers to object browser. """
|
||||||
|
server_id = test_server_dict["server"][0]["server_id"]
|
||||||
|
if not server_id:
|
||||||
|
raise Exception("Server not found to test GET API")
|
||||||
|
response = self.tester.get(self.url + str(utils.SERVER_GROUP) + '/' +
|
||||||
|
str(server_id),
|
||||||
|
follow_redirects=True)
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
server_utils.get_server(self.tester)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def tearDownClass(cls):
|
|
||||||
"""
|
|
||||||
This function deletes the added server and the 'parent_id.pkl' file
|
|
||||||
which is created in setup() function.
|
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
server_utils.delete_server(cls.tester)
|
|
||||||
utils.delete_parent_id_file()
|
|
||||||
|
|
|
@ -23,55 +23,35 @@ class ServerUpdateTestCase(BaseTestGenerator):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
"""
|
"""This function add the server to test the PUT API"""
|
||||||
This function perform the four tasks
|
server_utils.add_server(cls.server)
|
||||||
1. Add the test server
|
|
||||||
2. Get the server
|
|
||||||
3. Connect to server
|
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Firstly, add the server
|
|
||||||
server_utils.add_server(cls.tester)
|
|
||||||
|
|
||||||
# Get the server
|
|
||||||
server_utils.get_server(cls.tester)
|
|
||||||
|
|
||||||
# Connect to server
|
|
||||||
cls.server_connect, cls.server_group, cls.server_ids = \
|
|
||||||
server_utils.connect_server(cls.tester)
|
|
||||||
|
|
||||||
if len(cls.server_connect) == 0:
|
|
||||||
raise Exception("No Server(s) connected to update!!!")
|
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
""" This function will update the server's comment field. """
|
"""This function update the server details"""
|
||||||
|
all_id = utils.get_node_info_dict()
|
||||||
|
servers_info = all_id["sid"]
|
||||||
|
|
||||||
for server_id in self.server_ids:
|
if len(servers_info) == 0:
|
||||||
data = {
|
raise Exception("No server to update.")
|
||||||
"comment":
|
|
||||||
server_utils.config_data['server_update_data'][0][
|
|
||||||
'comment'],
|
|
||||||
"id": server_id
|
|
||||||
}
|
|
||||||
put_response = self.tester.put(
|
|
||||||
self.url + str(self.server_group) + '/' +
|
|
||||||
str(server_id), data=json.dumps(data),
|
|
||||||
content_type='html/json')
|
|
||||||
self.assertEquals(put_response.status_code, 200)
|
|
||||||
|
|
||||||
response_data = json.loads(put_response.data.decode())
|
server_id = list(servers_info[0].keys())[0]
|
||||||
self.assertTrue(response_data['success'], 1)
|
data = {
|
||||||
|
"comment":
|
||||||
|
server_utils.config_data['server_update_data'][0][
|
||||||
|
'comment'],
|
||||||
|
"id": server_id
|
||||||
|
}
|
||||||
|
put_response = self.tester.put(
|
||||||
|
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||||
|
str(server_id), data=json.dumps(data),
|
||||||
|
content_type='html/json')
|
||||||
|
self.assertEquals(put_response.status_code, 200)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
"""
|
"""
|
||||||
This function deletes the added server and the 'parent_id.pkl' file
|
This function delete the server from SQLite & clears the node_info_dict
|
||||||
which is created in setup() function.
|
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
"""
|
||||||
|
server_id = server_utils.get_server_id()
|
||||||
server_utils.delete_server(cls.tester)
|
utils.delete_server(server_id)
|
||||||
utils.delete_parent_id_file()
|
utils.clear_node_info_dict()
|
||||||
|
|
|
@ -7,154 +7,64 @@
|
||||||
#
|
#
|
||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
|
|
||||||
import json
|
from __future__ import print_function
|
||||||
import os
|
|
||||||
import pickle
|
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import sqlite3
|
||||||
|
import config
|
||||||
|
|
||||||
|
from regression import node_info_dict
|
||||||
from regression import test_utils as utils
|
from regression import test_utils as utils
|
||||||
from regression.test_setup import pickle_path, config_data
|
from regression.test_setup import config_data
|
||||||
|
|
||||||
SERVER_URL = '/browser/server/obj/'
|
SERVER_URL = '/browser/server/obj/'
|
||||||
SERVER_CONNECT_URL = 'browser/server/connect/'
|
SERVER_CONNECT_URL = 'browser/server/connect/'
|
||||||
|
|
||||||
|
|
||||||
def write_server_id(response_data, pickle_id_dict):
|
def get_server_id():
|
||||||
"""
|
"""This function returns the server id from node_info_dict"""
|
||||||
This function writes the server's details to file parent_id.pkl
|
|
||||||
|
|
||||||
:param response_data: server's data
|
server_id = 0
|
||||||
:type response_data: list of dictionary
|
if "sid" in node_info_dict:
|
||||||
:param pickle_id_dict: contains ids of server,database,tables etc.
|
if node_info_dict['sid']:
|
||||||
:type pickle_id_dict: dict
|
server_id = list(node_info_dict['sid'][0].keys())[0]
|
||||||
:return: None
|
return server_id
|
||||||
"""
|
|
||||||
|
|
||||||
server_id = response_data['node']['_id']
|
|
||||||
if os.path.isfile(pickle_path):
|
|
||||||
existed_server_id = open(pickle_path, 'rb')
|
|
||||||
pickle_id_dict = pickle.load(existed_server_id)
|
|
||||||
|
|
||||||
pickle_id_dict["sid"].append(str(server_id))
|
|
||||||
output = open(pickle_path, 'wb')
|
|
||||||
pickle.dump(pickle_id_dict, output)
|
|
||||||
output.close()
|
|
||||||
|
|
||||||
|
|
||||||
def add_server(tester):
|
def connect_server(self, server_id):
|
||||||
"""
|
|
||||||
This function add the server in the existing server group
|
|
||||||
|
|
||||||
:param tester: test object
|
|
||||||
:type tester: flask test object
|
|
||||||
:return:None
|
|
||||||
"""
|
|
||||||
|
|
||||||
server_group, db_data, pickle_id_dict = utils.get_config_data()
|
|
||||||
url = "{0}{1}/".format(SERVER_URL, server_group)
|
|
||||||
for db_detail in db_data:
|
|
||||||
response = tester.post(url, data=json.dumps(db_detail),
|
|
||||||
content_type='html/json')
|
|
||||||
assert response.status_code == 200
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
|
||||||
write_server_id(response_data, pickle_id_dict)
|
|
||||||
|
|
||||||
|
|
||||||
def get_server(tester):
|
|
||||||
"""
|
|
||||||
This function gets the added serer details
|
|
||||||
|
|
||||||
:param tester: test client object
|
|
||||||
:type tester: flask test object
|
|
||||||
:return: response_data
|
|
||||||
:rtype: list
|
|
||||||
"""
|
|
||||||
|
|
||||||
all_id = utils.get_ids()
|
|
||||||
server_ids = all_id["sid"]
|
|
||||||
for server_id in server_ids:
|
|
||||||
response = tester.get(SERVER_URL + str(utils.SERVER_GROUP) + '/' +
|
|
||||||
str(server_id),
|
|
||||||
follow_redirects=True)
|
|
||||||
assert response.status_code == 200
|
|
||||||
|
|
||||||
|
|
||||||
def connect_server(tester):
|
|
||||||
"""
|
"""
|
||||||
This function used to connect added server
|
This function used to connect added server
|
||||||
|
:param self: class object of server's test class
|
||||||
:param tester:test client object
|
:type self: class
|
||||||
:type tester: flask test object
|
:param server_id: flag for db add test case
|
||||||
:param add_db_flag: flag for db add test case
|
:type server_id: bool
|
||||||
:type add_db_flag: bool
|
|
||||||
:return: server_connect, server_group, server_id
|
|
||||||
:rtype: server_connect:dict, server_group:dict, server_id:str
|
|
||||||
"""
|
"""
|
||||||
|
response = self.tester.post(SERVER_CONNECT_URL + str(utils.SERVER_GROUP) +
|
||||||
server_connect = []
|
'/' + str(server_id),
|
||||||
servers = []
|
data=dict(password=self.server['db_password']),
|
||||||
server_config = None
|
follow_redirects=True)
|
||||||
|
assert response.status_code == 200
|
||||||
srv_id = utils.get_ids()
|
response_data = json.loads(response.data.decode('utf-8'))
|
||||||
server_ids = srv_id["sid"]
|
return response_data
|
||||||
|
|
||||||
# Connect to all servers
|
|
||||||
for server_id in server_ids:
|
|
||||||
response = tester.post(SERVER_CONNECT_URL + str(utils.SERVER_GROUP) +
|
|
||||||
'/' + server_id,
|
|
||||||
data=dict(
|
|
||||||
password=config_data
|
|
||||||
['server_credentials'][0]
|
|
||||||
['db_password']),
|
|
||||||
follow_redirects=True)
|
|
||||||
server_connect_detail = json.loads(response.data.decode('utf-8'))
|
|
||||||
db_user = server_connect_detail['data']['user']['name']
|
|
||||||
server_connect_detail['tablespace_path'] = None
|
|
||||||
|
|
||||||
# Get the server config of appropriate db user
|
|
||||||
for config in config_data['server_credentials']:
|
|
||||||
if db_user == config['db_username']:
|
|
||||||
server_config = config
|
|
||||||
|
|
||||||
if "tablespace_path" in server_config:
|
|
||||||
server_connect_detail['tablespace_path'] = \
|
|
||||||
server_config['tablespace_path']
|
|
||||||
|
|
||||||
server_connect.append(server_connect_detail)
|
|
||||||
servers.append(server_id)
|
|
||||||
return server_connect, utils.SERVER_GROUP, servers
|
|
||||||
|
|
||||||
|
|
||||||
def verify_server(tester, server_group, server_id):
|
def add_server(server):
|
||||||
"""This function verifies that server is connecting or not"""
|
try:
|
||||||
|
conn = sqlite3.connect(config.SQLITE_PATH)
|
||||||
response = tester.post(
|
cur = conn.cursor()
|
||||||
'{0}{1}/{2}'.format(SERVER_CONNECT_URL, server_group, server_id),
|
server_details = (
|
||||||
data=dict(password=config_data
|
1, utils.SERVER_GROUP, server['name'], server['host'],
|
||||||
['server_credentials'][0]
|
server['port'], server['db'], server['username'],
|
||||||
['db_password']),
|
server['role'], server['sslmode'],
|
||||||
follow_redirects=True)
|
server['comment'])
|
||||||
srv_connect = json.loads(response.data.decode('utf-8'))
|
cur.execute(
|
||||||
return srv_connect
|
'INSERT INTO server (user_id, servergroup_id, name, host, '
|
||||||
|
'port, maintenance_db, username, role, ssl_mode,'
|
||||||
|
' comment) VALUES (?,?,?,?,?,?,?,?,?,?)', server_details)
|
||||||
def delete_server(tester):
|
server_id = cur.lastrowid
|
||||||
"""
|
# Add server info to node_info_dict
|
||||||
This function used to delete the added servers
|
utils.write_node_info(int(server_id), "sid", server)
|
||||||
|
conn.commit()
|
||||||
:param tester: test client object
|
except Exception as err:
|
||||||
:return: None
|
raise Exception(err)
|
||||||
"""
|
|
||||||
|
|
||||||
all_id = utils.get_ids()
|
|
||||||
server_ids = all_id["sid"]
|
|
||||||
url = SERVER_URL + str(utils.SERVER_GROUP) + "/"
|
|
||||||
|
|
||||||
if len(server_ids) == 0:
|
|
||||||
raise Exception("No server(s) to delete!!!")
|
|
||||||
|
|
||||||
# Call api to delete the servers
|
|
||||||
for server_id in server_ids:
|
|
||||||
response = tester.delete(url + str(server_id))
|
|
||||||
assert response.status_code == 200
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
|
||||||
assert response_data['success'] == 1
|
|
||||||
|
|
|
@ -7,8 +7,14 @@
|
||||||
#
|
#
|
||||||
##############################################################
|
##############################################################
|
||||||
|
|
||||||
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
|
from importlib import import_module
|
||||||
|
from werkzeug.utils import find_modules
|
||||||
|
|
||||||
|
import config
|
||||||
|
|
||||||
|
|
||||||
class TestsGeneratorRegistry(ABCMeta):
|
class TestsGeneratorRegistry(ABCMeta):
|
||||||
|
@ -43,20 +49,26 @@ class TestsGeneratorRegistry(ABCMeta):
|
||||||
|
|
||||||
ABCMeta.__init__(cls, name, bases, d)
|
ABCMeta.__init__(cls, name, bases, d)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def import_app_modules(module_name):
|
||||||
|
"""As we are running test suite for each server. To catch
|
||||||
|
the test cases, delete the previously imported module
|
||||||
|
"""
|
||||||
|
if str(module_name) in sys.modules.keys():
|
||||||
|
del sys.modules[module_name]
|
||||||
|
import_module(module_name)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_generators(cls, pkg):
|
def load_generators(cls, pkg):
|
||||||
|
|
||||||
cls.registry = dict()
|
cls.registry = dict()
|
||||||
|
|
||||||
from importlib import import_module
|
|
||||||
from werkzeug.utils import find_modules
|
|
||||||
import config
|
|
||||||
|
|
||||||
# Check for SERVER mode
|
# Check for SERVER mode
|
||||||
if config.SERVER_MODE:
|
if config.SERVER_MODE:
|
||||||
for module_name in find_modules(pkg, False, True):
|
for module_name in find_modules(pkg, False, True):
|
||||||
try:
|
try:
|
||||||
module = import_module(module_name)
|
if "tests." in str(module_name):
|
||||||
|
cls.import_app_modules(module_name)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -65,7 +77,7 @@ class TestsGeneratorRegistry(ABCMeta):
|
||||||
# Exclude the test cases in browser node if SERVER_MODE
|
# Exclude the test cases in browser node if SERVER_MODE
|
||||||
# is False
|
# is False
|
||||||
if "pgadmin.browser.tests" not in module_name:
|
if "pgadmin.browser.tests" not in module_name:
|
||||||
module = import_module(module_name)
|
cls.import_app_modules(module_name)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -75,6 +87,11 @@ import six
|
||||||
@six.add_metaclass(TestsGeneratorRegistry)
|
@six.add_metaclass(TestsGeneratorRegistry)
|
||||||
class BaseTestGenerator(unittest.TestCase):
|
class BaseTestGenerator(unittest.TestCase):
|
||||||
# Defining abstract method which will override by individual testcase.
|
# Defining abstract method which will override by individual testcase.
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setTestServer(cls, server):
|
||||||
|
cls.server = server
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
# ##########################################################################
|
||||||
|
#
|
||||||
|
# #pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# #Copyright (C) 2013 - 2016, The pgAdmin Development Team
|
||||||
|
# #This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
# ##########################################################################
|
||||||
|
|
||||||
|
global node_info_dict
|
||||||
|
node_info_dict = {
|
||||||
|
"sid": [], # server
|
||||||
|
"did": [], # database
|
||||||
|
"lrid": [], # role
|
||||||
|
"tsid": [], # tablespace
|
||||||
|
"scid": [], # schema
|
||||||
|
"tfnid": [], # trigger functions
|
||||||
|
"coid": [], # collation
|
||||||
|
"cid": [], # casts
|
||||||
|
"etid": [], # event_trigger
|
||||||
|
"eid": [], # extension
|
||||||
|
"fid": [], # FDW
|
||||||
|
"fsid": [], # FRS
|
||||||
|
"umid": [], # user_mapping
|
||||||
|
"seid": [] # sequence
|
||||||
|
}
|
||||||
|
|
||||||
|
global test_server_dict
|
||||||
|
test_server_dict = {
|
||||||
|
"server": [],
|
||||||
|
"database": []
|
||||||
|
}
|
|
@ -9,10 +9,13 @@
|
||||||
|
|
||||||
""" This file collect all modules/files present in tests directory and add
|
""" This file collect all modules/files present in tests directory and add
|
||||||
them to TestSuite. """
|
them to TestSuite. """
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import signal
|
||||||
|
import atexit
|
||||||
import unittest
|
import unittest
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -25,30 +28,60 @@ root = os.path.dirname(CURRENT_PATH)
|
||||||
|
|
||||||
if sys.path[0] != root:
|
if sys.path[0] != root:
|
||||||
sys.path.insert(0, root)
|
sys.path.insert(0, root)
|
||||||
|
os.chdir(root)
|
||||||
|
|
||||||
from pgadmin import create_app
|
from pgadmin import create_app
|
||||||
import config
|
import config
|
||||||
|
import test_setup
|
||||||
|
|
||||||
|
# Execute setup.py if test SQLite database doesn't exist.
|
||||||
|
if os.path.isfile(config.TEST_SQLITE_PATH):
|
||||||
|
print("The configuration database already exists at '%s'. "
|
||||||
|
"Please remove the database and re-run the test suite." %
|
||||||
|
config.TEST_SQLITE_PATH)
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
config.TESTING_MODE = True
|
||||||
|
pgadmin_credentials = test_setup.config_data
|
||||||
|
|
||||||
|
# Set environment variables for email and password
|
||||||
|
os.environ['PGADMIN_SETUP_EMAIL'] = ''
|
||||||
|
os.environ['PGADMIN_SETUP_PASSWORD'] = ''
|
||||||
|
if pgadmin_credentials:
|
||||||
|
if 'pgAdmin4_login_credentials' in pgadmin_credentials:
|
||||||
|
if all(item in pgadmin_credentials['pgAdmin4_login_credentials']
|
||||||
|
for item in ['login_username', 'login_password']):
|
||||||
|
pgadmin_credentials = pgadmin_credentials[
|
||||||
|
'pgAdmin4_login_credentials']
|
||||||
|
os.environ['PGADMIN_SETUP_EMAIL'] = pgadmin_credentials[
|
||||||
|
'login_username']
|
||||||
|
os.environ['PGADMIN_SETUP_PASSWORD'] = pgadmin_credentials[
|
||||||
|
'login_password']
|
||||||
|
|
||||||
|
# Execute the setup file
|
||||||
|
exec (open("setup.py").read())
|
||||||
|
|
||||||
# Get the config database schema version. We store this in pgadmin.model
|
# Get the config database schema version. We store this in pgadmin.model
|
||||||
# as it turns out that putting it in the config files isn't a great idea
|
# as it turns out that putting it in the config files isn't a great idea
|
||||||
from pgadmin.model import SCHEMA_VERSION
|
from pgadmin.model import SCHEMA_VERSION
|
||||||
from test_utils import login_tester_account, logout_tester_account
|
|
||||||
|
# Delay the import test_utils as it needs updated config.SQLITE_PATH
|
||||||
|
import test_utils
|
||||||
|
|
||||||
config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION
|
config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION
|
||||||
|
|
||||||
# Override some other defaults
|
# Override some other defaults
|
||||||
from logging import WARNING
|
from logging import WARNING
|
||||||
|
|
||||||
config.CONSOLE_LOG_LEVEL = WARNING
|
config.CONSOLE_LOG_LEVEL = WARNING
|
||||||
|
|
||||||
# Create the app
|
# Create the app
|
||||||
app = create_app()
|
app = create_app()
|
||||||
app.config['WTF_CSRF_ENABLED'] = False
|
app.config['WTF_CSRF_ENABLED'] = False
|
||||||
test_client = app.test_client()
|
test_client = app.test_client()
|
||||||
# Login the test client
|
|
||||||
login_tester_account(test_client)
|
|
||||||
|
|
||||||
|
|
||||||
def get_suite(arguments, test_app_client):
|
def get_suite(arguments, server, test_app_client):
|
||||||
"""
|
"""
|
||||||
This function loads the all modules in the tests directory into testing
|
This function loads the all modules in the tests directory into testing
|
||||||
environment.
|
environment.
|
||||||
|
@ -56,6 +89,8 @@ def get_suite(arguments, test_app_client):
|
||||||
:param arguments: this is command line arguments for module name to
|
:param arguments: this is command line arguments for module name to
|
||||||
which test suite will run
|
which test suite will run
|
||||||
:type arguments: str
|
:type arguments: str
|
||||||
|
:param server: server details
|
||||||
|
:type server: dict
|
||||||
:param test_app_client: test client
|
:param test_app_client: test client
|
||||||
:type test_app_client: pgadmin app object
|
:type test_app_client: pgadmin app object
|
||||||
:return pgadmin_suite: test suite with test cases
|
:return pgadmin_suite: test suite with test cases
|
||||||
|
@ -71,18 +106,24 @@ def get_suite(arguments, test_app_client):
|
||||||
if arguments['pkg'] is None or arguments['pkg'] == "all":
|
if arguments['pkg'] is None or arguments['pkg'] == "all":
|
||||||
TestsGeneratorRegistry.load_generators('pgadmin')
|
TestsGeneratorRegistry.load_generators('pgadmin')
|
||||||
else:
|
else:
|
||||||
TestsGeneratorRegistry.load_generators('pgadmin.{}.tests'.format(
|
TestsGeneratorRegistry.load_generators('pgadmin.%s.tests' %
|
||||||
arguments['pkg']))
|
arguments['pkg'])
|
||||||
|
|
||||||
|
# Sort module list so that test suite executes the test cases sequentially
|
||||||
|
module_list = TestsGeneratorRegistry.registry.items()
|
||||||
|
module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
|
||||||
|
|
||||||
# Get the each test module and add into list
|
# Get the each test module and add into list
|
||||||
for key, klass in TestsGeneratorRegistry.registry.items():
|
for key, klass in module_list:
|
||||||
gen = klass
|
gen = klass
|
||||||
modules.append(gen)
|
modules.append(gen)
|
||||||
|
|
||||||
# Set the test client to each module & generate the scenarios
|
# Set the test client to each module & generate the scenarios
|
||||||
for module in modules:
|
for module in modules:
|
||||||
obj = module()
|
obj = module()
|
||||||
|
obj.setApp(app)
|
||||||
obj.setTestClient(test_app_client)
|
obj.setTestClient(test_app_client)
|
||||||
|
obj.setTestServer(server)
|
||||||
scenario = generate_scenarios(obj)
|
scenario = generate_scenarios(obj)
|
||||||
pgadmin_suite.addTests(scenario)
|
pgadmin_suite.addTests(scenario)
|
||||||
|
|
||||||
|
@ -106,6 +147,10 @@ def add_arguments():
|
||||||
return arg
|
return arg
|
||||||
|
|
||||||
|
|
||||||
|
def sig_handler(signo, frame):
|
||||||
|
test_utils.drop_objects()
|
||||||
|
|
||||||
|
|
||||||
class StreamToLogger(object):
|
class StreamToLogger(object):
|
||||||
def __init__(self, logger, log_level=logging.INFO):
|
def __init__(self, logger, log_level=logging.INFO):
|
||||||
self.terminal = sys.stderr
|
self.terminal = sys.stderr
|
||||||
|
@ -131,6 +176,14 @@ class StreamToLogger(object):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
# Register cleanup function to cleanup on exit
|
||||||
|
atexit.register(test_utils.drop_objects)
|
||||||
|
# Set signal handler for cleanup
|
||||||
|
signal.signal(signal.SIGTERM, sig_handler)
|
||||||
|
signal.signal(signal.SIGABRT, sig_handler)
|
||||||
|
signal.signal(signal.SIGINT, sig_handler)
|
||||||
|
signal.signal(signal.SIGQUIT, sig_handler)
|
||||||
|
|
||||||
# Set basic logging configuration for log file
|
# Set basic logging configuration for log file
|
||||||
logging.basicConfig(level=logging.DEBUG,
|
logging.basicConfig(level=logging.DEBUG,
|
||||||
format='%(asctime)s:%(levelname)s:%(name)s:%(message)s'
|
format='%(asctime)s:%(levelname)s:%(name)s:%(message)s'
|
||||||
|
@ -144,11 +197,25 @@ if __name__ == '__main__':
|
||||||
sys.stderr = StreamToLogger(stderr_logger, logging.ERROR)
|
sys.stderr = StreamToLogger(stderr_logger, logging.ERROR)
|
||||||
|
|
||||||
args = vars(add_arguments())
|
args = vars(add_arguments())
|
||||||
suite = get_suite(args, test_client)
|
|
||||||
tests = unittest.TextTestRunner(stream=sys.stderr, descriptions=True,
|
|
||||||
verbosity=2).run(suite)
|
|
||||||
|
|
||||||
# Logout the test client
|
servers_info = test_utils.get_config_data()
|
||||||
logout_tester_account(test_client)
|
try:
|
||||||
|
for server in servers_info:
|
||||||
|
print("\n=============Running the test cases for '%s'============="
|
||||||
|
% server['name'], file=sys.stderr)
|
||||||
|
test_utils.create_test_server(server)
|
||||||
|
# Login the test client
|
||||||
|
test_utils.login_tester_account(test_client)
|
||||||
|
|
||||||
|
suite = get_suite(args, server, test_client)
|
||||||
|
tests = unittest.TextTestRunner(stream=sys.stderr,
|
||||||
|
descriptions=True,
|
||||||
|
verbosity=2).run(suite)
|
||||||
|
# Logout the test client
|
||||||
|
test_utils.logout_tester_account(test_client)
|
||||||
|
|
||||||
|
test_utils.delete_test_server(server)
|
||||||
|
except SystemExit:
|
||||||
|
test_utils.drop_objects()
|
||||||
|
|
||||||
print("Please check output in file: %s/regression.log " % CURRENT_PATH)
|
print("Please check output in file: %s/regression.log " % CURRENT_PATH)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"add_database_data": [
|
"add_database_data":
|
||||||
{
|
{
|
||||||
"privileges_acl": [
|
"privileges_acl": [
|
||||||
{
|
{
|
||||||
|
@ -93,13 +93,11 @@
|
||||||
"privileges": [],
|
"privileges": [],
|
||||||
"securities": [],
|
"securities": [],
|
||||||
"variables": []
|
"variables": []
|
||||||
}
|
},
|
||||||
],
|
"db_update_data":
|
||||||
"db_update_data": [
|
|
||||||
{
|
{
|
||||||
"comment": "This is db update comment"
|
"comment": "This is db update comment"
|
||||||
}
|
},
|
||||||
],
|
|
||||||
|
|
||||||
"lr_credentials": {
|
"lr_credentials": {
|
||||||
"can_login": "true",
|
"can_login": "true",
|
||||||
|
@ -445,7 +443,7 @@
|
||||||
{
|
{
|
||||||
"comment": "This is event trigger update comment"
|
"comment": "This is event trigger update comment"
|
||||||
},
|
},
|
||||||
|
|
||||||
"sequence_credentials":
|
"sequence_credentials":
|
||||||
[{
|
[{
|
||||||
"cache": "1",
|
"cache": "1",
|
||||||
|
@ -492,5 +490,3 @@
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,9 @@
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))
|
CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
# with open(CURRENT_PATH + '/test_config.json') as data_file:
|
|
||||||
# config_data = json.load(data_file)
|
|
||||||
#
|
|
||||||
# with open(CURRENT_PATH + '/test_advanced_config.json') as data_file:
|
|
||||||
# advanced_config_data = json.load(data_file)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(CURRENT_PATH + '/test_config.json') as data_file:
|
with open(CURRENT_PATH + '/test_config.json') as data_file:
|
||||||
|
@ -31,5 +27,3 @@ try:
|
||||||
except:
|
except:
|
||||||
with open(CURRENT_PATH + '/test_advanced_config.json.in') as data_file:
|
with open(CURRENT_PATH + '/test_advanced_config.json.in') as data_file:
|
||||||
advanced_config_data = json.load(data_file)
|
advanced_config_data = json.load(data_file)
|
||||||
|
|
||||||
pickle_path = os.path.join(CURRENT_PATH, 'parent_id.pkl')
|
|
||||||
|
|
|
@ -6,87 +6,52 @@
|
||||||
# This software is released under the PostgreSQL Licence
|
# This software is released under the PostgreSQL Licence
|
||||||
#
|
#
|
||||||
# ##################################################################
|
# ##################################################################
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pickle
|
import sys
|
||||||
from test_setup import config_data, pickle_path
|
import psycopg2
|
||||||
|
import sqlite3
|
||||||
|
import config
|
||||||
|
|
||||||
|
import test_setup
|
||||||
|
import regression
|
||||||
|
|
||||||
|
SERVER_GROUP = test_setup.config_data['server_group']
|
||||||
|
|
||||||
|
|
||||||
SERVER_GROUP = config_data['server_group']
|
def get_db_connection(db, username, password, host, port):
|
||||||
|
"""This function retruns the connection object of psycopg"""
|
||||||
|
connection = psycopg2.connect(database=db,
|
||||||
|
user=username,
|
||||||
|
password=password,
|
||||||
|
host=host,
|
||||||
|
port=port)
|
||||||
|
return connection
|
||||||
|
|
||||||
|
|
||||||
def get_pickle_id_dict():
|
def get_node_info_dict():
|
||||||
"""This function returns the empty dict of server config data"""
|
return regression.node_info_dict
|
||||||
|
|
||||||
pickle_id_dict = {
|
|
||||||
"sid": [], # server
|
|
||||||
"did": [], # database
|
|
||||||
"lrid": [], # role
|
|
||||||
"tsid": [], # tablespace
|
|
||||||
"scid": [], # schema
|
|
||||||
"tfnid": [], # trigger functions
|
|
||||||
"coid": [], # collation
|
|
||||||
"cid": [], # casts
|
|
||||||
"etid": [], # event_trigger
|
|
||||||
"eid": [], # extension
|
|
||||||
"fid": [], # FDW
|
|
||||||
"fsid": [], # FRS
|
|
||||||
"umid": [], # user_mapping
|
|
||||||
"seid": [] # sequence
|
|
||||||
}
|
|
||||||
return pickle_id_dict
|
|
||||||
|
|
||||||
|
|
||||||
def get_ids(url=pickle_path):
|
|
||||||
"""
|
|
||||||
This function read the parent node's id and return it
|
|
||||||
|
|
||||||
:param url: file path from which it will red the ids
|
|
||||||
:type url: str
|
|
||||||
:return: node ids
|
|
||||||
:rtype: dict
|
|
||||||
"""
|
|
||||||
|
|
||||||
output = open(url, 'rb')
|
|
||||||
ids = pickle.load(output)
|
|
||||||
output.close()
|
|
||||||
return ids
|
|
||||||
|
|
||||||
|
|
||||||
# def test_getnodes(tester=None):
|
|
||||||
# # Connect to server and database.
|
|
||||||
#
|
|
||||||
# if not tester:
|
|
||||||
# return None
|
|
||||||
#
|
|
||||||
# all_id = get_ids()
|
|
||||||
#
|
|
||||||
# server_ids = all_id["sid"]
|
|
||||||
# db_ids_dict = all_id["did"][0]
|
|
||||||
#
|
|
||||||
# db_con = []
|
|
||||||
# for server_id in server_ids:
|
|
||||||
# db_id = db_ids_dict[int(server_id)]
|
|
||||||
# db_con.append(verify_database(tester, SERVER_GROUP, server_id, db_id))
|
|
||||||
# return db_con
|
|
||||||
|
|
||||||
|
|
||||||
def login_tester_account(tester):
|
def login_tester_account(tester):
|
||||||
"""
|
"""
|
||||||
This function login the test account using credentials mentioned in
|
This function login the test client using env variables email and password
|
||||||
config file
|
|
||||||
|
|
||||||
:param tester: test client
|
:param tester: test client
|
||||||
:type tester: flask test client object
|
:type tester: flask test client object
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
if os.environ['PGADMIN_SETUP_EMAIL'] and os.environ[
|
||||||
email = \
|
'PGADMIN_SETUP_PASSWORD']:
|
||||||
config_data['pgAdmin4_login_credentials']['login_username']
|
email = os.environ['PGADMIN_SETUP_EMAIL']
|
||||||
password = \
|
password = os.environ['PGADMIN_SETUP_PASSWORD']
|
||||||
config_data['pgAdmin4_login_credentials']['login_password']
|
tester.post('/login', data=dict(email=email, password=password),
|
||||||
response = tester.post('/login', data=dict(
|
follow_redirects=True)
|
||||||
email=email, password=password), follow_redirects=True)
|
else:
|
||||||
|
print("Unable to login test client, email and password not found.",
|
||||||
|
file=sys.stderr)
|
||||||
|
drop_objects()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def logout_tester_account(tester):
|
def logout_tester_account(tester):
|
||||||
|
@ -101,63 +66,231 @@ def logout_tester_account(tester):
|
||||||
response = tester.get('/logout')
|
response = tester.get('/logout')
|
||||||
|
|
||||||
|
|
||||||
# Config data for parent_id.pkl
|
|
||||||
def get_config_data():
|
def get_config_data():
|
||||||
"""
|
"""This function reads the server data from config_data"""
|
||||||
This function get the data related to server group and database
|
server_data = []
|
||||||
like db name, host, port and username etc.
|
for srv in test_setup.config_data['server_credentials']:
|
||||||
|
|
||||||
:return: server_group, db_data, pickle_id_dict
|
|
||||||
:rtype: server_group:dict, db_data:list, pickle_id_dict:dict
|
|
||||||
"""
|
|
||||||
|
|
||||||
db_data = []
|
|
||||||
pickle_id_dict = get_pickle_id_dict()
|
|
||||||
server_group = config_data['server_group']
|
|
||||||
|
|
||||||
for srv in config_data['server_credentials']:
|
|
||||||
data = {"name": srv['name'],
|
data = {"name": srv['name'],
|
||||||
"comment": "",
|
"comment": "",
|
||||||
"host": srv['host'],
|
"host": srv['host'],
|
||||||
"port": srv['db_port'],
|
"port": srv['db_port'],
|
||||||
"db": srv['maintenance_db'],
|
"db": srv['maintenance_db'],
|
||||||
"username": srv['db_username'],
|
"username": srv['db_username'],
|
||||||
|
"db_password": srv['db_password'],
|
||||||
"role": "",
|
"role": "",
|
||||||
"sslmode": srv['sslmode']}
|
"sslmode": srv['sslmode'],
|
||||||
db_data.append(data)
|
"tablespace_path": srv['tablespace_path']}
|
||||||
return server_group, db_data, pickle_id_dict
|
server_data.append(data)
|
||||||
|
return server_data
|
||||||
|
|
||||||
|
|
||||||
def write_parent_id(response_data, pickle_id_dict):
|
def write_node_info(node_id, key, node_info=None):
|
||||||
"""
|
"""
|
||||||
This function writes the server's details to file parent_id.pkl
|
This function append the node details to
|
||||||
|
:param node_id: node id
|
||||||
|
:type node_id: int
|
||||||
|
:param key: dict key name to store node info
|
||||||
|
:type key: str
|
||||||
|
:param node_info: node details
|
||||||
|
:type node_info: dict
|
||||||
|
:return: node_info_dict
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
node_info_dict = regression.node_info_dict
|
||||||
|
if node_info_dict:
|
||||||
|
if key in node_info_dict and node_info_dict[key]:
|
||||||
|
node_info_dict[key].append({node_id: node_info})
|
||||||
|
else:
|
||||||
|
node_info_dict[key] = [{node_id: node_info}]
|
||||||
|
else:
|
||||||
|
raise Exception("node_info_dict is null.")
|
||||||
|
|
||||||
:param response_data: server's data
|
|
||||||
:type response_data: list of dictionary
|
def clear_node_info_dict():
|
||||||
:param pickle_id_dict: contains ids of server,database,tables etc.
|
"""This function used to clears the node_info_dict variable"""
|
||||||
:type pickle_id_dict: dict
|
node_info_dict = regression.node_info_dict
|
||||||
|
for node in node_info_dict:
|
||||||
|
del node_info_dict[node][:]
|
||||||
|
|
||||||
|
|
||||||
|
def create_database(server, db_name):
|
||||||
|
"""This function used to create database and returns the database id"""
|
||||||
|
try:
|
||||||
|
connection = get_db_connection(server['db'],
|
||||||
|
server['username'],
|
||||||
|
server['db_password'],
|
||||||
|
server['host'],
|
||||||
|
server['port'])
|
||||||
|
old_isolation_level = connection.isolation_level
|
||||||
|
connection.set_isolation_level(0)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
pg_cursor.execute("CREATE DATABASE %s" % db_name)
|
||||||
|
connection.set_isolation_level(old_isolation_level)
|
||||||
|
connection.commit()
|
||||||
|
|
||||||
|
# Get 'oid' from newly created database
|
||||||
|
pg_cursor.execute(
|
||||||
|
"SELECT db.oid from pg_database db WHERE db.datname='%s'" %
|
||||||
|
db_name)
|
||||||
|
oid = pg_cursor.fetchone()
|
||||||
|
db_id = ''
|
||||||
|
if oid:
|
||||||
|
db_id = oid[0]
|
||||||
|
connection.close()
|
||||||
|
return db_id
|
||||||
|
except Exception as exception:
|
||||||
|
raise Exception("Error while creating database. %s" % exception)
|
||||||
|
|
||||||
|
|
||||||
|
def drop_database(connection, db_name):
|
||||||
|
"""This function used to drop the database"""
|
||||||
|
try:
|
||||||
|
old_isolation_level = connection.isolation_level
|
||||||
|
connection.set_isolation_level(0)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
pg_cursor.execute('''DROP DATABASE "%s"''' % db_name)
|
||||||
|
connection.set_isolation_level(old_isolation_level)
|
||||||
|
connection.commit()
|
||||||
|
connection.close()
|
||||||
|
except Exception as exception:
|
||||||
|
raise Exception("Exception while dropping the database. %s" %
|
||||||
|
exception)
|
||||||
|
|
||||||
|
|
||||||
|
def create_server(server):
|
||||||
|
"""This function is used to create server"""
|
||||||
|
try:
|
||||||
|
conn = sqlite3.connect(config.SQLITE_PATH)
|
||||||
|
# Create the server
|
||||||
|
cur = conn.cursor()
|
||||||
|
server_details = (1, SERVER_GROUP, server['name'], server['host'],
|
||||||
|
server['port'], server['db'], server['username'],
|
||||||
|
server['role'], server['sslmode'], server['comment'])
|
||||||
|
cur.execute('INSERT INTO server (user_id, servergroup_id, name, host, '
|
||||||
|
'port, maintenance_db, username, role, ssl_mode,'
|
||||||
|
' comment) VALUES (?,?,?,?,?,?,?,?,?,?)', server_details)
|
||||||
|
server_id = cur.lastrowid
|
||||||
|
conn.commit()
|
||||||
|
return server_id
|
||||||
|
except Exception as exception:
|
||||||
|
raise Exception("Error while creating server. %s" % exception)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_server(sid):
|
||||||
|
"""This function used to delete server from SQLite"""
|
||||||
|
try:
|
||||||
|
conn = sqlite3.connect(config.SQLITE_PATH)
|
||||||
|
cur = conn.cursor()
|
||||||
|
servers = cur.execute('SELECT * FROM server WHERE id=%s' % sid)
|
||||||
|
servers_count = len(servers.fetchall())
|
||||||
|
if servers_count:
|
||||||
|
cur.execute('DELETE FROM server WHERE id=%s' % sid)
|
||||||
|
conn.commit()
|
||||||
|
else:
|
||||||
|
print("No servers found to delete.", file=sys.stderr)
|
||||||
|
except Exception as err:
|
||||||
|
raise Exception("Error while deleting server %s" % err)
|
||||||
|
|
||||||
|
|
||||||
|
def create_test_server(server):
|
||||||
|
"""
|
||||||
|
This function create the test server which will act as parent server,
|
||||||
|
the other node will add under this server
|
||||||
|
:param server: server details
|
||||||
|
:type server: dict
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
# Create the server
|
||||||
|
server_id = create_server(server)
|
||||||
|
|
||||||
server_id = response_data['node']['_id']
|
# Create test database
|
||||||
if os.path.isfile(pickle_path):
|
test_db_name = "test_db"
|
||||||
existed_server_id = open(pickle_path, 'rb')
|
db_id = create_database(server, test_db_name)
|
||||||
pickle_id_dict = pickle.load(existed_server_id)
|
|
||||||
|
|
||||||
pickle_id_dict["sid"].append(str(server_id))
|
# Add server info to test_server_dict
|
||||||
output = open(pickle_path, 'wb')
|
regression.test_server_dict["server"].append({"server_id": server_id,
|
||||||
pickle.dump(pickle_id_dict, output)
|
"server": server})
|
||||||
output.close()
|
regression.test_server_dict["database"].append({"server_id": server_id,
|
||||||
|
"db_id": db_id,
|
||||||
|
"db_name": test_db_name})
|
||||||
|
|
||||||
|
|
||||||
def delete_parent_id_file():
|
def delete_test_server(server):
|
||||||
"""
|
test_server_dict = regression.test_server_dict
|
||||||
This function deletes the file parent_id.pkl which contains server and
|
if test_server_dict:
|
||||||
database details
|
connection = get_db_connection(server['db'],
|
||||||
|
server['username'],
|
||||||
|
server['db_password'],
|
||||||
|
server['host'],
|
||||||
|
server['port'])
|
||||||
|
db_name = test_server_dict["database"][0]["db_name"]
|
||||||
|
drop_database(connection, db_name)
|
||||||
|
# Delete the server
|
||||||
|
server_id = test_server_dict['server'][0]["server_id"]
|
||||||
|
conn = sqlite3.connect(config.SQLITE_PATH)
|
||||||
|
cur = conn.cursor()
|
||||||
|
servers = cur.execute('SELECT * FROM server WHERE id=%s' % server_id)
|
||||||
|
servers_count = len(servers.fetchall())
|
||||||
|
if servers_count:
|
||||||
|
cur.execute('DELETE FROM server WHERE id=%s' % server_id)
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
server_dict = regression.test_server_dict["server"]
|
||||||
|
|
||||||
:return: None
|
# Pop the server from dict if it's deleted
|
||||||
"""
|
server_dict = [server_dict.pop(server_dict.index(item))
|
||||||
|
for item in server_dict
|
||||||
|
if str(server_id) == str(item["server_id"])]
|
||||||
|
|
||||||
if os.path.isfile(pickle_path):
|
# Pop the db from dict if it's deleted
|
||||||
os.remove(pickle_path)
|
db_dict = regression.test_server_dict["database"]
|
||||||
|
db_dict = [db_dict.pop(db_dict.index(item)) for item in db_dict
|
||||||
|
if server_id == item["server_id"]]
|
||||||
|
|
||||||
|
|
||||||
|
def drop_objects():
|
||||||
|
"""This function use to cleanup the created the objects(servers, databases,
|
||||||
|
schemas etc) during the test suite run"""
|
||||||
|
|
||||||
|
# Cleanup in node_info_dict
|
||||||
|
servers_info = regression.node_info_dict['sid']
|
||||||
|
if servers_info:
|
||||||
|
for server in servers_info:
|
||||||
|
server_id = server.keys()[0]
|
||||||
|
server = server.values()[0]
|
||||||
|
if regression.node_info_dict['did']:
|
||||||
|
db_conn = get_db_connection(server['db'],
|
||||||
|
server['username'],
|
||||||
|
server['db_password'],
|
||||||
|
server['host'],
|
||||||
|
server['port'])
|
||||||
|
db_dict = regression.node_info_dict['did'][0]
|
||||||
|
if int(server_id) in db_dict:
|
||||||
|
db_name = db_dict[int(server_id)]["db_name"]
|
||||||
|
drop_database(db_conn, db_name)
|
||||||
|
delete_server(server_id)
|
||||||
|
|
||||||
|
# Cleanup in test_server_dict
|
||||||
|
servers = regression.test_server_dict["server"]
|
||||||
|
if servers:
|
||||||
|
for server in servers:
|
||||||
|
server_id = server["server_id"]
|
||||||
|
server = server["server"]
|
||||||
|
if regression.test_server_dict["database"]:
|
||||||
|
db_info = regression.test_server_dict["database"]
|
||||||
|
db_dict = [item for item in db_info
|
||||||
|
if server_id == item["server_id"]]
|
||||||
|
if db_dict:
|
||||||
|
for db in db_dict:
|
||||||
|
db_name = db["db_name"]
|
||||||
|
db_conn = get_db_connection(server['db'],
|
||||||
|
server['username'],
|
||||||
|
server['db_password'],
|
||||||
|
server['host'],
|
||||||
|
server['port'])
|
||||||
|
drop_database(db_conn, db_name)
|
||||||
|
delete_server(server_id)
|
||||||
|
|
||||||
|
# Remove the test SQLite database
|
||||||
|
if os.path.isfile(config.SQLITE_PATH):
|
||||||
|
os.remove(config.SQLITE_PATH)
|
||||||
|
|
|
@ -29,6 +29,7 @@ import config
|
||||||
# Get the config database schema version. We store this in pgadmin.model
|
# Get the config database schema version. We store this in pgadmin.model
|
||||||
# as it turns out that putting it in the config files isn't a great idea
|
# as it turns out that putting it in the config files isn't a great idea
|
||||||
from pgadmin.model import SCHEMA_VERSION
|
from pgadmin.model import SCHEMA_VERSION
|
||||||
|
|
||||||
config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION
|
config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION
|
||||||
|
|
||||||
# If script is running under python2 then change the behaviour of functions
|
# If script is running under python2 then change the behaviour of functions
|
||||||
|
@ -50,30 +51,40 @@ def do_setup(app):
|
||||||
else:
|
else:
|
||||||
print("NOTE: Configuring authentication for SERVER mode.\n")
|
print("NOTE: Configuring authentication for SERVER mode.\n")
|
||||||
|
|
||||||
# Prompt the user for their default username and password.
|
if all(value in os.environ for value in
|
||||||
print("""
|
['PGADMIN_SETUP_EMAIL', 'PGADMIN_SETUP_PASSWORD']):
|
||||||
Enter the email address and password to use for the initial pgAdmin user \
|
email = ''
|
||||||
account:\n""")
|
p1 = ''
|
||||||
email_filter = re.compile(
|
if os.environ['PGADMIN_SETUP_EMAIL'] and os.environ[
|
||||||
"^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9]"
|
'PGADMIN_SETUP_PASSWORD']:
|
||||||
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9]"
|
email = os.environ['PGADMIN_SETUP_EMAIL']
|
||||||
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
|
p1 = os.environ['PGADMIN_SETUP_PASSWORD']
|
||||||
|
else:
|
||||||
|
# Prompt the user for their default username and password.
|
||||||
|
print("""
|
||||||
|
Enter the email address and password to use for the initial pgAdmin user \
|
||||||
|
account:\n""")
|
||||||
|
email_filter = re.compile(
|
||||||
|
"^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9]"
|
||||||
|
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9]"
|
||||||
|
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
|
||||||
|
|
||||||
email = input("Email address: ")
|
|
||||||
while email == '' or not email_filter.match(email):
|
|
||||||
print('Invalid email address. Please try again.')
|
|
||||||
email = input("Email address: ")
|
email = input("Email address: ")
|
||||||
|
while email == '' or not email_filter.match(email):
|
||||||
|
print('Invalid email address. Please try again.')
|
||||||
|
email = input("Email address: ")
|
||||||
|
|
||||||
def pprompt():
|
def pprompt():
|
||||||
return getpass.getpass(), getpass.getpass('Retype password:')
|
return getpass.getpass(), getpass.getpass('Retype password:')
|
||||||
|
|
||||||
p1, p2 = pprompt()
|
|
||||||
while p1 != p2 or len(p1) < 6:
|
|
||||||
if p1 != p2:
|
|
||||||
print('Passwords do not match. Please try again.')
|
|
||||||
else:
|
|
||||||
print('Password must be at least 6 characters. Please try again.')
|
|
||||||
p1, p2 = pprompt()
|
p1, p2 = pprompt()
|
||||||
|
while p1 != p2 or len(p1) < 6:
|
||||||
|
if p1 != p2:
|
||||||
|
print('Passwords do not match. Please try again.')
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
'Password must be at least 6 characters. Please try again.')
|
||||||
|
p1, p2 = pprompt()
|
||||||
|
|
||||||
# Setup Flask-Security
|
# Setup Flask-Security
|
||||||
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
||||||
|
@ -91,7 +102,6 @@ account:\n""")
|
||||||
name='User',
|
name='User',
|
||||||
description='pgAdmin User Role'
|
description='pgAdmin User Role'
|
||||||
)
|
)
|
||||||
|
|
||||||
user_datastore.create_user(email=email, password=password)
|
user_datastore.create_user(email=email, password=password)
|
||||||
db.session.flush()
|
db.session.flush()
|
||||||
user_datastore.add_role_to_user(email, 'Administrator')
|
user_datastore.add_role_to_user(email, 'Administrator')
|
||||||
|
@ -338,6 +348,10 @@ ALTER TABLE SERVER
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.from_object(config)
|
app.config.from_object(config)
|
||||||
|
|
||||||
|
if config.TESTING_MODE:
|
||||||
|
config.SQLITE_PATH = config.TEST_SQLITE_PATH
|
||||||
|
|
||||||
app.config['SQLALCHEMY_DATABASE_URI'] = \
|
app.config['SQLALCHEMY_DATABASE_URI'] = \
|
||||||
'sqlite:///' + config.SQLITE_PATH.replace('\\', '/')
|
'sqlite:///' + config.SQLITE_PATH.replace('\\', '/')
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
|
@ -346,9 +360,10 @@ if __name__ == '__main__':
|
||||||
print("======================================\n")
|
print("======================================\n")
|
||||||
|
|
||||||
local_config = os.path.join(
|
local_config = os.path.join(
|
||||||
os.path.dirname(os.path.realpath(__file__)),
|
os.path.dirname(os.path.dirname(__file__)),
|
||||||
'config_local.py'
|
'config_local.py'
|
||||||
)
|
)
|
||||||
|
|
||||||
if not os.path.isfile(local_config):
|
if not os.path.isfile(local_config):
|
||||||
print("""
|
print("""
|
||||||
The configuration file - {0} does not exist.
|
The configuration file - {0} does not exist.
|
||||||
|
|
Loading…
Reference in New Issue