Hi Dave, Please find the revised patch for unit tests of pgAdmin4 APIs.
This patch includes- 1. test_advance_config.json(for user it’s test_advance_config.json.in) for advance test configuration for database/server(Priyanka was working on this) 2. test_config.json(for user it’s test_config_json.in) for basic credentials data for database/server 3. From now onward we can execute test cases node wise/package wise. I have slightly modified the way of running the testsuite. We used the command line arguments(pkg) which denotes for which package testsuite going to run. Run the testsuite for all packages by following command Python regression/testsuite.py --pkg all Here, ‘all’ means for all python packages(i.e.browser,server_groups,server, databases etc. which are same names in project directory structure) This will find the ‘tests’ directory in each package & execute the test cases. Run the testsuite for single package by following command Python regression/testsuite.py --pkg browser (this execute the tests in ‘browser’ package only) Python regression/testsuite.py --pkg browser.server_groups.servers.databases (this execute the tests in ‘databases’ package only) 4. Logger file. Which include the detailed output of the testsuite. Testsuite also prints the test summary on the console. 5. Previously, we set the priority to each test case. In this patch priority logic is removed as there is no need to set priority. 6. Resolution of AttributeError for attribute 'APP_ROOT'(Which is mentioned by you in a previous email) Note: You might get ‘AttributeError’ while running this patch on Python 3.4 (I have raised this bug in RM(#1464)), But still you can run the testsuite. It will run on Python 2.7 without error. On Fri, Jul 15, 2016 at 6:23 PM, Dave Page <dave.p...@enterprisedb.com> wrote: > Hi > > On Mon, Jul 11, 2016 at 2:16 PM, Navnath Gadakh < > navnath.gad...@enterprisedb.com> wrote: > >> Hi Dave, >> PFA updated patch for modular API test cases. >> >> On Mon, Jul 11, 2016 at 5:11 PM, Dave Page <dave.p...@enterprisedb.com> >> wrote: >> >>> >>> >>> On Fri, Jul 8, 2016 at 2:30 PM, Navnath Gadakh < >>> navnath.gad...@enterprisedb.com> wrote: >>> >>>> >>>> Hi Dave, >>>> >>>> PFA patch for modular API test cases. >>>> >>>> Kindly, review the same and let me know for any modification. >>>> >>> >>> Please re-create the patch so that it doesn't revert various changes >>> made to config.py etc. over the last couple of weeks. >>> >> >> config.py file was not updated at my end, I have updated it in the >> current patch. I have also added code related to advance test data >> configuration which was created by Priyanka (Seprated the test data >> configuration files). >> >> >>> What is the patch for? Is it fixing issues in Priyanka's last patch, or >>> something else? >>> This patch is for - >>> 1. Now we can run testsuite node/module wise(like for browser only, for >>> databases only) OR for all nodes/modules >>> 2. I have modified the existing functionality for testsuite and all test >>> case classes (Made all test cases independently runnable, removed >>> the priority logic). >>> >> >> > For more details please refer the file 'regression/README'. >> > > When running all tests, I get: > > ... > ... > <Rule '//static/<filename>' (HEAD, OPTIONS, GET) -> redirects.static>, > <Rule '/backup/<filename>' (HEAD, OPTIONS, GET) -> backup.static>, > <Rule '/reset/<token>' (HEAD, POST, OPTIONS, GET) -> > security.reset_password>, > <Rule '/about/<filename>' (HEAD, OPTIONS, GET) -> about.static>]) > Traceback (most recent call last): > File "regression/testsuite.py", line 151, in <module> > suite = get_suite(args, test_client) > File "regression/testsuite.py", line 75, in get_suite > TestsGeneratorRegistry.load_generators('pgadmin') > File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/route.py", line 56, in > load_generators > module = import_module(module_name) > File > "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", > line 37, in import_module > __import__(name) > File > "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups/servers/databases/tests/test_db_add.py", > line 14, in <module> > from regression import test_utils as utils > File "/Users/dpage/git/pgadmin4/web/regression/test_utils.py", line 23, > in <module> > def get_ids(url=config.APP_ROOT + '/regression/parent_id.pkl'): > AttributeError: 'module' object has no attribute 'APP_ROOT' > > That's not overly surprising, as we don't have an APP_ROOT setting in the > config (nor should we - it should be calculated dynamically). Please fix, > and remember to test your patches against a clean copy of the git tree in > the future! > > Thanks! > > -- > Dave Page > VP, Chief Architect, Tools & Installers > EnterpriseDB: http://www.enterprisedb.com > The Enterprise PostgreSQL Company > > Blog: http://pgsnake.blogspot.com > Twitter: @pgsnake > -- Thanks, Navnath Gadakh Software Engineer EnterpriseDB Corporation Mobile: +91 9975389878
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 0000000..aa01297 --- /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 0000000..14b9749 --- /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.config import advance_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 0000000..46c59e4 --- /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.config 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 0000000..3edd6b8 --- /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.config 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 0000000..347e684 --- /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.config import config_data, advance_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": advance_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 28cdb94..55a3a17 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 0af13d3..847b1b6 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 pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils from regression.config 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 runTest(self): + def setUp(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 login the test account before running the logout + test case """ - 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']} + utils.login_tester_account(self.tester) - url = self.url + str(srv_grp) + "/" + def runTest(self): + """ This function will add the server under default server group.""" - 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 329d74f..4f312cf 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 pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils from regression.config 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 runTest(self): + def setUp(self): """ - This function will get all available servers under object browser - and delete the servers using server id. + This function perform the two tasks + 1. Login to test client + 2. Add the test server + + :return: None """ - srv_grp = config_data['test_server_group'] + utils.login_tester_account(self.tester) + # Firstly, add the server + utils.add_server(self.tester) - for srv in config_data['test_server_credentials']: + def runTest(self): + """ This function will get all available servers under object browser + and delete the last server using server id.""" - 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']} + srv_grp = config_data['test_server_group'] + all_id = get_ids() + server_ids = all_id["sid"] - url = self.url + str(srv_grp) + "/" + url = self.url + str(srv_grp) + "/" + if len(server_ids) == 0: + raise Exception("No server(s) to delete!!!") - 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) + + 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 + """ - 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) + 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 050843e..6356a6b 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 pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils from regression.config 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']} - - 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) + 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) + + 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 306bb03..31d3eb2 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 pgadmin.utils.route import BaseTestGenerator +from regression import test_utils as utils from regression.config 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 runTest(self): - """ - This function will edit and update the server's comment field - by the server id. + 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 - 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') + :return: None + """ - self.assertTrue(response.status_code, 200) - respdata = json.loads(response.data) + 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!!!") - for server in respdata: + 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 deletes the 'parent_id.pkl' file which is created in + setup() function. Also this function logout the test client - url = self.url + str(srv_grp) + "/" + json.dumps(server['id']) + :return: None + """ - 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 9fabed9..7fdd5c7 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 e70bb65..0000000 --- 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 0000000..07bbe96 --- /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.config 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 2381efd..3fab6fe 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 dedb7d9..605aa0f 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 pgadmin.utils.route import BaseTestGenerator from regression.config 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 7c2b796..8856700 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 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 8971e72..c2ccf94 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 030b182..96404df 100644 --- a/web/pgadmin/browser/tests/test_reset_password.py +++ b/web/pgadmin/browser/tests/test_reset_password.py @@ -11,6 +11,7 @@ import uuid from pgadmin.utils.route import BaseTestGenerator from regression.config 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 fb9de69..a2cd1eb 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 e0003e4..6a91911 100644 --- a/web/regression/README +++ b/web/regression/README @@ -40,29 +40,40 @@ 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_advance_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 '/<installation dir>/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 configuration + files are owned by root/user. The pgAdmin4 regression framework expects + to find the files in the directory '/<installation dir>/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_advance_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 ----------------- @@ -92,5 +103,16 @@ Execution: and registered automatically by its module name in 'pgadmin4/web/pgadmin/utils/test.py' file. -- Execute test framework run 'regression/testsuite.py' file. +- As the test framework is modular and dynamically locates the tests + package, We can now executes test framework node wise + +- Execute test framework for all nodes + run 'regression/testsuite.py --pkg all' + +- Execute test framework for single node at a time + + Example 1) Run test framework for 'browser' node + run 'regression/testsuite.py --pkg browser' + Example 2) Run test framework for 'database' node + run 'regression/testsuite.py --pkg browser.server_groups.servers.databases' diff --git a/web/regression/config.py b/web/regression/config.py index bef65fb..564d1c2 100644 --- a/web/regression/config.py +++ b/web/regression/config.py @@ -10,7 +10,12 @@ import json import os -root = os.path.dirname(os.path.realpath(__file__)) +from regression.testsuite import CURRENT_PATH -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_advance_config.json') as data_file: + advance_config_data = json.load(data_file) + +pickle_path = os.path.join(CURRENT_PATH, 'parent_id.pkl') diff --git a/web/regression/test_advance_config.json.in b/web/regression/test_advance_config.json.in new file mode 100644 index 0000000..bcb867c --- /dev/null +++ b/web/regression/test_advance_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/test_utils.py b/web/regression/test_utils.py new file mode 100644 index 0000000..14d186c --- /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 regression.config import config_data, advance_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 = advance_config_data[ + 'test_add_database_data'][0] + else: + # Get the advance test data of 'enterprisedb' user + adv_config_data = advance_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 index 75d437b..9c57c3e 100644 --- a/web/regression/testsuite.py +++ b/web/regression/testsuite.py @@ -10,16 +10,18 @@ """ 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 -# 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) +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) @@ -30,50 +32,113 @@ 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! +# 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 +test_client = app.test_client() -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 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 + """ -def suite(): - """ Defining test suite which will execute all the testcases present in - tests directory according to set priority.""" + from pgadmin.utils.route import TestsGeneratorRegistry + modules = [] pgadmin_suite = unittest.TestSuite() - modules = [] + # Load the test modules which are in given package(i.e. in arguments.pkg) + if 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) - modules.insert(gen.priority, gen) - - for m in modules: - obj = m() - obj.setTestClient(test_client) + # 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__': - suite = suite() - tests = unittest.TextTestRunner(descriptions=True, verbosity=2).run(suite) + # Set basic logging configuration for log file + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s:%(levelname)s:%(name)s:%(message)s', + filename=CURRENT_PATH + "/" + "logger.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: logger.log placed at ", + CURRENT_PATH)
-- Sent via pgadmin-hackers mailing list (pgadmin-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgadmin-hackers