Migration to View/Model design (#195)
Squashed commit of the following: commit 7929b8f0f6ec21ae0fb90203205e4224ce5bc1b7 Author: donoban <donoban@riseup.net> Date: Tue Jul 28 17:21:11 2020 +0200 Try to fix sort commit 5e4598e1d6aba0e2208e7bca761be83931457a26 Author: donoban <donoban@riseup.net> Date: Mon Jul 27 04:06:37 2020 +0200 Fix import commit 60f53e7ef0e35fde9143835b18015db570739544 Author: donoban <donoban@riseup.net> Date: Mon Jul 27 04:03:17 2020 +0200 Fix 218 test commit e430e394774bba4ca306f2fb0b8d55e10f9e2bc2 Author: donoban <donoban@riseup.net> Date: Mon Jul 27 04:01:56 2020 +0200 Avoid error if dvm is None commit 679880ff4f3d7117784e90d6cb53538b7fba4f0d Author: donoban <donoban@riseup.net> Date: Mon Jul 27 03:58:59 2020 +0200 Fix sorting again commit f84edcdc02bf311de9d60274ae7fba90566a460e Author: donoban <donoban@riseup.net> Date: Sun Jul 26 03:30:14 2020 +0200 Yes, it's needed commit 5d00c91db45f99c78d7f15f77dd65a51b286fc77 Author: donoban <donoban@riseup.net> Date: Sat Jul 25 23:08:38 2020 +0200 Fix pylint error commit 88a54dc3d2927a04c44e8d4c9548e123852b3e39 Author: donoban <donoban@riseup.net> Date: Sat Jul 25 18:56:40 2020 +0200 Style change commit 42ae96c45b37e03823e782c67b0995f588c7e0bd Author: donoban <donoban@riseup.net> Date: Sat Jul 25 18:56:00 2020 +0200 Fix sorting errores commit daa872297b2082237860a66bb01e2c71fda3e55d Author: donoban <donoban@riseup.net> Date: Sat Jul 25 18:54:21 2020 +0200 Fixed sort test errors commit 73ad25ed9e77d25bfc6a4159b8ef9a6f24e3294a Author: donoban <donoban@riseup.net> Date: Sat Jul 25 00:25:37 2020 +0200 Var rename commit 825d8ad6f7d3a9a7bb11252ebe5a5402851d56a9 Author: donoban <donoban@riseup.net> Date: Fri Jul 24 23:37:04 2020 +0200 Restored Cleanup commit 09f183946d23fb4a92e428395834ef3ad4473ffb Author: donoban <donoban@riseup.net> Date: Fri Jul 24 23:35:20 2020 +0200 Removed workaround, now works properly without clear reason commit 2f5bde0484e3eb0a3128e8b98f61a5311e0f529e Author: donoban <donoban@riseup.net> Date: Fri Jul 24 23:29:20 2020 +0200 Multiple tests fixes commit e21f9ab7416e728d1ef0409fb9ca880e23d9240c Author: donoban <donoban@riseup.net> Date: Fri Jul 24 23:28:32 2020 +0200 Save dvm name instead VM object commit 46e2fe1cf68708fa41df59661d11691ddb331984 Author: donoban <donoban@riseup.net> Date: Fri Jul 24 01:11:15 2020 +0200 Deleted wrong mapToSource() commit b155e051beb4ffcf0c1d48c5c9e24576c7db2e94 Author: donoban <donoban@riseup.net> Date: Fri Jul 24 01:10:43 2020 +0200 Fix get 'Is DVM Template' widget commit 61d7a6dc05f39055cbfd473c2a5cd638194aa132 Author: donoban <donoban@riseup.net> Date: Wed Jul 22 12:17:10 2020 +0200 fix set_keyboar_layout test fail commit 1dba52eb14b1d9c190d3a8c7bedf026ba242ac7d Author: donoban <donoban@riseup.net> Date: Sun Jul 19 00:05:53 2020 +0200 More test fixes commit 665a1453eca121a3c60975fe4c9e08b05e4831fe Author: donoban <donoban@riseup.net> Date: Sun Jul 12 23:39:07 2020 +0200 Fixed power state checking commit 6733fb1cd80cbc0917a5d1e42680d5424364649d Author: donoban <donoban@riseup.net> Date: Sun Jul 12 17:44:01 2020 +0200 Return vm object instead name on select_vm functions commit 80f3b3f7498c8c98517ae77053861861aaecfba7 Author: donoban <donoban@riseup.net> Date: Sun Jul 12 17:43:27 2020 +0200 Removed wrong calls to text() commit 32bbb864bf96ad3e37b6aaddc25817a5ad38a0cc Author: donoban <donoban@riseup.net> Date: Sun Jul 12 17:42:45 2020 +0200 Removed implicity calls to sortItems() commit bc288b616b80a5fabe179954eb18953ee59c18bc Author: donoban <donoban@riseup.net> Date: Sun Jul 12 17:03:22 2020 +0200 setCurrentItem() -> setCurrentIndex() commit 10bac8d300aa5d428080a0dc6a689e88230d93d2 Author: donoban <donoban@riseup.net> Date: Sun Jul 12 16:43:41 2020 +0200 get_table_vminfo renamed to get_table_vm commit cee7b0af871183e4917fdb535bbcc83facd64446 Author: donoban <donoban@riseup.net> Date: Sat Jul 11 23:46:41 2020 +0200 First version fixing tests commit 42d566f032941679608669d1ccc28a4523715b8a Author: donoban <donoban@riseup.net> Date: Sat Jul 11 23:38:33 2020 +0200 Fixing tests commit ccd7c162ef2a3f882c7d683d5b9c97db11829ac6 Merge: 24e5d588a74e43
Author: donoban <donoban@riseup.net> Date: Mon Jun 8 22:16:34 2020 +0200 Merge branch 'master' of https://github.com/QubesOS/qubes-manager # Conflicts: # qubesmanager/qube_manager.py commit 24e5d58c98981b3635b3c6dfa9202cac3e3455d8 Author: donoban <donoban@riseup.net> Date: Sun Jun 7 19:03:09 2020 +0200 Added workaround for dom0 sorting commit db2781a6392ff32c2d26053999819e08cb0e0ca0 Author: donoban <donoban@riseup.net> Date: Sun Jun 7 18:57:28 2020 +0200 Fixed Sorting Case Insensivity commit 93330ea6a45598a212811251843d32682a20016a Author: donoban <donoban@riseup.net> Date: Sun Jun 7 18:51:39 2020 +0200 Added "default" to netvm and default dispvm commit a40156c4f4b08a201fb877fc92f547c5138a7e32 Author: donoban <donoban@riseup.net> Date: Sun Jun 7 18:18:03 2020 +0200 Fixed QSettings saving commit a1d96e78778c84fe077b62196c8ed561978de9bc Author: donoban <donoban@riseup.net> Date: Wed Jun 3 00:23:50 2020 +0200 Added 'defaultValue' on settings load commit a0a7ee812298e6361a2ee585049c96303d1bbda7 Author: donoban <donoban@riseup.net> Date: Wed Jun 3 00:10:31 2020 +0200 Init view menu out of load_manager_settings commit 6f9a60004282e85c32727baa4b49c0a4d080f74e Author: donoban <donoban@riseup.net> Date: Tue Jun 2 23:19:09 2020 +0200 "Size" renamed to "Disk Usage" commit 5fbda06b370de790e31a9a983891a69ab8d031de Author: donoban <donoban@riseup.net> Date: Tue Jun 2 01:34:56 2020 +0200 Replaced unneded elif's with if's commit 5516bca8616d2e1ab99d4c40b11ff7b69cdbea48 Author: donoban <donoban@riseup.net> Date: Tue Jun 2 01:30:46 2020 +0200 Use "Yes"/"" for bool properties commit 1e5429e7ef9240570a5f31eae3a49a8380f97ee4 Author: donoban <donoban@riseup.net> Date: Tue Jun 2 01:12:46 2020 +0200 Restored exactly old icon size commit 270c82547365fbecddab1a21afef637da3eb2aa6 Author: donoban <donoban@riseup.net> Date: Sun May 31 12:52:03 2020 +0200 AdminVM and DispVM icon workaround commit cfb8a87b6dbdfda6f1652a6a4c82299e60b8c158 Author: donoban <donoban@riseup.net> Date: Sun May 31 12:51:44 2020 +0200 Icon size adjusted to 128/4 commit 173dc9413c6ae81e851026538beb101e385e5974 Author: donoban <donoban@riseup.net> Date: Sat May 30 00:56:40 2020 +0200 Add italic and gray color for differentiate templates and standalone/dom0 commit 2062f9308833241994b3ba87964f4f871b115e2a Author: donoban <donoban@riseup.net> Date: Thu May 28 00:21:58 2020 +0200 Fixig Marek comments commit 348485e960d18c5d7fd1746448251374480d270b Author: donoban <donoban@riseup.net> Date: Thu May 28 00:03:44 2020 +0200 More readable commit dc823a3923ab6c110fa8c51d4d66e501bc3e9f97 Author: donoban <donoban@riseup.net> Date: Thu May 28 00:01:02 2020 +0200 Needed for pylint proplerly import PyQt5 modules on fedora 32 commit 4478b284ce6f4521d1bddd5f6dc3d564c6c02408 Author: donoban <donoban@riseup.net> Date: Tue May 19 01:11:05 2020 +0200 Removed unused unued vars commit 450f0e32525792d48f121edfb890f0f24e6f6c36 Author: donoban <donoban@riseup.net> Date: Fri May 8 00:26:59 2020 +0200 Fix wrong var names commit c1bd9577e21e79a708870bbd22ff557ec0f48547 Author: donoban <donoban@riseup.net> Date: Fri May 8 00:24:31 2020 +0200 Fixed params order to VmSettingsWindow() commit 6d50d033d5866aa9cd0913822189bf235c8c7bdd Author: donoban <donoban@riseup.net> Date: Fri May 8 00:20:06 2020 +0200 Modeless settings windows commit ef3ac6a962b09e34602a624b3e8fdbdaf4cf8a42 Author: donoban <donoban@riseup.net> Date: Thu May 7 23:51:30 2020 +0200 Fix some vm/vm_info confusion commit 09392f99dc1ecd2e96e756884dd75c22090aa127 Author: donoban <donoban@riseup.net> Date: Wed Apr 29 10:26:58 2020 +0200 removed trailing whitespace commit 9e35ddf882053b25e2ab1d6cce6393cb77b95e79 Author: donoban <donoban@riseup.net> Date: Wed Apr 29 00:50:27 2020 +0200 columns_indices redudancy fixed and menu_view auto generation commit 8d96ef46d7f1eb0f26cf8d92203a22890c6165c0 Author: donoban <donoban@riseup.net> Date: Sat Apr 25 00:29:53 2020 +0200 Use col_name instead col number, improves readiblity commit 1cae3cab93d31592819941eee16ed239805d9cc8 Author: donoban <donoban@riseup.net> Date: Fri Apr 24 00:52:12 2020 +0200 Add QubesNoSuchProperyError commit aed771d4eb3b6b16652ec1ae27abb0761ebe2fa9 Author: donoban <donoban@riseup.net> Date: Fri Apr 24 00:45:59 2020 +0200 Added missing virt_mode commit 580749b83376204880da7be93d6325c6cdc0c239 Merge: 70878dcb058db4
Author: donoban <donoban@riseup.net> Date: Fri Apr 24 00:16:48 2020 +0200 Merge branch 'master' of https://github.com/QubesOS/qubes-manager commit 70878dc647cf34f716cfe0f4753f41cd1487a45e Author: donoban <donoban@riseup.net> Date: Fri Apr 24 00:16:31 2020 +0200 Let's try travis commit 5f65477abdb304413c3d3800d6e109c51275e13a Author: donoban <donoban@riseup.net> Date: Fri Apr 24 00:11:37 2020 +0200 Fix ProgressDialog not being properly drawn commit b577cb91d908e065ba43e68c613ff0eca449bbd7 Author: donoban <donoban@riseup.net> Date: Sun Apr 12 23:44:27 2020 +0200 pylint fixes and wrong 'outdated' commit 2a55c5d65b0cb3f7bb9d4adb10f5e41f662a85fe Author: donoban <donoban@riseup.net> Date: Sun Apr 12 23:35:47 2020 +0200 Restored menubar and toolbar context menu commit ac7086011328f1ef8f94a838425f8fe872b4fd20 Author: donoban <donoban@riseup.net> Date: Sun Apr 12 23:28:02 2020 +0200 restored logs commit a0b2b7be3cb6bf2693644289a9ae0452ce330cb5 Author: donoban <donoban@riseup.net> Date: Sun Apr 12 23:16:03 2020 +0200 Removed unused attributes commit cb514949f55e50925e1eabb19c8303e914c20d17 Author: donoban <donoban@riseup.net> Date: Sun Apr 12 23:08:00 2020 +0200 Part of last commit... commit 7f0c42fb9a9622d33f5281f8134c7f669a1ae7a4 Author: donoban <donoban@riseup.net> Date: Sun Apr 12 23:07:20 2020 +0200 Save sort settings on closeEvent commit 8dcfc3c9a9467e512b6c58e8b0a53c727bce7e89 Author: donoban <donoban@riseup.net> Date: Sun Apr 12 13:02:37 2020 +0200 Pylint fixes commit 8e5f9ff1d4e33d1a8d97842a696ba45ec40c7103 Author: donoban <donoban@riseup.net> Date: Mon Apr 6 23:35:15 2020 +0200 State converted to dict making pylint happier commit 233ec124736d09f0a64f65ce2d7e19383942e73a Author: donoban <donoban@riseup.net> Date: Mon Apr 6 00:25:34 2020 +0200 Pylint fixes commit 37790f01e3755dccbb6da24b3170320fcf2b2fe9 Author: donoban <donoban@riseup.net> Date: Sun Apr 5 23:47:17 2020 +0200 pylint commit 7dbe393047a00e4d5914368f8dad3c23d5a69586 Author: donoban <donoban@riseup.net> Date: Sun Apr 5 23:41:12 2020 +0200 pylint fixes commit f79f096ce3307167256308ce44ef8d3cf5f9a824 Author: donoban <donoban@riseup.net> Date: Sun Apr 5 23:37:03 2020 +0200 fixed wrong info_by_id refrences commit dbf17bde761a6efc03ff29b87e65623a214a44d2 Author: donoban <donoban@riseup.net> Date: Sun Apr 5 17:46:31 2020 +0200 Added QubesCache QubesTableModel and main app should operate directly to the cache commit 42d124520f7910f2ba0e77531fa6f469dd1932e5 Author: donoban <donoban@riseup.net> Date: Sun Apr 5 13:50:00 2020 +0200 Fixing multiple pylint warnings commit c708b4293035d8d296680b8a7513a066eb475f2b Author: donoban <donoban@riseup.net> Date: Sun Apr 5 12:59:43 2020 +0200 Added action_open_console setEnabled commit de1499464d47f145d10250619f83f8dfec2861b5 Author: donoban <donoban@riseup.net> Date: Fri Apr 3 00:25:07 2020 +0200 Forgot context_menu.actions() commit d24903b2462e416c5148036ed1184b90b02bd8b0 Author: donoban <donoban@riseup.net> Date: Fri Apr 3 00:03:16 2020 +0200 Elegant alternative for _enable_all() commit a0603870a3bbb78128d4cb23e259d3d00449b94c Author: donoban <donoban@riseup.net> Date: Thu Apr 2 00:22:46 2020 +0200 Fixed outdate commit 36e4b310080738bd9d8f9c92a16ad012735eb01a Author: donoban <donoban@riseup.net> Date: Wed Apr 1 11:36:28 2020 +0200 Removed table_widgets.py dependency commit 72e679e2d17e663b64213c23530e14cd6f6f843c Author: donoban <donoban@riseup.net> Date: Wed Apr 1 00:55:10 2020 +0200 Fixed pylint warnings commit 8e118be165d0ec77d9415cb90ef32c8b73c57612 Author: donoban <donoban@riseup.net> Date: Wed Apr 1 00:26:14 2020 +0200 Added get_selected_vms() and UserRole + 1 commit fd12a95280c5296a92a04bf3dbdb8487c8190729 Author: donoban <donoban@riseup.net> Date: Tue Mar 31 01:10:51 2020 +0200 fix some pylint warnings commit 09dfe83d89a14ba4a3745ec86ee59ad89ac153ae Author: donoban <donoban@riseup.net> Date: Tue Mar 31 00:34:51 2020 +0200 Removed unneded margins commit f0c81bf5a93f51c95b6afb01744f14a387dd4610 Merge: 00876bcf1ad829
Author: donoban <donoban@riseup.net> Date: Tue Mar 31 00:33:53 2020 +0200 Merge branch 'master' of https://github.com/QubesOS/qubes-manager commit 00876bcbfc7b70cd51848938ceb9f8f969848698 Author: donoban <donoban@riseup.net> Date: Mon Mar 30 23:31:18 2020 +0200 Alternative pyqt imports After reading official pyqt doc this seems the standard way (Continue previous commit) commit 6cf09d319021ab7b6491347c579f2911fbcb4e05 Author: donoban <donoban@riseup.net> Date: Mon Mar 30 23:29:21 2020 +0200 Alternative pyqt imports After reading official pyqt doc this seems the standard way commit 410dbaefca27fe3be85fc306db6afc04292f8f6f Author: donoban <donoban@riseup.net> Date: Mon Mar 30 00:12:09 2020 +0200 Restored sorting and filtering using QSortFilterProxyModel() commit 0b7fd6e7301009ebab702933b1114254ee5b6a93 Author: donoban <donoban@riseup.net> Date: Tue Mar 24 12:46:18 2020 +0100 Added QSortFilterProyModel indexes need proxy.mapToSource(index) model.layoutChanged.emit(), replaced by proxy.invalidate() commit 97440e8a616b84e49e446dc11576a987dae33da2 Author: donoban <donoban@riseup.net> Date: Tue Mar 24 12:34:35 2020 +0100 Removed unneded calls to setContentsMargins commit 1ad2aaac2cdfa4c7fc4323a3cf82220340de462f Author: donoban <donoban@riseup.net> Date: Sun Mar 22 22:56:33 2020 +0100 fix removevm with multiselection commit 19be1da69f3f43b1a9a4d9c5c561d4a6c9004d0c Author: donoban <donoban@riseup.net> Date: Sun Mar 22 22:34:52 2020 +0100 Restored context menu commit f43394a446ecb23b36fda029f62f2a0633ee01b6 Author: donoban <donoban@riseup.net> Date: Sun Mar 22 00:08:43 2020 +0100 Deleted unedeed updates after change of settings commit c98ba627579871b302563f42678ac412e9ccdd48 Merge: 103c572cf3f102
Author: donoban <donoban@riseup.net> Date: Sat Mar 21 23:45:46 2020 +0100 Merge branch 'master' of https://github.com/QubesOS/qubes-manager commit 103c5721d3f9f9c1ef6e922aeba053a2eb69b332 Merge: 2756864da2826d
Author: donoban <donoban@riseup.net> Date: Sat Feb 29 16:40:22 2020 +0100 Merge branch 'master' of https://github.com/QubesOS/qubes-manager commit 2756864bd04b1b16cf819fb4e726fff40189c8f3 Merge: 2e2a14b8902727
Author: donoban <donoban@riseup.net> Date: Thu Jan 23 23:43:32 2020 +0100 Merge branch 'master' of https://github.com/QubesOS/qubes-manager commit 2e2a14bdcaf8f6e7ce2f8fcec944109f18aad27f Author: donoban <donoban@riseup.net> Date: Wed Jan 8 16:41:30 2020 +0100 Removed fill_table :) commit 9f3f61a5d0c6c11e9eca81bbedcfe7affa187148 Author: donoban <donoban@riseup.net> Date: Tue Dec 31 17:29:39 2019 +0100 When Template changes status, all AppVMs should update too commit b970a703ab5bb559b6627c637466558651403f74 Author: donoban <donoban@riseup.net> Date: Fri Dec 27 17:59:05 2019 +0100 Improved multi row system commit 2f3fc988707252c2079998343de3c508ac4d9a74 Merge: 1f21da6cca5d7d
Author: donoban <donoban@riseup.net> Date: Fri Dec 27 17:25:15 2019 +0100 Merge remote-tracking branch 'upstream/master' commit 1f21da6d48d1bdddfc75c3ab47d28e92ed221a6d Author: donoban <donoban@riseup.net> Date: Mon Sep 23 21:41:39 2019 +0200 Restored 'selection changed' with multiple row support It reacts to selection changes but it is missing real functionally yet. commit bdf16015cd2a4ba894ae1d5c2c495403bb78be0d Author: donoban <donoban@riseup.net> Date: Wed Sep 18 07:27:47 2019 +0200 Restored add/remove/change events handling commit 2f9b21f07241b43655fb579dd4130a9c72d3db42 Author: donoban <donoban@riseup.net> Date: Wed Sep 18 07:00:49 2019 +0200 Added StateIconDelegate and StateInfo Used for paint different icons on same cell with custom tooltips. commit ccfa5453b2fe1ca5948406126a0f32a2caf4bde0 Author: donoban <donoban@riseup.net> Date: Wed Sep 18 06:35:12 2019 +0200 Removed Default and Minium horizonal header section size It affects resizeColumnsToContents() commit 628073e9522af5bff83224491645addbdcfb7418 Author: donoban <donoban@riseup.net> Date: Sun Sep 15 10:45:36 2019 +0200 Uncompatible with TableView commit 52ddd56bf293ca704205824f9c3b0f25f2c8d4c4 Merge: 0a87cf91ced452
Author: donoban <donoban@riseup.net> Date: Sun Sep 15 10:43:13 2019 +0200 Merge branch 'master' of https://github.com/QubesOS/qubes-manager commit 0a87cf963388bc9a33d241146e642a8ce9518ddb Author: donoban <donoban@riseup.net> Date: Mon Sep 2 21:55:21 2019 +0200 Restored precises updates https://github.com/QubesOS/qubes-manager/pull/195#issuecomment-525795486 commit 030bf13fab31cd57c5891d6ff692faf57c500f0a Author: donoban <donoban@riseup.net> Date: Sun Aug 25 18:33:11 2019 +0200 New and dirty first Model/View version commit 981ee9c1c3ccd6af4fe8b2745b7b5ddb29ecc0c4 Author: donoban <donoban@riseup.net> Date: Sun Aug 25 18:32:28 2019 +0200 QtableWidget > QTableView commit 41beaed24b69e7e9dc9223fa100605b0fd5bb40e Author: donoban <donoban@riseup.net> Date: Sun Aug 25 18:31:59 2019 +0200 Removed table_widgets
This commit is contained in:
parent
e4be77b75b
commit
bb1995af2e
@ -14,6 +14,7 @@ ignore=tests,
|
||||
ui_restoredlg.py,
|
||||
ui_settingsdlg.py,
|
||||
resources_rc.py
|
||||
extension-pkg-whitelist=PyQt5
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
# abstract-class-little-used: see http://www.logilab.org/ticket/111138
|
||||
|
@ -33,7 +33,6 @@ SOURCES = \
|
||||
qubesmanager/resources_rc.py \
|
||||
qubesmanager/restore.py \
|
||||
qubesmanager/settings.py \
|
||||
qubesmanager/table_widgets.py \
|
||||
qubesmanager/template_manager.py \
|
||||
qubesmanager/ui_about.py \
|
||||
qubesmanager/ui_backupdlg.py \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,510 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- coding: utf8 -*-
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2014 Marek Marczykowski-Górecki
|
||||
# <marmarek@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
import datetime
|
||||
|
||||
from PyQt5 import QtWidgets, QtCore, QtGui # pylint: disable=import-error
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
power_order = QtCore.Qt.DescendingOrder
|
||||
update_order = QtCore.Qt.AscendingOrder
|
||||
|
||||
|
||||
row_height = 30
|
||||
|
||||
|
||||
class VmIconWidget(QtWidgets.QWidget):
|
||||
def __init__(self, icon_path, enabled=True, size_multiplier=0.7,
|
||||
tooltip=None, parent=None,
|
||||
icon_sz=(32, 32)): # pylint: disable=unused-argument
|
||||
super(VmIconWidget, self).__init__(parent)
|
||||
|
||||
self.enabled = enabled
|
||||
self.size_multiplier = size_multiplier
|
||||
self.label_icon = QtWidgets.QLabel()
|
||||
self.set_icon(icon_path)
|
||||
|
||||
if tooltip is not None:
|
||||
self.label_icon.setToolTip(tooltip)
|
||||
|
||||
layout = QtWidgets.QHBoxLayout()
|
||||
layout.addWidget(self.label_icon)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.setLayout(layout)
|
||||
|
||||
def setToolTip(self, tooltip): # pylint: disable=invalid-name
|
||||
if tooltip is not None:
|
||||
self.label_icon.setToolTip(tooltip)
|
||||
else:
|
||||
self.label_icon.setToolTip('')
|
||||
|
||||
def set_icon(self, icon_path):
|
||||
|
||||
if icon_path[0] in ':/':
|
||||
icon = QtGui.QIcon(icon_path)
|
||||
else:
|
||||
icon = QtGui.QIcon.fromTheme(icon_path)
|
||||
icon_sz = QtCore.QSize(row_height * self.size_multiplier,
|
||||
row_height * self.size_multiplier)
|
||||
icon_pixmap = icon.pixmap(
|
||||
icon_sz,
|
||||
QtGui.QIcon.Disabled if not self.enabled else QtGui.QIcon.Normal)
|
||||
self.label_icon.setPixmap(icon_pixmap)
|
||||
self.label_icon.setFixedSize(icon_sz)
|
||||
|
||||
|
||||
class VmTypeWidget(VmIconWidget):
|
||||
class VmTypeItem(QtWidgets.QTableWidgetItem):
|
||||
def __init__(self, value, vm):
|
||||
super(VmTypeWidget.VmTypeItem, self).__init__()
|
||||
self.value = value
|
||||
self.qid = vm.qid
|
||||
self.name = vm.name
|
||||
|
||||
def set_value(self, value):
|
||||
self.value = value
|
||||
|
||||
# pylint: disable=too-many-return-statements
|
||||
def __lt__(self, other):
|
||||
if self.qid == 0:
|
||||
return True
|
||||
if other.qid == 0:
|
||||
return False
|
||||
if self.value == other.value:
|
||||
return self.name < other.name
|
||||
return self.value < other.value
|
||||
|
||||
def __init__(self, vm, parent=None):
|
||||
(icon_path, tooltip) = self.get_vm_icon(vm)
|
||||
super(VmTypeWidget, self).__init__(
|
||||
icon_path, True, 0.8, tooltip, parent)
|
||||
self.vm = vm
|
||||
self.table_item = self.VmTypeItem(self.value, vm)
|
||||
self.value = None
|
||||
|
||||
# TODO: add "provides network" column
|
||||
|
||||
def get_vm_icon(self, vm):
|
||||
if vm.klass == 'AdminVM':
|
||||
self.value = 0
|
||||
icon_name = "dom0"
|
||||
elif vm.klass == 'TemplateVM':
|
||||
self.value = 3
|
||||
icon_name = "templatevm"
|
||||
elif vm.klass == 'StandaloneVM':
|
||||
self.value = 4
|
||||
icon_name = "standalonevm"
|
||||
else:
|
||||
self.value = 5 + vm.label.index
|
||||
icon_name = "appvm"
|
||||
|
||||
return ":/" + icon_name + ".png", vm.klass
|
||||
|
||||
|
||||
class VmLabelWidget(VmIconWidget):
|
||||
class VmLabelItem(QtWidgets.QTableWidgetItem):
|
||||
def __init__(self, value, vm):
|
||||
super(VmLabelWidget.VmLabelItem, self).__init__()
|
||||
self.value = value
|
||||
self.qid = vm.qid
|
||||
self.name = vm.name
|
||||
|
||||
def set_value(self, value):
|
||||
self.value = value
|
||||
|
||||
# pylint: disable=too-many-return-statements
|
||||
def __lt__(self, other):
|
||||
if self.qid == 0:
|
||||
return True
|
||||
if other.qid == 0:
|
||||
return False
|
||||
if self.value == other.value:
|
||||
return self.name < other.name
|
||||
return self.value < other.value
|
||||
|
||||
def __init__(self, vm, parent=None):
|
||||
self.icon_path = self.get_vm_icon_path(vm)
|
||||
super(VmLabelWidget, self).__init__(self.icon_path,
|
||||
True, 0.8, None, parent)
|
||||
self.vm = vm
|
||||
self.table_item = self.VmLabelItem(self.value, vm)
|
||||
self.value = None
|
||||
|
||||
def get_vm_icon_path(self, vm):
|
||||
self.value = vm.label.index
|
||||
return vm.label.icon
|
||||
|
||||
def update(self):
|
||||
icon_path = self.get_vm_icon_path(self.vm)
|
||||
if icon_path != self.icon_path:
|
||||
self.icon_path = icon_path
|
||||
self.set_icon(icon_path)
|
||||
|
||||
|
||||
class VmStatusIcon(QtWidgets.QLabel):
|
||||
def __init__(self, vm, parent=None):
|
||||
super(VmStatusIcon, self).__init__(parent)
|
||||
self.vm = vm
|
||||
self.status = None
|
||||
self.set_on_icon()
|
||||
self.previous_power_state = self.vm.get_power_state()
|
||||
|
||||
def update(self):
|
||||
if self.previous_power_state != self.vm.get_power_state():
|
||||
self.set_on_icon()
|
||||
self.previous_power_state = self.vm.get_power_state()
|
||||
|
||||
def set_on_icon(self):
|
||||
if self.vm.get_power_state() == "Running":
|
||||
icon = QtGui.QIcon(":/on.png")
|
||||
self.status = 3
|
||||
elif self.vm.get_power_state() in ["Paused", "Suspended"]:
|
||||
icon = QtGui.QIcon(":/paused.png")
|
||||
self.status = 2
|
||||
elif self.vm.get_power_state() in ["Transient", "Halting", "Dying"]:
|
||||
icon = QtGui.QIcon(":/transient.png")
|
||||
self.status = 1
|
||||
else:
|
||||
icon = QtGui.QIcon(":/off.png")
|
||||
self.status = 0
|
||||
|
||||
icon_sz = QtCore.QSize(row_height * 0.5, row_height * 0.5)
|
||||
icon_pixmap = icon.pixmap(icon_sz)
|
||||
self.setPixmap(icon_pixmap)
|
||||
self.setFixedSize(icon_sz)
|
||||
|
||||
|
||||
class VmInfoWidget(QtWidgets.QWidget):
|
||||
class VmInfoItem(QtWidgets.QTableWidgetItem):
|
||||
def __init__(self, on_icon, upd_info_item, vm):
|
||||
super(VmInfoWidget.VmInfoItem, self).__init__()
|
||||
self.on_icon = on_icon
|
||||
self.upd_info_item = upd_info_item
|
||||
self.vm = vm
|
||||
self.qid = vm.qid
|
||||
self.name = vm.name
|
||||
|
||||
def __lt__(self, other):
|
||||
# pylint: disable=too-many-return-statements
|
||||
if self.qid == 0:
|
||||
return True
|
||||
if other.qid == 0:
|
||||
return False
|
||||
|
||||
self_val = self.upd_info_item.value
|
||||
other_val = other.upd_info_item.value
|
||||
|
||||
if self.tableWidget().\
|
||||
horizontalHeader().sortIndicatorOrder() == update_order:
|
||||
# the result will be sorted by upd, sorting order: Ascending
|
||||
self_val += 1 if self.on_icon.status > 0 else 0
|
||||
other_val += 1 if other.on_icon.status > 0 else 0
|
||||
if self_val == other_val:
|
||||
return self.name < other.name
|
||||
return self_val > other_val
|
||||
if self.tableWidget().\
|
||||
horizontalHeader().sortIndicatorOrder() == power_order:
|
||||
# the result will be sorted by power state,
|
||||
# sorting order: Descending
|
||||
if self.on_icon.status == other.on_icon.status:
|
||||
return self.name < other.name
|
||||
return self_val > other_val
|
||||
# it would be strange if this happened
|
||||
return
|
||||
|
||||
def __init__(self, vm, parent=None):
|
||||
super(VmInfoWidget, self).__init__(parent)
|
||||
self.vm = vm
|
||||
layout = QtWidgets.QHBoxLayout()
|
||||
|
||||
self.on_icon = VmStatusIcon(vm)
|
||||
self.upd_info = VmUpdateInfoWidget(vm, show_text=False)
|
||||
self.error_icon = VmIconWidget(":/warning.png")
|
||||
self.blk_icon = VmIconWidget(":/mount.png")
|
||||
self.rec_icon = VmIconWidget(":/mic.png")
|
||||
|
||||
layout.addWidget(self.on_icon)
|
||||
layout.addWidget(self.upd_info)
|
||||
layout.addWidget(self.error_icon)
|
||||
layout.addItem(QtWidgets.QSpacerItem(0, 10,
|
||||
QtWidgets.QSizePolicy.Expanding,
|
||||
QtWidgets.QSizePolicy.Expanding))
|
||||
layout.addWidget(self.blk_icon)
|
||||
layout.addWidget(self.rec_icon)
|
||||
|
||||
layout.setContentsMargins(5, 0, 5, 0)
|
||||
self.setLayout(layout)
|
||||
|
||||
self.rec_icon.setVisible(False)
|
||||
self.blk_icon.setVisible(False)
|
||||
self.error_icon.setVisible(False)
|
||||
|
||||
self.table_item = self.VmInfoItem(self.on_icon,
|
||||
self.upd_info.table_item, vm)
|
||||
|
||||
def update_vm_state(self):
|
||||
self.on_icon.update()
|
||||
self.upd_info.update_outdated()
|
||||
|
||||
|
||||
class VMPropertyItem(QtWidgets.QTableWidgetItem):
|
||||
def __init__(self, vm, property_name, empty_function=(lambda x: False),
|
||||
check_default=False):
|
||||
"""
|
||||
Class used to represent Qube Manager table widget.
|
||||
:param vm: vm object
|
||||
:param property_name: name of the property the widget represents
|
||||
:param empty_function: a function that, when applied to values of
|
||||
vm.property_name, returns True when the property value should be
|
||||
represented as an empty string and False otherwise; by default this
|
||||
function always returns false (vm.property_name is represented by an
|
||||
empty string only when it actually is one)
|
||||
:param check_default: if True, the widget will prepend its text with
|
||||
"default" if the if the property is set to DEFAULT
|
||||
"""
|
||||
super(VMPropertyItem, self).__init__()
|
||||
self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
|
||||
self.setTextAlignment(QtCore.Qt.AlignVCenter)
|
||||
self.vm = vm
|
||||
self.qid = vm.qid
|
||||
self.property_name = property_name
|
||||
self.name = vm.name
|
||||
self.empty_function = empty_function
|
||||
self.check_default = check_default
|
||||
self.update()
|
||||
|
||||
def update(self):
|
||||
val = getattr(self.vm, self.property_name, None)
|
||||
if self.empty_function(val):
|
||||
text = ""
|
||||
elif val is None:
|
||||
text = QtCore.QCoreApplication.translate("QubeManager", "n/a")
|
||||
elif val is True:
|
||||
text = QtCore.QCoreApplication.translate("QubeManager", "Yes")
|
||||
else:
|
||||
text = str(val)
|
||||
|
||||
if self.check_default and hasattr(self.vm, self.property_name) and \
|
||||
self.vm.property_is_default(self.property_name):
|
||||
text = QtCore.QCoreApplication.translate(
|
||||
"QubeManager", 'default ({})').format(text)
|
||||
self.setText(text)
|
||||
|
||||
def __lt__(self, other):
|
||||
if self.qid == 0:
|
||||
return True
|
||||
if other.qid == 0:
|
||||
return False
|
||||
if self.text() == other.text():
|
||||
return self.name < other.name
|
||||
return super(VMPropertyItem, self).__lt__(other)
|
||||
|
||||
|
||||
class VmTemplateItem(VMPropertyItem):
|
||||
def __init__(self, vm):
|
||||
super(VmTemplateItem, self).__init__(vm, "template")
|
||||
|
||||
def update(self):
|
||||
if getattr(self.vm, 'template', None) is not None:
|
||||
self.setText(self.vm.template.name)
|
||||
else:
|
||||
font = QtGui.QFont()
|
||||
font.setStyle(QtGui.QFont.StyleItalic)
|
||||
self.setFont(font)
|
||||
self.setForeground(QtGui.QBrush(QtGui.QColor("gray")))
|
||||
|
||||
self.setText(self.vm.klass)
|
||||
|
||||
|
||||
class VmInternalItem(VMPropertyItem):
|
||||
def __init__(self, vm):
|
||||
super(VmInternalItem, self).__init__(vm, None)
|
||||
|
||||
def update(self):
|
||||
internal = self.vm.features.get('internal', False)
|
||||
self.setText(QtCore.QCoreApplication.translate(
|
||||
"QubeManager", "Yes") if internal else "")
|
||||
|
||||
|
||||
# features man qvm-features
|
||||
class VmUpdateInfoWidget(QtWidgets.QWidget):
|
||||
class VmUpdateInfoItem(QtWidgets.QTableWidgetItem):
|
||||
def __init__(self, value, vm):
|
||||
super(VmUpdateInfoWidget.VmUpdateInfoItem, self).__init__()
|
||||
self.value = 0
|
||||
self.vm = vm
|
||||
self.qid = vm.qid
|
||||
self.name = vm.name
|
||||
self.set_value(value)
|
||||
|
||||
def set_value(self, value):
|
||||
if value in ("outdated", "to-be-outdated"):
|
||||
self.value = 30
|
||||
elif value == "update":
|
||||
self.value = 20
|
||||
else:
|
||||
self.value = 0
|
||||
|
||||
def __lt__(self, other):
|
||||
if self.qid == 0:
|
||||
return True
|
||||
if other.qid == 0:
|
||||
return False
|
||||
if self.value == other.value:
|
||||
return self.name < other.name
|
||||
return self.value < other.value
|
||||
|
||||
def __init__(self, vm, show_text=True, parent=None):
|
||||
super(VmUpdateInfoWidget, self).__init__(parent)
|
||||
layout = QtWidgets.QHBoxLayout()
|
||||
self.show_text = show_text
|
||||
if self.show_text:
|
||||
self.label = QtWidgets.QLabel("")
|
||||
layout.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)
|
||||
else:
|
||||
self.icon = QtWidgets.QLabel("")
|
||||
layout.addWidget(self.icon, alignment=QtCore.Qt.AlignCenter)
|
||||
self.setLayout(layout)
|
||||
|
||||
self.vm = vm
|
||||
|
||||
self.previous_outdated_state = None
|
||||
self.previous_update_recommended = None
|
||||
self.value = None
|
||||
self.table_item = VmUpdateInfoWidget.VmUpdateInfoItem(self.value, vm)
|
||||
self.update_outdated()
|
||||
|
||||
def update_outdated(self):
|
||||
outdated_state = False
|
||||
is_disposable = getattr(self.vm, 'auto_cleanup', False)
|
||||
|
||||
if not is_disposable and self.vm.is_running():
|
||||
if hasattr(self.vm, 'template') and self.vm.template.is_running():
|
||||
outdated_state = "to-be-outdated"
|
||||
|
||||
if not outdated_state:
|
||||
for vol in self.vm.volumes.values():
|
||||
if vol.is_outdated():
|
||||
outdated_state = "outdated"
|
||||
break
|
||||
|
||||
if not is_disposable and \
|
||||
self.vm.klass in {'TemplateVM', 'StandaloneVM'} and \
|
||||
self.vm.features.get('updates-available', False):
|
||||
outdated_state = 'update'
|
||||
|
||||
self.update_status_widget(outdated_state)
|
||||
|
||||
def update_status_widget(self, state):
|
||||
if state == self.previous_outdated_state:
|
||||
return
|
||||
|
||||
self.previous_outdated_state = state
|
||||
self.value = state
|
||||
self.table_item.set_value(state)
|
||||
if state == "update":
|
||||
label_text = "<font color=\"#CCCC00\">{}</font>".format(
|
||||
QtCore.QCoreApplication.translate("QubeManager",
|
||||
"Check updates"))
|
||||
icon_path = ":/update-recommended.png"
|
||||
tooltip_text = QtCore.QCoreApplication.translate("QubeManager",
|
||||
"Updates pending!")
|
||||
elif state == "outdated":
|
||||
label_text = "<font color=\"red\">{}</font>".format(
|
||||
QtCore.QCoreApplication.translate("QubeManager",
|
||||
"Qube outdated"))
|
||||
icon_path = ":/outdated.png"
|
||||
tooltip_text = QtCore.QCoreApplication.translate(
|
||||
"QubeManager",
|
||||
"The qube must be restarted for its filesystem to reflect the "
|
||||
"template's recent committed changes.")
|
||||
elif state == "to-be-outdated":
|
||||
label_text = "<font color=\"#800000\">{}</font>".format(
|
||||
QtCore.QCoreApplication.translate("QubeManager",
|
||||
"Template running"))
|
||||
icon_path = ":/to-be-outdated.png"
|
||||
tooltip_text = QtCore.QCoreApplication.translate(
|
||||
"QubeManager",
|
||||
"The Template must be stopped before changes from its "
|
||||
"current session can be picked up by this qube.")
|
||||
else:
|
||||
label_text = None
|
||||
tooltip_text = None
|
||||
icon_path = None
|
||||
|
||||
if hasattr(self, 'icon'):
|
||||
self.icon.setVisible(False)
|
||||
self.layout().removeWidget(self.icon)
|
||||
del self.icon
|
||||
|
||||
if self.show_text:
|
||||
self.label.setText(label_text)
|
||||
else:
|
||||
if icon_path is not None:
|
||||
self.icon = VmIconWidget(icon_path, True, 0.7)
|
||||
self.icon.setToolTip(tooltip_text)
|
||||
self.layout().addWidget(self.icon,
|
||||
alignment=QtCore.Qt.AlignCenter)
|
||||
self.icon.setVisible(True)
|
||||
|
||||
|
||||
class VmSizeOnDiskItem(QtWidgets.QTableWidgetItem):
|
||||
def __init__(self, vm):
|
||||
super(VmSizeOnDiskItem, self).__init__()
|
||||
self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
|
||||
|
||||
self.vm = vm
|
||||
self.qid = vm.qid
|
||||
self.name = vm.name
|
||||
self.value = 0
|
||||
self.update()
|
||||
self.setTextAlignment(QtCore.Qt.AlignVCenter)
|
||||
|
||||
def update(self):
|
||||
if self.vm.qid == 0:
|
||||
self.setText(QtCore.QCoreApplication.translate("QubeManager",
|
||||
"n/a"))
|
||||
else:
|
||||
self.value = 10
|
||||
self.value = round(self.vm.get_disk_utilization()/(1024*1024), 2)
|
||||
self.setText(str(self.value) + " MiB")
|
||||
|
||||
def __lt__(self, other):
|
||||
if self.qid == 0:
|
||||
return True
|
||||
if other.qid == 0:
|
||||
return False
|
||||
if self.value == other.value:
|
||||
return self.name < other.name
|
||||
return self.value < other.value
|
||||
|
||||
|
||||
class VmLastBackupItem(VMPropertyItem):
|
||||
def __init__(self, vm, property_name):
|
||||
super(VmLastBackupItem, self).__init__(vm, property_name)
|
||||
|
||||
def update(self):
|
||||
backup_timestamp = getattr(self.vm, 'backup_timestamp', None)
|
||||
|
||||
if backup_timestamp:
|
||||
self.setText(
|
||||
str(datetime.datetime.fromtimestamp(backup_timestamp)))
|
||||
else:
|
||||
self.setText("")
|
@ -30,11 +30,16 @@ import datetime
|
||||
import time
|
||||
|
||||
from PyQt5 import QtTest, QtCore, QtWidgets
|
||||
from PyQt5.QtCore import (Qt, QSize)
|
||||
from PyQt5.QtGui import (QIcon)
|
||||
|
||||
from qubesadmin import Qubes, events, exc
|
||||
import qubesmanager.qube_manager as qube_manager
|
||||
from qubesmanager.tests import init_qtapp
|
||||
|
||||
|
||||
icon_size = QSize(24, 24)
|
||||
|
||||
class QubeManagerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
super(QubeManagerTest, self).setUp()
|
||||
@ -58,14 +63,14 @@ class QubeManagerTest(unittest.TestCase):
|
||||
def test_001_correct_vms_listed(self):
|
||||
vms_in_table = []
|
||||
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
self.assertIsNotNone(vm)
|
||||
vms_in_table.append(vm.name)
|
||||
|
||||
# check that name is listed correctly
|
||||
name_item = self._get_table_item(row, "Name")
|
||||
self.assertEqual(name_item.text(), vm.name,
|
||||
self.assertEqual(name_item, vm.name,
|
||||
"Incorrect VM name for {}".format(vm.name))
|
||||
|
||||
actual_vms = [vm.name for vm in self.qapp.domains]
|
||||
@ -76,39 +81,42 @@ class QubeManagerTest(unittest.TestCase):
|
||||
"Incorrect VMs loaded")
|
||||
|
||||
def test_002_correct_template_listed(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
# check that template is listed correctly
|
||||
template_item = self._get_table_item(row, "Template")
|
||||
if getattr(vm, "template", None):
|
||||
self.assertEqual(vm.template,
|
||||
template_item.text(),
|
||||
template_item,
|
||||
"Incorrect template for {}".format(vm.name))
|
||||
else:
|
||||
self.assertEqual(vm.klass, template_item.text(),
|
||||
self.assertEqual(vm.klass, template_item,
|
||||
"Incorrect class for {}".format(vm.name))
|
||||
|
||||
def test_003_correct_netvm_listed(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
|
||||
# check that netvm is listed correctly
|
||||
netvm_item = self._get_table_item(row, "NetVM")
|
||||
netvm_value = getattr(vm, "netvm", None)
|
||||
netvm_value = "n/a" if not netvm_value else netvm_value
|
||||
|
||||
if not netvm_value:
|
||||
netvm_value = "n/a"
|
||||
|
||||
if netvm_value and hasattr(vm, "netvm") \
|
||||
and vm.property_is_default("netvm"):
|
||||
netvm_value = "default ({})".format(netvm_value)
|
||||
|
||||
self.assertEqual(netvm_value,
|
||||
netvm_item.text(),
|
||||
netvm_item,
|
||||
"Incorrect netvm for {}".format(vm.name))
|
||||
|
||||
def test_004_correct_disk_usage_listed(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
|
||||
size_item = self._get_table_item(row, "Size")
|
||||
size_item = self._get_table_item(row, "Disk Usage")
|
||||
if vm.klass == 'AdminVM':
|
||||
size_value = "n/a"
|
||||
else:
|
||||
@ -116,22 +124,22 @@ class QubeManagerTest(unittest.TestCase):
|
||||
size_value = str(size_value) + " MiB"
|
||||
|
||||
self.assertEqual(size_value,
|
||||
size_item.text(),
|
||||
size_item,
|
||||
"Incorrect size for {}".format(vm.name))
|
||||
|
||||
def test_005_correct_internal_listed(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
|
||||
internal_item = self._get_table_item(row, "Internal")
|
||||
internal_value = "Yes" if vm.features.get('internal', False) else ""
|
||||
|
||||
self.assertEqual(internal_item.text(), internal_value,
|
||||
self.assertEqual(internal_item, internal_value,
|
||||
"Incorrect internal value for {}".format(vm.name))
|
||||
|
||||
def test_006_correct_ip_listed(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
|
||||
ip_item = self._get_table_item(row, "IP")
|
||||
if hasattr(vm, 'ip'):
|
||||
@ -140,24 +148,24 @@ class QubeManagerTest(unittest.TestCase):
|
||||
else:
|
||||
ip_value = "n/a"
|
||||
|
||||
self.assertEqual(ip_value, ip_item.text(),
|
||||
self.assertEqual(ip_value, ip_item,
|
||||
"Incorrect ip value for {}".format(vm.name))
|
||||
|
||||
def test_007_incl_in_backups_listed(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
|
||||
incl_backups_item = self._get_table_item(row, "Include in backups")
|
||||
incl_backups_value = getattr(vm, 'include_in_backups', False)
|
||||
incl_backups_value = "Yes" if incl_backups_value else ""
|
||||
|
||||
self.assertEqual(
|
||||
incl_backups_value, incl_backups_item.text(),
|
||||
incl_backups_value, incl_backups_item,
|
||||
"Incorrect include in backups value for {}".format(vm.name))
|
||||
|
||||
def test_008_last_backup_listed(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
|
||||
last_backup_item = self._get_table_item(row, "Last backup")
|
||||
last_backup_value = getattr(vm, 'backup_timestamp', None)
|
||||
@ -165,16 +173,14 @@ class QubeManagerTest(unittest.TestCase):
|
||||
if last_backup_value:
|
||||
last_backup_value = str(
|
||||
datetime.datetime.fromtimestamp(last_backup_value))
|
||||
else:
|
||||
last_backup_value = ""
|
||||
|
||||
self.assertEqual(
|
||||
last_backup_value, last_backup_item.text(),
|
||||
last_backup_value, last_backup_item,
|
||||
"Incorrect last backup value for {}".format(vm.name))
|
||||
|
||||
def test_009_def_dispvm_listed(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
|
||||
def_dispvm_item = self._get_table_item(row, "Default DispVM")
|
||||
if vm.property_is_default("default_dispvm"):
|
||||
@ -184,45 +190,40 @@ class QubeManagerTest(unittest.TestCase):
|
||||
def_dispvm_value = getattr(vm, "default_dispvm", None)
|
||||
|
||||
self.assertEqual(
|
||||
str(def_dispvm_value), def_dispvm_item.text(),
|
||||
def_dispvm_value, def_dispvm_item,
|
||||
"Incorrect default dispvm value for {}".format(vm.name))
|
||||
|
||||
def test_010_is_dvm_template_listed(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
|
||||
is_dvm_template_item = self._get_table_item(row, "Is DVM Template")
|
||||
is_dvm_template_value = "Yes" if \
|
||||
getattr(vm, "template_for_dispvms", False) else ""
|
||||
|
||||
self.assertEqual(
|
||||
is_dvm_template_value, is_dvm_template_item.text(),
|
||||
is_dvm_template_value, is_dvm_template_item,
|
||||
"Incorrect is DVM template value for {}".format(vm.name))
|
||||
|
||||
def test_011_is_label_correct(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
icon = QIcon.fromTheme(vm.label.icon)
|
||||
icon = icon.pixmap(icon_size)
|
||||
|
||||
label_item = self._get_table_item(row, "Label")
|
||||
|
||||
self.assertEqual(label_item.icon_path, vm.label.icon)
|
||||
label_pixmap = self._get_table_item(row, "Label", Qt.DecorationRole)
|
||||
|
||||
self.assertEqual(label_pixmap.toImage(), icon.toImage())
|
||||
|
||||
def test_012_is_state_correct(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
vm = self._get_table_item(row, "Name").vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_vm(row)
|
||||
|
||||
state_item = self._get_table_item(row, "State")
|
||||
|
||||
# this should not be done like that in table_widgets
|
||||
displayed_power_state = state_item.on_icon.status
|
||||
|
||||
if vm.is_running():
|
||||
correct_power_state = 3
|
||||
else:
|
||||
correct_power_state = 0
|
||||
displayed_power_state = self._get_table_item(row, "State")['power']
|
||||
|
||||
self.assertEqual(
|
||||
displayed_power_state, correct_power_state,
|
||||
displayed_power_state, vm.get_power_state(),
|
||||
"Wrong power state displayed for {}".format(vm.name))
|
||||
|
||||
def test_013_incorrect_settings_file(self):
|
||||
@ -245,25 +246,23 @@ class QubeManagerTest(unittest.TestCase):
|
||||
self.assertEqual(mock_warning.call_count, 1)
|
||||
|
||||
def test_100_sorting(self):
|
||||
|
||||
self.dialog.table.sortByColumn(self.dialog.columns_indices["Template"],
|
||||
QtCore.Qt.AscendingOrder)
|
||||
col = self.dialog.qubes_model.columns_indices.index("Template")
|
||||
self.dialog.table.sortByColumn(col, QtCore.Qt.AscendingOrder)
|
||||
self.__check_sorting("Template")
|
||||
|
||||
self.dialog.table.sortByColumn(self.dialog.columns_indices["Name"],
|
||||
QtCore.Qt.AscendingOrder)
|
||||
col = self.dialog.qubes_model.columns_indices.index("Name")
|
||||
self.dialog.table.sortByColumn(col, QtCore.Qt.AscendingOrder)
|
||||
self.__check_sorting("Name")
|
||||
|
||||
@unittest.mock.patch('qubesmanager.qube_manager.QtCore.QSettings.setValue')
|
||||
@unittest.mock.patch('qubesmanager.qube_manager.QtCore.QSettings.sync')
|
||||
def test_101_hide_column(self, mock_sync, mock_settings):
|
||||
self.dialog.action_is_dvm_template.trigger()
|
||||
mock_settings.assert_called_with('columns/Is DVM Template', False)
|
||||
self.assertEqual(mock_sync.call_count, 1, "Hidden column not synced")
|
||||
|
||||
self.dialog.action_is_dvm_template.trigger()
|
||||
@unittest.mock.patch('qubesmanager.qube_manager.QSettings.setValue')
|
||||
def test_101_hide_column(self, mock_settings):
|
||||
model = self.dialog.qubes_model
|
||||
action_no = model.columns_indices.index('Is DVM Template')
|
||||
self.dialog.menu_view.actions()[action_no].trigger()
|
||||
mock_settings.assert_called_with('columns/Is DVM Template', True)
|
||||
self.assertEqual(mock_sync.call_count, 2, "Hidden column not synced")
|
||||
|
||||
self.dialog.menu_view.actions()[action_no].trigger()
|
||||
mock_settings.assert_called_with('columns/Is DVM Template', False)
|
||||
|
||||
@unittest.mock.patch('qubesmanager.settings.VMSettingsWindow')
|
||||
def test_200_vm_open_settings(self, mock_window):
|
||||
@ -282,9 +281,9 @@ class QubeManagerTest(unittest.TestCase):
|
||||
self.assertFalse(self.dialog.action_settings.isEnabled(),
|
||||
"Settings not disabled for admin VM")
|
||||
self.assertFalse(self.dialog.action_editfwrules.isEnabled(),
|
||||
"Settings not disabled for admin VM")
|
||||
"Editfw not disabled for admin VM")
|
||||
self.assertFalse(self.dialog.action_appmenus.isEnabled(),
|
||||
"Settings not disabled for admin VM")
|
||||
"Appmenus not disabled for admin VM")
|
||||
|
||||
@unittest.mock.patch('qubesmanager.settings.VMSettingsWindow')
|
||||
def test_202_vm_open_firewall(self, mock_window):
|
||||
@ -461,16 +460,17 @@ class QubeManagerTest(unittest.TestCase):
|
||||
|
||||
self.assertFalse(self.dialog.action_removevm.isEnabled())
|
||||
|
||||
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox")
|
||||
@unittest.mock.patch("qubesmanager.qube_manager.QMessageBox")
|
||||
@unittest.mock.patch('qubesadmin.utils.vm_dependencies')
|
||||
def test_218_remove_vm_dependencies(self, mock_dependencies, mock_msgbox):
|
||||
action = self.dialog.action_removevm
|
||||
|
||||
mock_vm = unittest.mock.Mock(spec=['name'],
|
||||
**{'name.return_value': 'test-vm'})
|
||||
mock_dependencies.return_value = [(mock_vm, "test_prop")]
|
||||
|
||||
action = self.dialog.action_removevm
|
||||
self._select_non_admin_vm()
|
||||
action.trigger()
|
||||
|
||||
mock_msgbox().show.assert_called_with()
|
||||
|
||||
@unittest.mock.patch('PyQt5.QtWidgets.QMessageBox.warning')
|
||||
@ -486,7 +486,7 @@ class QubeManagerTest(unittest.TestCase):
|
||||
|
||||
with unittest.mock.patch('qubesmanager.common_threads.RemoveVMThread')\
|
||||
as mock_thread:
|
||||
mock_input.return_value = (selected_vm.name, False)
|
||||
mock_input.return_value = (selected_vm, False)
|
||||
action.trigger()
|
||||
self.assertEqual(mock_thread.call_count, 0,
|
||||
"VM removed despite user clicking 'cancel")
|
||||
@ -766,7 +766,7 @@ class QubeManagerTest(unittest.TestCase):
|
||||
self.assertEqual(len(self.dialog.threads_list), 3)
|
||||
|
||||
def test_400_event_domain_added(self):
|
||||
number_of_vms = self.dialog.table.rowCount()
|
||||
number_of_vms = self.dialog.table.model().rowCount()
|
||||
|
||||
self.addCleanup(subprocess.call, ["qvm-remove", "-f", "test-vm"])
|
||||
|
||||
@ -774,7 +774,7 @@ class QubeManagerTest(unittest.TestCase):
|
||||
["qvm-create", "--label", "red", "test-vm"])
|
||||
|
||||
# a single row was added to the table
|
||||
self.assertEqual(self.dialog.table.rowCount(), number_of_vms + 1)
|
||||
self.assertEqual(self.dialog.table.model().rowCount(), number_of_vms+1)
|
||||
|
||||
# table contains the correct vms
|
||||
vms_in_table = self._create_set_of_current_vms()
|
||||
@ -785,15 +785,14 @@ class QubeManagerTest(unittest.TestCase):
|
||||
"correctly after add")
|
||||
|
||||
# check if sorting works
|
||||
self.dialog.table.sortItems(self.dialog.columns_indices["Name"],
|
||||
QtCore.Qt.AscendingOrder)
|
||||
self.__check_sorting("Name")
|
||||
|
||||
# try opening settings for the added vm
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
name = self._get_table_item(row, "Name")
|
||||
if name.text() == "test-vm":
|
||||
self.dialog.table.setCurrentItem(name)
|
||||
if name == "test-vm":
|
||||
index = self.dialog.table.model().index(row, 0)
|
||||
self.dialog.table.setCurrentIndex(index)
|
||||
break
|
||||
with unittest.mock.patch('qubesmanager.settings.VMSettingsWindow')\
|
||||
as mock_settings:
|
||||
@ -816,8 +815,6 @@ class QubeManagerTest(unittest.TestCase):
|
||||
self.assertEqual(initial_vms, current_vms)
|
||||
|
||||
# check if sorting works
|
||||
self.dialog.table.sortItems(self.dialog.columns_indices["Name"],
|
||||
QtCore.Qt.AscendingOrder)
|
||||
self.__check_sorting("Name")
|
||||
|
||||
def test_403_event_dispvm_added(self):
|
||||
@ -874,27 +871,28 @@ class QubeManagerTest(unittest.TestCase):
|
||||
target_vm_name = "work"
|
||||
vm_row = self._find_vm_row(target_vm_name)
|
||||
|
||||
current_label_path = self._get_table_item(vm_row, "Label").icon_path
|
||||
current_label = self._get_table_item(vm_row, "Label", Qt.DecorationRole)
|
||||
|
||||
self.addCleanup(
|
||||
subprocess.call, ["qvm-prefs", target_vm_name, "label", "blue"])
|
||||
self._run_command_and_process_events(
|
||||
["qvm-prefs", target_vm_name, "label", "red"])
|
||||
|
||||
new_label_path = self._get_table_item(vm_row, "Label").icon_path
|
||||
new_label = self._get_table_item(vm_row, "Label", Qt.DecorationRole)
|
||||
|
||||
self.assertNotEqual(current_label_path, new_label_path,
|
||||
"Label path did not change")
|
||||
self.assertEqual(
|
||||
new_label_path,
|
||||
self.qapp.domains[target_vm_name].label.icon,
|
||||
"Incorrect label")
|
||||
self.assertNotEqual(current_label.toImage(), new_label.toImage(),
|
||||
"Label icon did not change")
|
||||
|
||||
icon = QIcon.fromTheme(self.qapp.domains[target_vm_name].label.icon)
|
||||
icon = icon.pixmap(icon_size)
|
||||
|
||||
self.assertEqual(new_label.toImage(), icon.toImage(), "Incorrect label")
|
||||
|
||||
def test_406_prop_change_template(self):
|
||||
target_vm_name = "work"
|
||||
vm_row = self._find_vm_row(target_vm_name)
|
||||
|
||||
old_template = self._get_table_item(vm_row, "Template").text()
|
||||
old_template = self._get_table_item(vm_row, "Template")
|
||||
new_template = None
|
||||
for vm in self.qapp.domains:
|
||||
if vm.klass == 'TemplateVM' and vm.name != old_template:
|
||||
@ -908,10 +906,10 @@ class QubeManagerTest(unittest.TestCase):
|
||||
["qvm-prefs", target_vm_name, "template", new_template])
|
||||
|
||||
self.assertNotEqual(old_template,
|
||||
self._get_table_item(vm_row, "Template").text(),
|
||||
self._get_table_item(vm_row, "Template"),
|
||||
"Template did not change")
|
||||
self.assertEqual(
|
||||
self._get_table_item(vm_row, "Template").text(),
|
||||
self._get_table_item(vm_row, "Template"),
|
||||
self.qapp.domains[target_vm_name].template.name,
|
||||
"Incorrect template")
|
||||
|
||||
@ -919,7 +917,7 @@ class QubeManagerTest(unittest.TestCase):
|
||||
target_vm_name = "work"
|
||||
vm_row = self._find_vm_row(target_vm_name)
|
||||
|
||||
old_netvm = self._get_table_item(vm_row, "NetVM").text()
|
||||
old_netvm = self._get_table_item(vm_row, "NetVM")
|
||||
new_netvm = None
|
||||
for vm in self.qapp.domains:
|
||||
if getattr(vm, "provides_network", False) and vm.name != old_netvm:
|
||||
@ -932,10 +930,10 @@ class QubeManagerTest(unittest.TestCase):
|
||||
["qvm-prefs", target_vm_name, "netvm", new_netvm])
|
||||
|
||||
self.assertNotEqual(old_netvm,
|
||||
self._get_table_item(vm_row, "NetVM").text(),
|
||||
self._get_table_item(vm_row, "NetVM"),
|
||||
"NetVM did not change")
|
||||
self.assertEqual(
|
||||
self._get_table_item(vm_row, "NetVM").text(),
|
||||
self._get_table_item(vm_row, "NetVM"),
|
||||
self.qapp.domains[target_vm_name].netvm.name,
|
||||
"Incorrect NetVM")
|
||||
|
||||
@ -950,7 +948,7 @@ class QubeManagerTest(unittest.TestCase):
|
||||
["qvm-features", "work", "interal", "1"])
|
||||
|
||||
self.assertEqual(
|
||||
self._get_table_item(vm_row, "Internal").text(),
|
||||
self._get_table_item(vm_row, "Internal"),
|
||||
"Yes",
|
||||
"Incorrect value for internal VM")
|
||||
|
||||
@ -958,7 +956,7 @@ class QubeManagerTest(unittest.TestCase):
|
||||
["qvm-features", "--unset", "work", "interal"])
|
||||
|
||||
self.assertEqual(
|
||||
self._get_table_item(vm_row, "Internal").text(),
|
||||
self._get_table_item(vm_row, "Internal"),
|
||||
"",
|
||||
"Incorrect value for non-internal VM")
|
||||
|
||||
@ -966,7 +964,7 @@ class QubeManagerTest(unittest.TestCase):
|
||||
target_vm_name = "work"
|
||||
vm_row = self._find_vm_row(target_vm_name)
|
||||
|
||||
old_ip = self._get_table_item(vm_row, "IP").text()
|
||||
old_ip = self._get_table_item(vm_row, "IP")
|
||||
new_ip = old_ip.replace(".0.", ".5.")
|
||||
|
||||
self.addCleanup(
|
||||
@ -975,10 +973,10 @@ class QubeManagerTest(unittest.TestCase):
|
||||
["qvm-prefs", target_vm_name, "ip", new_ip])
|
||||
|
||||
self.assertNotEqual(old_ip,
|
||||
self._get_table_item(vm_row, "IP").text(),
|
||||
self._get_table_item(vm_row, "IP"),
|
||||
"IP did not change")
|
||||
self.assertEqual(
|
||||
self._get_table_item(vm_row, "IP").text(),
|
||||
self._get_table_item(vm_row, "IP"),
|
||||
self.qapp.domains[target_vm_name].ip,
|
||||
"Incorrect IP")
|
||||
|
||||
@ -996,7 +994,7 @@ class QubeManagerTest(unittest.TestCase):
|
||||
["qvm-prefs", target_vm_name, "include_in_backups", str(new_value)])
|
||||
|
||||
self.assertEqual(
|
||||
self._get_table_item(vm_row, "Internal").text(),
|
||||
self._get_table_item(vm_row, "Internal"),
|
||||
"Yes" if new_value else "",
|
||||
"Incorrect value for include_in_backups")
|
||||
|
||||
@ -1005,7 +1003,7 @@ class QubeManagerTest(unittest.TestCase):
|
||||
target_timestamp = "2015-01-01 17:00:00"
|
||||
vm_row = self._find_vm_row(target_vm_name)
|
||||
|
||||
old_value = self._get_table_item(vm_row, "Last backup").text()
|
||||
old_value = self._get_table_item(vm_row, "Last backup")
|
||||
new_value = datetime.datetime.strptime(
|
||||
target_timestamp, "%Y-%m-%d %H:%M:%S")
|
||||
|
||||
@ -1017,10 +1015,10 @@ class QubeManagerTest(unittest.TestCase):
|
||||
str(int(new_value.timestamp()))])
|
||||
|
||||
self.assertNotEqual(old_value,
|
||||
self._get_table_item(vm_row, "Last backup").text(),
|
||||
self._get_table_item(vm_row, "Last backup"),
|
||||
"Last backup date did not change")
|
||||
self.assertEqual(
|
||||
self._get_table_item(vm_row, "Last backup").text(),
|
||||
self._get_table_item(vm_row, "Last backup"),
|
||||
target_timestamp,
|
||||
"Incorrect Last backup date")
|
||||
|
||||
@ -1028,8 +1026,9 @@ class QubeManagerTest(unittest.TestCase):
|
||||
target_vm_name = "work"
|
||||
vm_row = self._find_vm_row(target_vm_name)
|
||||
|
||||
|
||||
old_default_dispvm =\
|
||||
self._get_table_item(vm_row, "Default DispVM").text()
|
||||
self._get_table_item(vm_row, "Default DispVM")
|
||||
new_default_dispvm = None
|
||||
for vm in self.qapp.domains:
|
||||
if getattr(vm, "template_for_dispvms", False) and vm.name !=\
|
||||
@ -1045,11 +1044,11 @@ class QubeManagerTest(unittest.TestCase):
|
||||
|
||||
self.assertNotEqual(
|
||||
old_default_dispvm,
|
||||
self._get_table_item(vm_row, "Default DispVM").text(),
|
||||
self._get_table_item(vm_row, "Default DispVM"),
|
||||
"Default DispVM did not change")
|
||||
|
||||
self.assertEqual(
|
||||
self._get_table_item(vm_row, "Default DispVM").text(),
|
||||
self._get_table_item(vm_row, "Default DispVM"),
|
||||
self.qapp.domains[target_vm_name].default_dispvm.name,
|
||||
"Incorrect Default DispVM")
|
||||
|
||||
@ -1064,7 +1063,7 @@ class QubeManagerTest(unittest.TestCase):
|
||||
["qvm-prefs", target_vm_name, "template_for_dispvms", "True"])
|
||||
|
||||
self.assertEqual(
|
||||
self._get_table_item(vm_row, "Is DVM Template").text(),
|
||||
self._get_table_item(vm_row, "Is DVM Template"),
|
||||
"Yes",
|
||||
"Incorrect value for DVM Template")
|
||||
|
||||
@ -1072,7 +1071,7 @@ class QubeManagerTest(unittest.TestCase):
|
||||
["qvm-prefs", "--default", target_vm_name, "template_for_dispvms"])
|
||||
|
||||
self.assertEqual(
|
||||
self._get_table_item(vm_row, "Is DVM Template").text(),
|
||||
self._get_table_item(vm_row, "Is DVM Template"),
|
||||
"",
|
||||
"Incorrect value for not DVM Template")
|
||||
|
||||
@ -1088,19 +1087,17 @@ class QubeManagerTest(unittest.TestCase):
|
||||
self._run_command_and_process_events(
|
||||
["qvm-start", target_vm_name], timeout=60)
|
||||
|
||||
status_item = self._get_table_item(vm_row, "State")
|
||||
displayed_state = self._get_table_item(vm_row, "State")
|
||||
|
||||
displayed_power_state = status_item.on_icon.status
|
||||
|
||||
self.assertEqual(displayed_power_state, 3,
|
||||
self.assertEqual(displayed_state['power'], 'Running',
|
||||
"Power state failed to update on start")
|
||||
|
||||
self._run_command_and_process_events(
|
||||
["qvm-shutdown", "--wait", target_vm_name], timeout=30)
|
||||
|
||||
displayed_power_state = status_item.on_icon.status
|
||||
displayed_state = self._get_table_item(vm_row, "State")
|
||||
|
||||
self.assertEqual(displayed_power_state, 0,
|
||||
self.assertEqual(displayed_state['power'], 'Halted',
|
||||
"Power state failed to update on shutdown")
|
||||
|
||||
def test_415_template_vm_started(self):
|
||||
@ -1116,9 +1113,8 @@ class QubeManagerTest(unittest.TestCase):
|
||||
if target_vm_name:
|
||||
break
|
||||
|
||||
for i in range(self.dialog.table.rowCount()):
|
||||
self._get_table_item(i, "State").update_vm_state =\
|
||||
unittest.mock.Mock()
|
||||
for i in range(self.dialog.table.model().rowCount()):
|
||||
self._get_table_vminfo(i).update = unittest.mock.Mock()
|
||||
|
||||
self.addCleanup(
|
||||
subprocess.call,
|
||||
@ -1126,12 +1122,12 @@ class QubeManagerTest(unittest.TestCase):
|
||||
self._run_command_and_process_events(
|
||||
["qvm-start", target_vm_name], timeout=60)
|
||||
|
||||
for i in range(self.dialog.table.rowCount()):
|
||||
call_count = self._get_table_item(
|
||||
i, "State").update_vm_state.call_count
|
||||
if self._get_table_item(i, "Template").text() == target_vm_name:
|
||||
for i in range(self.dialog.table.model().rowCount()):
|
||||
call_count = self._get_table_vminfo(
|
||||
i).update.call_count
|
||||
if self._get_table_item(i, "Template") == target_vm_name:
|
||||
self.assertGreater(call_count, 0)
|
||||
elif self._get_table_item(i, "Name").text() == target_vm_name:
|
||||
elif self._get_table_item(i, "Name") == target_vm_name:
|
||||
self.assertGreater(call_count, 0)
|
||||
else:
|
||||
self.assertEqual(call_count, 0)
|
||||
@ -1168,15 +1164,15 @@ class QubeManagerTest(unittest.TestCase):
|
||||
"Same logs found for dom0 and non-adminVM")
|
||||
|
||||
def _find_vm_row(self, vm_name):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
name = self._get_table_item(row, "Name")
|
||||
if name.text() == vm_name:
|
||||
if name == vm_name:
|
||||
return row
|
||||
return None
|
||||
|
||||
def _count_visible_table_rows(self):
|
||||
result = 0
|
||||
for i in range(self.dialog.table.rowCount()):
|
||||
for i in range(self.dialog.table.model().rowCount()):
|
||||
if not self.dialog.table.isRowHidden(i):
|
||||
result += 1
|
||||
return result
|
||||
@ -1210,54 +1206,51 @@ class QubeManagerTest(unittest.TestCase):
|
||||
|
||||
def _create_set_of_current_vms(self):
|
||||
result = set()
|
||||
for i in range(self.dialog.table.rowCount()):
|
||||
result.add(self._get_table_item(i, "Name").vm.name)
|
||||
for i in range(self.dialog.table.model().rowCount()):
|
||||
result.add(self._get_table_item(i, "Name"))
|
||||
return result
|
||||
|
||||
def _select_admin_vm(self):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
template = self.dialog.table.item(
|
||||
row, self.dialog.columns_indices["Template"])
|
||||
if template.text() == 'AdminVM':
|
||||
self.dialog.table.setCurrentItem(template)
|
||||
return template.vm
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
template = self._get_table_item(row, "Template")
|
||||
if template == 'AdminVM':
|
||||
index = self.dialog.table.model().index(row, 0)
|
||||
self.dialog.table.setCurrentIndex(index)
|
||||
return index.data(Qt.UserRole).vm
|
||||
return None
|
||||
|
||||
def _select_non_admin_vm(self, running=None):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
template = self.dialog.table.item(
|
||||
row, self.dialog.columns_indices["Template"])
|
||||
status = self.dialog.table.item(
|
||||
row, self.dialog.columns_indices["State"])
|
||||
if template.text() != 'AdminVM' and \
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
template = self._get_table_item(row, "Template")
|
||||
vm = self._get_table_vm(row)
|
||||
if template != 'AdminVM' and \
|
||||
(running is None
|
||||
or (running and status.on_icon.status == 3)
|
||||
or (not running and status.on_icon.status != 3)):
|
||||
self.dialog.table.setCurrentItem(template)
|
||||
return template.vm
|
||||
or (running and vm.is_running())
|
||||
or (not running and not vm.is_running())):
|
||||
index = self.dialog.table.model().index(row, 0)
|
||||
self.dialog.table.setCurrentIndex(index)
|
||||
return vm
|
||||
return None
|
||||
|
||||
def _select_templatevm(self, running=None):
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
template = self.dialog.table.item(
|
||||
row, self.dialog.columns_indices["Template"])
|
||||
status = self.dialog.table.item(
|
||||
row, self.dialog.columns_indices["State"])
|
||||
if template.text() == 'TemplateVM' and \
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
template = self._get_table_item(row, "Template")
|
||||
vm = self._get_table_vm(row)
|
||||
if template == 'TemplateVM' and \
|
||||
(running is None
|
||||
or (running and status.on_icon.status == 3)
|
||||
or (not running and status.on_icon.status != 3)):
|
||||
self.dialog.table.setCurrentItem(template)
|
||||
return template.vm
|
||||
or (running and vm.is_running())
|
||||
or (not running and not vm.is_running())):
|
||||
index = self.dialog.table.model().index(row, 0)
|
||||
self.dialog.table.setCurrentIndex(index)
|
||||
return vm
|
||||
return None
|
||||
|
||||
def __check_sorting(self, column_name):
|
||||
last_text = None
|
||||
last_vm = None
|
||||
for row in range(self.dialog.table.rowCount()):
|
||||
|
||||
vm = self._get_table_item(row, "Name").vm.name
|
||||
text = self._get_table_item(row, column_name).text().lower()
|
||||
for row in range(self.dialog.table.model().rowCount()):
|
||||
vm = self._get_table_item(row, "Name")
|
||||
text = self._get_table_item(row, column_name)
|
||||
|
||||
if row == 0:
|
||||
self.assertEqual(vm, "dom0", "dom0 is not sorted first")
|
||||
@ -1267,24 +1260,27 @@ class QubeManagerTest(unittest.TestCase):
|
||||
else:
|
||||
if last_text == text:
|
||||
self.assertGreater(
|
||||
vm, last_vm,
|
||||
vm.lower(), last_vm.lower(),
|
||||
"Incorrect sorting for {}".format(column_name))
|
||||
else:
|
||||
self.assertGreater(
|
||||
text, last_text,
|
||||
text.lower(), last_text.lower(),
|
||||
"Incorrect sorting for {}".format(column_name))
|
||||
last_text = text
|
||||
last_vm = vm
|
||||
|
||||
def _get_table_item(self, row, column_name):
|
||||
value = self.dialog.table.cellWidget(
|
||||
row, self.dialog.columns_indices[column_name])
|
||||
if not value:
|
||||
value = self.dialog.table.item(
|
||||
row, self.dialog.columns_indices[column_name])
|
||||
def _get_table_vminfo(self, row):
|
||||
model = self.dialog.table.model()
|
||||
return model.index(row, 0).data(Qt.UserRole)
|
||||
|
||||
return value
|
||||
def _get_table_vm(self, row):
|
||||
model = self.dialog.table.model()
|
||||
return model.index(row, 0).data(Qt.UserRole).vm
|
||||
|
||||
def _get_table_item(self, row, column_name, role = Qt.DisplayRole):
|
||||
model = self.dialog.table.model()
|
||||
column = self.dialog.qubes_model.columns_indices.index(column_name)
|
||||
return model.index(row, column).data(role)
|
||||
|
||||
class QubeManagerThreadTest(unittest.TestCase):
|
||||
def test_01_startvm_thread(self):
|
||||
|
@ -71,7 +71,6 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%{python3_sitelib}/qubesmanager/__pycache__
|
||||
%{python3_sitelib}/qubesmanager/__init__.py
|
||||
%{python3_sitelib}/qubesmanager/clipboard.py
|
||||
%{python3_sitelib}/qubesmanager/table_widgets.py
|
||||
%{python3_sitelib}/qubesmanager/appmenu_select.py
|
||||
%{python3_sitelib}/qubesmanager/backup.py
|
||||
%{python3_sitelib}/qubesmanager/backup_utils.py
|
||||
|
@ -11,6 +11,9 @@ class QubesVMNotStartedError(BaseException):
|
||||
class QubesPropertyAccessError(BaseException):
|
||||
pass
|
||||
|
||||
class QubesNoSuchPropertyError(BaseException):
|
||||
pass
|
||||
|
||||
class QubesDaemonNoResponseError(BaseException):
|
||||
pass
|
||||
|
||||
|
@ -52,21 +52,6 @@
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="searchContainer">
|
||||
<property name="spacing">
|
||||
@ -85,7 +70,7 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QTableWidget" name="table">
|
||||
<widget class="QTableView" name="table">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
@ -140,21 +125,9 @@
|
||||
<property name="cornerButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="rowCount">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>14</number>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderMinimumSectionSize">
|
||||
<number>150</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>150</number>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
@ -292,25 +265,6 @@ Template</string>
|
||||
<property name="title">
|
||||
<string>&View</string>
|
||||
</property>
|
||||
<addaction name="action_vm_type"/>
|
||||
<addaction name="action_label"/>
|
||||
<addaction name="action_state"/>
|
||||
<addaction name="action_template"/>
|
||||
<addaction name="action_netvm"/>
|
||||
<addaction name="action_size_on_disk"/>
|
||||
<addaction name="action_internal"/>
|
||||
<addaction name="action_ip"/>
|
||||
<addaction name="action_backups"/>
|
||||
<addaction name="action_last_backup"/>
|
||||
<addaction name="action_dispvm_template"/>
|
||||
<addaction name="action_is_dvm_template"/>
|
||||
<addaction name="action_virt_mode"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_toolbar"/>
|
||||
<addaction name="action_menubar"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_search"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_vm">
|
||||
<property name="title">
|
||||
|
Loading…
Reference in New Issue
Block a user