test_global_settings.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #!/usr/bin/python3
  2. #
  3. # The Qubes OS Project, https://www.qubes-os.org/
  4. #
  5. # Copyright (C) 2016 Marta Marczykowska-Górecka
  6. # <marmarta@invisiblethingslab.com>
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License along
  19. # with this program; if not, write to the Free Software Foundation, Inc.,
  20. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. #
  22. import logging.handlers
  23. import sys
  24. import unittest
  25. import unittest.mock
  26. from PyQt4 import QtGui, QtTest, QtCore
  27. from qubesadmin import Qubes
  28. from qubes.tests import SystemTestCase
  29. import qubesmanager.global_settings as global_settings
  30. import concurrent.futures
  31. # sudo systemctl stop qubesd; sudo -E python3 test_backup.py -v ; sudo systemctl start qubesd
  32. def wrap_in_loop(func):
  33. def wrapped(self):
  34. self.loop.run_until_complete(
  35. self.loop.run_in_executor(self.executor,
  36. func, self))
  37. return wrapped
  38. class GlobalSettingsTest(SystemTestCase):
  39. def setUp(self):
  40. super(GlobalSettingsTest, self).setUp()
  41. self.qtapp = QtGui.QApplication(sys.argv)
  42. self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
  43. self.setUpInExecutor()
  44. @wrap_in_loop
  45. def setUpInExecutor(self):
  46. self.qapp = Qubes()
  47. self.dialog = global_settings.GlobalSettingsWindow(
  48. self.qtapp, self.qapp)
  49. def tearDown(self):
  50. self.tearDownInExecutor()
  51. super(GlobalSettingsTest, self).tearDown()
  52. @wrap_in_loop
  53. def tearDownInExecutor(self):
  54. del self.dialog
  55. del self.qtapp
  56. @wrap_in_loop
  57. def test_00_settings_started(self):
  58. # non-empty drop-downs
  59. self.assertNotEqual(
  60. self.dialog.default_kernel_combo.currentText(), "")
  61. self.assertNotEqual(
  62. self.dialog.default_netvm_combo.currentText(), "")
  63. self.assertNotEqual(
  64. self.dialog.default_template_combo.currentText(),
  65. "")
  66. self.assertNotEqual(
  67. self.dialog.clock_vm_combo.currentText(), "")
  68. self.assertNotEqual(
  69. self.dialog.update_vm_combo.currentText(), "")
  70. @wrap_in_loop
  71. def test_01_load_correct_defs(self):
  72. # correctly selected default template
  73. selected_default_template = \
  74. self.dialog.default_template_combo.currentText()
  75. self.assertTrue(
  76. selected_default_template.startswith(
  77. self.app.default_template.name))
  78. # correctly selected default NetVM
  79. selected_default_netvm = \
  80. self.dialog.default_netvm_combo.currentText()
  81. self.assertTrue(selected_default_netvm.startswith(
  82. self.app.default_netvm.name))
  83. # correctly selected default kernel
  84. selected_default_kernel = \
  85. self.dialog.default_kernel_combo.currentText()
  86. self.assertTrue(selected_default_kernel.startswith(
  87. self.app.default_kernel))
  88. # correct ClockVM
  89. selected_clockvm = \
  90. self.dialog.clock_vm_combo.currentText()
  91. correct_clockvm = self.app.clockvm.name if self.app.clockvm \
  92. else "(none)"
  93. self.assertTrue(selected_clockvm.startswith(correct_clockvm))
  94. # correct updateVM
  95. selected_updatevm = \
  96. self.dialog.update_vm_combo.currentText()
  97. correct_updatevm = \
  98. self.app.updatevm.name if self.app.updatevm else "(none)"
  99. self.assertTrue(selected_updatevm.startswith(correct_updatevm))
  100. # update vm status
  101. self.assertEqual(self.app.check_updates_vm,
  102. self.dialog.updates_vm.isChecked())
  103. @wrap_in_loop
  104. def test_02_dom0_updates_load(self):
  105. # check dom0 updates
  106. try:
  107. dom0_updates = self.app.check_updates_dom0
  108. except AttributeError:
  109. self.skipTest("check_updates_dom0 property not implemented")
  110. return
  111. self.assertEqual(dom0_updates, self.dialog.updates_dom0.isChecked())
  112. def __set_noncurrent(self, widget):
  113. if widget.count() < 2:
  114. self.skipTest("not enough choices for " + widget.objectName())
  115. widget.setCurrentIndex(0)
  116. while widget.currentText().endswith("(current)") \
  117. or widget.currentText().startswith("(none)"):
  118. widget.setCurrentIndex(widget.currentIndex() + 1)
  119. return widget.currentText()
  120. def __set_none(self, widget):
  121. widget.setCurrentIndex(0)
  122. while not widget.currentText().startswith("(none)"):
  123. if widget.currentIndex() == widget.count():
  124. self.skipTest("none not available for " + widget.objectName())
  125. widget.setCurrentIndex(widget.currentIndex() + 1)
  126. def __click_ok(self):
  127. okwidget = self.dialog.buttonBox.button(
  128. self.dialog.buttonBox.Ok)
  129. QtTest.QTest.mouseClick(okwidget,
  130. QtCore.Qt.LeftButton)
  131. @wrap_in_loop
  132. def test_10_set_update_vm(self):
  133. new_updatevm_name = self.__set_noncurrent(self.dialog.update_vm_combo)
  134. self.__click_ok()
  135. self.assertEqual(self.app.updatevm.name, new_updatevm_name)
  136. @wrap_in_loop
  137. def test_11_set_update_vm_to_none(self):
  138. self.__set_none(self.dialog.update_vm_combo)
  139. self.__click_ok()
  140. self.assertIsNone(self.app.updatevm)
  141. @wrap_in_loop
  142. def test_12_set_update_vm_to_none2(self):
  143. self.app.updatevm = None
  144. self.dialog = global_settings.GlobalSettingsWindow(
  145. self.qtapp, self.qapp)
  146. self.assertEqual(self.dialog.update_vm_combo.currentText(),
  147. "(none) (current)")
  148. @wrap_in_loop
  149. def test_20_set_clock_vm(self):
  150. new_clockvm_name = self.__set_noncurrent(self.dialog.clock_vm_combo)
  151. self.__click_ok()
  152. self.assertEqual(self.app.clockvm.name, new_clockvm_name)
  153. @wrap_in_loop
  154. def test_21_set_clock_vm_to_none(self):
  155. self.__set_none(self.dialog.clock_vm_combo)
  156. self.__click_ok()
  157. self.assertIsNone(self.app.clockvm)
  158. @wrap_in_loop
  159. def test_22_set_clock_vm_to_none2(self):
  160. self.app.clockvm = None
  161. self.dialog = global_settings.GlobalSettingsWindow(
  162. self.qtapp, self.qapp)
  163. self.assertEqual(self.dialog.clock_vm_combo.currentText(),
  164. "(none) (current)")
  165. @wrap_in_loop
  166. def test_30_set_default_netvm(self):
  167. new_netvm_name = self.__set_noncurrent(self.dialog.default_netvm_combo)
  168. self.__click_ok()
  169. self.assertEqual(self.app.default_netvm.name, new_netvm_name)
  170. @wrap_in_loop
  171. def test_31_set_default_netvm_to_none(self):
  172. self.__set_none(self.dialog.default_netvm_combo)
  173. self.__click_ok()
  174. self.assertIsNone(self.app.default_netvm)
  175. @wrap_in_loop
  176. def test_32_set_default_netvm_to_none2(self):
  177. self.app.default_netvm = None
  178. self.dialog = global_settings.GlobalSettingsWindow(
  179. self.qtapp, self.qapp)
  180. self.assertEqual(self.dialog.default_netvm_combo.currentText(),
  181. "(none) (current)")
  182. @wrap_in_loop
  183. def test_40_set_default_template(self):
  184. new_def_template_name = self.__set_noncurrent(
  185. self.dialog.default_template_combo)
  186. self.__click_ok()
  187. self.assertEqual(self.app.default_template.name, new_def_template_name)
  188. @wrap_in_loop
  189. def test_50_set_default_kernel(self):
  190. new_def_kernel_name = self.__set_noncurrent(
  191. self.dialog.default_kernel_combo)
  192. self.__click_ok()
  193. self.assertEqual(self.app.default_kernel, new_def_kernel_name)
  194. @wrap_in_loop
  195. def test_51_set_default_kernel_to_none(self):
  196. self.__set_none(self.dialog.default_kernel_combo)
  197. self.__click_ok()
  198. self.assertEqual(self.app.default_kernel, '')
  199. @wrap_in_loop
  200. def test_52_set_default_kernel_to_none2(self):
  201. self.app.default_kernel = None
  202. self.dialog = global_settings.GlobalSettingsWindow(
  203. self.qtapp, self.qapp)
  204. self.assertEqual(self.dialog.default_kernel_combo.currentText(),
  205. "(none) (current)")
  206. @wrap_in_loop
  207. def test_60_set_dom0_updates_true(self):
  208. self.dialog.updates_dom0.setChecked(True)
  209. self.__click_ok()
  210. if not hasattr(self.app, 'check_updates_dom0'):
  211. self.skipTest("check_updates_dom0 property not implemented")
  212. self.assertTrue(self.app.check_updates_dom0)
  213. @wrap_in_loop
  214. def test_61_set_dom0_updates_false(self):
  215. self.dialog.updates_dom0.setChecked(False)
  216. self.__click_ok()
  217. if not hasattr(self.app, 'check_updates_dom0'):
  218. self.skipTest("check_updates_dom0 property not implemented")
  219. self.assertFalse(self.app.check_updates_dom0)
  220. @wrap_in_loop
  221. def test_70_set_vm_updates_true(self):
  222. self.dialog.updates_vm.setChecked(True)
  223. self.__click_ok()
  224. self.assertTrue(self.app.check_updates_vm)
  225. @wrap_in_loop
  226. def test_71_set_vm_updates_false(self):
  227. self.dialog.updates_vm.setChecked(False)
  228. self.__click_ok()
  229. self.assertFalse(self.app.check_updates_vm)
  230. @wrap_in_loop
  231. def test_72_set_all_vms_true(self):
  232. with unittest.mock.patch("PyQt4.QtGui.QMessageBox.question",
  233. return_value=QtGui.QMessageBox.Yes) as msgbox:
  234. QtTest.QTest.mouseClick(self.dialog.enable_updates_all,
  235. QtCore.Qt.LeftButton)
  236. msgbox.assert_called_once_with(
  237. self.dialog,
  238. "Change state of all qubes",
  239. "Are you sure you want to set all qubes to check for updates?",
  240. unittest.mock.ANY)
  241. for vm in self.app.domains:
  242. self.assertTrue(vm.features['check-updates'])
  243. @wrap_in_loop
  244. def test_73_set_all_vms_false(self):
  245. with unittest.mock.patch("PyQt4.QtGui.QMessageBox.question",
  246. return_value=QtGui.QMessageBox.Yes) as msgbox:
  247. QtTest.QTest.mouseClick(self.dialog.disable_updates_all,
  248. QtCore.Qt.LeftButton)
  249. msgbox.assert_called_once_with(
  250. self.dialog,
  251. "Change state of all qubes",
  252. "Are you sure you want to set all qubes to not check "
  253. "for updates?",
  254. unittest.mock.ANY)
  255. for vm in self.app.domains:
  256. self.assertFalse(vm.features['check-updates'])
  257. if __name__ == "__main__":
  258. ha_syslog = logging.handlers.SysLogHandler('/dev/log')
  259. ha_syslog.setFormatter(
  260. logging.Formatter('%(name)s[%(process)d]: %(message)s'))
  261. logging.root.addHandler(ha_syslog)
  262. unittest.main()