Description of problem: Running RHOS 13 tempest tests with TLS everywhere enabled, test_novnc tempest test failed with "Not a valid html document in the response" error How reproducible: always Steps to Reproduce: 1. Deploy RHOS 13 with TLS everywhere 2. Run tempest.api.compute.servers.test_novnc.NoVNCConsoleTestJSON.test_novnc tempest test Actual results: testtools.matchers._impl.MismatchError: '<html>' not in u'<!DOCTYPE html>\n<html lang="en">\n<head>\n\n <!--\n noVNC example: lightweight example using minimal UI and features\n\n This is a self-contained file which doesn\'t import WebUtil or external CSS.\n\n Copyright (C) 2018 The noVNC Authors\n noVNC is licensed under the MPL 2.0 (see LICENSE.txt)\n This file is licensed under the 2-Clause BSD license (see LICENSE.txt).\n\n Connect parameters are provided in query string:\n http://example.com/?host=HOST&port=PORT&scale=true\n -->\n <title>noVNC</title>\n\n <meta charset="utf-8">\n\n <style>\n\n body {\n margin: 0;\n background-color: dimgrey;\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n html {\n height: 100%;\n }\n\n #top_bar {\n background-color: #6e84a3;\n color: white;\n font: bold 12px Helvetica;\n padding: 6px 5px 4px 5px;\n border-bottom: 1px outset;\n }\n #status {\n text-align: center;\n }\n #sendCtrlAltDelButton {\n position: fixed;\n top: 0px;\n right: 0px;\n border: 1px outset;\n padding: 5px 5px 4px 5px;\n cursor: pointer;\n }\n\n #screen {\n flex: 1; /* fill remaining space */\n overflow: hidden;\n }\n\n </style>\n\n <!-- Promise polyfill for IE11 -->\n <script src="vendor/promise.js"></script>\n\n <!-- ES2015/ES6 modules polyfill -->\n <script type="module">\n window._noVNC_has_module_support = true;\n </script>\n <script>\n window.addEventListener("load", function() {\n if (window._noVNC_has_module_support) return;\n const loader = document.createElement("script");\n loader.src = "vendor/browser-es-module-loader/dist/" +\n "browser-es-module-loader.js";\n document.head.appendChild(loader);\n });\n </script>\n\n <!-- actual script modules -->\n <script type="module" crossorigin="anonymous">\n // RFB holds the API to connect and communicate with a VNC server\n import RFB from \'./core/rfb.js\';\n\n let rfb;\n let desktopName;\n\n // When this function is called we have\n // successfully connected to a server\n function connectedToServer(e) {\n status("Connected to " + desktopName);\n }\n\n // This function is called when we are disconnected\n function disconnectedFromServer(e) {\n if (e.detail.clean) {\n status("Disconnected");\n } else {\n status("Something went wrong, connection is closed");\n }\n }\n\n // When this function is called, the server requires\n // credentials to authenticate\n function credentialsAreRequired(e) {\n const password = prompt("Password Required:");\n rfb.sendCredentials({ password: password });\n }\n\n // When this function is called we have received\n // a desktop name from the server\n function updateDesktopName(e) {\n desktopName = e.detail.name;\n }\n\n // Since most operating systems will catch Ctrl+Alt+Del\n // before they get a chance to be intercepted by the browser,\n // we provide a way to emulate this key sequence.\n function sendCtrlAltDel() {\n rfb.sendCtrlAltDel();\n return false;\n }\n\n // Show a status text in the top bar\n function status(text) {\n document.getElementById(\'status\').textContent = text;\n }\n\n // This function extracts the value of one variable from the\n // query string. If the variable isn\'t defined in the URL\n // it returns the default value instead.\n function readQueryVariable(name, defaultValue) {\n // A URL with a query parameter can look like this:\n // https://www.example.com?myqueryparam=myvalue\n //\n // Note that we use location.href instead of location.search\n // because Firefox < 53 has a bug w.r.t location.search\n const re = new RegExp(\'.*[?&]\' + name + \'=([^&#]*)\'),\n match = document.location.href.match(re);\n if (typeof defaultValue === \'undefined\') { defaultValue = null; }\n\n if (match) {\n // We have to decode the URL since want the cleartext value\n return decodeURIComponent(match[1]);\n }\n\n return defaultValue;\n }\n\n document.getElementById(\'sendCtrlAltDelButton\')\n .onclick = sendCtrlAltDel;\n\n // Read parameters specified in the URL query string\n // By default, use the host and port of server that served this file\n const host = readQueryVariable(\'host\', window.location.hostname);\n let port = readQueryVariable(\'port\', window.location.port);\n const password = readQueryVariable(\'password\', \'\');\n const path = readQueryVariable(\'path\', \'websockify\');\n\n // | | | | | |\n // | | | Connect | | |\n // v v v v v v\n\n status("Connecting");\n\n // Build the websocket URL used to connect\n let url;\n if (window.location.protocol === "https:") {\n url = \'wss\';\n } else {\n url = \'ws\';\n }\n url += \'://\' + host;\n if(port) {\n url += \':\' + port;\n }\n url += \'/\' + path;\n\n // Creating a new RFB object will start a new connection\n rfb = new RFB(document.getElementById(\'screen\'), url,\n { credentials: { password: password } });\n\n // Add listeners to important events from the RFB module\n rfb.addEventListener("connect", connectedToServer);\n rfb.addEventListener("disconnect", disconnectedFromServer);\n rfb.addEventListener("credentialsrequired", credentialsAreRequired);\n rfb.addEventListener("desktopname", updateDesktopName);\n\n // Set parameters that can be changed on an active connection\n rfb.viewOnly = readQueryVariable(\'view_only\', false);\n rfb.scaleViewport = readQueryVariable(\'scale\', false);\n </script>\n</head>\n\n<body>\n <div id="top_bar">\n <div id="status">Loading</div>\n <div id="sendCtrlAltDelButton">Send CtrlAltDel</div>\n </div>\n <div id="screen">\n <!-- This is where the remote screen will appear -->\n </div>\n</body>\n</html>\n': Not a valid html document in the response. Expected results: Test passed Additional info:
This is simply a bad Tempest test. Tempest is checking for a '<html>' tag, but the response contains a '<html lang="en">' tag. The matcher should just be cleverer. Then again you shouldn't parse [1] HTML [2] with regex [3] so... :) In any case, reassigning component. [1] https://blog.codinghorror.com/parsing-html-the-cthulhu-way/ [2] http://web.archive.org/web/20060505114433/http://www.alpha-geek.com/2004/01/12/bring_me_your_regexs_i_will_create_html_to_break_them [3] https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454
This was already resolved upstream [1]. You need a newer version of Tempest. [1] https://review.opendev.org/#/c/655827/
The fix will need to be backported in order to get it packaged for RHOS-13.
The issue is fixed in the Fixed in version package. Currently even the newer version of the package (openstack-tempest-18.0.0-15.el7ost) is present via latest symlink in the rhos-13 repositories. I confirmed the test is passing in a job using the openstack-tempest-18.0.0-14.el7ost or newer.
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2020:2719
Great post. Thanks for sharing this my bug query is finally resolved today thanks for sharing this. https://www.dollartree-compass.com