Fixed manager tests to use Qt5

Also due to old workarounds not working around anymore,
switched over to "single QApplication object" model.
This commit is contained in:
Marta Marczykowska-Górecka 2019-10-15 00:00:18 +02:00
parent 12481fd561
commit 6f73ef2163
No known key found for this signature in database
GPG Key ID: 9A752C30B26FD04B
7 changed files with 121 additions and 246 deletions

View File

@ -0,0 +1,16 @@
import asyncio
import sys
import quamash
from PyQt5 import QtWidgets
qtapp = None
loop = None
def init_qtapp():
global qtapp, loop
if qtapp is None:
qtapp = QtWidgets.QApplication(sys.argv)
loop = quamash.QEventLoop(qtapp)
asyncio.set_event_loop(loop)
return qtapp, loop

View File

@ -20,21 +20,20 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
import logging.handlers
import sys
import unittest
import unittest.mock
from PyQt4 import QtGui, QtTest, QtCore
from PyQt5 import QtTest, QtCore, QtWidgets
from qubesadmin import Qubes, events, utils, exc
from qubesmanager import backup
import quamash
from qubesmanager.tests import init_qtapp
import asyncio
import gc
class BackupTest(unittest.TestCase):
def setUp(self):
super(BackupTest, self).setUp()
self.qtapp, self.loop = init_qtapp()
# mock up nonexistence of saved backup settings
self.patcher_open = unittest.mock.patch('builtins.open')
@ -49,43 +48,16 @@ class BackupTest(unittest.TestCase):
self.addCleanup(self.patcher_thread.stop)
self.qapp = Qubes()
self.qtapp = QtGui.QApplication(["test", "-style", "cleanlooks"])
self.dispatcher = events.EventsDispatcher(self.qapp)
self.loop = quamash.QEventLoop(self.qtapp)
self.dialog = backup.BackupVMsWindow(
self.qtapp, self.qapp, self.dispatcher)
self.dialog.show()
def tearDown(self):
self.dialog.hide()
# process any pending events before destroying the object
self.dialog.close()
self.qtapp.processEvents()
# queue destroying the QApplication object, do that for any other QT
# related objects here too
self.qtapp.deleteLater()
self.dialog.deleteLater()
# process any pending events (other than just queued destroy),
# just in case
self.qtapp.processEvents()
# execute main loop, which will process all events, _
# including just queued destroy_
self.loop.run_until_complete(asyncio.sleep(0))
# at this point it QT objects are destroyed, cleanup all remaining
# references;
# del other QT object here too
self.loop.close()
del self.dialog
del self.qtapp
del self.loop
gc.collect()
yield from asyncio.sleep(1)
super(BackupTest, self).tearDown()
def test_00_window_loads(self):
@ -106,16 +78,17 @@ class BackupTest(unittest.TestCase):
"Compress backup should be checked by default")
# correct VMs are selected
include_in_backups_no = len([vm for vm in self.qapp.domains
if not vm.features.get('internal', False)
and getattr(vm, 'include_in_backups', True)])
include_in_backups_no = len(
[vm for vm in self.qapp.domains
if not vm.features.get('internal', False)
and getattr(vm, 'include_in_backups', True)])
selected_no = self.dialog.select_vms_widget.selected_list.count()
self.assertEqual(include_in_backups_no, selected_no,
"Incorrect VMs selected by default")
# passphrase is empty
self.assertEqual(self.dialog.passphrase_line_edit.text(), "",
"Passphrase should be empty")
"Passphrase should be empty")
# save defaults
self.assertTrue(self.dialog.save_profile_checkbox.isChecked(),
@ -399,7 +372,7 @@ class BackupTest(unittest.TestCase):
self.assertTrue(self.dialog.unrecognized_config_label.isVisible())
@unittest.mock.patch('qubesmanager.backup_utils.load_backup_profile')
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.information')
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.information')
def test_22_loading_settings_exc(self, mock_info, mock_load):
mock_load.side_effect = exc.QubesException('Error')
@ -436,7 +409,7 @@ class BackupTest(unittest.TestCase):
mock_remove.assert_called_once_with(
'/etc/qubes/backup/qubes-manager-backup-tmp.conf')
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.warning')
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.warning')
@unittest.mock.patch('qubesmanager.backup_utils.write_backup_profile')
@unittest.mock.patch('qubesadmin.Qubes.qubesd_call',
return_value=b'backup output')
@ -461,7 +434,7 @@ class BackupTest(unittest.TestCase):
mock_remove.assert_called_once_with(
'/etc/qubes/backup/qubes-manager-backup-tmp.conf')
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.warning')
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.warning')
@unittest.mock.patch('os.system')
@unittest.mock.patch('os.remove')
@unittest.mock.patch('qubesmanager.backup_utils.write_backup_profile')
@ -501,7 +474,7 @@ class BackupTest(unittest.TestCase):
self.assertEqual(mock_warning.call_count, 0,
"Backup succeeded but received warning")
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.warning')
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.warning')
@unittest.mock.patch('os.system')
@unittest.mock.patch('os.remove')
@unittest.mock.patch('qubesmanager.backup_utils.write_backup_profile')
@ -540,7 +513,7 @@ class BackupTest(unittest.TestCase):
self.assertEqual(mock_warning.call_count, 0,
"Backup succeeded but received warning")
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.warning')
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.warning')
@unittest.mock.patch('os.system')
@unittest.mock.patch('os.remove')
@unittest.mock.patch('qubesmanager.backup_utils.write_backup_profile')
@ -578,14 +551,14 @@ class BackupTest(unittest.TestCase):
"Attempted shutdown at failed backup")
self.assertEqual(mock_warn.call_count, 1)
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.warning')
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.warning')
@unittest.mock.patch('os.system')
@unittest.mock.patch('os.remove')
@unittest.mock.patch('qubesmanager.backup_utils.write_backup_profile')
@unittest.mock.patch('qubesadmin.Qubes.qubesd_call',
return_value=b'backup output')
def test_28_progress(
self, _a, _b, mock_remove, mock_system, mock_warn):
self, _a, _b, _mock_remove, _mock_system, _mock_warn):
self._click_next()
self.assertTrue(self.dialog.currentPage()
is self.dialog.select_dir_page)
@ -626,11 +599,11 @@ class BackupTest(unittest.TestCase):
widget.setCurrentIndex(widget.currentIndex() + 1)
def _click_next(self):
next_widget = self.dialog.button(QtGui.QWizard.NextButton)
next_widget = self.dialog.button(QtWidgets.QWizard.NextButton)
QtTest.QTest.mouseClick(next_widget, QtCore.Qt.LeftButton)
def _click_cancel(self):
cancel_widget = self.dialog.button(QtGui.QWizard.CancelButton)
cancel_widget = self.dialog.button(QtWidgets.QWizard.CancelButton)
QtTest.QTest.mouseClick(cancel_widget, QtCore.Qt.LeftButton)
def _select_vm(self, name_starts_with):

View File

@ -23,48 +23,31 @@ import logging.handlers
import unittest.mock
import quamash
import asyncio
import gc
from PyQt4 import QtGui
import sys
from PyQt5 import QtWidgets
from qubesadmin import Qubes
from qubesmanager import backup_utils
qtapp = QtWidgets.QApplication(sys.argv)
loop = quamash.QEventLoop(qtapp)
asyncio.set_event_loop(loop)
class BackupUtilsTest(unittest.TestCase):
def setUp(self):
super(BackupUtilsTest, self).setUp()
self.qapp = Qubes()
self.qtapp = QtGui.QApplication(["test", "-style", "cleanlooks"])
self.loop = quamash.QEventLoop(self.qtapp)
self.loop = quamash.QEventLoop(qtapp)
def tearDown(self):
# process any pending events before destroying the object
self.qtapp.processEvents()
# queue destroying the QApplication object, do that for any other QT
# related objects here too
self.qtapp.deleteLater()
# process any pending events (other than just queued destroy),
# just in case
self.qtapp.processEvents()
# execute main loop, which will process all events, _
# including just queued destroy_
self.loop.run_until_complete(asyncio.sleep(0))
# at this point it QT objects are destroyed, cleanup all remaining
# references;
# del other QT object here too
self.loop.close()
del self.qtapp
del self.loop
gc.collect()
qtapp.processEvents()
yield from loop.sleep(1)
super(BackupUtilsTest, self).tearDown()
def test_01_fill_apvms(self):
dialog = QtGui.QDialog()
combobox = QtGui.QComboBox()
dialog = QtWidgets.QDialog()
combobox = QtWidgets.QComboBox()
dialog.appvm_combobox = combobox
dialog.qubes_app = self.qapp
@ -87,8 +70,6 @@ class BackupUtilsTest(unittest.TestCase):
"VM list not filled correctly")
if __name__ == "__main__":
ha_syslog = logging.handlers.SysLogHandler('/dev/log')
ha_syslog.setFormatter(

View File

@ -20,25 +20,22 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
import logging.handlers
import quamash
import asyncio
import unittest
import unittest.mock
import qubesadmin
import gc
from PyQt4 import QtGui, QtTest, QtCore
from PyQt5 import QtTest, QtCore
from qubesadmin import Qubes
from qubesmanager.tests import init_qtapp
from qubesmanager import create_new_vm
class NewVmTest(unittest.TestCase):
def setUp(self):
super(NewVmTest, self).setUp()
self.qtapp, self.loop = init_qtapp()
self.qapp = Qubes()
self.qtapp = QtGui.QApplication(["test", "-style", "cleanlooks"])
self.loop = quamash.QEventLoop(self.qtapp)
# mock up the Create VM Thread to avoid changing system state
self.patcher_thread = unittest.mock.patch(
@ -48,39 +45,16 @@ class NewVmTest(unittest.TestCase):
# mock the progress dialog to speed testing up
self.patcher_progress = unittest.mock.patch(
'PyQt4.QtGui.QProgressDialog')
'PyQt5.QtWidgets.QProgressDialog')
self.mock_progress = self.patcher_progress.start()
self.addCleanup(self.patcher_progress.stop)
self.dialog = create_new_vm.NewVmDlg(
self.qtapp, self.qapp)
self.dialog = create_new_vm.NewVmDlg(self.qtapp, self.qapp)
def tearDown(self):
# process any pending events before destroying the object
self.dialog.close()
self.qtapp.processEvents()
# queue destroying the QApplication object, do that for any other QT
# related objects here too
self.qtapp.deleteLater()
self.dialog.deleteLater()
# process any pending events (other than just queued destroy),
# just in case
self.qtapp.processEvents()
# execute main loop, which will process all events, _
# including just queued destroy_
self.loop.run_until_complete(asyncio.sleep(0))
# at this point it QT objects are destroyed, cleanup all remaining
# references;
# del other QT object here too
self.loop.close()
del self.dialog
del self.qtapp
del self.loop
gc.collect()
yield from self.loop.sleep(1)
super(NewVmTest, self).tearDown()
def test_00_window_loads(self):

View File

@ -20,24 +20,21 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
import logging.handlers
import quamash
import asyncio
import unittest
import unittest.mock
import gc
from PyQt4 import QtGui, QtTest, QtCore
from PyQt5 import QtTest, QtCore, QtWidgets
from qubesadmin import Qubes
from qubesmanager.tests import init_qtapp
import qubesmanager.global_settings as global_settings
class GlobalSettingsTest(unittest.TestCase):
def setUp(self):
super(GlobalSettingsTest, self).setUp()
self.qtapp, self.loop = init_qtapp()
self.qapp = Qubes()
self.qtapp = QtGui.QApplication(["test", "-style", "cleanlooks"])
self.loop = quamash.QEventLoop(self.qtapp)
self.dialog = global_settings.GlobalSettingsWindow(self.qtapp,
self.qapp)
@ -47,30 +44,9 @@ class GlobalSettingsTest(unittest.TestCase):
self.addCleanup(self.setattr_patcher.stop)
def tearDown(self):
# process any pending events before destroying the object
self.dialog.close()
self.qtapp.processEvents()
# queue destroying the QApplication object, do that for any other QT
# related objects here too
self.qtapp.deleteLater()
self.dialog.deleteLater()
# process any pending events (other than just queued destroy),
# just in case
self.qtapp.processEvents()
# execute main loop, which will process all events, _
# including just queued destroy_
self.loop.run_until_complete(asyncio.sleep(0))
# at this point it QT objects are destroyed, cleanup all remaining
# references;
# del other QT object here too
self.loop.close()
del self.dialog
del self.qtapp
del self.loop
gc.collect()
yield from self.loop.sleep(1)
super(GlobalSettingsTest, self).tearDown()
def test_00_settings_started(self):
@ -290,8 +266,8 @@ class GlobalSettingsTest(unittest.TestCase):
self.setattr_mock.assert_called_once_with('check_updates_vm',
not current_state)
@unittest.mock.patch("PyQt4.QtGui.QMessageBox.question",
return_value=QtGui.QMessageBox.Yes)
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox.question",
return_value=QtWidgets.QMessageBox.Yes)
@unittest.mock.patch('qubesadmin.features.Features.__setitem__')
def test_72_set_all_vms_true(self, mock_features, msgbox):
@ -308,8 +284,8 @@ class GlobalSettingsTest(unittest.TestCase):
self.assertListEqual(call_list_expected,
mock_features.call_args_list)
@unittest.mock.patch("PyQt4.QtGui.QMessageBox.question",
return_value=QtGui.QMessageBox.Yes)
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox.question",
return_value=QtWidgets.QMessageBox.Yes)
@unittest.mock.patch('qubesadmin.features.Features.__setitem__')
def test_73_set_all_vms_false(self, mock_features, msgbox):

View File

@ -22,64 +22,39 @@
import asyncio
import contextlib
import logging.handlers
import sys
import unittest
import unittest.mock
import gc
import subprocess
import datetime
import time
import quamash
from PyQt4 import QtGui, QtTest, QtCore
from PyQt5 import QtTest, QtCore, QtWidgets
from qubesadmin import Qubes, events, exc
import qubesmanager.qube_manager as qube_manager
from qubesmanager.tests import init_qtapp
class QubeManagerTest(unittest.TestCase):
def setUp(self):
super(QubeManagerTest, self).setUp()
self.qtapp, self.loop = init_qtapp()
self.mock_qprogress = unittest.mock.patch('PyQt4.QtGui.QProgressDialog')
self.mock_qprogress = unittest.mock.patch(
'PyQt5.QtWidgets.QProgressDialog')
self.mock_qprogress.start()
self.addCleanup(self.mock_qprogress.stop)
self.qapp = Qubes()
self.qtapp = QtGui.QApplication(["test", "-style", "cleanlooks"])
self.dispatcher = events.EventsDispatcher(self.qapp)
self.loop = quamash.QEventLoop(self.qtapp)
self.dialog = qube_manager.VmManagerWindow(
self.qtapp, self.qapp, self.dispatcher)
def tearDown(self):
# process any pending events before destroying the object
self.dialog.close()
self.qtapp.processEvents()
# queue destroying the QApplication object, do that for any other QT
# related objects here too
self.qtapp.deleteLater()
self.dialog.deleteLater()
# process any pending events (other than just queued destroy),
# just in case
self.qtapp.processEvents()
# execute main loop, which will process all events, _
# including just queued destroy_
self.loop.run_until_complete(asyncio.sleep(0))
# at this point it QT objects are destroyed, cleanup all remaining
# references;
# del other QT object here too
self.loop.close()
del self.dialog
del self.qtapp
del self.loop
gc.collect()
yield from self.loop.sleep(1)
super(QubeManagerTest, self).tearDown()
def test_000_window_loads(self):
@ -262,8 +237,9 @@ class QubeManagerTest(unittest.TestCase):
mock_settings.side_effect = (
lambda x, *args, **kwargs: settings_result_dict.get(x))
with unittest.mock.patch('PyQt4.QtCore.QSettings.value', mock_settings),\
unittest.mock.patch('PyQt4.QtGui.QMessageBox.warning')\
with unittest.mock.patch('PyQt5.QtCore.QSettings.value',
mock_settings),\
unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.warning')\
as mock_warning:
self.dialog = qube_manager.VmManagerWindow(
self.qtapp, self.qapp, self.dispatcher)
@ -357,8 +333,8 @@ class QubeManagerTest(unittest.TestCase):
self.assertFalse(self.dialog.action_set_keyboard_layout.isEnabled())
@unittest.mock.patch("PyQt4.QtGui.QMessageBox.question",
return_value=QtGui.QMessageBox.Yes)
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox.question",
return_value=QtWidgets.QMessageBox.Yes)
def test_207_update_vm_not_running(self, _):
selected_vm = self._select_templatevm(running=False)
self.assertIsNotNone(selected_vm, "No valid template VM found")
@ -387,7 +363,7 @@ class QubeManagerTest(unittest.TestCase):
mock_update.assert_called_once_with(selected_vm)
mock_update().start.assert_called_once_with()
@unittest.mock.patch("PyQt4.QtGui.QInputDialog.getText",
@unittest.mock.patch("PyQt5.QtWidgets.QInputDialog.getText",
return_value=("command to run", True))
def test_209_run_command_in_vm(self, _):
selected_vm = self._select_non_admin_vm()
@ -408,7 +384,7 @@ class QubeManagerTest(unittest.TestCase):
self.assertFalse(self.dialog.action_run_command_in_vm.isEnabled(),
"Should not be able to run commands for dom0")
@unittest.mock.patch("PyQt4.QtGui.QMessageBox.warning")
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox.warning")
def test_211_pausevm(self, mock_warn):
selected_vm = self._select_non_admin_vm(running=True)
@ -446,9 +422,9 @@ class QubeManagerTest(unittest.TestCase):
self._select_non_admin_vm(running=True)
self.assertFalse(self.dialog.action_resumevm.isEnabled())
@unittest.mock.patch("PyQt4.QtGui.QMessageBox.question",
return_value=QtGui.QMessageBox.Yes)
@unittest.mock.patch('PyQt4.QtCore.QTimer.singleShot')
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox.question",
return_value=QtWidgets.QMessageBox.Yes)
@unittest.mock.patch('PyQt5.QtCore.QTimer.singleShot')
@unittest.mock.patch('qubesmanager.qube_manager.VmShutdownMonitor')
def test_214_shutdownvm(self, mock_monitor, mock_timer, _):
selected_vm = self._select_non_admin_vm(running=True)
@ -484,7 +460,7 @@ class QubeManagerTest(unittest.TestCase):
self.assertFalse(self.dialog.action_removevm.isEnabled())
@unittest.mock.patch("PyQt4.QtGui.QMessageBox")
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox")
@unittest.mock.patch('qubesadmin.utils.vm_dependencies')
def test_218_remove_vm_dependencies(self, mock_dependencies, mock_msgbox):
action = self.dialog.action_removevm
@ -496,8 +472,8 @@ class QubeManagerTest(unittest.TestCase):
action.trigger()
mock_msgbox().show.assert_called_with()
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.warning')
@unittest.mock.patch("PyQt4.QtGui.QInputDialog.getText")
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.warning')
@unittest.mock.patch("PyQt5.QtWidgets.QInputDialog.getText")
@unittest.mock.patch('qubesadmin.utils.vm_dependencies')
def test_219_remove_vm_no_depencies(
self, mock_dependencies, mock_input, mock_warning):
@ -531,10 +507,10 @@ class QubeManagerTest(unittest.TestCase):
self._select_non_admin_vm(running=False)
self.assertFalse(self.dialog.action_restartvm.isEnabled())
@unittest.mock.patch('PyQt4.QtCore.QTimer.singleShot')
@unittest.mock.patch('PyQt5.QtCore.QTimer.singleShot')
@unittest.mock.patch('qubesmanager.qube_manager.VmShutdownMonitor')
@unittest.mock.patch("PyQt4.QtGui.QMessageBox.question",
return_value=QtGui.QMessageBox.Yes)
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox.question",
return_value=QtWidgets.QMessageBox.Yes)
def test_221_restartvm_running_vm(self, _msgbox, mock_monitor, _qtimer):
selected_vm = self._select_non_admin_vm(running=True)
@ -550,8 +526,8 @@ class QubeManagerTest(unittest.TestCase):
unittest.mock.ANY, True, unittest.mock.ANY)
@unittest.mock.patch('qubesmanager.qube_manager.StartVMThread')
@unittest.mock.patch("PyQt4.QtGui.QMessageBox.question",
return_value=QtGui.QMessageBox.Yes)
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox.question",
return_value=QtWidgets.QMessageBox.Yes)
def test_222_restartvm_shutdown_meantime(self, _, mock_thread):
selected_vm = self._select_non_admin_vm(running=True)
@ -577,8 +553,8 @@ class QubeManagerTest(unittest.TestCase):
self.dialog.clear_threads)
mock_thread().start.assert_called_once_with()
@unittest.mock.patch("PyQt4.QtGui.QMessageBox.question",
return_value=QtGui.QMessageBox.Yes)
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox.question",
return_value=QtWidgets.QMessageBox.Yes)
@unittest.mock.patch('qubesmanager.qube_manager.UpdateVMThread')
def test_224_updatevm_halted(self, mock_thread, _):
selected_vm = self._select_non_admin_vm(running=False)
@ -590,8 +566,8 @@ class QubeManagerTest(unittest.TestCase):
self.dialog.clear_threads)
mock_thread().start.assert_called_once_with()
@unittest.mock.patch("PyQt4.QtGui.QMessageBox.question",
return_value=QtGui.QMessageBox.Yes)
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox.question",
return_value=QtWidgets.QMessageBox.Yes)
def test_224_killvm(self, _):
selected_vm = self._select_non_admin_vm(running=True)
action = self.dialog.action_killvm
@ -600,8 +576,8 @@ class QubeManagerTest(unittest.TestCase):
action.trigger()
mock_kill.assert_called_once_with()
@unittest.mock.patch("PyQt4.QtGui.QMessageBox.question",
return_value=QtGui.QMessageBox.Cancel)
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox.question",
return_value=QtWidgets.QMessageBox.Cancel)
def test_225_killvm_cancel(self, _):
selected_vm = self._select_non_admin_vm(running=True)
action = self.dialog.action_killvm
@ -659,7 +635,7 @@ class QubeManagerTest(unittest.TestCase):
mock_subprocess.assert_called_once_with('qubes-template-manager')
@unittest.mock.patch('qubesmanager.common_threads.CloneVMThread')
@unittest.mock.patch('PyQt4.QtGui.QInputDialog.getText')
@unittest.mock.patch('PyQt5.QtWidgets.QInputDialog.getText')
def test_232_clonevm(self, mock_input, mock_thread):
action = self.dialog.action_clonevm
@ -714,7 +690,7 @@ class QubeManagerTest(unittest.TestCase):
"Incorrect number of vms shown for cleared search box")
def test_235_hide_show_toolbars(self):
with unittest.mock.patch('PyQt4.QtCore.QSettings.setValue')\
with unittest.mock.patch('PyQt5.QtCore.QSettings.setValue')\
as mock_setvalue:
self.dialog.action_menubar.trigger()
mock_setvalue.assert_called_with('view/menubar_visible', False)
@ -741,8 +717,8 @@ class QubeManagerTest(unittest.TestCase):
self.assertEqual(expected_number, actual_number,
"Incorrect number of vms shown for cleared search box")
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.information')
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.warning')
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.information')
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.warning')
def test_300_clear_threads(self, mock_warning, mock_info):
mock_thread_finished_ok = unittest.mock.Mock(
spec=['isFinished', 'msg', 'msg_is_success'],
@ -1422,8 +1398,8 @@ class QubeManagerThreadTest(unittest.TestCase):
class VMShutdownMonitorTest(unittest.TestCase):
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.question')
@unittest.mock.patch('PyQt4.QtCore.QTimer')
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.question')
@unittest.mock.patch('PyQt5.QtCore.QTimer')
def test_01_vm_shutdown_correct(self, mock_timer, mock_question):
mock_vm = unittest.mock.Mock()
mock_vm.is_running.return_value = False
@ -1437,9 +1413,9 @@ class VMShutdownMonitorTest(unittest.TestCase):
self.assertEqual(mock_timer.call_count, 0)
monitor.restart_vm_if_needed.assert_called_once_with()
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.question',
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.question',
return_value=1)
@unittest.mock.patch('PyQt4.QtCore.QTimer.singleShot')
@unittest.mock.patch('PyQt5.QtCore.QTimer.singleShot')
def test_02_vm_not_shutdown_wait(self, mock_timer, mock_question):
mock_vm = unittest.mock.Mock()
mock_vm.is_running.return_value = True
@ -1453,9 +1429,9 @@ class VMShutdownMonitorTest(unittest.TestCase):
self.assertEqual(mock_question.call_count, 1)
self.assertEqual(mock_timer.call_count, 1)
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.question',
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.question',
return_value=0)
@unittest.mock.patch('PyQt4.QtCore.QTimer.singleShot')
@unittest.mock.patch('PyQt5.QtCore.QTimer.singleShot')
def test_03_vm_kill(self, mock_timer, mock_question):
mock_vm = unittest.mock.Mock()
mock_vm.is_running.return_value = True
@ -1472,9 +1448,9 @@ class VMShutdownMonitorTest(unittest.TestCase):
mock_vm.kill.assert_called_once_with()
monitor.restart_vm_if_needed.assert_called_once_with()
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.question',
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.question',
return_value=0)
@unittest.mock.patch('PyQt4.QtCore.QTimer.singleShot')
@unittest.mock.patch('PyQt5.QtCore.QTimer.singleShot')
def test_04_check_later(self, mock_timer, mock_question):
mock_vm = unittest.mock.Mock()
mock_vm.is_running.return_value = True

View File

@ -24,56 +24,35 @@ import unittest
import unittest.mock
import gc
import quamash
import asyncio
from PyQt4 import QtGui, QtTest, QtCore
from PyQt5 import QtTest, QtCore, QtWidgets
from qubesadmin import Qubes
import qubesmanager.settings as vm_settings
from qubesmanager.tests import init_qtapp
class VMSettingsTest(unittest.TestCase):
def setUp(self):
super(VMSettingsTest, self).setUp()
self.qtapp, self.loop = init_qtapp()
self.mock_qprogress = unittest.mock.patch('PyQt4.QtGui.QProgressDialog')
self.mock_qprogress = unittest.mock.patch(
'PyQt5.QtWidgets.QProgressDialog')
self.mock_qprogress.start()
self.addCleanup(self.mock_qprogress.stop)
self.qapp = Qubes()
self.qtapp = QtGui.QApplication(["test", "-style", "cleanlooks"])
self.loop = quamash.QEventLoop(self.qtapp)
if "testvm" in self.qapp.domains:
del self.qapp.domains["testvm"]
def tearDown(self):
del self.qapp.domains["testvm"]
# process any pending events before destroying the object
self.qtapp.processEvents()
yield from self.loop.sleep(1)
# queue destroying the QApplication object, do that for any other QT
# related objects here too
self.dialog.deleteLater()
self.qtapp.deleteLater()
# process any pending events (other than just queued destroy),
# just in case
self.qtapp.processEvents()
self.qtapp.processEvents()
self.qtapp.processEvents()
# execute main loop, which will process all events, _
# including just queued destroy_
self.loop.run_until_complete(asyncio.sleep(0))
# at this point it QT objects are destroyed, cleanup all remaining
# references;
# del other QT object here too
self.loop.close()
del self.dialog
del self.qtapp
del self.loop
gc.collect()
super(VMSettingsTest, self).tearDown()
def test_00_load_correct_tab(self):
@ -325,8 +304,8 @@ class VMSettingsTest(unittest.TestCase):
# TODO are dependencies correctly processed
@unittest.mock.patch('PyQt4.QtGui.QProgressDialog')
@unittest.mock.patch('PyQt4.QtGui.QInputDialog.getText')
@unittest.mock.patch('PyQt5.QtWidgets.QProgressDialog')
@unittest.mock.patch('PyQt5.QtWidgets.QInputDialog.getText')
@unittest.mock.patch('qubesmanager.settings.RenameVMThread')
def test_11_rename_vm(self, mock_thread, mock_input, _):
self.vm = self.qapp.add_new_vm("AppVM", "testvm", "blue")
@ -343,8 +322,8 @@ class VMSettingsTest(unittest.TestCase):
# TODO: thread tests for rename
@unittest.mock.patch('PyQt4.QtGui.QProgressDialog')
@unittest.mock.patch('PyQt4.QtGui.QInputDialog.getText')
@unittest.mock.patch('PyQt5.QtWidgets.QProgressDialog')
@unittest.mock.patch('PyQt5.QtWidgets.QInputDialog.getText')
@unittest.mock.patch('qubesmanager.common_threads.CloneVMThread')
def test_12_clone_vm(self, mock_thread, mock_input, _):
self.vm = self.qapp.add_new_vm("AppVM", "testvm", "blue")
@ -359,9 +338,9 @@ class VMSettingsTest(unittest.TestCase):
mock_thread.assert_called_with(self.vm, "testvm2")
mock_thread().start.assert_called_with()
@unittest.mock.patch('PyQt4.QtGui.QMessageBox.warning')
@unittest.mock.patch('PyQt4.QtGui.QProgressDialog')
@unittest.mock.patch('PyQt4.QtGui.QInputDialog.getText')
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.warning')
@unittest.mock.patch('PyQt5.QtWidgets.QProgressDialog')
@unittest.mock.patch('PyQt5.QtWidgets.QInputDialog.getText')
@unittest.mock.patch('qubesmanager.common_threads.RemoveVMThread')
def test_13_remove_vm(self, mock_thread, mock_input, _, mock_warning):
self.vm = self.qapp.add_new_vm("AppVM", "testvm", "blue")