3
0
Fork 0

feat: add "progress" page for executing upgrades

show scrolling stdout from subprocess

nb. this does *not* show stderr, although that is captured
This commit is contained in:
Lance Edgar 2024-08-25 15:52:29 -05:00
parent e5e31a7d32
commit 8669ca2283
6 changed files with 392 additions and 41 deletions

View file

@ -1342,8 +1342,11 @@ class TestMasterView(WebTestCase):
def test_execute(self):
self.pyramid_config.add_route('settings.view', '/settings/{name}')
self.pyramid_config.add_route('progress', '/progress/{key}')
model = self.app.model
self.app.save_setting(self.session, 'foo', 'bar')
user = model.User(username='barney')
self.session.add(user)
self.session.commit()
with patch.multiple(mod.MasterView, create=True,
@ -1352,18 +1355,54 @@ class TestMasterView(WebTestCase):
Session=MagicMock(return_value=self.session)):
view = self.make_view()
self.request.matchdict = {'name': 'foo'}
self.request.session.id = 'mockid'
self.request.user = user
# basic usage, redirects to view obj url
response = view.execute()
self.assertEqual(response.status_code, 302)
self.assertEqual(self.request.session.pop_flash(), ["Setting was executed."])
# execution error
with patch.object(view, 'execute_instance', side_effect=RuntimeError):
# basic usage; user is shown progress page
with patch.object(mod, 'threading') as threading:
response = view.execute()
self.assertEqual(response.status_code, 302)
self.assertEqual(self.request.session.pop_flash(), [])
self.assertEqual(self.request.session.pop_flash('error'), ["RuntimeError"])
threading.Thread.return_value.start.assert_called_once_with()
self.assertEqual(response.status_code, 200)
def test_execute_thread(self):
model = self.app.model
enum = self.app.enum
user = model.User(username='barney')
self.session.add(user)
upgrade = model.Upgrade(description='test', created_by=user,
status=enum.UpgradeStatus.PENDING)
self.session.add(upgrade)
self.session.commit()
with patch.multiple(mod.MasterView, create=True,
model_class=model.Upgrade):
view = self.make_view()
# basic execute, no progress
with patch.object(view, 'execute_instance') as execute_instance:
view.execute_thread({'uuid': upgrade.uuid}, user.uuid)
execute_instance.assert_called_once()
# basic execute, with progress
with patch.object(view, 'execute_instance') as execute_instance:
progress = MagicMock()
view.execute_thread({'uuid': upgrade.uuid}, user.uuid, progress=progress)
execute_instance.assert_called_once()
progress.handle_success.assert_called_once_with()
# error, no progress
with patch.object(view, 'execute_instance') as execute_instance:
execute_instance.side_effect = RuntimeError
view.execute_thread({'uuid': upgrade.uuid}, user.uuid)
execute_instance.assert_called_once()
# error, with progress
with patch.object(view, 'execute_instance') as execute_instance:
progress = MagicMock()
execute_instance.side_effect = RuntimeError
view.execute_thread({'uuid': upgrade.uuid}, user.uuid, progress=progress)
execute_instance.assert_called_once()
progress.handle_error.assert_called_once()
def test_configure(self):
self.pyramid_config.include('wuttaweb.views.common')