Commit cb84175c authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Update code & tests for Anyio 3

parent 29ebfe30
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -85,4 +85,4 @@ repos:
  - id: mypy
    args: [--config=setup.cfg]
    additional_dependencies: [anyio, trio-typing]
    exclude: setup\.py
    exclude: setup\.py|test_.*
+11 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ packages = find:
setup_requires =
  setuptools >= 40.6
install_requires =
  anyio >=1.0
  anyio ~=3.0

[options.packages.find]
include =
@@ -88,6 +88,7 @@ force_single_line = true

[mypy]
strict = true
warn_unused_configs = True
warn_unreachable = true
implicit_reexport = true
follow_imports = skip
@@ -109,6 +110,7 @@ per-file-ignores =
  tests/*.py: D100, C801
  **/__init__.py: D104, F401, F403
  **/__main__.py: D100, E702
  **/_*.py: D

ignore =
  ;[ Missing docstring in public method ]
@@ -149,6 +151,14 @@ ignore =
  ; Prefer B950 implementation
  E501

  ;[ multiple statements on one line (colon) ]
  E701

  ;[ unexpected number of spaces at start of statement line ]
  ;[ unexpected number of tabs and spaces at start of statement line ]
  ; Don't want spaces...
  ET122 ET128

  ;[ Line break before binary operator ]
  ; Not considered current
  W503
+10 −9
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import sys
from functools import wraps
from typing import Any
from typing import Callable
from typing import Coroutine
from typing import Tuple
from unittest import mock

@@ -27,23 +28,23 @@ import anyio

py_version = sys.version_info[:2]

AnyFunc = Callable[..., Any]
Decorator = Callable[[AnyFunc], AnyFunc]
AsyncTestFunc = Callable[..., Coroutine[Any, Any, None]]
TestFunc = Callable[..., None]


def with_anyio(timeout: int = 10) -> Decorator:
def with_anyio(timeout: int = 10) -> Callable[[AsyncTestFunc], TestFunc]:
	"""
	Create a wrapping decorator to run asynchronous test functions
	"""

	def decorator(testfunc: AnyFunc) -> AnyFunc:
		async def test_async_wrapper(args: Tuple[Any]) -> Any:
			async with anyio.fail_after(timeout):
				return await testfunc(*args)
	def decorator(testfunc: AsyncTestFunc) -> TestFunc:
		async def test_async_wrapper(tc: TestCase, args: Tuple[mock.Mock]) -> None:
			with anyio.fail_after(timeout):
				await testfunc(tc, *args)

		@wraps(testfunc)
		def test_wrapper(*args: Any) -> Any:
			return anyio.run(test_async_wrapper, args)
		def test_wrapper(*args: mock.Mock) -> None:
			anyio.run(test_async_wrapper, args)

		return test_wrapper

+84 −91
Original line number Diff line number Diff line
@@ -26,9 +26,13 @@ from wpa_supplicant import errors
from wpa_supplicant.client import base


@mock.patch("wpa_supplicant.util.connect_unix_datagram", new_callable=anyio_mock.AsyncMock)
@mock.patch(
	"wpa_supplicant.client.base.BaseClient.send_command", new_callable=anyio_mock.AsyncMock,
	"wpa_supplicant.client.base.connect_unix_datagram",
	new_callable=anyio_mock.AsyncMock,
)
@mock.patch(
	"wpa_supplicant.client.base.BaseClient.send_command",
	new_callable=anyio_mock.AsyncMock,
)
class ConnectTests(unittest.TestCase):
	"""
@@ -74,12 +78,10 @@ class SendMessageTests(unittest.TestCase):
	"""

	def setUp(self):
		async def _make_client():
			return base.BaseClient()

		self.client = client = anyio.run(_make_client)
		client.sock = anyio_mock.AsyncMock()
		client.sock.send.side_effect = len
		self.client = client = base.BaseClient()
		client.sock = anyio_mock.AsyncMock(spec=anyio.abc.SocketStream)
		client.sock.send.return_value = None
		assert isinstance(client.sock, anyio.abc.SocketStream)

	@anyio_mock.with_anyio()
	async def test_simple(self):
@@ -87,7 +89,7 @@ class SendMessageTests(unittest.TestCase):
		Check that a response is processed after a command
		"""
		async with self.client as client:
			client.sock.recv.return_value = b"OK"
			client.sock.receive.return_value = b"OK"
			assert await client.send_command("SOME_COMMAND") is None

	@anyio_mock.with_anyio()
@@ -96,7 +98,7 @@ class SendMessageTests(unittest.TestCase):
		Check that an alternate expected response is processed
		"""
		async with self.client as client:
			client.sock.recv.return_value = b"PONG"
			client.sock.receive.return_value = b"PONG"
			assert await client.send_command("PING", expect="PONG") is None

	@anyio_mock.with_anyio()
@@ -105,7 +107,7 @@ class SendMessageTests(unittest.TestCase):
		Check that an unexpected response raises an UnexpectedResponseError
		"""
		async with self.client as client:
			client.sock.recv.return_value = b"DING"
			client.sock.receive.return_value = b"DING"
			with self.assertRaises(errors.UnexpectedResponseError):
				await client.send_command("PING")
			with self.assertRaises(errors.UnexpectedResponseError):
@@ -117,7 +119,7 @@ class SendMessageTests(unittest.TestCase):
		Check that a response is passed through a converter if given
		"""
		async with self.client as client:
			client.sock.recv.return_value = b"FOO\nBAR\nBAZ\n"
			client.sock.receive.return_value = b"FOO\nBAR\nBAZ\n"
			self.assertListEqual(
				await client.send_command(
					"SOME_COMMAND", convert=lambda x: x.splitlines(),
@@ -131,7 +133,7 @@ class SendMessageTests(unittest.TestCase):
		Check that 'convert' overrides 'expect'
		"""
		async with self.client as client:
			client.sock.recv.return_value = b"FOO\nBAR\nBAZ\n"
			client.sock.receive.return_value = b"FOO\nBAR\nBAZ\n"
			self.assertListEqual(
				await client.send_command(
					"SOME_COMMAND", convert=lambda x: x.splitlines(), expect="PONG",
@@ -145,7 +147,7 @@ class SendMessageTests(unittest.TestCase):
		Check that a response of 'FAIL' causes CommandFailed to be raised
		"""
		async with self.client as client:
			client.sock.recv.return_value = b"FAIL"
			client.sock.receive.return_value = b"FAIL"
			with self.assertRaises(errors.CommandFailed):
				await client.send_command("SOME_COMMAND")

@@ -155,27 +157,17 @@ class SendMessageTests(unittest.TestCase):
		Check that a response of 'UNKNOWN COMMAND' causes ValueError to be raised
		"""
		async with self.client as client:
			client.sock.recv.return_value = b"UNKNOWN COMMAND"
			client.sock.receive.return_value = b"UNKNOWN COMMAND"
			with self.assertRaises(ValueError):
				await client.send_command("SOME_COMMAND")

	@anyio_mock.with_anyio()
	async def test_simple_too_large(self):
		"""
		Check that MessageTooLargeError is raised if send() reports an incomplete send
		"""
		async with self.client as client:
			client.sock.send.side_effect = lambda b: len(b) / 2
			with self.assertRaises(errors.MessageTooLargeError):
				await client.send_command("SOME_COMMAND")

	@anyio_mock.with_anyio()
	async def test_interleaved(self):
		"""
		Check that messages are processed alongside replies
		"""
		async with self.client as client:
			client.sock.recv.side_effect = [
			client.sock.receive.side_effect = [
				b"<2>SOME-MESSAGE",
				b"<1>SOME-OTHER-MESSAGE with|args",
				b"OK",
@@ -189,7 +181,7 @@ class SendMessageTests(unittest.TestCase):
		Check that unexpected replies are logged cleanly
		"""
		async with self.client as client:
			client.sock.recv.side_effect = [
			client.sock.receive.side_effect = [
				b"OK",  # Response to "ATTACH"
				b"UNEXPECTED1",
				b"UNEXPECTED2",
@@ -205,20 +197,18 @@ class EventTests(unittest.TestCase):
	"""

	def setUp(self):
		async def _make_client():
			return base.BaseClient()

		self.client = client = anyio.run(_make_client)
		self.client = client = base.BaseClient()
		client.sock = anyio_mock.AsyncMock()
		client.sock.send.side_effect = len
		client.sock.send.return_value = None

	@anyio_mock.with_anyio()
	async def test_simple(self):
		"""
		Check that an awaited message is returned when is arrives
		"""
		async with self.client as client, anyio.fail_after(2):
			client.sock.recv.side_effect = [
		with anyio.fail_after(2):
			async with self.client as client:
				client.sock.receive.side_effect = [
					b"OK",  # Respond to ATTACH
					b"<2>CTRL-EVENT-EXAMPLE",
					b"OK",  # Respond to DETACH
@@ -233,8 +223,9 @@ class EventTests(unittest.TestCase):
		"""
		Check that an awaited messages is returned when it arrives between others
		"""
		async with self.client as client, anyio.fail_after(2):
			client.sock.recv.side_effect = [
		with anyio.fail_after(2):
			async with self.client as client:
				client.sock.receive.side_effect = [
					b"OK",  # Respond to ATTACH
					b"<1>OTHER-MESSAGE",
					b"<2>CTRL-EVENT-OTHER",
@@ -252,8 +243,9 @@ class EventTests(unittest.TestCase):
		"""
		Check that the first of several awaited events is returned
		"""
		async with self.client as client, anyio.fail_after(2):
			client.sock.recv.side_effect = [
		with anyio.fail_after(2):
			async with self.client as client:
				client.sock.receive.side_effect = [
					b"OK",  # Respond to ATTACH
					b"<1>OTHER-MESSAGE",
					b"<2>CTRL-EVENT-OTHER",
@@ -274,8 +266,9 @@ class EventTests(unittest.TestCase):
		"""
		Check that messages are processed as well as replies
		"""
		async with self.client as client, anyio.fail_after(2):
			client.sock.recv.side_effect = [
		with anyio.fail_after(2):
			async with self.client as client:
				client.sock.receive.side_effect = [
					b"<1>OTHER-MESSAGE",
					b"OK",  # Respond to SOME_COMMAND
					b"OK",  # Respond to ATTACH
+6 −11
Original line number Diff line number Diff line
@@ -19,8 +19,6 @@ Test cases for wpa_supplicant.client.interfaces.InterfaceClient
import unittest
from unittest.mock import call

import anyio

from tests.unit import _anyio as anyio_mock
from wpa_supplicant import config
from wpa_supplicant.client import interfaces
@@ -32,12 +30,9 @@ class MethodsTests(unittest.TestCase):
	"""

	def setUp(self):
		async def _make_client():
			return interfaces.InterfaceClient()

		self.client = client = anyio.run(_make_client)
		self.client = client = interfaces.InterfaceClient()
		client.sock = anyio_mock.AsyncMock()
		client.sock.send.side_effect = len
		client.sock.send.return_value = None

	@anyio_mock.with_anyio()
	async def test_scan(self):
@@ -45,7 +40,7 @@ class MethodsTests(unittest.TestCase):
		Check that a scan command waits for a notification then terminates correctly
		"""
		async with self.client as client:
			client.sock.recv.side_effect = [
			client.sock.receive.side_effect = [
				b"OK",  # Response to "ATTACH"
				b"OK",  # Response to "SCAN"
				b"<3>CTRL-EVENT-SCAN-RESULTS",
@@ -65,7 +60,7 @@ class MethodsTests(unittest.TestCase):
		Check that set_network sends values to the daemon and raises TypeError for bad types
		"""
		async with self.client as client:
			client.sock.recv.return_value = b"OK"
			client.sock.receive.return_value = b"OK"
			send = client.sock.send

			with self.subTest("good string"):
@@ -79,7 +74,7 @@ class MethodsTests(unittest.TestCase):
				send.reset_mock()

			with self.subTest("good enum"):
				await client.set_network("0", "key_mgmt", config.KeyManagementValue.WPA_PSK)
				await client.set_network("0", "key_mgmt", config.KeyManagementValue.WPA_PSK)  # type: ignore
				send.assert_called_once_with(b"SET_NETWORK 0 key_mgmt WPA-PSK")
				send.reset_mock()

@@ -106,7 +101,7 @@ class MethodsTests(unittest.TestCase):
		"""
		async with self.client as client:
			send = client.sock.send
			client.sock.recv.side_effect = [
			client.sock.receive.side_effect = [
				b"0",
				b"OK",
				b"OK",
Loading