Skip to content

Commit

Permalink
remove all txaio.make_logger refs from generic code (#1564)
Browse files Browse the repository at this point in the history
  • Loading branch information
oberstet committed May 9, 2022
1 parent 5a50788 commit 2e2ee5f
Show file tree
Hide file tree
Showing 13 changed files with 270 additions and 210 deletions.
1 change: 1 addition & 0 deletions autobahn/asyncio/test/test_aio_rawsocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os

from unittest.mock import Mock, call

from autobahn.asyncio.rawsocket import PrefixProtocol, RawSocketClientProtocol, RawSocketServerProtocol, \
WampRawSocketClientFactory, WampRawSocketServerFactory
from autobahn.asyncio.util import get_serializers
Expand Down
2 changes: 0 additions & 2 deletions autobahn/asyncio/test/test_aio_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

from autobahn.asyncio.websocket import WebSocketServerFactory

# https://medium.com/ideas-at-igenius/testing-asyncio-python-code-with-pytest-a2f3628f82bc


async def echo_async(what, when):
await asyncio.sleep(when)
Expand Down
134 changes: 134 additions & 0 deletions autobahn/asyncio/test/test_wamp_runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
###############################################################################
#
# The MIT License (MIT)
#
# Copyright (c) Crossbar.io Technologies GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
###############################################################################

import unittest
from txaio.testutil import replace_loop

import asyncio
from unittest.mock import patch, Mock

from autobahn.asyncio.wamp import ApplicationRunner


class TestApplicationRunner(unittest.TestCase):
"""
Test the autobahn.asyncio.wamp.ApplicationRunner class.
"""
def _assertRaisesRegex(self, exception, error, *args, **kw):
try:
self.assertRaisesRegex
except AttributeError:
f = self.assertRaisesRegexp
else:
f = self.assertRaisesRegex
f(exception, error, *args, **kw)

def test_explicit_SSLContext(self):
"""
Ensure that loop.create_connection is called with the exact SSL
context object that is passed (as ssl) to the __init__ method of
ApplicationRunner.
"""
with replace_loop(Mock()) as loop:
with patch.object(asyncio, 'get_event_loop', return_value=loop):
loop.run_until_complete = Mock(return_value=(Mock(), Mock()))
ssl = {}
runner = ApplicationRunner('ws://127.0.0.1:8080/ws', 'realm',
ssl=ssl)
runner.run('_unused_')
self.assertIs(ssl, loop.create_connection.call_args[1]['ssl'])

def test_omitted_SSLContext_insecure(self):
"""
Ensure that loop.create_connection is called with ssl=False
if no ssl argument is passed to the __init__ method of
ApplicationRunner and the websocket URL starts with "ws:".
"""
with replace_loop(Mock()) as loop:
with patch.object(asyncio, 'get_event_loop', return_value=loop):
loop.run_until_complete = Mock(return_value=(Mock(), Mock()))
runner = ApplicationRunner('ws://127.0.0.1:8080/ws', 'realm')
runner.run('_unused_')
self.assertIs(False, loop.create_connection.call_args[1]['ssl'])

def test_omitted_SSLContext_secure(self):
"""
Ensure that loop.create_connection is called with ssl=True
if no ssl argument is passed to the __init__ method of
ApplicationRunner and the websocket URL starts with "wss:".
"""
with replace_loop(Mock()) as loop:
with patch.object(asyncio, 'get_event_loop', return_value=loop):
loop.run_until_complete = Mock(return_value=(Mock(), Mock()))
runner = ApplicationRunner('wss://127.0.0.1:8080/wss', 'realm')
runner.run(self.fail)
self.assertIs(True, loop.create_connection.call_args[1]['ssl'])

def test_conflict_SSL_True_with_ws_url(self):
"""
ApplicationRunner must raise an exception if given an ssl value of True
but only a "ws:" URL.
"""
with replace_loop(Mock()) as loop:
loop.run_until_complete = Mock(return_value=(Mock(), Mock()))
runner = ApplicationRunner('ws://127.0.0.1:8080/wss', 'realm',
ssl=True)
error = (r'^ssl argument value passed to ApplicationRunner '
r'conflicts with the "ws:" prefix of the url '
r'argument\. Did you mean to use "wss:"\?$')
self._assertRaisesRegex(Exception, error, runner.run, '_unused_')

def test_conflict_SSLContext_with_ws_url(self):
"""
ApplicationRunner must raise an exception if given an ssl value that is
an instance of SSLContext, but only a "ws:" URL.
"""
import ssl
try:
# Try to create an SSLContext, to be as rigorous as we can be
# by avoiding making assumptions about the ApplicationRunner
# implementation. If we happen to be on a Python that has no
# SSLContext, we pass ssl=True, which will simply cause this
# test to degenerate to the behavior of
# test_conflict_SSL_True_with_ws_url (above). In fact, at the
# moment (2015-05-10), none of this matters because the
# ApplicationRunner implementation does not check to require
# that its ssl argument is either a bool or an SSLContext. But
# that may change, so we should be careful.
ssl.create_default_context
except AttributeError:
context = True
else:
context = ssl.create_default_context()

with replace_loop(Mock()) as loop:
loop.run_until_complete = Mock(return_value=(Mock(), Mock()))
runner = ApplicationRunner('ws://127.0.0.1:8080/wss', 'realm',
ssl=context)
error = (r'^ssl argument value passed to ApplicationRunner '
r'conflicts with the "ws:" prefix of the url '
r'argument\. Did you mean to use "wss:"\?$')
self._assertRaisesRegex(Exception, error, runner.run, '_unused_')
2 changes: 2 additions & 0 deletions autobahn/asyncio/wamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import signal

import txaio
txaio.use_asyncio() # noqa

from autobahn.util import public
from autobahn.wamp import protocol
from autobahn.wamp.types import ComponentConfig
Expand Down
18 changes: 18 additions & 0 deletions autobahn/asyncio/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
from typing import Optional

import txaio
txaio.use_asyncio() # noqa

from autobahn.util import public, hltype
from autobahn.asyncio.util import create_transport_details
from autobahn.wamp import websocket
Expand Down Expand Up @@ -193,6 +195,8 @@ class WebSocketServerProtocol(WebSocketAdapterProtocol, protocol.WebSocketServer
* :class:`autobahn.websocket.interfaces.IWebSocketChannel`
"""

log = txaio.make_logger()


@public
class WebSocketClientProtocol(WebSocketAdapterProtocol, protocol.WebSocketClientProtocol):
Expand All @@ -204,6 +208,8 @@ class WebSocketClientProtocol(WebSocketAdapterProtocol, protocol.WebSocketClient
* :class:`autobahn.websocket.interfaces.IWebSocketChannel`
"""

log = txaio.make_logger()

def _onConnect(self, response):
res = self.onConnect(response)
self.log.info('{func}: {res}', func=hltype(self._onConnect), res=res)
Expand Down Expand Up @@ -236,6 +242,8 @@ class WebSocketServerFactory(WebSocketAdapterFactory, protocol.WebSocketServerFa
* :class:`autobahn.websocket.interfaces.IWebSocketServerChannelFactory`
"""

log = txaio.make_logger()

protocol = WebSocketServerProtocol

def __init__(self, *args, **kwargs):
Expand All @@ -262,6 +270,8 @@ class WebSocketClientFactory(WebSocketAdapterFactory, protocol.WebSocketClientFa
* :class:`autobahn.websocket.interfaces.IWebSocketClientChannelFactory`
"""

log = txaio.make_logger()

def __init__(self, *args, **kwargs):
"""
Expand All @@ -287,13 +297,17 @@ class WampWebSocketServerProtocol(websocket.WampWebSocketServerProtocol, WebSock
* :class:`autobahn.wamp.interfaces.ITransport`
"""

log = txaio.make_logger()


@public
class WampWebSocketServerFactory(websocket.WampWebSocketServerFactory, WebSocketServerFactory):
"""
asyncio-based WAMP-over-WebSocket server factory.
"""

log = txaio.make_logger()

protocol = WampWebSocketServerProtocol

def __init__(self, factory, *args, **kwargs):
Expand Down Expand Up @@ -329,13 +343,17 @@ class WampWebSocketClientProtocol(websocket.WampWebSocketClientProtocol, WebSock
* :class:`autobahn.wamp.interfaces.ITransport`
"""

log = txaio.make_logger()


@public
class WampWebSocketClientFactory(websocket.WampWebSocketClientFactory, WebSocketClientFactory):
"""
asyncio-based WAMP-over-WebSocket client factory.
"""

log = txaio.make_logger()

protocol = WampWebSocketClientProtocol

def __init__(self, factory, *args, **kwargs):
Expand Down
90 changes: 90 additions & 0 deletions autobahn/twisted/test/test_wamp_runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
###############################################################################
#
# The MIT License (MIT)
#
# Copyright (c) Crossbar.io Technologies GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
###############################################################################

import unittest

from unittest.mock import patch
from zope.interface import implementer
from twisted.internet.interfaces import IReactorTime


@implementer(IReactorTime)
class FakeReactor(object):
"""
This just fakes out enough reactor methods so .run() can work.
"""
stop_called = False

def __init__(self, to_raise):
self.stop_called = False
self.to_raise = to_raise
self.delayed = []

def run(self, *args, **kw):
raise self.to_raise

def stop(self):
self.stop_called = True

def callLater(self, delay, func, *args, **kwargs):
self.delayed.append((delay, func, args, kwargs))

def connectTCP(self, *args, **kw):
raise RuntimeError("ConnectTCP shouldn't get called")


class TestWampTwistedRunner(unittest.TestCase):
# XXX should figure out *why* but the test_protocol timeout
# tests fail if we *don't* patch out this txaio stuff. So,
# presumably it's messing up some global state that both tests
# implicitly depend on ...

@patch('txaio.use_twisted')
@patch('txaio.start_logging')
@patch('txaio.config')
def test_connect_error(self, *args):
"""
Ensure the runner doesn't swallow errors and that it exits the
reactor properly if there is one.
"""
try:
from autobahn.twisted.wamp import ApplicationRunner
from twisted.internet.error import ConnectionRefusedError
# the 'reactor' member doesn't exist until we import it
from twisted.internet import reactor # noqa: F401
except ImportError:
raise unittest.SkipTest('No twisted')

runner = ApplicationRunner('ws://localhost:1', 'realm')
exception = ConnectionRefusedError("It's a trap!")

with patch('twisted.internet.reactor', FakeReactor(exception)) as mockreactor:
self.assertRaises(
ConnectionRefusedError,
# pass a no-op session-creation method
runner.run, lambda _: None, start_reactor=True
)
self.assertTrue(mockreactor.stop_called)
4 changes: 4 additions & 0 deletions autobahn/twisted/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,8 @@ class WebSocketServerFactory(WebSocketAdapterFactory, protocol.WebSocketServerFa
Implements :class:`autobahn.websocket.interfaces.IWebSocketServerChannelFactory`
"""

log = txaio.make_logger()

def __init__(self, *args, **kwargs):
"""
Expand All @@ -480,6 +482,8 @@ class WebSocketClientFactory(WebSocketAdapterFactory, protocol.WebSocketClientFa
Implements :class:`autobahn.websocket.interfaces.IWebSocketClientChannelFactory`
"""

log = txaio.make_logger()

def __init__(self, *args, **kwargs):
"""
Expand Down
9 changes: 9 additions & 0 deletions autobahn/wamp/test/test_wamp_cryptosign.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,21 @@
#
###############################################################################

import os
import hashlib
import binascii
import unittest
from unittest.mock import Mock

import txaio

if os.environ.get('USE_TWISTED', None):
txaio.use_twisted()
elif os.environ.get('USE_ASYNCIO', None):
txaio.use_asyncio()
else:
raise RuntimeError('need either USE_TWISTED=1 or USE_ASYNCIO=1')

from autobahn.wamp.cryptosign import _makepad, HAS_CRYPTOSIGN
from autobahn.wamp import types
from autobahn.wamp.auth import create_authenticator
Expand Down

0 comments on commit 2e2ee5f

Please sign in to comment.