1) Added support to show all background processes in separate panel. Fixes #3709

2) Port process watcher to React. Fixes #7404
This commit is contained in:
Aditya Toshniwal
2022-08-11 10:49:45 +05:30
committed by Akshay Joshi
parent 271b6d91fc
commit c2b23465cc
100 changed files with 1949 additions and 1638 deletions

View File

@@ -6,7 +6,6 @@
# This software is released under the PostgreSQL Licence
#
##########################################################################
"""Implements Backup Utility"""
import simplejson as json
@@ -103,9 +102,12 @@ class BackupMessage(IProcessDesc):
else:
self.cmd += cmd_arg(arg)
def get_server_details(self):
def get_server_name(self):
s = get_server(self.sid)
if s is None:
return _("Not available")
from pgadmin.utils.driver import get_driver
driver = get_driver(PG_DEFAULT_DRIVER)
manager = driver.connection_manager(self.sid)
@@ -113,7 +115,10 @@ class BackupMessage(IProcessDesc):
host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
return s.name, host, port
s.name = html.safe_str(s.name)
host = html.safe_str(host)
port = html.safe_str(port)
return "{0} ({1}:{2})".format(s.name, host, port)
@property
def type_desc(self):
@@ -129,77 +134,45 @@ class BackupMessage(IProcessDesc):
@property
def message(self):
name, host, port = self.get_server_details()
name = html.safe_str(name)
host = html.safe_str(host)
port = html.safe_str(port)
server_name = self.get_server_name()
if self.backup_type == BACKUP.OBJECT:
return _(
"Backing up an object on the server '{0}' "
"from database '{1}'"
).format(self.args_str.format(name, host, port),
).format(server_name,
html.safe_str(self.database)
)
if self.backup_type == BACKUP.GLOBALS:
return _("Backing up the global objects on "
"the server '{0}'").format(
self.args_str.format(
name, host, port
)
server_name
)
elif self.backup_type == BACKUP.SERVER:
return _("Backing up the server '{0}'").format(
self.args_str.format(
name, host, port
)
server_name
)
else:
# It should never reach here.
return "Unknown Backup"
def details(self, cmd, args):
name, host, port = self.get_server_details()
res = '<div>'
server_name = self.get_server_name()
backup_type = _("Backup")
if self.backup_type == BACKUP.OBJECT:
msg = _(
"Backing up an object on the server '{0}' "
"from database '{1}'..."
).format(
self.args_str.format(
name, host, port
),
self.database
)
res += html.safe_str(msg)
backup_type = _("Backup Object")
elif self.backup_type == BACKUP.GLOBALS:
msg = _("Backing up the global objects on "
"the server '{0}'...").format(
self.args_str.format(
name, host, port
)
)
res += html.safe_str(msg)
backup_type = _("Backup Globals")
elif self.backup_type == BACKUP.SERVER:
msg = _("Backing up the server '{0}'...").format(
self.args_str.format(
name, host, port
)
)
res += html.safe_str(msg)
else:
# It should never reach here.
res += "Backup"
backup_type = _("Backup Server")
res += '</div><div class="py-1">'
res += _("Running command:")
res += '<div class="pg-bg-cmd enable-selection p-1">'
res += html.safe_str(cmd + self.cmd)
res += '</div></div>'
return res
return {
"message": self.message,
"cmd": cmd + self.cmd,
"server": server_name,
"object": self.database,
"type": backup_type,
}
@blueprint.route("/")
@@ -487,7 +460,7 @@ def create_backup_objects_job(sid):
# Return response
return make_json_response(
data={'job_id': jid, 'Success': 1}
data={'job_id': jid, 'desc': p.desc.message, 'Success': 1}
)

View File

@@ -181,7 +181,7 @@ define([
gettext(data.errormsg)
);
} else {
pgBrowser.Events.trigger('pgadmin-bgprocess:created');
pgBrowser.BgProcessManager.startProcess(data.data.job_id, data.data.desc);
}
},
url_for_utility_exists(id, params){

View File

@@ -731,6 +731,7 @@ class BackupCreateJobTest(BaseTestGenerator):
self.class_params['username'],
self.class_params['database']
)
mock_result = server_mock.query.filter_by.return_value
mock_result.first.return_value = mock_obj
@@ -743,7 +744,8 @@ class BackupCreateJobTest(BaseTestGenerator):
batch_process_mock.return_value.start = MagicMock(
return_value=True
)
backup_message_mock.message = 'test'
batch_process_mock.return_value.desc = backup_message_mock
export_password_env_mock.return_value = True
server_response = server_utils.connect_server(self, self.server_id)

View File

@@ -125,12 +125,13 @@ class BackupMessageTest(BaseTestGenerator):
]
@patch('pgadmin.utils.get_storage_directory')
@patch('pgadmin.tools.backup.BackupMessage.get_server_details')
def runTest(self, get_server_details_mock, get_storage_directory_mock):
get_server_details_mock.return_value = \
self.class_params['name'],\
self.class_params['host'],\
self.class_params['port']
@patch('pgadmin.tools.backup.BackupMessage.get_server_name')
def runTest(self, get_server_name_mock, get_storage_directory_mock):
get_server_name_mock.return_value = "{0} ({1}:{2})"\
.format(
self.class_params['name'],
self.class_params['host'],
self.class_params['port'])
backup_obj = BackupMessage(
self.class_params['type'],
@@ -149,4 +150,4 @@ class BackupMessageTest(BaseTestGenerator):
obj_details = backup_obj.details(self.class_params['cmd'],
self.class_params['args'])
self.assertIn(self.expected_details_cmd, obj_details)
self.assertEqual(self.expected_details_cmd, obj_details['cmd'])

View File

@@ -56,16 +56,16 @@ def run_backup_job(tester, job_id, expected_params, assert_in, assert_not_in,
backup_file = None
if 'details' in the_process:
backup_det = the_process['details']
backup_file = backup_det[int(backup_det.find('--file')) +
8:int(backup_det.find('--host')) - 2]
backup_cmd = the_process['details']['cmd']
backup_file = backup_cmd[int(backup_cmd.find('--file')) +
8:int(backup_cmd.find('--host')) - 2]
if expected_params['expected_cmd_opts']:
for opt in expected_params['expected_cmd_opts']:
assert_in(opt, the_process['details'])
assert_in(opt, the_process['details']['cmd'])
if expected_params['not_expected_cmd_opts']:
for opt in expected_params['not_expected_cmd_opts']:
assert_not_in(opt, the_process['details'])
assert_not_in(opt, the_process['details']['cmd'])
# Check the process details
p_details = tester.get('/misc/bgprocess/{0}?_={1}'.format(

View File

@@ -13,6 +13,12 @@ from pgadmin.tools.backup import BackupMessage, BACKUP
from pgadmin.utils.route import BaseTestGenerator
from pickle import dumps, loads
from unittest.mock import patch, MagicMock
from pgadmin.utils.preferences import Preferences
import datetime
import pytz
start_time = \
datetime.datetime.now(pytz.utc).strftime("%Y-%m-%d %H:%M:%S.%f %z")
class BatchProcessTest(BaseTestGenerator):
@@ -101,13 +107,14 @@ class BatchProcessTest(BaseTestGenerator):
))
]
@patch('pgadmin.tools.backup.BackupMessage.get_server_details')
@patch.object(Preferences, 'module', return_value=MagicMock())
@patch('pgadmin.tools.backup.BackupMessage.get_server_name')
@patch('pgadmin.misc.bgprocess.processes.Popen')
@patch('pgadmin.misc.bgprocess.processes.db')
@patch('pgadmin.tools.backup.current_user')
@patch('pgadmin.misc.bgprocess.processes.current_user')
def runTest(self, current_user_mock, current_user, db_mock,
popen_mock, get_server_details_mock):
popen_mock, get_server_name_mock, pref_module):
with self.app.app_context():
current_user.id = 1
current_user_mock.id = 1
@@ -137,10 +144,14 @@ class BatchProcessTest(BaseTestGenerator):
db_mock.session.add.side_effect = db_session_add_mock
db_mock.session.commit = MagicMock(return_value=True)
get_server_details_mock.return_value = \
self.class_params['name'], \
self.class_params['host'], \
self.class_params['port']
pref_module.return_value.preference.return_value.get.\
return_value = 5
get_server_name_mock.return_value = "{0} ({1}:{2})" \
.format(
self.class_params['name'],
self.class_params['host'],
self.class_params['port'])
backup_obj = BackupMessage(
self.class_params['type'],
@@ -171,13 +182,15 @@ class BatchProcessTest(BaseTestGenerator):
def __init__(self, desc, args, cmd):
self.pid = 1
self.exit_code = 1
self.start_time = '2018-04-17 06:18:56.315445 +0000'
self.start_time = start_time
self.end_time = None
self.desc = dumps(desc)
self.arguments = " ".join(args)
self.command = cmd
self.acknowledge = None
self.process_state = 0
self.utility_pid = 123
self.server_id = None
mock_result = process_mock.query.filter_by.return_value
mock_result.first.return_value = TestMockProcess(
@@ -205,9 +218,7 @@ class BatchProcessTest(BaseTestGenerator):
@patch('pgadmin.misc.bgprocess.processes.Process')
@patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
'update_process_info')
@patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
'_operate_orphan_process')
def _check_list(self, p, backup_obj, _operate_orphan_process_mock,
def _check_list(self, p, backup_obj,
update_process_info_mock, process_mock,
get_complete_file_path_mock, get_storage_directory_mock,
realpath_mock):
@@ -215,13 +226,15 @@ class BatchProcessTest(BaseTestGenerator):
def __init__(self, desc, args, cmd):
self.pid = 1
self.exit_code = 1
self.start_time = '2018-04-17 06:18:56.315445 +0000'
self.start_time = start_time
self.end_time = None
self.desc = dumps(desc)
self.arguments = " ".join(args)
self.command = cmd
self.acknowledge = None
self.process_state = 0
self.utility_pid = 123
self.server_id = None
process_mock.query.filter_by.return_value = [
TestMockProcess(backup_obj,
@@ -232,7 +245,6 @@ class BatchProcessTest(BaseTestGenerator):
get_complete_file_path_mock.return_value = self.class_params['bfile']
realpath_mock.return_value = self.class_params['bfile']
get_storage_directory_mock.return_value = '//'
_operate_orphan_process_mock.return_value = False
ret_value = p.list()
self.assertEqual(1, len(ret_value))