Handle 'path' query parameter for test_novnc
Starting in v1.1.0 of noVNC, it no longer forwards a token from the
URI via a cookie and we must instead specify the token as part of the
'path' query parameter.
This adds handling of the 'path' query parameter so the test_novnc
tests will be able to work with a console access url that has the token
in the 'path' query parameter instead of in a cookie and thus work with
noVNC >= v1.1.0.
Related-Bug: #1822676
Change-Id: Ifc0262f869e4d08d2746275438575980213fe9b2
diff --git a/tempest/api/compute/servers/test_novnc.py b/tempest/api/compute/servers/test_novnc.py
index 5980455..7cf6d83 100644
--- a/tempest/api/compute/servers/test_novnc.py
+++ b/tempest/api/compute/servers/test_novnc.py
@@ -16,6 +16,7 @@
import struct
import six
+import six.moves.urllib.parse as urlparse
import urllib3
from tempest.api.compute import base
@@ -73,8 +74,9 @@
'initial call: ' + six.text_type(resp.status))
# Do some basic validation to make sure it is an expected HTML document
resp_data = resp.data.decode()
- self.assertIn('<html>', resp_data,
- 'Not a valid html document in the response.')
+ # This is needed in the case of example: <html lang="en">
+ self.assertRegex(resp_data, '<html.*>',
+ 'Not a valid html document in the response.')
self.assertIn('</html>', resp_data,
'Not a valid html document in the response.')
# Just try to make sure we got JavaScript back for noVNC, since we
@@ -206,7 +208,18 @@
type='novnc')['console']
self.assertEqual('novnc', body['type'])
# Do the WebSockify HTTP Request to novncproxy with a bad token
- url = body['url'].replace('token=', 'token=bad')
+ parts = urlparse.urlparse(body['url'])
+ qparams = urlparse.parse_qs(parts.query)
+ if 'path' in qparams:
+ qparams['path'] = urlparse.unquote(qparams['path'][0]).replace(
+ 'token=', 'token=bad')
+ elif 'token' in qparams:
+ qparams['token'] = 'bad' + qparams['token'][0]
+ new_query = urlparse.urlencode(qparams)
+ new_parts = urlparse.ParseResult(parts.scheme, parts.netloc,
+ parts.path, parts.params, new_query,
+ parts.fragment)
+ url = urlparse.urlunparse(new_parts)
self._websocket = compute.create_websocket(url)
# Make sure the novncproxy rejected the connection and closed it
data = self._websocket.receive_frame()
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 1489e60..4ac92d9 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -392,8 +392,11 @@
def _upgrade(self, url):
"""Upgrade the HTTP connection to a WebSocket and verify."""
- # The real request goes to the /websockify URI always
- reqdata = 'GET /websockify HTTP/1.1\r\n'
+ # It is possible to pass the path as a query parameter in the request,
+ # so use it if present
+ qparams = urlparse.parse_qs(url.query)
+ path = qparams['path'][0] if 'path' in qparams else '/websockify'
+ reqdata = 'GET %s HTTP/1.1\r\n' % path
reqdata += 'Host: %s' % url.hostname
# Add port only if we have one specified
if url.port:
@@ -402,7 +405,7 @@
reqdata += '\r\n'
# Tell the HTTP Server to Upgrade the connection to a WebSocket
reqdata += 'Upgrade: websocket\r\nConnection: Upgrade\r\n'
- # The token=xxx is sent as a Cookie not in the URI
+ # The token=xxx is sent as a Cookie not in the URI for noVNC < v1.1.0
reqdata += 'Cookie: %s\r\n' % url.query
# Use a hard-coded WebSocket key since a test program
reqdata += 'Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n'