[FIX] bus, website_livechat: prevent psycopg2 errors during tests
`psycopg2` errors sometimes happen during tests. This is caused by race conditions between several `cr.execute()`/`cr.fetch*`. This is even worse with websockets that are long lived connections that sometimes open a cursor in the middle of the test. Before websockets, longpolling was just disabled during tests. This commits disable websockets as well in order to prevent those errors as much as possible. Some live chat tours were updated in [1] after the websockets intro- duction due to some race conditions. This was reverted as the fix relied on a hack on websockets that are now unavailable. fixes runbot-25357,24809 [1]: https://github.com/odoo/odoo/pull/103521 closes odoo/odoo#143647 X-original-commit: e3b07a301036fcce76ebbbd856b507326b88160a Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com> Signed-off-by: Matthieu Stockbauer (tsm) <tsm@odoo.com>
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import json
|
||||
from werkzeug.exceptions import ServiceUnavailable
|
||||
|
||||
from odoo.http import Controller, request, route, SessionExpiredException
|
||||
from odoo.addons.base.models.assetsbundle import AssetsBundle
|
||||
@@ -16,10 +15,6 @@ class WebsocketController(Controller):
|
||||
Handle the websocket handshake, upgrade the connection if
|
||||
successfull.
|
||||
"""
|
||||
is_headful_browser = request.httprequest.user_agent and 'Headless' not in request.httprequest.user_agent.string
|
||||
if request.registry.in_test_mode() and is_headful_browser:
|
||||
# Prevent browsers from interfering with the unittests
|
||||
raise ServiceUnavailable()
|
||||
return WebsocketConnectionHandler.open_connection(request)
|
||||
|
||||
@route('/websocket/health', type='http', auth='none', save_session=False)
|
||||
|
||||
@@ -358,6 +358,7 @@ QUnit.test("Can reconnect after late close event", async (assert) => {
|
||||
|
||||
QUnit.test("Fallback on simple worker when shared worker failed to initialize", async (assert) => {
|
||||
addBusServicesToRegistry();
|
||||
patchWebsocketWorkerWithCleanup();
|
||||
const originalSharedWorker = browser.SharedWorker;
|
||||
const originalWorker = browser.Worker;
|
||||
patchWithCleanup(browser, {
|
||||
|
||||
@@ -12,12 +12,12 @@ except ImportError:
|
||||
websocket = None
|
||||
|
||||
import odoo.tools
|
||||
from odoo.tests import HOST, common
|
||||
from odoo.tests import HOST, HttpCase
|
||||
from ..websocket import CloseCode, Websocket, WebsocketConnectionHandler
|
||||
from ..models.bus import dispatch, hashable, channel_with_db
|
||||
|
||||
|
||||
class WebsocketCase(common.HttpCase):
|
||||
class WebsocketCase(HttpCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
@@ -25,6 +25,8 @@ class WebsocketCase(common.HttpCase):
|
||||
cls._logger.warning("websocket-client module is not installed")
|
||||
raise unittest.SkipTest("websocket-client module is not installed")
|
||||
cls._WEBSOCKET_URL = f"ws://{HOST}:{odoo.tools.config['http_port']}/websocket"
|
||||
websocket_allowed_patch = patch.object(WebsocketConnectionHandler, "websocket_allowed", return_value=True)
|
||||
cls.startClassPatcher(websocket_allowed_patch)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@@ -183,17 +183,6 @@ class TestWebsocketCaryall(WebsocketCase):
|
||||
self.assertEqual(notifications[0]['message']['type'], 'notif_type')
|
||||
self.assertEqual(notifications[0]['message']['payload'], 'another_message')
|
||||
|
||||
def test_opening_websocket_connection_during_tests(self):
|
||||
# During tests, browsers can't open websocket connections.
|
||||
headers = ['User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36']
|
||||
with self.assertRaises(WebSocketBadStatusException) as error_catcher:
|
||||
self.websocket_connect(header=headers)
|
||||
self.assertEqual(error_catcher.exception.status_code, 503)
|
||||
|
||||
# But ChromeHeadless still can.
|
||||
headers = ['User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/102.0.0.0 Safari/537.36']
|
||||
self.websocket_connect()
|
||||
|
||||
def test_subscribe_higher_last_notification_id(self):
|
||||
server_last_notification_id = self.env['bus.bus'].sudo().search([], limit=1, order='id desc').id or 0
|
||||
client_last_notification_id = server_last_notification_id + 1
|
||||
|
||||
@@ -19,7 +19,7 @@ from urllib.parse import urlparse
|
||||
from weakref import WeakSet
|
||||
|
||||
from werkzeug.local import LocalStack
|
||||
from werkzeug.exceptions import BadRequest, HTTPException
|
||||
from werkzeug.exceptions import BadRequest, HTTPException, ServiceUnavailable
|
||||
|
||||
import odoo
|
||||
from odoo import api
|
||||
@@ -821,6 +821,10 @@ class WebsocketConnectionHandler:
|
||||
'sec-websocket-version', 'upgrade', 'origin',
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def websocket_allowed(cls, request):
|
||||
return not request.registry.in_test_mode()
|
||||
|
||||
@classmethod
|
||||
def open_connection(cls, request):
|
||||
"""
|
||||
@@ -831,6 +835,8 @@ class WebsocketConnectionHandler:
|
||||
versions the client supports and those we support.
|
||||
:raise: BadRequest if the handshake data is incorrect.
|
||||
"""
|
||||
if not cls.websocket_allowed(request):
|
||||
raise ServiceUnavailable("Websocket is disabled in test mode")
|
||||
cls._handle_public_configuration(request)
|
||||
try:
|
||||
response = cls._get_handshake_response(request.httprequest.headers)
|
||||
|
||||
Reference in New Issue
Block a user