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

@@ -56,9 +56,10 @@ blueprint = RestoreModule(
class RestoreMessage(IProcessDesc):
def __init__(self, _sid, _bfile, *_args):
def __init__(self, _sid, _bfile, *_args, **_kwargs):
self.sid = _sid
self.bfile = _bfile
self.database = _kwargs['database'] if 'database' in _kwargs else None
self.cmd = ''
def cmd_arg(x):
@@ -75,11 +76,12 @@ class RestoreMessage(IProcessDesc):
else:
self.cmd += cmd_arg(arg)
def get_server_details(self):
# Fetch the server details like hostname, port, roles etc
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)
@@ -87,42 +89,28 @@ class RestoreMessage(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 message(self):
name, host, port = self.get_server_details()
return _("Restoring backup on the server '{0}'").format(
"{0} ({1}:{2})".format(
html.safe_str(name),
html.safe_str(host),
html.safe_str(port)
),
)
return _("Restoring backup on the server '{0}'")\
.format(self.get_server_name())
@property
def type_desc(self):
return _("Restoring backup on the server")
def details(self, cmd, args):
name, host, port = self.get_server_details()
res = '<div>'
res += html.safe_str(
_(
"Restoring backup on the server '{0}'..."
).format(
"{0} ({1}:{2})".format(name, host, port)
)
)
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": self.get_server_name(),
"object": getattr(self, 'database', ''),
"type": _("Restore"),
}
@blueprint.route("/")
@@ -409,7 +397,8 @@ def create_restore_job(sid):
data['file'].encode('utf-8') if hasattr(
data['file'], 'encode'
) else data['file'],
*args
*args,
database=data['database']
),
cmd=utility, args=args
)
@@ -434,7 +423,7 @@ def create_restore_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

@@ -97,7 +97,7 @@ define('tools.restore', [
gettext(data.errormsg)
);
} else {
pgBrowser.Events.trigger('pgadmin-bgprocess:created');
pgBrowser.BgProcessManager.startProcess(data.data.job_id, data.data.desc);
}
},
setExtraParameters: function(treeInfo, nodeData) {

View File

@@ -13,6 +13,12 @@ from pgadmin.tools.restore import RestoreMessage
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):
@@ -46,13 +52,14 @@ class BatchProcessTest(BaseTestGenerator):
))
]
@patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
@patch.object(Preferences, 'module', return_value=MagicMock())
@patch('pgadmin.tools.restore.RestoreMessage.get_server_name')
@patch('pgadmin.misc.bgprocess.processes.Popen')
@patch('pgadmin.misc.bgprocess.processes.db')
@patch('pgadmin.tools.restore.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
@@ -75,10 +82,14 @@ class BatchProcessTest(BaseTestGenerator):
self.class_params['database']
))
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'])
db_mock.session.add.side_effect = db_session_add_mock
db_mock.session.commit = MagicMock(return_value=True)
@@ -110,13 +121,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(
@@ -142,21 +155,21 @@ 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, restore_obj, _operate_orphan_process_mock,
def _check_list(self, p, restore_obj,
update_process_info_mock, process_mock):
class TestMockProcess():
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(restore_obj,
@@ -165,7 +178,6 @@ class BatchProcessTest(BaseTestGenerator):
]
update_process_info_mock.return_value = [True, True]
_operate_orphan_process_mock.return_value = False
ret_value = p.list()
self.assertEqual(1, len(ret_value))

View File

@@ -143,10 +143,10 @@ class RestoreJobTest(BaseTestGenerator):
if self.expected_cmd_opts:
for opt in self.expected_cmd_opts:
self.assertIn(opt, the_process['details'])
self.assertIn(opt, the_process['details']['cmd'])
if self.not_expected_cmd_opts:
for opt in self.not_expected_cmd_opts:
self.assertNotIn(opt, the_process['details'])
self.assertNotIn(opt, the_process['details']['cmd'])
# Check the process details
p_details = self.tester.get('/misc/bgprocess/{0}?_={1}'.format(

View File

@@ -348,6 +348,8 @@ class RestoreCreateJobTest(BaseTestGenerator):
return_value=True
)
restore_message_mock.message = 'test'
batch_process_mock.return_value.desc = restore_message_mock
export_password_env_mock.return_value = True
server_response = server_utils.connect_server(self, self.server_id)

View File

@@ -49,12 +49,13 @@ class RestoreMessageTest(BaseTestGenerator):
))
]
@patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
def runTest(self, get_server_details_mock):
get_server_details_mock.return_value = \
self.class_params['name'],\
self.class_params['host'],\
self.class_params['port']
@patch('pgadmin.tools.restore.RestoreMessage.get_server_name')
def runTest(self, get_server_name_mock):
get_server_name_mock.return_value = "{0} ({1}:{2})" \
.format(
self.class_params['name'],
self.class_params['host'],
self.class_params['port'])
restore_obj = RestoreMessage(
self.class_params['sid'],
@@ -68,4 +69,4 @@ class RestoreMessageTest(BaseTestGenerator):
# Check the command
obj_details = restore_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'])