Enhancements to the regression test suite.

Navnath Gadakh and Priyanka Shendge
This commit is contained in:
Dave Page 2016-07-18 14:50:21 +01:00
parent c7d25c33f2
commit f17c2e3b84
25 changed files with 1293 additions and 308 deletions

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -12,4 +12,4 @@ from pgadmin.utils.route import BaseTestGenerator
class ServerGenerateTestCase(BaseTestGenerator):
def runTest(self):
print ("In ServerGenerateTestCase...")
return

View File

@ -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)

View File

@ -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']
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']}
all_id = get_ids()
server_ids = all_id["sid"]
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)
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)

View File

@ -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)

View File

@ -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)

View File

@ -12,4 +12,4 @@ from pgadmin.utils.route import BaseTestGenerator
class SGGenerateTestCase(BaseTestGenerator):
def runTest(self):
print ("In SGGenerateTestCase...")
return

View File

@ -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)

View File

@ -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)

View File

@ -12,4 +12,4 @@ from pgadmin.utils.route import BaseTestGenerator
class BrowserGenerateTestCase(BaseTestGenerator):
def runTest(self):
print ("In BrowserGenerateTestCase...")
return

View File

@ -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)

View File

@ -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)

View File

@ -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'))

View File

@ -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)

View File

@ -52,8 +52,10 @@ class TestsGeneratorRegistry(ABCMeta):
from werkzeug.utils import find_modules
for module_name in find_modules(pkg, False, True):
try:
module = import_module(module_name)
except ImportError:
pass
import six

View File

@ -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
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 \
$ 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
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 '/<installation dir>/web/regression/'.
If you move the file to another location, you must create a symbolic link
that specifies the new location.
If you move the file to another location, you must create a symbolic
link that specifies the new location.
2c) Specifying Server Configuration file:
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.
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.
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'

147
web/regression/runtests.py Normal file
View File

@ -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)

View File

@ -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"
}
]
}

View File

@ -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')

View File

@ -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

View File

@ -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)