From 1aab64d5b0b35e56ed92ad03a17918b694bf13e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 24 May 2017 12:44:46 +0200 Subject: [PATCH] tests: add more test cases for qvm-start-gui --- qubesadmin/tests/tools/qvm_start_gui.py | 198 ++++++++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/qubesadmin/tests/tools/qvm_start_gui.py b/qubesadmin/tests/tools/qvm_start_gui.py index 9ae1ce3..b54c5c1 100644 --- a/qubesadmin/tests/tools/qvm_start_gui.py +++ b/qubesadmin/tests/tools/qvm_start_gui.py @@ -17,7 +17,9 @@ # # You should have received a copy of the GNU Lesser General Public License along # with this program; if not, see . +import functools import os +import signal import tempfile import unittest.mock @@ -25,6 +27,7 @@ import asyncio import qubesadmin.tests import qubesadmin.tools.qvm_start_gui +import qubesadmin.vm class TC_00_qvm_start_gui(qubesadmin.tests.QubesTestCase): @@ -373,3 +376,198 @@ HDMI1 connected 2560x1920+0+0 (normal left inverted right x axis y axis) 206mm x self.assertEqual(qubesadmin.tools.qvm_start_gui.get_monitor_layout(), ['2560 1920 0 0 {} {}\n'.format( int(2560/dpi*254/10), int(1920/dpi*254/10))]) + + def test_060_send_monitor_layout(self): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + self.addCleanup(loop.close) + + self.app.expected_calls[ + ('dom0', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm class=AppVM state=Running\n' + self.app.expected_calls[ + ('test-vm', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm class=AppVM state=Running\n' + self.app.expected_calls[ + ('test-vm', 'admin.vm.feature.CheckWithTemplate', + 'no-monitor-layout', None)] = \ + b'2\x00QubesFeatureNotFoundError\x00\x00Feature not set\x00' + + vm = self.app.domains['test-vm'] + mock_run_service = unittest.mock.Mock(spec={}) + patch_run_service = unittest.mock.patch.object( + qubesadmin.vm.QubesVM, 'run_service_for_stdio', + mock_run_service) + patch_run_service.start() + self.addCleanup(patch_run_service.stop) + monitor_layout = ['1920 1080 0 0\n'] + loop.run_until_complete(self.launcher.send_monitor_layout( + vm, layout=monitor_layout, startup=True)) + mock_run_service.assert_called_once_with( + 'qubes.SetMonitorLayout', b'1920 1080 0 0\n') + self.assertAllCalled() + + def test_061_send_monitor_layout_exclude(self): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + self.addCleanup(loop.close) + + self.app.expected_calls[ + ('dom0', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm class=AppVM state=Running\n' + self.app.expected_calls[ + ('test-vm', 'admin.vm.feature.CheckWithTemplate', + 'no-monitor-layout', None)] = \ + b'0\x00True' + + vm = self.app.domains['test-vm'] + mock_run_service = unittest.mock.Mock() + patch_run_service = unittest.mock.patch.object( + qubesadmin.vm.QubesVM, 'run_service_for_stdio', + mock_run_service) + patch_run_service.start() + self.addCleanup(patch_run_service.stop) + monitor_layout = ['1920 1080 0 0\n'] + loop.run_until_complete(self.launcher.send_monitor_layout( + vm, layout=monitor_layout, startup=True)) + self.assertFalse(mock_run_service.called) + self.assertAllCalled() + + def test_062_send_monitor_layout_not_running(self): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + self.addCleanup(loop.close) + + self.app.expected_calls[ + ('dom0', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm class=AppVM state=Halted\n' + self.app.expected_calls[ + ('test-vm', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm class=AppVM state=Halted\n' + self.app.expected_calls[ + ('test-vm', 'admin.vm.feature.CheckWithTemplate', + 'no-monitor-layout', None)] = \ + b'2\x00QubesFeatureNotFoundError\x00\x00Feature not set\x00' + + vm = self.app.domains['test-vm'] + mock_run_service = unittest.mock.Mock() + patch_run_service = unittest.mock.patch.object( + qubesadmin.vm.QubesVM, 'run_service_for_stdio', + mock_run_service) + patch_run_service.start() + self.addCleanup(patch_run_service.stop) + monitor_layout = ['1920 1080 0 0\n'] + loop.run_until_complete(self.launcher.send_monitor_layout( + vm, layout=monitor_layout, startup=True)) + self.assertFalse(mock_run_service.called) + self.assertAllCalled() + + def test_063_send_monitor_layout_signal_existing(self): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + self.addCleanup(loop.close) + + self.app.expected_calls[ + ('dom0', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm class=AppVM state=Running\n' + self.app.expected_calls[ + ('test-vm', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm class=AppVM state=Running\n' + self.app.expected_calls[ + ('test-vm', 'admin.vm.property.Get', 'xid', None)] = \ + b'0\x00default=False type=int 123' + self.app.expected_calls[ + ('test-vm', 'admin.vm.property.Get', 'stubdom_xid', None)] = \ + b'0\x00default=False type=int 124' + self.app.expected_calls[ + ('test-vm', 'admin.vm.feature.CheckWithTemplate', + 'no-monitor-layout', None)] = \ + b'2\x00QubesFeatureNotFoundError\x00\x00Feature not set\x00' + + vm = self.app.domains['test-vm'] + self.addCleanup(unittest.mock.patch.stopall) + + with tempfile.NamedTemporaryFile() as pidfile: + pidfile.write(b'1234\n') + pidfile.flush() + + patch_guid_pidfile = unittest.mock.patch.object( + self.launcher, 'guid_pidfile') + mock_guid_pidfile = patch_guid_pidfile.start() + mock_guid_pidfile.return_value = pidfile.name + + mock_kill = unittest.mock.patch('os.kill').start() + + monitor_layout = ['1920 1080 0 0\n'] + loop.run_until_complete(self.launcher.send_monitor_layout( + vm, layout=monitor_layout, startup=False)) + self.assertEqual(mock_guid_pidfile.mock_calls, + [unittest.mock.call(123), + unittest.mock.call(124)]) + self.assertEqual(mock_kill.mock_calls, + [unittest.mock.call(1234, signal.SIGHUP), + unittest.mock.call(1234, signal.SIGHUP)]) + self.assertAllCalled() + + def test_070_send_monitor_layout_all(self): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + self.addCleanup(loop.close) + + self.app.expected_calls[ + ('dom0', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm class=AppVM state=Running\n' \ + b'test-vm2 class=AppVM state=Running\n' \ + b'test-vm3 class=AppVM state=Runnig\n' \ + b'test-vm4 class=AppVM state=Halted\n' + self.app.expected_calls[ + ('test-vm', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm class=AppVM state=Running\n' + self.app.expected_calls[ + ('test-vm2', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm2 class=AppVM state=Running\n' + self.app.expected_calls[ + ('test-vm3', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm3 class=AppVM state=Running\n' + self.app.expected_calls[ + ('test-vm4', 'admin.vm.List', None, None)] = \ + b'0\x00test-vm4 class=AppVM state=Halted\n' + self.app.expected_calls[ + ('test-vm', 'admin.vm.feature.CheckWithTemplate', + 'gui', None)] = \ + b'2\x00QubesFeatureNotFoundError\x00\x00Feature not set\x00' + self.app.expected_calls[ + ('test-vm2', 'admin.vm.feature.CheckWithTemplate', + 'gui', None)] = \ + b'0\x00True' + self.app.expected_calls[ + ('test-vm3', 'admin.vm.feature.CheckWithTemplate', + 'gui', None)] = \ + b'0\x00' + + vm = self.app.domains['test-vm'] + vm2 = self.app.domains['test-vm2'] + + self.addCleanup(unittest.mock.patch.stopall) + + mock_send_monitor_layout = unittest.mock.Mock() + patch_send_monitor_layout = unittest.mock.patch.object( + self.launcher, 'send_monitor_layout', + functools.partial(self.mock_coroutine, mock_send_monitor_layout)) + patch_send_monitor_layout.start() + monitor_layout = ['1920 1080 0 0\n'] + mock_get_monior_layout = unittest.mock.patch( + 'qubesadmin.tools.qvm_start_gui.get_monitor_layout').start() + mock_get_monior_layout.return_value = monitor_layout + + self.launcher.send_monitor_layout_all() + loop.stop() + loop.run_forever() + + # test-vm3 not called b/c feature 'gui' set to false + # test-vm4 not called b/c not running + self.assertCountEqual(mock_send_monitor_layout.mock_calls, + [unittest.mock.call(vm, monitor_layout), + unittest.mock.call(vm2, monitor_layout)]) + mock_get_monior_layout.assert_called_once_with() + self.assertAllCalled()