xref: /qemu/tests/avocado/vnc.py (revision b6aed193)
1bbbd9b6eSWillian Rampazzo# Simple functional tests for VNC functionality
2bbbd9b6eSWillian Rampazzo#
3bbbd9b6eSWillian Rampazzo# Copyright (c) 2018 Red Hat, Inc.
4bbbd9b6eSWillian Rampazzo#
5bbbd9b6eSWillian Rampazzo# Author:
6bbbd9b6eSWillian Rampazzo#  Cleber Rosa <crosa@redhat.com>
7bbbd9b6eSWillian Rampazzo#
8bbbd9b6eSWillian Rampazzo# This work is licensed under the terms of the GNU GPL, version 2 or
9bbbd9b6eSWillian Rampazzo# later.  See the COPYING file in the top-level directory.
10bbbd9b6eSWillian Rampazzo
110d90da82SVladimir Sementsov-Ogievskiyimport socket
120d90da82SVladimir Sementsov-Ogievskiyfrom typing import List
130d90da82SVladimir Sementsov-Ogievskiy
142283b627SPhilippe Mathieu-Daudéfrom avocado_qemu import QemuSystemTest
15bbbd9b6eSWillian Rampazzo
16bbbd9b6eSWillian Rampazzo
170d90da82SVladimir Sementsov-OgievskiyVNC_ADDR = '127.0.0.1'
180d90da82SVladimir Sementsov-OgievskiyVNC_PORT_START = 32768
190d90da82SVladimir Sementsov-OgievskiyVNC_PORT_END = VNC_PORT_START + 1024
200d90da82SVladimir Sementsov-Ogievskiy
210d90da82SVladimir Sementsov-Ogievskiy
220d90da82SVladimir Sementsov-Ogievskiydef check_bind(port: int) -> bool:
230d90da82SVladimir Sementsov-Ogievskiy    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
240d90da82SVladimir Sementsov-Ogievskiy        try:
250d90da82SVladimir Sementsov-Ogievskiy            sock.bind((VNC_ADDR, port))
260d90da82SVladimir Sementsov-Ogievskiy        except OSError:
270d90da82SVladimir Sementsov-Ogievskiy            return False
280d90da82SVladimir Sementsov-Ogievskiy
290d90da82SVladimir Sementsov-Ogievskiy    return True
300d90da82SVladimir Sementsov-Ogievskiy
310d90da82SVladimir Sementsov-Ogievskiy
320d90da82SVladimir Sementsov-Ogievskiydef check_connect(port: int) -> bool:
330d90da82SVladimir Sementsov-Ogievskiy    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
340d90da82SVladimir Sementsov-Ogievskiy        try:
350d90da82SVladimir Sementsov-Ogievskiy            sock.connect((VNC_ADDR, port))
360d90da82SVladimir Sementsov-Ogievskiy        except ConnectionRefusedError:
370d90da82SVladimir Sementsov-Ogievskiy            return False
380d90da82SVladimir Sementsov-Ogievskiy
390d90da82SVladimir Sementsov-Ogievskiy    return True
400d90da82SVladimir Sementsov-Ogievskiy
410d90da82SVladimir Sementsov-Ogievskiy
420d90da82SVladimir Sementsov-Ogievskiydef find_free_ports(count: int) -> List[int]:
430d90da82SVladimir Sementsov-Ogievskiy    result = []
440d90da82SVladimir Sementsov-Ogievskiy    for port in range(VNC_PORT_START, VNC_PORT_END):
450d90da82SVladimir Sementsov-Ogievskiy        if check_bind(port):
460d90da82SVladimir Sementsov-Ogievskiy            result.append(port)
470d90da82SVladimir Sementsov-Ogievskiy            if len(result) >= count:
480d90da82SVladimir Sementsov-Ogievskiy                break
490d90da82SVladimir Sementsov-Ogievskiy    assert len(result) == count
500d90da82SVladimir Sementsov-Ogievskiy    return result
510d90da82SVladimir Sementsov-Ogievskiy
520d90da82SVladimir Sementsov-Ogievskiy
532283b627SPhilippe Mathieu-Daudéclass Vnc(QemuSystemTest):
54bbbd9b6eSWillian Rampazzo    """
55bbbd9b6eSWillian Rampazzo    :avocado: tags=vnc,quick
565104b738SAlex Bennée    :avocado: tags=machine:none
57bbbd9b6eSWillian Rampazzo    """
58bbbd9b6eSWillian Rampazzo    def test_no_vnc(self):
59bbbd9b6eSWillian Rampazzo        self.vm.add_args('-nodefaults', '-S')
60bbbd9b6eSWillian Rampazzo        self.vm.launch()
61bbbd9b6eSWillian Rampazzo        self.assertFalse(self.vm.qmp('query-vnc')['return']['enabled'])
62bbbd9b6eSWillian Rampazzo
63bbbd9b6eSWillian Rampazzo    def test_no_vnc_change_password(self):
64bbbd9b6eSWillian Rampazzo        self.vm.add_args('-nodefaults', '-S')
65bbbd9b6eSWillian Rampazzo        self.vm.launch()
66bbbd9b6eSWillian Rampazzo        self.assertFalse(self.vm.qmp('query-vnc')['return']['enabled'])
67bbbd9b6eSWillian Rampazzo        set_password_response = self.vm.qmp('change-vnc-password',
68bbbd9b6eSWillian Rampazzo                                            password='new_password')
69bbbd9b6eSWillian Rampazzo        self.assertIn('error', set_password_response)
70bbbd9b6eSWillian Rampazzo        self.assertEqual(set_password_response['error']['class'],
71bbbd9b6eSWillian Rampazzo                         'GenericError')
72bbbd9b6eSWillian Rampazzo        self.assertEqual(set_password_response['error']['desc'],
73bbbd9b6eSWillian Rampazzo                         'Could not set password')
74bbbd9b6eSWillian Rampazzo
75bbbd9b6eSWillian Rampazzo    def test_change_password_requires_a_password(self):
76bbbd9b6eSWillian Rampazzo        self.vm.add_args('-nodefaults', '-S', '-vnc', ':0')
77bbbd9b6eSWillian Rampazzo        self.vm.launch()
78bbbd9b6eSWillian Rampazzo        self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled'])
79bbbd9b6eSWillian Rampazzo        set_password_response = self.vm.qmp('change-vnc-password',
80bbbd9b6eSWillian Rampazzo                                            password='new_password')
81bbbd9b6eSWillian Rampazzo        self.assertIn('error', set_password_response)
82bbbd9b6eSWillian Rampazzo        self.assertEqual(set_password_response['error']['class'],
83bbbd9b6eSWillian Rampazzo                         'GenericError')
84bbbd9b6eSWillian Rampazzo        self.assertEqual(set_password_response['error']['desc'],
85bbbd9b6eSWillian Rampazzo                         'Could not set password')
86bbbd9b6eSWillian Rampazzo
87bbbd9b6eSWillian Rampazzo    def test_change_password(self):
88bbbd9b6eSWillian Rampazzo        self.vm.add_args('-nodefaults', '-S', '-vnc', ':0,password=on')
89bbbd9b6eSWillian Rampazzo        self.vm.launch()
90bbbd9b6eSWillian Rampazzo        self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled'])
91b6aed193SVladimir Sementsov-Ogievskiy        self.vm.cmd('change-vnc-password',
92bbbd9b6eSWillian Rampazzo                    password='new_password')
930d90da82SVladimir Sementsov-Ogievskiy
940d90da82SVladimir Sementsov-Ogievskiy    def test_change_listen(self):
950d90da82SVladimir Sementsov-Ogievskiy        a, b, c = find_free_ports(3)
960d90da82SVladimir Sementsov-Ogievskiy        self.assertFalse(check_connect(a))
970d90da82SVladimir Sementsov-Ogievskiy        self.assertFalse(check_connect(b))
980d90da82SVladimir Sementsov-Ogievskiy        self.assertFalse(check_connect(c))
990d90da82SVladimir Sementsov-Ogievskiy
1000d90da82SVladimir Sementsov-Ogievskiy        self.vm.add_args('-nodefaults', '-S', '-vnc', f'{VNC_ADDR}:{a - 5900}')
1010d90da82SVladimir Sementsov-Ogievskiy        self.vm.launch()
1020d90da82SVladimir Sementsov-Ogievskiy        self.assertEqual(self.vm.qmp('query-vnc')['return']['service'], str(a))
1030d90da82SVladimir Sementsov-Ogievskiy        self.assertTrue(check_connect(a))
1040d90da82SVladimir Sementsov-Ogievskiy        self.assertFalse(check_connect(b))
1050d90da82SVladimir Sementsov-Ogievskiy        self.assertFalse(check_connect(c))
1060d90da82SVladimir Sementsov-Ogievskiy
107b6aed193SVladimir Sementsov-Ogievskiy        self.vm.cmd('display-update', type='vnc',
1080d90da82SVladimir Sementsov-Ogievskiy                    addresses=[{'type': 'inet', 'host': VNC_ADDR,
1090d90da82SVladimir Sementsov-Ogievskiy                                'port': str(b)},
1100d90da82SVladimir Sementsov-Ogievskiy                               {'type': 'inet', 'host': VNC_ADDR,
1110d90da82SVladimir Sementsov-Ogievskiy                                'port': str(c)}])
1120d90da82SVladimir Sementsov-Ogievskiy        self.assertEqual(self.vm.qmp('query-vnc')['return']['service'], str(b))
1130d90da82SVladimir Sementsov-Ogievskiy        self.assertFalse(check_connect(a))
1140d90da82SVladimir Sementsov-Ogievskiy        self.assertTrue(check_connect(b))
1150d90da82SVladimir Sementsov-Ogievskiy        self.assertTrue(check_connect(c))
116