xref: /openbmc/qemu/tests/avocado/vnc.py (revision 8e28b65f)
1# Simple functional tests for VNC functionality
2#
3# Copyright (c) 2018 Red Hat, Inc.
4#
5# Author:
6#  Cleber Rosa <crosa@redhat.com>
7#
8# This work is licensed under the terms of the GNU GPL, version 2 or
9# later.  See the COPYING file in the top-level directory.
10
11import socket
12from typing import List
13
14from avocado_qemu import QemuSystemTest
15
16
17VNC_ADDR = '127.0.0.1'
18VNC_PORT_START = 32768
19VNC_PORT_END = VNC_PORT_START + 1024
20
21
22def check_bind(port: int) -> bool:
23    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
24        try:
25            sock.bind((VNC_ADDR, port))
26        except OSError:
27            return False
28
29    return True
30
31
32def check_connect(port: int) -> bool:
33    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
34        try:
35            sock.connect((VNC_ADDR, port))
36        except ConnectionRefusedError:
37            return False
38
39    return True
40
41
42def find_free_ports(count: int) -> List[int]:
43    result = []
44    for port in range(VNC_PORT_START, VNC_PORT_END):
45        if check_bind(port):
46            result.append(port)
47            if len(result) >= count:
48                break
49    assert len(result) == count
50    return result
51
52
53class Vnc(QemuSystemTest):
54    """
55    :avocado: tags=vnc,quick
56    """
57    def test_no_vnc(self):
58        self.vm.add_args('-nodefaults', '-S')
59        self.vm.launch()
60        self.assertFalse(self.vm.qmp('query-vnc')['return']['enabled'])
61
62    def test_no_vnc_change_password(self):
63        self.vm.add_args('-nodefaults', '-S')
64        self.vm.launch()
65        self.assertFalse(self.vm.qmp('query-vnc')['return']['enabled'])
66        set_password_response = self.vm.qmp('change-vnc-password',
67                                            password='new_password')
68        self.assertIn('error', set_password_response)
69        self.assertEqual(set_password_response['error']['class'],
70                         'GenericError')
71        self.assertEqual(set_password_response['error']['desc'],
72                         'Could not set password')
73
74    def test_change_password_requires_a_password(self):
75        self.vm.add_args('-nodefaults', '-S', '-vnc', ':0')
76        self.vm.launch()
77        self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled'])
78        set_password_response = self.vm.qmp('change-vnc-password',
79                                            password='new_password')
80        self.assertIn('error', set_password_response)
81        self.assertEqual(set_password_response['error']['class'],
82                         'GenericError')
83        self.assertEqual(set_password_response['error']['desc'],
84                         'Could not set password')
85
86    def test_change_password(self):
87        self.vm.add_args('-nodefaults', '-S', '-vnc', ':0,password=on')
88        self.vm.launch()
89        self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled'])
90        set_password_response = self.vm.qmp('change-vnc-password',
91                                            password='new_password')
92        self.assertEqual(set_password_response['return'], {})
93
94    def test_change_listen(self):
95        a, b, c = find_free_ports(3)
96        self.assertFalse(check_connect(a))
97        self.assertFalse(check_connect(b))
98        self.assertFalse(check_connect(c))
99
100        self.vm.add_args('-nodefaults', '-S', '-vnc', f'{VNC_ADDR}:{a - 5900}')
101        self.vm.launch()
102        self.assertEqual(self.vm.qmp('query-vnc')['return']['service'], str(a))
103        self.assertTrue(check_connect(a))
104        self.assertFalse(check_connect(b))
105        self.assertFalse(check_connect(c))
106
107        res = self.vm.qmp('display-update', type='vnc',
108                          addresses=[{'type': 'inet', 'host': VNC_ADDR,
109                                      'port': str(b)},
110                                     {'type': 'inet', 'host': VNC_ADDR,
111                                      'port': str(c)}])
112        self.assertEqual(res['return'], {})
113        self.assertEqual(self.vm.qmp('query-vnc')['return']['service'], str(b))
114        self.assertFalse(check_connect(a))
115        self.assertTrue(check_connect(b))
116        self.assertTrue(check_connect(c))
117