From f17c2e3b84015666267676b582c29f2bd59f77cf Mon Sep 17 00:00:00 2001 From: Dave Page Date: Mon, 18 Jul 2016 14:50:21 +0100 Subject: [PATCH] Enhancements to the regression test suite. Navnath Gadakh and Priyanka Shendge --- .../servers/databases/tests/__init__.py | 15 + .../servers/databases/tests/test_db_add.py | 74 ++++ .../servers/databases/tests/test_db_delete.py | 73 ++++ .../servers/databases/tests/test_db_get.py | 72 ++++ .../servers/databases/tests/test_db_put.py | 79 ++++ .../server_groups/servers/tests/__init__.py | 2 +- .../servers/tests/test_server_add.py | 65 +-- .../servers/tests/test_server_delete.py | 72 ++-- .../servers/tests/test_server_get.py | 58 +-- .../servers/tests/test_server_put.py | 94 +++-- .../browser/server_groups/tests/__init__.py | 2 +- .../server_groups/tests/test_sg_add.py | 36 -- .../server_groups/tests/test_sg_get.py | 48 +++ web/pgadmin/browser/tests/__init__.py | 2 +- .../browser/tests/test_change_password.py | 47 ++- web/pgadmin/browser/tests/test_login.py | 25 +- web/pgadmin/browser/tests/test_logout.py | 31 +- .../browser/tests/test_reset_password.py | 25 +- web/pgadmin/utils/route.py | 6 +- web/regression/README | 64 +-- web/regression/runtests.py | 147 +++++++ web/regression/test_advanced_config.json.in | 105 +++++ web/regression/{config.py => test_setup.py} | 9 +- web/regression/test_utils.py | 371 ++++++++++++++++++ web/regression/testsuite.py | 79 ---- 25 files changed, 1293 insertions(+), 308 deletions(-) create mode 100644 web/pgadmin/browser/server_groups/servers/databases/tests/__init__.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/tests/test_db_add.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/tests/test_db_delete.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/tests/test_db_get.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/tests/test_db_put.py delete mode 100644 web/pgadmin/browser/server_groups/tests/test_sg_add.py create mode 100644 web/pgadmin/browser/server_groups/tests/test_sg_get.py create mode 100644 web/regression/runtests.py create mode 100644 web/regression/test_advanced_config.json.in rename web/regression/{config.py => test_setup.py} (53%) create mode 100644 web/regression/test_utils.py delete mode 100644 web/regression/testsuite.py diff --git a/web/pgadmin/browser/server_groups/servers/databases/tests/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/tests/__init__.py new file mode 100644 index 000000000..aa01297a7 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/tests/__init__.py @@ -0,0 +1,15 @@ +# ########################################################################## +# +# #pgAdmin 4 - PostgreSQL Tools +# +# #Copyright (C) 2013 - 2016, The pgAdmin Development Team +# #This software is released under the PostgreSQL Licence +# +# ########################################################################## + +from pgadmin.utils.route import BaseTestGenerator + + +class DatabaseCreateTestCase(BaseTestGenerator): + def runTest(self): + return diff --git a/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_add.py b/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_add.py new file mode 100644 index 000000000..c0e1430a2 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_add.py @@ -0,0 +1,74 @@ +# ################################################################# +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# ################################################################## + +import json +import uuid + +from pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils +from regression.test_setup import advanced_config_data + + +class DatabaseAddTestCase(BaseTestGenerator): + """ + This class will check server group node present on the object browser's + tree node by response code. + """ + + scenarios = [ + # Fetching default URL for database node. + ('Check Databases Node URL', dict(url='/browser/database/obj/')) + ] + + def setUp(self): + """ + This function perform the two tasks + 1. Login to test client + 2. Add the test server + + :return: None + """ + + utils.login_tester_account(self.tester) + # Add the server + utils.add_server(self.tester) + + def runTest(self): + """ This function will add database under 1st server of tree node. """ + + server_connect_response, server_group, server_ids = \ + utils.connect_server(self.tester) + + # Store db id. Which is use to delete in tearDown() + self.db_id = '' + for server_connect, server_id in zip(server_connect_response, + server_ids): + if server_connect['data']['connected']: + data = utils.get_db_data(server_connect) + db_response = self.tester.post(self.url + str(server_group) + + "/" + server_id + "/", + data=json.dumps(data), + content_type='html/json') + self.assertTrue(db_response.status_code, 200) + response_data = json.loads(db_response.data.decode('utf-8')) + utils.write_db_parent_id(response_data) + self.db_id = response_data['node']['_id'] + + def tearDown(self): + """ + This function deletes the 'parent_id.pkl' file which is created in + setup() function. Also this function logout the test client + + :return: None + """ + + utils.delete_database(self.tester, self.db_id) + utils.delete_server(self.tester) + utils.delete_parent_id_file() + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_delete.py b/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_delete.py new file mode 100644 index 000000000..5f160f96d --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_delete.py @@ -0,0 +1,73 @@ +# ################################################################# +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# ################################################################## + +import json + +from pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils +from regression.test_setup import config_data +from regression.test_utils import get_ids, test_getnodes + + +class DatabaseDeleteTestCase(BaseTestGenerator): + """ This class will delete the database under last added server. """ + + scenarios = [ + # Fetching default URL for database node. + ('Check Databases Node URL', dict(url='/browser/database/obj/')) + ] + + def setUp(self): + """ + This function perform the three tasks + 1. Login to test client + 2. Add the test server + 3. Connect to server + + :return: None + """ + + utils.login_tester_account(self.tester) + # Firstly, add the server + utils.add_server(self.tester) + # Secondly, connect to server/database + utils.connect_server(self.tester) + + def runTest(self): + """ This function will delete the database.""" + + srv_grp = config_data['test_server_group'] + all_id = get_ids() + server_ids = all_id["sid"] + + # TODO: Need to modify the code , to delete the databases for all + # TODO: servers. Currently it delete only one database. + db_id = all_id["did"][0] + db_con = test_getnodes(self.tester) + if len(db_con) == 0: + raise Exception("No database(s) to delete!!!") + for server_id in server_ids: + response = self.tester.delete(self.url + str(srv_grp) + '/' + + str(server_id) + '/' + str(db_id), + follow_redirects=True) + + response_data = json.loads(response.data.decode('utf-8')) + self.assertTrue(response_data['success'], 1) + + def tearDown(self): + """ + This function deletes the 'parent_id.pkl' file which is created in + setup() function. Also this function logout the test client + + :return: None + """ + + utils.delete_server(self.tester) + utils.delete_parent_id_file() + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_get.py b/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_get.py new file mode 100644 index 000000000..a42e0c148 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_get.py @@ -0,0 +1,72 @@ +# ################################################################# +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# ################################################################## + +from pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils +from regression.test_setup import config_data +from regression.test_utils import get_ids, test_getnodes + + +class DatabasesGetTestCase(BaseTestGenerator): + """ + This class will fetch database added under last added server. + """ + + scenarios = [ + # Fetching default URL for database node. + ('Check Databases Node URL', dict(url='/browser/database/obj/')) + ] + + def setUp(self): + """ + This function perform the three tasks + 1. Login to test client + 2. Add the test server + 3. Connect to server + + :return: None + """ + + utils.login_tester_account(self.tester) + # Firstly, add the server + utils.add_server(self.tester) + # Secondly, connect to server/database + utils.connect_server(self.tester) + + def runTest(self): + """ This function will fetch added database. """ + + all_id = get_ids() + server_ids = all_id["sid"] + + # TODO: Code is remaining to get all databases of all servers + self.db_id = all_id["did"][0] + srv_grp = config_data['test_server_group'] + + for server_id in server_ids: + db_con = test_getnodes(self.tester) + if db_con["info"] == "Database connected.": + response = self.tester.get(self.url + str(srv_grp) + '/' + + str(server_id) + '/' + str( + self.db_id), + follow_redirects=True) + self.assertEquals(response.status_code, 200) + + def tearDown(self): + """ + This function deletes the 'parent_id.pkl' file which is created in + setup() function. Also this function logout the test client + + :return: None + """ + + utils.delete_database(self.tester, self.db_id) + utils.delete_server(self.tester) + utils.delete_parent_id_file() + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_put.py b/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_put.py new file mode 100644 index 000000000..c5f92cc1f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_put.py @@ -0,0 +1,79 @@ +# ################################################################# +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# ################################################################## + +import json + +from pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils +from regression.test_setup import config_data, advanced_config_data +from regression.test_utils import get_ids, test_getnodes + + +class DatabasesUpdateTestCase(BaseTestGenerator): + """ + This class will update the database under last added server. + """ + + scenarios = [ + # Fetching default URL for database node. + ('Check Databases Node', dict(url='/browser/database/obj/')) + ] + + def setUp(self): + """ + This function perform the three tasks + 1. Login to test client + 2. Add the test server + 3. Connect to server + + :return: None + """ + + utils.login_tester_account(self.tester) + # Firstly, add the server + utils.add_server(self.tester) + # Secondly, connect to server/database + utils.connect_server(self.tester) + + def runTest(self): + """ This function will update the comments field of database.""" + + srv_grp = config_data['test_server_group'] + all_id = get_ids() + server_ids = all_id["sid"] + + # TODO: Need to modify the code , to delete the databases for all + # TODO: servers. Currently it delete only one database. + db_id = all_id["did"][0] + test_getnodes(self.tester) + + data = { + "comments": advanced_config_data["test_db_update_data"][0] + ["test_comment"], + "id": db_id + } + + for server_id in server_ids: + put_response = self.tester.put(self.url + str(srv_grp) + '/' + + str(server_id) + '/' + str(db_id), + data=json.dumps(data), + follow_redirects=True) + self.assertEquals(put_response.status_code, 200) + + def tearDown(self): + """ + This function deletes the 'parent_id.pkl' file which is created in + setup() function. Also this function logout the test client + + :return: None + """ + + utils.delete_server(self.tester) + utils.delete_parent_id_file() + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/browser/server_groups/servers/tests/__init__.py b/web/pgadmin/browser/server_groups/servers/tests/__init__.py index 28cdb94d3..55a3a17f9 100644 --- a/web/pgadmin/browser/server_groups/servers/tests/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/tests/__init__.py @@ -12,4 +12,4 @@ from pgadmin.utils.route import BaseTestGenerator class ServerGenerateTestCase(BaseTestGenerator): def runTest(self): - print ("In ServerGenerateTestCase...") + return \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py b/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py index 0af13d340..0f07d2101 100644 --- a/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py +++ b/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py @@ -9,45 +9,50 @@ import json -from pgadmin.browser.tests.test_login import LoginTestCase -from regression.config import config_data +from pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils +from regression.test_setup import config_data +from regression.test_utils import get_ids -class ServersAddTestCase(LoginTestCase): - """ - This class will add the servers under default server group and verify with - server's name. - """ - - priority = 4 +class ServersAddTestCase(BaseTestGenerator): + """ This class will add the servers under default server group. """ scenarios = [ # Fetch the default url for server object ('Default Server Node url', dict(url='/browser/server/obj/')) ] + def setUp(self): + """ + This function login the test account before running the logout + test case + """ + + utils.login_tester_account(self.tester) + def runTest(self): - """ - This function will add the server under default server group. - Verify the added server with response code as well as server name. - """ + """ This function will add the server under default server group.""" - srv_grp = config_data['test_server_group'] - - for srv in config_data['test_server_credentials']: - data = {"name": srv['test_name'], - "comment": "", - "host": srv['test_host'], - "port": srv['test_db_port'], - "db": srv['test_maintenance_db'], - "username": srv['test_db_username'], - "role": "", - "sslmode": srv['test_sslmode']} - - url = self.url + str(srv_grp) + "/" - - response = self.tester.post(url, data=json.dumps(data), + server_group, config_data, pickle_id_dict = utils.get_config_data() + for server_data in config_data: + url = "{0}{1}/".format(self.url, server_group) + response = self.tester.post(url, data=json.dumps(server_data), content_type='html/json') + self.assertTrue(response.status_code, 200) - respdata = json.loads(response.data) - self.assertTrue(respdata['node']['label'], srv['test_name']) + + response_data = json.loads(response.data.decode()) + utils.write_parent_id(response_data, pickle_id_dict) + + def tearDown(self): + """ + This function deletes the 'parent_id.pkl' file which is created in + setup() function. Also this function logout the test client + + :return: None + """ + + utils.delete_server(self.tester) + utils.delete_parent_id_file() + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_server_delete.py b/web/pgadmin/browser/server_groups/servers/tests/test_server_delete.py index 329d74fc6..765a37143 100644 --- a/web/pgadmin/browser/server_groups/servers/tests/test_server_delete.py +++ b/web/pgadmin/browser/server_groups/servers/tests/test_server_delete.py @@ -9,49 +9,59 @@ import json -from pgadmin.browser.tests.test_login import LoginTestCase -from regression.config import config_data +from pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils +from regression.test_setup import config_data +from regression.test_utils import get_ids -class ServersDeleteTestCase(LoginTestCase): - """ - This class will check server node present on the object browser's tree node - by response code. - """ - priority = 7 +class ServerDeleteTestCase(BaseTestGenerator): + """ This class will delete the last server present under tree node.""" scenarios = [ # Fetching the default url for server node ('Default Server Node url', dict(url='/browser/server/obj/')) ] + def setUp(self): + """ + This function perform the two tasks + 1. Login to test client + 2. Add the test server + + :return: None + """ + + utils.login_tester_account(self.tester) + # Firstly, add the server + utils.add_server(self.tester) + def runTest(self): - """ - This function will get all available servers under object browser - and delete the servers using server id. - """ + """ This function will get all available servers under object browser + and delete the last server using server id.""" srv_grp = config_data['test_server_group'] + all_id = get_ids() + server_ids = all_id["sid"] - for srv in config_data['test_server_credentials']: + url = self.url + str(srv_grp) + "/" + if len(server_ids) == 0: + raise Exception("No server(s) to delete!!!") - data = {"name": srv['test_name'], - "host": srv['test_host'], - "port": srv['test_db_port'], - "db": srv['test_maintenance_db'], - "username": srv['test_db_username'], - "role": "", - "sslmode": srv['test_sslmode']} - - url = self.url + str(srv_grp) + "/" - - response = self.tester.get(url, data=json.dumps(data), - content_type='html/json') + # Call api to delete the servers + for server_id in server_ids: + response = self.tester.delete(url + str(server_id)) self.assertTrue(response.status_code, 200) - respdata = json.loads(response.data) + response_data = json.loads(response.data.decode()) + self.assertTrue(response_data['success'], 1) - for server in respdata: - response = self.tester.delete(url + json.dumps(server['id'])) - self.assertTrue(response.status_code, 200) - respdata = json.loads(response.data) - self.assertTrue(respdata['success'], 1) + def tearDown(self): + """ + This function deletes the 'parent_id.pkl' file which is created in + setup() function. Also this function logout the test client + + :return: None + """ + + utils.delete_parent_id_file() + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_server_get.py b/web/pgadmin/browser/server_groups/servers/tests/test_server_get.py index 050843ebf..6ff8e162a 100644 --- a/web/pgadmin/browser/server_groups/servers/tests/test_server_get.py +++ b/web/pgadmin/browser/server_groups/servers/tests/test_server_get.py @@ -7,43 +7,55 @@ # # ########################################################################## -import json - -from pgadmin.browser.tests.test_login import LoginTestCase -from regression.config import config_data +from pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils +from regression.test_setup import config_data +from regression.test_utils import get_ids -class ServersGetTestCase(LoginTestCase): +class ServersGetTestCase(BaseTestGenerator): """ - This class will check server node present on the object browser's tree node + This class will fetch added servers under default server group by response code. """ - priority = 5 - scenarios = [ # Fetch the default url for server node ('Default Server Node url', dict(url='/browser/server/obj/')) ] - def runTest(self): + def setUp(self): """ - This function will get all available servers present under - object browser. + This function perform the two tasks + 1. Login to test client + 2. Add the test server + + :return: None """ + utils.login_tester_account(self.tester) + utils.add_server(self.tester) + + def runTest(self): + """ This function will fetch the added servers to object browser. """ + + all_id = get_ids() + server_ids = all_id["sid"] srv_grp = config_data['test_server_group'] - for srv in config_data['test_server_credentials']: - data = {"name": srv['test_name'], - "host": srv['test_host'], - "port": srv['test_db_port'], - "db": srv['test_maintenance_db'], - "username": srv['test_db_username'], - "role": "", - "sslmode": srv['test_sslmode']} + for server_id in server_ids: + url = "{0}{1}/{2}".format(self.url, srv_grp, server_id) + response = self.tester.get(url, content_type='html/json') + self.assertEquals(response.status_code, 200) - url = self.url + str(srv_grp) + "/" - response = self.tester.get(url, data=json.dumps(data), - content_type='html/json') - self.assertTrue(response.status_code, 200) + def tearDown(self): + """ + This function deletes the 'parent_id.pkl' file which is created in + setup() function. Also this function logout the test client + + :return: None + """ + + utils.delete_server(self.tester) + utils.delete_parent_id_file() + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_server_put.py b/web/pgadmin/browser/server_groups/servers/tests/test_server_put.py index 306bb03be..659e674e4 100644 --- a/web/pgadmin/browser/server_groups/servers/tests/test_server_put.py +++ b/web/pgadmin/browser/server_groups/servers/tests/test_server_put.py @@ -9,57 +9,67 @@ import json -from pgadmin.browser.tests.test_login import LoginTestCase -from regression.config import config_data +from pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils +from regression.test_setup import config_data -class ServersUpdateTestCase(LoginTestCase): - """ - This class will check server node present on the object browser's tree node - by response code. - """ - - priority = 6 +class ServerUpdateTestCase(BaseTestGenerator): + """ This class will update server's comment field. """ scenarios = [ # Fetching the default url for server node ('Default Server Node url', dict(url='/browser/server/obj/')) ] + def setUp(self): + """ + This function perform the four tasks + 1. Login to test client + 2. Add the test server + 3. Get the server + 4. Connect to server + + :return: None + """ + + utils.login_tester_account(self.tester) + # Firstly, add the server + utils.add_server(self.tester) + # Get the server + utils.get_server(self.tester) + # Connect to server + self.server_connect, self.server_group, self.server_ids = \ + utils.connect_server(self.tester) + if len(self.server_connect) == 0: + raise Exception("No Server(s) connected to update!!!") + def runTest(self): + """ This function will update the server's comment field. """ + + for server_id in self.server_ids: + data = { + "comment": + config_data['test_server_update_data'][0]['test_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()) + self.assertTrue(response_data['success'], 1) + + def tearDown(self): """ - This function will edit and update the server's comment field - by the server id. + This function deletes the 'parent_id.pkl' file which is created in + setup() function. Also this function logout the test client + + :return: None """ - srv_grp = config_data['test_server_group'] - - for srv in config_data['test_server_credentials']: - - data = {"name": srv['test_name'], - "host": srv['test_host'], - "port": srv['test_db_port'], - "db": srv['test_maintenance_db'], - "username": srv['test_db_username'], - "role": "", - "sslmode": srv['test_sslmode']} - - url = self.url + str(srv_grp) + "/" - - response = self.tester.get(url, data=json.dumps(data), - content_type='html/json') - - self.assertTrue(response.status_code, 200) - respdata = json.loads(response.data) - - for server in respdata: - - url = self.url + str(srv_grp) + "/" + json.dumps(server['id']) - - for server in config_data['test_server_update_data']: - data = {"comment": server['test_comment']} - response = self.tester.put(url, data=json.dumps(data), - content_type='html/json') - self.assertTrue(response.status_code, 200) - respdata = json.loads(response.data) - self.assertTrue(respdata['success'], 1) + utils.delete_server(self.tester) + utils.delete_parent_id_file() + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/browser/server_groups/tests/__init__.py b/web/pgadmin/browser/server_groups/tests/__init__.py index 9fabed955..7fdd5c731 100644 --- a/web/pgadmin/browser/server_groups/tests/__init__.py +++ b/web/pgadmin/browser/server_groups/tests/__init__.py @@ -12,4 +12,4 @@ from pgadmin.utils.route import BaseTestGenerator class SGGenerateTestCase(BaseTestGenerator): def runTest(self): - print ("In SGGenerateTestCase...") + return \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/tests/test_sg_add.py b/web/pgadmin/browser/server_groups/tests/test_sg_add.py deleted file mode 100644 index e70bb6526..000000000 --- a/web/pgadmin/browser/server_groups/tests/test_sg_add.py +++ /dev/null @@ -1,36 +0,0 @@ -########################################################################### -# -# pgAdmin 4 - PostgreSQL Tools -# -# Copyright (C) 2013 - 2016, The pgAdmin Development Team -# This software is released under the PostgreSQL Licence -# -########################################################################### - -import json - -from pgadmin.browser.tests.test_login import LoginTestCase -from regression.config import config_data - - -class SgNodeTestCase(LoginTestCase): - """ - This class will check available server groups in pgAdmin. - """ - - priority = 1 - - scenarios = [ - # Fetching the default url for server group node - ('Check Server Group Node', dict(url='/browser/server-group/obj/')) - ] - - def runTest(self): - """This function will check available server groups.""" - - i = config_data['test_server_group'] - - response = self.tester.get(self.url + str(i), content_type='html/json') - self.assertTrue(response.status_code, 200) - respdata = json.loads(response.data) - self.assertTrue(respdata['id'], i) diff --git a/web/pgadmin/browser/server_groups/tests/test_sg_get.py b/web/pgadmin/browser/server_groups/tests/test_sg_get.py new file mode 100644 index 000000000..adcb28ae7 --- /dev/null +++ b/web/pgadmin/browser/server_groups/tests/test_sg_get.py @@ -0,0 +1,48 @@ +########################################################################### +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################### + +import json + +from pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils +from regression.test_setup import config_data + + +class SgNodeTestCase(BaseTestGenerator): + """ + This class will check available server groups in pgAdmin. + """ + + scenarios = [ + # Fetching the default url for server group node + ('Check Server Group Node', dict(url='/browser/server-group/obj/')) + ] + + def setUp(self): + """ + This function login the test account before running the logout + test case + """ + + utils.login_tester_account(self.tester) + + def runTest(self): + """This function will check available server groups.""" + + server_group_id = config_data['test_server_group'] + response = self.tester.get(self.url + str(server_group_id), + content_type='html/json') + self.assertTrue(response.status_code, 200) + response_data = json.loads(response.data.decode('utf8')) + self.assertTrue(response_data['id'], server_group_id) + + def tearDown(self): + """This function logout the test account """ + + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/browser/tests/__init__.py b/web/pgadmin/browser/tests/__init__.py index 2381efd5a..3fab6fe27 100644 --- a/web/pgadmin/browser/tests/__init__.py +++ b/web/pgadmin/browser/tests/__init__.py @@ -12,4 +12,4 @@ from pgadmin.utils.route import BaseTestGenerator class BrowserGenerateTestCase(BaseTestGenerator): def runTest(self): - print ("In BrowserGenerateTestCase...") + return \ No newline at end of file diff --git a/web/pgadmin/browser/tests/test_change_password.py b/web/pgadmin/browser/tests/test_change_password.py index dedb7d9f0..4b77a07e4 100644 --- a/web/pgadmin/browser/tests/test_change_password.py +++ b/web/pgadmin/browser/tests/test_change_password.py @@ -9,19 +9,18 @@ import uuid -from pgadmin.browser.tests.test_login import LoginTestCase -from regression.config import config_data +from pgadmin.utils.route import BaseTestGenerator +from regression.test_setup import config_data +from regression import test_utils as utils -class ChangePasswordTestCase(LoginTestCase): +class ChangePasswordTestCase(BaseTestGenerator): """ This class validates the change password functionality by defining change password scenarios; where dict of parameters describes the scenario appended by test name. """ - priority = 2 - scenarios = [ # This testcase validates invalid confirmation password ('TestCase for Validating Incorrect_New_Password', dict( @@ -48,8 +47,7 @@ class ChangePasswordTestCase(LoginTestCase): new_password='', new_password_confirm='', respdata='Password not provided')), - # This testcase validates if current entered password - # is incorrect + # This testcase validates if current entered password is incorrect ('TestCase for Validating Incorrect_Current_Password', dict( password=str(uuid.uuid4())[4:8], new_password=(config_data['pgAdmin4_login_credentials'] @@ -70,6 +68,7 @@ class ChangePasswordTestCase(LoginTestCase): ['test_new_password']), respdata='You successfully changed your password.')), ('Reassigning_Password', dict( + test_case='reassigning_password', password=(config_data['pgAdmin4_login_credentials'] ['test_new_password']), new_password=(config_data['pgAdmin4_login_credentials'] @@ -81,14 +80,44 @@ class ChangePasswordTestCase(LoginTestCase): ] + def setUp(self): + """ + This function login the test account before running the logout + test case + """ + + utils.login_tester_account(self.tester) + def runTest(self): """This function will check change password functionality.""" + # Check for 'test_case' exists in self For reassigning the password. + # Password gets change in change password test case. + if 'test_case' in dir(self): + email = \ + config_data['pgAdmin4_login_credentials'][ + 'test_login_username'] + password = \ + config_data['pgAdmin4_login_credentials'][ + 'test_new_password'] + response = self.tester.post('/login', data=dict( + email=email, password=password), follow_redirects=True) + response = self.tester.get('/change', follow_redirects=True) - self.assertIn('pgAdmin 4 Password Change', response.data) + self.assertIn('pgAdmin 4 Password Change', response.data.decode()) + response = self.tester.post('/change', data=dict( password=self.password, new_password=self.new_password, new_password_confirm=self.new_password_confirm), follow_redirects=True) - self.assertIn(self.respdata, response.data) + self.assertIn(self.respdata, response.data.decode('utf-8')) + + def tearDown(self): + """ + This function logout the test client + + :return: None + """ + + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/browser/tests/test_login.py b/web/pgadmin/browser/tests/test_login.py index 7c2b79632..0c8a16dcf 100644 --- a/web/pgadmin/browser/tests/test_login.py +++ b/web/pgadmin/browser/tests/test_login.py @@ -8,9 +8,9 @@ ########################################################################## import uuid - from pgadmin.utils.route import BaseTestGenerator -from regression.config import config_data +from regression.test_setup import config_data +from regression import test_utils as utils class LoginTestCase(BaseTestGenerator): @@ -20,8 +20,6 @@ class LoginTestCase(BaseTestGenerator): describe the scenario appended by test name. """ - priority = 0 - scenarios = [ # This test case validates the invalid/incorrect password ('TestCase for Checking Invalid_Password', dict( @@ -67,13 +65,28 @@ class LoginTestCase(BaseTestGenerator): ['test_login_username']), password=(config_data['pgAdmin4_login_credentials'] ['test_login_password']), - respdata='You are currently running version')) + respdata='Gravatar image for %s' % + config_data['pgAdmin4_login_credentials'] + ['test_login_username'])) ] + def setUp(self): + pass + def runTest(self): """This function checks login functionality.""" response = self.tester.post('/login', data=dict( email=self.email, password=self.password), follow_redirects=True) - self.assertIn(self.respdata, response.data) + self.assertIn(self.respdata, response.data.decode('utf8')) + + def tearDown(self): + """ + This function deletes the 'parent_id.pkl' file which is created in + setup() function. Also this function logout the test client + + :return: None + """ + + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/browser/tests/test_logout.py b/web/pgadmin/browser/tests/test_logout.py index 8971e72a8..c2ccf948c 100644 --- a/web/pgadmin/browser/tests/test_logout.py +++ b/web/pgadmin/browser/tests/test_logout.py @@ -7,38 +7,33 @@ # # ########################################################################## -from pgadmin.browser.tests.test_login import LoginTestCase -from regression.config import config_data + +from pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils -class LogoutTest(LoginTestCase): +class LogoutTest(BaseTestGenerator): """ This class verifies the logout functionality; provided the user is already logged-in. Dictionary parameters define the scenario appended by test name. """ - priority = 3 - scenarios = [ # This test case validate the logout page ('Logging Out', dict(respdata='Redirecting...')) ] + def setUp(self): + """ + This function login the test account before running the logout + test case + """ + + utils.login_tester_account(self.tester) + def runTest(self): """This function checks the logout functionality.""" response = self.tester.get('/logout') - self.assertIn(self.respdata, response.data) - - def tearDown(self): - """ - Defining tear down class, which will run after each test method execute. - Re-logging in as further modules require login. - """ - - self.tester.post('/login', data=dict( - email=(config_data['pgAdmin4_login_credentials'] - ['test_login_username']), - password=(config_data['pgAdmin4_login_credentials'] - ['test_login_password'])), follow_redirects=True) + self.assertIn(self.respdata, response.data.decode('utf8')) diff --git a/web/pgadmin/browser/tests/test_reset_password.py b/web/pgadmin/browser/tests/test_reset_password.py index 030b182ae..d0a6fa7ba 100644 --- a/web/pgadmin/browser/tests/test_reset_password.py +++ b/web/pgadmin/browser/tests/test_reset_password.py @@ -10,7 +10,8 @@ import uuid from pgadmin.utils.route import BaseTestGenerator -from regression.config import config_data +from regression.test_setup import config_data +from regression import test_utils as utils class ResetPasswordTestCase(BaseTestGenerator): @@ -19,7 +20,6 @@ class ResetPasswordTestCase(BaseTestGenerator): scenarios; Each dict parameter describe a scenario appended by test name. """ - priority = 1 scenarios = [ # This test case validates the empty email field @@ -37,12 +37,29 @@ class ResetPasswordTestCase(BaseTestGenerator): ['test_login_username'], respdata='pgAdmin 4')) ] + def setUp(self): + """ + This function login the test account before running the logout + test case + """ + + utils.login_tester_account(self.tester) + def runTest(self): """This function checks reset password functionality.""" response = self.tester.get('/reset') - self.assertIn('Recover pgAdmin 4 Password', response.data) + self.assertIn('Recover pgAdmin 4 Password', response.data.decode()) response = self.tester.post( '/reset', data=dict(email=self.email), follow_redirects=True) - self.assertIn(self.respdata, response.data) + self.assertIn(self.respdata, response.data.decode('utf-8')) + + def tearDown(self): + """ + This function logout the test client + + :return: None + """ + + utils.logout_tester_account(self.tester) diff --git a/web/pgadmin/utils/route.py b/web/pgadmin/utils/route.py index fb9de6996..a2cd1eb79 100644 --- a/web/pgadmin/utils/route.py +++ b/web/pgadmin/utils/route.py @@ -52,8 +52,10 @@ class TestsGeneratorRegistry(ABCMeta): from werkzeug.utils import find_modules for module_name in find_modules(pkg, False, True): - module = import_module(module_name) - + try: + module = import_module(module_name) + except ImportError: + pass import six diff --git a/web/regression/README b/web/regression/README index e0003e40e..de7552ee0 100644 --- a/web/regression/README +++ b/web/regression/README @@ -1,10 +1,8 @@ pgAdmin 4 Test Framework ======================== -This regression framework is designed for executing the individual unit tests -available for the existing modules and to help catch regressions. In addition -to that this should be helpful for other new plugged-in module that can come -in later in time. +This regression framework is designed to execute unit tests for all modules to +help catch regressions in the code. Assumptions ----------- @@ -40,29 +38,39 @@ General Information 3. test_server_get.py 4. test_server_update.py -2) The pgAdmin4 source tree includes a file template for the server configuration - named ‘test_config.json.in' in the ‘pgAdmin4/web/regression’ directory. After - completing the pgAdmin4 configuration, you must make a working copy of the - template called test_config.json before modifying the file contents. +2) The pgAdmin4 source tree includes 2 different configuration file templates. + One file template for the server configuration + named ‘test_config.json.in' and another for test configuration named + 'test_advanced_config.json.in' in the ‘pgAdmin4/web/regression’ directory. + After completing the pgAdmin4 configuration, you must make a working copy of + the templates called test_config.json and test_advance_config.json + before modifying the file contents. - 2a) The following command copies the test_config.json.in file, creating a - configuration file named test_config.json + 2a) The following command copies the test_config.json.in file, creating a + configuration file named test_config.json (same way user can copy + test_advance_config.json.in file into test_advance_config.json) - # cp pgadmin4/web/regression/test_config.json.in \ - pgadmin4/web/regression/test_config.json + $ cp pgadmin4/web/regression/test_config.json.in \ + pgadmin4/web/regression/test_config.json - 2b) After creating the server configuration file, add (or modify) - parameter values as per requirements. The configuration - files are owned by root/user. The pgAdmin4 regression framework expects - to find the files in the directory '//web/regression/'. - If you move the file to another location, you must create a symbolic link - that specifies the new location. + 2b) After creating the server and test configuration file, add (or modify) + parameter values as per requirements. The pgAdmin4 regression framework expects + to find the files in the directory '//web/regression/'. + If you move the file to another location, you must create a symbolic + link that specifies the new location. - 2c) Specifying Server Configuration file: + 2c) Specifying Server Configuration file: + + Server details and connection properties as per their local setup. The + test_config file is in JSON format and property values are + case-sensitive. + + 2d) Specifying the Test Configuration file: + + The user can add/change test data as per their need. The + test_advanced_config file is in JSON format and property values are + case-sensitive. - The user can use the parameters in the configuration file to specify the - server details and connection properties as per their local setup. The - test_config file is in json format and property values are case-sensitive. Test Data Details ----------------- @@ -87,10 +95,20 @@ Test Data Details Execution: ----------- + - The test framework is modular and pluggable and dynamically locates tests for modules which are discovered at runtime. All test cases are found and registered automatically by its module name in 'pgadmin4/web/pgadmin/utils/test.py' file. -- Execute test framework run 'regression/testsuite.py' file. +- Execute the test framework for all nodes + run 'regression/runtests.py --pkg all' or just: + 'regression/runtests.py' +- Execute test framework for single node at a time + + Example 1) Run test framework for 'browser' node + run 'regression/runtests.py --pkg browser' + + Example 2) Run test framework for 'database' node + run 'regression/runtests.py --pkg browser.server_groups.servers.databases' diff --git a/web/regression/runtests.py b/web/regression/runtests.py new file mode 100644 index 000000000..2e3520a55 --- /dev/null +++ b/web/regression/runtests.py @@ -0,0 +1,147 @@ +############################################################# +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +############################################################## + +""" This file collect all modules/files present in tests directory and add +them to TestSuite. """ + +import argparse +import os +import sys +import unittest +import logging + +from testscenarios.scenarios import generate_scenarios + +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) + +# Set sys path to current directory so that we can import pgadmin package +root = os.path.dirname(CURRENT_PATH) + +if sys.path[0] != root: + sys.path.insert(0, root) + +from pgadmin import create_app +import config + +# 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 +from pgadmin.model import SCHEMA_VERSION + +config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION + +# Override some other defaults +from logging import WARNING +config.CONSOLE_LOG_LEVEL = WARNING + +# Create the app +app = create_app() +app.config['WTF_CSRF_ENABLED'] = False +test_client = app.test_client() + + +def get_suite(arguments, test_app_client): + """ + This function loads the all modules in the tests directory into testing + environment. + + :param arguments: this is command line arguments for module name to + which test suite will run + :type arguments: str + :param test_app_client: test client + :type test_app_client: pgadmin app object + :return pgadmin_suite: test suite with test cases + :rtype: TestSuite + """ + + from pgadmin.utils.route import TestsGeneratorRegistry + + modules = [] + pgadmin_suite = unittest.TestSuite() + + # Load the test modules which are in given package(i.e. in arguments.pkg) + if arguments.pkg is None or arguments.pkg == "all": + TestsGeneratorRegistry.load_generators('pgadmin') + else: + TestsGeneratorRegistry.load_generators('pgadmin.{}.tests'.format( + arguments.pkg)) + + # Get the each test module and add into list + for key, klass in TestsGeneratorRegistry.registry.items(): + gen = klass + modules.append(gen) + + # Set the test client to each module & generate the scenarios + for module in modules: + obj = module() + obj.setTestClient(test_app_client) + scenario = generate_scenarios(obj) + pgadmin_suite.addTests(scenario) + + return pgadmin_suite + + +def add_arguments(): + """ + This function parse the command line arguments(project's package name + e.g. browser) & add into parser + + :return args: command line argument for pgadmin's package name + :rtype: argparse namespace + """ + + parser = argparse.ArgumentParser(description='Test suite for pgAdmin4') + parser.add_argument('--pkg', help='Executes the test cases of particular' + ' package') + arg = parser.parse_args() + + return arg + + +class StreamToLogger(object): + def __init__(self, logger, log_level=logging.INFO): + self.terminal = sys.stderr + self.logger = logger + self.log_level = log_level + self.linebuf = '' + + def write(self, buf): + """ + This function writes the log in the logger file as well as on console + + :param buf: log message + :type buf: str + :return: None + """ + + self.terminal.write(buf) + for line in buf.rstrip().splitlines(): + self.logger.log(self.log_level, line.rstrip()) + + def flush(self): + pass + + +if __name__ == '__main__': + # Set basic logging configuration for log file + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s:%(levelname)s:%(name)s:%(message)s', + filename=CURRENT_PATH + "/" + "regression.log", + filemode='w' + ) + + # Create logger to write log in the logger file as well as on console + stderr_logger = logging.getLogger('STDERR') + sys.stderr = StreamToLogger(stderr_logger, logging.ERROR) + + args = add_arguments() + suite = get_suite(args, test_client) + tests = unittest.TextTestRunner(stream=sys.stderr, descriptions=True, + verbosity=2).run(suite) + + print("Please check output in file: %s/regression.log " % CURRENT_PATH) diff --git a/web/regression/test_advanced_config.json.in b/web/regression/test_advanced_config.json.in new file mode 100644 index 000000000..bcb867cea --- /dev/null +++ b/web/regression/test_advanced_config.json.in @@ -0,0 +1,105 @@ +{ + "test_add_database_data": [ + { + "test_privileges_acl": [ + { + "grantee": "postgres", + "grantor": "postgres", + "privileges": [ + { + "privilege_type": "C", + "privilege": true, + "with_grant": true + }, + { + "privilege_type": "T", + "privilege": true, + "with_grant": false + } + ] + } + ], + "test_conn_limit": -1, + "test_owner": "postgres", + "test_fun_acl": [ + { + "grantee": "postgres", + "grantor": "postgres", + "privileges": [ + { + "privilege_type": "X", + "privilege": true, + "with_grant": false + } + ] + } + ], + "test_seq_acl": [ + { + "grantee": "postgres", + "grantor": "postgres", + "privileges": [ + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "w", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "U", + "privilege": true, + "with_grant": false + } + ] + } + ], + "test_tbl_acl": [ + { + "grantee": "postgres", + "grantor": "postgres", + "privileges": [ + { + "privilege_type": "a", + "privilege": true, + "with_grant": true + }, + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + } + ] + } + ], + "test_type_acl": [ + { + "grantee": "postgres", + "grantor": "postgres", + "privileges": [ + { + "privilege_type": "U", + "privilege": true, + "with_grant": false + } + ] + } + ], + "test_encoding": "UTF8", + "test_name": "test_db_automation", + "test_privileges": [], + "test_securities": [], + "test_variables": [] + } + ], + + "test_db_update_data": [ + { + "test_comment": "This is db update comment" + } + ] + +} \ No newline at end of file diff --git a/web/regression/config.py b/web/regression/test_setup.py similarity index 53% rename from web/regression/config.py rename to web/regression/test_setup.py index bef65fbea..f7765bc7a 100644 --- a/web/regression/config.py +++ b/web/regression/test_setup.py @@ -10,7 +10,12 @@ import json import os -root = os.path.dirname(os.path.realpath(__file__)) +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) -with open(root + '/test_config.json') as data_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) + +pickle_path = os.path.join(CURRENT_PATH, 'parent_id.pkl') diff --git a/web/regression/test_utils.py b/web/regression/test_utils.py new file mode 100644 index 000000000..0bcc10fc8 --- /dev/null +++ b/web/regression/test_utils.py @@ -0,0 +1,371 @@ +# ################################################################# +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# ################################################################## + +import os +import pickle +import json +import uuid + +from test_setup import config_data, advanced_config_data, pickle_path + +SERVER_URL = '/browser/server/obj/' +SERVER_CONNECT_URL = 'browser/server/connect/' +DATABASE_CONNECT_URL = '/browser/database/obj/' + + +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_id = all_id["did"][0] + srv_grp = config_data['test_server_group'] + + # TODO: need to add code to handle multiple databases with servers + for server_id in server_ids: + # Connect to server + response = tester.post('browser/server/connect/{0}/{1}'.format( + srv_grp, server_id), data=dict( + password=config_data['test_server_credentials'][0][ + 'test_db_password']), + follow_redirects=True) + + # Connect to database + con_response = tester.post( + 'browser/database/connect/{0}/{1}/{2}'.format( + srv_grp, server_id, db_id), follow_redirects=True) + db_con = json.loads(con_response.data.decode('utf-8')) + + return db_con + + +def get_db_data(server_connect_data): + """ + 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 + """ + + db_user = server_connect_data['data']['user']['name'] + + if db_user == "postgres": + # Get the advance test data of 'postgres' user + adv_config_data = advanced_config_data[ + 'test_add_database_data'][0] + else: + # Get the advance test data of 'enterprisedb' user + adv_config_data = advanced_config_data[ + 'test_add_database_data'][1] + + data = { + "datacl": adv_config_data['test_privileges_acl'], + "datconnlimit": adv_config_data['test_conn_limit'], + "datowner": adv_config_data['test_owner'], + "deffuncacl": adv_config_data['test_fun_acl'], + "defseqacl": adv_config_data['test_seq_acl'], + "deftblacl": adv_config_data['test_tbl_acl'], + "deftypeacl": adv_config_data['test_type_acl'], + "encoding": adv_config_data['test_encoding'], + "name": str(uuid.uuid4())[1:8], + "privileges": adv_config_data['test_privileges'], + "securities": adv_config_data['test_securities'], + "variables": adv_config_data['test_variables'] + } + + return data + + +def login_tester_account(tester): + """ + This function login the test account using credentials mentioned in + config file + + :param tester: test client + :type tester: flask test client object + :return: None + """ + + email = \ + config_data['pgAdmin4_login_credentials']['test_login_username'] + password = \ + config_data['pgAdmin4_login_credentials']['test_login_password'] + response = tester.post('/login', data=dict( + email=email, password=password), follow_redirects=True) + + +def logout_tester_account(tester): + """ + This function logout the test account + + :param tester: test client + :type tester: flask test client object + :return: None + """ + + response = tester.get('/logout') + + +def get_config_data(): + """ + This function get the data related to server group and database + like db name, host, port and username etc. + + :return: server_group, db_data, pickle_id_dict + :rtype: server_group:dict, db_data:list, pickle_id_dict:dict + """ + + db_data = [] + + pickle_id_dict = { + "sid": [], # server + "did": [] # database + } + + server_group = config_data['test_server_group'] + + for srv in config_data['test_server_credentials']: + data = {"name": srv['test_name'], + "comment": "", + "host": srv['test_host'], + "port": srv['test_db_port'], + "db": srv['test_maintenance_db'], + "username": srv['test_db_username'], + "role": "", + "sslmode": srv['test_sslmode']} + db_data.append(data) + return server_group, db_data, pickle_id_dict + + +def write_parent_id(response_data, pickle_id_dict): + """ + This function writes the server's details to file parent_id.pkl + + :param response_data: server's data + :type response_data: list of dictionary + :param pickle_id_dict: contains ids of server,database,tables etc. + :type pickle_id_dict: dict + :return: None + """ + + 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(server_id) + output = open(pickle_path, 'wb') + pickle.dump(pickle_id_dict, output) + output.close() + + +def write_db_parent_id(response_data): + """ + 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'] + 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 + + pickle_id_dict["did"].append(db_id) + + db_output = open(pickle_path, 'wb') + pickle.dump(pickle_id_dict, db_output) + db_output.close() + + +def delete_parent_id_file(): + """ + This function deletes the file parent_id.pkl which contains server and + database details + + :return: None + """ + + if os.path.isfile(pickle_path): + os.remove(pickle_path) + + +def add_server(tester): + """ + 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 = 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') + response_data = json.loads(response.data.decode()) + write_parent_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 = get_ids() + server_ids = all_id["sid"] + server_group = config_data['test_server_group'] + for server_id in server_ids: + response = tester.get(SERVER_URL + str(server_group) + '/' + + str(server_id), + follow_redirects=True) + response_data = json.loads(response.data.decode()) + + +def connect_server(tester): + """ + This function used to connect added server + + :param tester:test client object + :type tester: flask test object + :return: server_connect, server_group, server_id + :rtype: server_connect:dict, server_group:dict, server_id:str + """ + + server_connect = [] + servers = [] + + srv_id = get_ids() + server_ids = srv_id["sid"] + server_group = config_data['test_server_group'] + + # Connect to all servers + for server_id in server_ids: + response = tester.post(SERVER_CONNECT_URL + str(server_group) + + '/' + server_id, + data=dict( + password=config_data + ['test_server_credentials'][0] + ['test_db_password']), + follow_redirects=True) + server_connect_detail = json.loads(response.data.decode()) + connect_database(tester, server_connect_detail, server_id, server_group) + server_connect.append(server_connect_detail) + servers.append(server_id) + return server_connect, server_group, servers + + +def connect_database(tester, server_connect, server_id, server_group): + """ + This function is used to connect database and writes it's details to + file 'parent_id.pkl' + + :param tester: test client object + :type tester: flask test client object + :param server_connect: server's data + :type server_connect: dict + :param server_id: server id + :type server_id: str + :param server_group: server group name + :type server_group: str + :return: None + """ + + if server_connect['data']['connected']: + db_data = get_db_data(server_connect) + db_response = tester.post( + DATABASE_CONNECT_URL + str(server_group) + "/" + server_id + "/", + data=json.dumps(db_data), + content_type='html/json') + response_data = json.loads(db_response.data.decode()) + write_db_parent_id(response_data) + + +def delete_server(tester): + """ + This function used to delete the added servers + + :param tester: test client object + :return: None + """ + + srv_grp = config_data['test_server_group'] + all_id = get_ids() + server_ids = all_id["sid"] + url = SERVER_URL + str(srv_grp) + "/" + + # 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()) + assert response_data['success'] == 1 + + +def delete_database(tester, db_id): + """ + This function used to delete the added databases + + :param tester: test client object + :param db_id: database id to be delete + :type db_id: int + :return: None + """ + + srv_grp = config_data['test_server_group'] + all_id = get_ids() + server_ids = all_id["sid"] + + # TODO: Need to modify the code , to delete the databases for all + # TODO: servers. Currently it delete only one database. + #db_id = all_id["did"][0] + + db_con = test_getnodes(tester) + if len(db_con) == 0: + raise Exception("No database(s) to delete.") + + for server_id in server_ids: + response = tester.delete(DATABASE_CONNECT_URL + str(srv_grp) + '/' + str( + server_id) + '/' + str(db_id), follow_redirects=True) + assert response.status_code == 200 + response_data = json.loads(response.data.decode('utf-8')) + assert response_data['success'] == 1 diff --git a/web/regression/testsuite.py b/web/regression/testsuite.py deleted file mode 100644 index 75d437b53..000000000 --- a/web/regression/testsuite.py +++ /dev/null @@ -1,79 +0,0 @@ -############################################################# -# -# pgAdmin 4 - PostgreSQL Tools -# -# Copyright (C) 2013 - 2016, The pgAdmin Development Team -# This software is released under the PostgreSQL Licence -# -############################################################## - -""" This file collect all modules/files present in tests directory and add -them to TestSuite. """ - -import os -import sys -import unittest - -from testscenarios.scenarios import generate_scenarios - -# We need to include the root directory in sys.path to ensure that we can -# find everything we need when running in the standalone runtime. -current_path = os.path.dirname(os.path.realpath(__file__)) -root = os.path.dirname(current_path) - -if sys.path[0] != root: - sys.path.insert(0, root) - -from pgadmin import create_app -import config - -# 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 -from pgadmin.model import SCHEMA_VERSION -config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION - -# Create the app! -app = create_app() - -# Disabling Cross-site request forgery(CSRF token) for testing purpose. -# CSRF prevent session against malicious Web site, or end users who wants to -# execute unwanted actions. -app.config['WTF_CSRF_ENABLED'] = False - -from pgadmin.utils.route import TestsGeneratorRegistry - -# Registry will load all the testcases/modules from pgadmin path those are -# register as BaseTestGenerator. -TestsGeneratorRegistry.load_generators('pgadmin') - -# Create test client -# werkzeug provides a test client which gives a simple interface to the -# application. We can trigger test request to the application. -test_client = app.test_client() - - -def suite(): - """ Defining test suite which will execute all the testcases present in - tests directory according to set priority.""" - - pgadmin_suite = unittest.TestSuite() - - modules = [] - - for key, klass in TestsGeneratorRegistry.registry.items(): - gen = klass - - modules.insert(gen.priority, gen) - - for m in modules: - obj = m() - obj.setTestClient(test_client) - scenario = generate_scenarios(obj) - pgadmin_suite.addTests(scenario) - - return pgadmin_suite - - -if __name__ == '__main__': - suite = suite() - tests = unittest.TextTestRunner(descriptions=True, verbosity=2).run(suite)