From a31e277a1c2a7ee5a57fe6b18fef7ef15695c277 Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Thu, 7 Dec 2023 11:41:32 +0100 Subject: [PATCH] Switch from pytest to unittest (#33) This saves a dev dependency which sometimes drops support for Python versions in minor versions. --- .github/workflows/ci.yaml | 15 +- .gitignore | 17 +- poetry.lock | 123 +----- pyproject.toml | 4 +- test_wakeonlan.py | 772 +++++++++++++++++++++----------------- 5 files changed, 439 insertions(+), 492 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 259c32a..32cac5b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -54,7 +54,7 @@ jobs: - run: poetry install - run: poetry run mypy . - pytest: + unittest: runs-on: ubuntu-latest strategy: matrix: @@ -70,13 +70,20 @@ jobs: python-version: ${{ matrix.python-version }} - run: pip install poetry - run: poetry install - - run: poetry run pytest --cov --cov-report=xml + - run: poetry run coverage run + - run: poetry run coverage report + - run: poetry run coverage lcov - uses: codecov/codecov-action@v3 if: ${{ matrix.python-version == '3.10' }} publish: runs-on: ubuntu-latest - needs: [black, build, flake8, mypy, pytest] + needs: + - black + - build + - flake8 + - mypy + - unittest if: startsWith(github.ref, 'refs/tags/') steps: - uses: actions/download-artifact@v3 @@ -86,4 +93,4 @@ jobs: - uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} \ No newline at end of file + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.gitignore b/.gitignore index 743fd44..3ec005b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,6 @@ -*.pyc -*.egg-info/ -/.coverage -/.eggs/ -/.mypy_cache/ -/.pytest_cache/ -/.tox/ -/build/ -/CHANGELOG.md -/dist/ -/docs/_build -/MANIFEST +.coverage +*.lcov +.mypy_cache/ __pycache__/ +_build/ +dist/ diff --git a/poetry.lock b/poetry.lock index 1c848f9..7372c35 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "black" @@ -146,20 +146,6 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] -[[package]] -name = "exceptiongroup" -version = "1.1.3" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, - {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, -] - -[package.extras] -test = ["pytest (>=6)"] - [[package]] name = "flake8" version = "5.0.4" @@ -206,37 +192,6 @@ files = [ pycodestyle = "*" setuptools = "*" -[[package]] -name = "importlib-metadata" -version = "6.7.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5"}, - {file = "importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4"}, -] - -[package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - [[package]] name = "mccabe" version = "0.7.0" @@ -342,24 +297,6 @@ files = [ docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] -[[package]] -name = "pluggy" -version = "1.2.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - [[package]] name = "pycodestyle" version = "2.9.1" @@ -399,47 +336,6 @@ files = [ {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, ] -[[package]] -name = "pytest" -version = "7.4.0" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, - {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-cov" -version = "4.1.0" -description = "Pytest plugin for measuring coverage." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, - {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, -] - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] - [[package]] name = "setuptools" version = "68.1.0" @@ -500,22 +396,7 @@ files = [ {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, ] -[[package]] -name = "zipp" -version = "3.15.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.7" -files = [ - {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, - {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "5ba876b81170d8243f702371422f4ca2a57f2ac0e6576e0921d73b4c49477b27" +content-hash = "ea6ff9ba19085111b386e22de2e41ce95797d96f2a60dd65c3f217be68902e4c" diff --git a/pyproject.toml b/pyproject.toml index 56e0ca2..0007ffa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,16 +28,16 @@ python = "^3.7" [tool.poetry.dev-dependencies] black = { version = "*", python = ">= 3.8" } +coverage = { version = "*", extras = ["toml"] } flake8 = { version = "*", python = ">= 3.8" } flake8-docstrings = { version = "*", python = ">= 3.8" } flake8-import-order = { version = "*", python = ">= 3.8" } mypy = { version = "*", python = ">=3.8" } -pytest = "*" -pytest-cov = "*" types-setuptools = { version = "*", python = ">=3.8" } [tool.coverage.run] branch = true +command_line = "-m unittest -v" source = ["wakeonlan"] [tool.coverage.report] diff --git a/test_wakeonlan.py b/test_wakeonlan.py index 235c775..c5fa6a9 100644 --- a/test_wakeonlan.py +++ b/test_wakeonlan.py @@ -3,23 +3,28 @@ """ import socket -from typing import List -from unittest.mock import Mock -from unittest.mock import call -from unittest.mock import patch - -import pytest +import unittest +from unittest import mock from wakeonlan import create_magic_packet from wakeonlan import main from wakeonlan import send_magic_packet -@pytest.mark.parametrize( - "mac,packet", - [ - ( - "000000000000", +class TestCreateMagicPacket(unittest.TestCase): + """ + Test :ref:`create_magic_packet`. + + """ + + def test_no_separators(self) -> None: + """ + Test without separators. + + """ + result = create_magic_packet("000000000000") + self.assertEqual( + result, b"\xff\xff\xff\xff\xff\xff" b"\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00" @@ -37,9 +42,16 @@ b"\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00", - ), - ( - "01:23:45:67:89:ab", + ) + + def test_colon(self) -> None: + """ + Test with a colon as separator. + + """ + result = create_magic_packet("01:23:45:67:89:ab") + self.assertEqual( + result, b"\xff\xff\xff\xff\xff\xff" b"\x01#Eg\x89\xab" b"\x01#Eg\x89\xab" @@ -57,9 +69,16 @@ b"\x01#Eg\x89\xab" b"\x01#Eg\x89\xab" b"\x01#Eg\x89\xab", - ), - ( - "ff-ff-ff-ff-ff-ff", + ) + + def test_hyphen(self) -> None: + """ + Test with a hyphen as separator. + + """ + result = create_magic_packet("ff-ff-ff-ff-ff-ff") + self.assertEqual( + result, b"\xff\xff\xff\xff\xff\xff" b"\xff\xff\xff\xff\xff\xff" b"\xff\xff\xff\xff\xff\xff" @@ -77,9 +96,16 @@ b"\xff\xff\xff\xff\xff\xff" b"\xff\xff\xff\xff\xff\xff" b"\xff\xff\xff\xff\xff\xff", - ), - ( - "ffff.ffff.ffff", + ) + + def test_dot(self) -> None: + """ + Test with a dot as separator. + + """ + result = create_magic_packet("ffff.ffff.ffff") + self.assertEqual( + result, b"\xff\xff\xff\xff\xff\xff" b"\xff\xff\xff\xff\xff\xff" b"\xff\xff\xff\xff\xff\xff" @@ -97,356 +123,396 @@ b"\xff\xff\xff\xff\xff\xff" b"\xff\xff\xff\xff\xff\xff" b"\xff\xff\xff\xff\xff\xff", - ), - ], - ids=["no separator", "colons", "hyphens", "dots"], -) -def test_create_magic_packet(mac: str, packet: List[int]) -> None: - """ - Test whether a correct magic packet is created. - - """ - result = create_magic_packet(mac) - assert result == packet + ) -@patch("socket.socket") -def test_send_magic_packet(sock: Mock) -> None: +class TestSendMagicPacket(unittest.TestCase): """ - Test whether the magic packets are broadcasted to the specified network. + Test :ref:`send_magic_packet`. """ - send_magic_packet( - "133713371337", "00-00-00-00-00-00", ip_address="example.com", port=7 - ) - assert sock.mock_calls == [ - call(socket.AF_INET, socket.SOCK_DGRAM), - call().__enter__(), - call().__enter__().setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1), - call().__enter__().connect(("example.com", 7)), - call() - .__enter__() - .send( - b"\xff\xff\xff\xff\xff\xff" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - ), - call() - .__enter__() - .send( - b"\xff\xff\xff\xff\xff\xff" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - ), - call().__exit__(None, None, None), - ] + @mock.patch("socket.socket") + def test_send_magic_packet(self, sock: mock.Mock) -> None: + """ + Test whether the magic packets are broadcasted to the specified network. -@patch("socket.socket") -def test_send_magic_packet_default(sock: Mock) -> None: - """ - Test whether the magic packets are broadcasted using default values. + """ + send_magic_packet( + "133713371337", "00-00-00-00-00-00", ip_address="example.com", port=7 + ) + self.assertEqual( + sock.mock_calls, + [ + mock.call(socket.AF_INET, socket.SOCK_DGRAM), + mock.call().__enter__(), + mock.call() + .__enter__() + .setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1), + mock.call().__enter__().connect(("example.com", 7)), + mock.call() + .__enter__() + .send( + b"\xff\xff\xff\xff\xff\xff" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + ), + mock.call() + .__enter__() + .send( + b"\xff\xff\xff\xff\xff\xff" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + ), + mock.call().__exit__(None, None, None), + ], + ) - """ - send_magic_packet("133713371337", "00-00-00-00-00-00") - assert sock.mock_calls == [ - call(socket.AF_INET, socket.SOCK_DGRAM), - call().__enter__(), - call().__enter__().setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1), - call().__enter__().connect(("255.255.255.255", 9)), - call() - .__enter__() - .send( - b"\xff\xff\xff\xff\xff\xff" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - ), - call() - .__enter__() - .send( - b"\xff\xff\xff\xff\xff\xff" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - ), - call().__exit__(None, None, None), - ] + @mock.patch("socket.socket") + def test_send_magic_packet_default(self, sock: mock.Mock) -> None: + """ + Test whether the magic packets are broadcasted using default values. + """ + send_magic_packet("133713371337", "00-00-00-00-00-00") + self.assertEqual( + sock.mock_calls, + [ + mock.call(socket.AF_INET, socket.SOCK_DGRAM), + mock.call().__enter__(), + mock.call() + .__enter__() + .setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1), + mock.call().__enter__().connect(("255.255.255.255", 9)), + mock.call() + .__enter__() + .send( + b"\xff\xff\xff\xff\xff\xff" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + ), + mock.call() + .__enter__() + .send( + b"\xff\xff\xff\xff\xff\xff" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + ), + mock.call().__exit__(None, None, None), + ], + ) -@patch("socket.socket") -def test_send_magic_packet_interface(sock: Mock) -> None: - """ - Test whether the magic packets are broadcasted to the specified network via specified interface. + @mock.patch("socket.socket") + def test_send_magic_packet_interface(self, sock: mock.Mock) -> None: + """ + Test whether the magic packets are broadcasted to the specified network via specified interface. - """ - send_magic_packet( - "133713371337", - "00-00-00-00-00-00", - ip_address="example.com", - port=7, - interface="192.168.0.2", - ) - assert sock.mock_calls == [ - call(socket.AF_INET, socket.SOCK_DGRAM), - call().__enter__(), - call().__enter__().bind(("192.168.0.2", 0)), - call().__enter__().setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1), - call().__enter__().connect(("example.com", 7)), - call() - .__enter__() - .send( - b"\xff\xff\xff\xff\xff\xff" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - ), - call() - .__enter__() - .send( - b"\xff\xff\xff\xff\xff\xff" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - ), - call().__exit__(None, None, None), - ] + """ + send_magic_packet( + "133713371337", + "00-00-00-00-00-00", + ip_address="example.com", + port=7, + interface="192.168.0.2", + ) + self.assertEqual( + sock.mock_calls, + [ + mock.call(socket.AF_INET, socket.SOCK_DGRAM), + mock.call().__enter__(), + mock.call().__enter__().bind(("192.168.0.2", 0)), + mock.call() + .__enter__() + .setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1), + mock.call().__enter__().connect(("example.com", 7)), + mock.call() + .__enter__() + .send( + b"\xff\xff\xff\xff\xff\xff" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + ), + mock.call() + .__enter__() + .send( + b"\xff\xff\xff\xff\xff\xff" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + ), + mock.call().__exit__(None, None, None), + ], + ) + @mock.patch("socket.socket") + def test_send_correct_af_chosen_with_ipv6_address(self, sock: mock.Mock) -> None: + """ + Test whether AF_INET6 automatically chosen when the `address_family` argument is not given. + """ + send_magic_packet( + "133713371337", + "00-00-00-00-00-00", + ip_address="fc00::", + port=7, + ) + self.assertEqual( + sock.mock_calls, + [ + mock.call(socket.AF_INET6, socket.SOCK_DGRAM), + mock.call().__enter__(), + mock.call() + .__enter__() + .setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1), + mock.call().__enter__().connect(("fc00::", 7)), + mock.call() + .__enter__() + .send( + b"\xff\xff\xff\xff\xff\xff" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + ), + mock.call() + .__enter__() + .send( + b"\xff\xff\xff\xff\xff\xff" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + ), + mock.call().__exit__(None, None, None), + ], + ) -@patch("socket.socket") -def test_send_correct_af_chosen_with_ipv6_address(sock: Mock) -> None: - """ - Test whether AF_INET6 automatically chosen when the `address_family` argument is not given. - """ - send_magic_packet( - "133713371337", - "00-00-00-00-00-00", - ip_address="fc00::", - port=7, - ) - assert sock.mock_calls == [ - call(socket.AF_INET6, socket.SOCK_DGRAM), - call().__enter__(), - call().__enter__().setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1), - call().__enter__().connect(("fc00::", 7)), - call() - .__enter__() - .send( - b"\xff\xff\xff\xff\xff\xff" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - ), - call() - .__enter__() - .send( - b"\xff\xff\xff\xff\xff\xff" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - ), - call().__exit__(None, None, None), - ] + @mock.patch("socket.socket") + def test_send_with_explicit_ipv6_address(self, sock: mock.Mock) -> None: + """ + Test whether the given address family is used instead automatically it automatically. + """ + send_magic_packet( + "133713371337", + "00-00-00-00-00-00", + ip_address="example.com", + port=7, + address_family=socket.AF_INET6, + ) + self.assertEqual( + sock.mock_calls, + [ + mock.call(socket.AF_INET6, socket.SOCK_DGRAM), + mock.call().__enter__(), + mock.call() + .__enter__() + .setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1), + mock.call().__enter__().connect(("example.com", 7)), + mock.call() + .__enter__() + .send( + b"\xff\xff\xff\xff\xff\xff" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + b"\x137\x137\x137" + ), + mock.call() + .__enter__() + .send( + b"\xff\xff\xff\xff\xff\xff" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00" + ), + mock.call().__exit__(None, None, None), + ], + ) -@patch("socket.socket") -def test_send_with_explicit_ipv6_address(sock: Mock) -> None: +class TestMain(unittest.TestCase): """ - Test whether the given address family is used instead automatically it automatically. + Test :ref:`main`. + """ - send_magic_packet( - "133713371337", - "00-00-00-00-00-00", - ip_address="example.com", - port=7, - address_family=socket.AF_INET6, - ) - assert sock.mock_calls == [ - call(socket.AF_INET6, socket.SOCK_DGRAM), - call().__enter__(), - call().__enter__().setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1), - call().__enter__().connect(("example.com", 7)), - call() - .__enter__() - .send( - b"\xff\xff\xff\xff\xff\xff" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - b"\x137\x137\x137" - ), - call() - .__enter__() - .send( - b"\xff\xff\xff\xff\xff\xff" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00" - ), - call().__exit__(None, None, None), - ] + @mock.patch("wakeonlan.send_magic_packet") + def test_main(self, send_magic_packet: mock.Mock) -> None: + """ + Test if processed arguments are passed to send_magic_packet. -@patch("wakeonlan.send_magic_packet") -def test_main(send_magic_packet: Mock) -> None: - """ - Test if processed arguments are passed to send_magic_packet. + """ + main(["00:11:22:33:44:55", "-i", "host.example", "-p", "1337"]) + main( + [ + "00:11:22:33:44:55", + "-i", + "host.example", + "-p", + "1337", + "-n", + "192.168.0.2", + ] + ) + main(["00:11:22:33:44:55", "-i", "host.example", "-p", "1337", "-6"]) + self.assertEqual( + send_magic_packet.mock_calls, + [ + mock.call( + "00:11:22:33:44:55", + ip_address="host.example", + port=1337, + interface=None, + address_family=None, + ), + mock.call( + "00:11:22:33:44:55", + ip_address="host.example", + port=1337, + interface="192.168.0.2", + address_family=None, + ), + mock.call( + "00:11:22:33:44:55", + ip_address="host.example", + port=1337, + interface=None, + address_family=socket.AF_INET6, + ), + ], + ) - """ - main(["00:11:22:33:44:55", "-i", "host.example", "-p", "1337"]) - main(["00:11:22:33:44:55", "-i", "host.example", "-p", "1337", "-n", "192.168.0.2"]) - main(["00:11:22:33:44:55", "-i", "host.example", "-p", "1337", "-6"]) - assert send_magic_packet.mock_calls == [ - call( - "00:11:22:33:44:55", - ip_address="host.example", - port=1337, - interface=None, - address_family=None, - ), - call( - "00:11:22:33:44:55", - ip_address="host.example", - port=1337, - interface="192.168.0.2", - address_family=None, - ), - call( - "00:11:22:33:44:55", - ip_address="host.example", - port=1337, - interface=None, - address_family=socket.AF_INET6, - ), - ] + +if __name__ == "__main__": + unittest.main()