Skip to content

Commit

Permalink
1.10.0 (#501)
Browse files Browse the repository at this point in the history
* Bump codecov/codecov-action from 4.3.0 to 4.3.1 (#491)

Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](codecov/codecov-action@v4.3.0...v4.3.1)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump actions/checkout from 4.1.5 to 4.1.6 (#496)

Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.5 to 4.1.6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4.1.5...v4.1.6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump codecov/codecov-action from 4.3.1 to 4.4.0 (#495)

Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.3.1 to 4.4.0.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](codecov/codecov-action@v4.3.1...v4.4.0)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Move the module imports into separate thread (#497)

* Improve exception messages in the connection module (#498)

* Bump codecov/codecov-action from 4.4.0 to 4.4.1 (#500)

Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.4.0 to 4.4.1.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](codecov/codecov-action@v4.4.0...v4.4.1)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Add AiMesh reboot (#499)

* Bump version to `1.10.0`

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
Vaskivskyi and dependabot[bot] authored May 21, 2024
1 parent 221802b commit bb41434
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 17 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
pip_cache_dir: ${{ steps.pip-cache.outputs.dir }}
steps:
- name: Checkout
uses: actions/[email protected].4
uses: actions/[email protected].5

- name: Set up Python ${{ matrix.python-version }}
uses: actions/[email protected]
Expand Down Expand Up @@ -60,7 +60,7 @@ jobs:
python-version: [3.11, 3.12]
steps:
- name: Checkout
uses: actions/[email protected].4
uses: actions/[email protected].5

- name: Set up Python ${{ matrix.python-version }}
uses: actions/[email protected]
Expand Down Expand Up @@ -106,7 +106,7 @@ jobs:
python-version: [3.11, 3.12]
steps:
- name: Checkout
uses: actions/[email protected].4
uses: actions/[email protected].5

- name: Set up Python ${{ matrix.python-version }}
uses: actions/[email protected]
Expand Down Expand Up @@ -152,7 +152,7 @@ jobs:
python-version: [3.11, 3.12]
steps:
- name: Checkout
uses: actions/[email protected].4
uses: actions/[email protected].5

- name: Download unit-tests coverage from artifacts
uses: actions/[email protected]
Expand All @@ -167,7 +167,7 @@ jobs:
path: .

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4.3.0
uses: codecov/codecov-action@v4.4.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

steps:
- name: Checkout the repository
uses: actions/[email protected].4
uses: actions/[email protected].6
with:
ref: ${{ github.event.release.target_commitish }}

Expand Down
11 changes: 7 additions & 4 deletions asusrouter/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,9 @@ async def async_connect(
await asyncio.sleep(DEFAULT_TIMEOUTS[retry])
return await self.async_connect(retry + 1, asyncio.Lock())
raise AsusRouterTimeoutError(
f"Reached maximum allowed timeout\
for a single connection attempt: {sum(DEFAULT_TIMEOUTS)}"
f"Reached maximum allowed timeout \
for a single connection attempt: {sum(DEFAULT_TIMEOUTS)}. \
The last error: {ex}"
) from ex
except Exception as ex: # pylint: disable=broad-except
_LOGGER.debug("Error while connecting to %s: %s", self._hostname, ex)
Expand Down Expand Up @@ -223,11 +224,13 @@ async def _send_request(
except aiohttp.ClientConnectorError as ex:
self.reset_connection()
raise AsusRouterConnectionError(
f"Cannot connect to {self._hostname}. Failed in `_send_request`"
f"Cannot connect to `{self._hostname}` on port `{self._port}`. \
Failed in `_send_request` with error: `{ex}`"
) from ex
except (aiohttp.ClientConnectionError, aiohttp.ClientOSError) as ex:
raise AsusRouterConnectionError(
f"Cannot connect to {self._hostname}. Failed in `_send_request`"
f"Cannot connect to `{self._hostname}` on port `{self._port}`. \
Failed in `_send_request` with error: `{ex}`"
) from ex
except Exception as ex: # pylint: disable=broad-except
raise ex
Expand Down
9 changes: 7 additions & 2 deletions asusrouter/modules/endpoint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import importlib
import logging
from concurrent.futures import ThreadPoolExecutor
from enum import Enum
from types import ModuleType
from typing import Any, Awaitable, Callable, Optional
Expand Down Expand Up @@ -57,8 +58,12 @@ def _get_module(endpoint: Endpoint | EndpointControl) -> Optional[ModuleType]:
try:
# Get the module name from the endpoint
module_name = f"asusrouter.modules.endpoint.{endpoint.name.lower()}"
# Import the module
submodule = importlib.import_module(module_name)

# Import the module in a separate thread to avoid blocking the main thread
with ThreadPoolExecutor(max_workers=1) as executor:
future = executor.submit(importlib.import_module, module_name)
submodule = future.result()

# Return the module
return submodule
except ModuleNotFoundError:
Expand Down
32 changes: 31 additions & 1 deletion asusrouter/modules/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

from __future__ import annotations

import logging
from enum import Enum
from typing import Any, Awaitable, Callable

_LOGGER = logging.getLogger(__name__)


class AsusSystem(str, Enum):
"""Asus system enum.
Expand All @@ -15,6 +18,12 @@ class AsusSystem(str, Enum):
Some services might not be tested and might not work as expected. Use with caution
and at your own risk."""

# ---------------------
# AiMesh
AIMESH_REBOOT = "device_reboot" # Restart router + all nodes
AIMESH_REBUILD = "re_reconnect" # Rebuild AiMesh
REBUILD_AIMESH = "_depr_re_reconnect" # Rebuild AiMesh / legacy name
# ---------------------
# Firmware
FIRMWARE_CHECK = "firmware_check" # Check for firmware update
# Firmware upgrade will upgrade the firmware to the latest version
Expand All @@ -23,7 +32,6 @@ class AsusSystem(str, Enum):
FIRMWARE_UPGRADE = "firmware_upgrade" # Firmware upgrade
PREPARE_CERT = "prepare_cert" # Prepare certificate
REBOOT = "reboot" # Reboot the router
REBUILD_AIMESH = "re_reconnect" # Rebuild AiMesh
RESTART_CHPASS = "restart_chpass"
RESTART_CLOUDSYNC = "restart_cloudsync" # AiCloud 2.0 sync
RESTART_CP = "restart_CP" # Captive Portal
Expand Down Expand Up @@ -90,8 +98,19 @@ class AsusSystem(str, Enum):
UPDATE_CLIENTS = "update_clients"


AsusSystemDeprecated = {
AsusSystem.REBUILD_AIMESH: (AsusSystem.AIMESH_REBUILD, None),
}


# Map AsusSystem special cases to service calls
STATE_MAP: dict[AsusSystem, dict[str, Any]] = {
AsusSystem.AIMESH_REBOOT: {
"service": None,
"arguments": {"action_mode": "device_reboot"},
"apply": False,
"expect_modify": False,
},
AsusSystem.FIRMWARE_CHECK: {
"service": None,
"arguments": {"action_mode": "firmware_check"},
Expand Down Expand Up @@ -120,6 +139,17 @@ async def set_state(
) -> bool:
"""Set the system state."""

if state in AsusSystemDeprecated:
repl_state, repl_ver = AsusSystemDeprecated[state]
message = f"Deprecated state `{state.name}` from `AsusSystem` \
enum used. Use `{repl_state.name}` instead"
if repl_ver:
message += f". This state will be removed in version {repl_ver}"
_LOGGER.warning(
message,
)
state = repl_state

# Get the arguments for the callback function based on the state
callback_args = STATE_MAP.get(
state,
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "asusrouter"
version = "1.9.0"
version = "1.10.0"
license = {text = "Apache-2.0"}
requires-python = ">=3.11.0"
readme = "README.md"
Expand Down
54 changes: 51 additions & 3 deletions tests/modules/test_system.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
"""Tests for the system module."""

from unittest.mock import AsyncMock
from unittest import mock

import pytest

from asusrouter.modules.system import STATE_MAP, AsusSystem, set_state
from asusrouter.modules.system import (
STATE_MAP,
AsusSystem,
AsusSystemDeprecated,
set_state,
)

async_callback = AsyncMock()
async_callback = mock.AsyncMock()


@pytest.mark.asyncio
Expand Down Expand Up @@ -34,3 +39,46 @@ async def test_set_state(state, expected_args):

# Reset the mock callback function
async_callback.reset_mock()


@pytest.mark.asyncio
@pytest.mark.parametrize(
"deprecated_state, repl_state, repl_ver",
[
(AsusSystem.REBUILD_AIMESH, AsusSystem.AIMESH_REBUILD, None),
(AsusSystem.REBUILD_AIMESH, AsusSystem.AIMESH_REBUILD, "1.0.0"),
],
)
async def test_set_state_deprecated(deprecated_state, repl_state, repl_ver):
"""Test set_state with a deprecated state."""

# Prepare the expected warning message
message = f"Deprecated state `{deprecated_state.name}` from `AsusSystem` \
enum used. Use `{repl_state.name}` instead"
if repl_ver is not None:
message += f". This state will be removed in version {repl_ver}"

# Prepare the expected arguments for the callback function
expected_args = STATE_MAP.get(
repl_state,
{
"service": repl_state.value,
"arguments": {},
"apply": True,
"expect_modify": False,
},
)

# Mock the AsusSystemDeprecated enum
with mock.patch.dict(
"asusrouter.modules.system.AsusSystemDeprecated",
{deprecated_state: (repl_state, repl_ver)},
):
# Test set_state with the deprecated state
with mock.patch("asusrouter.modules.system._LOGGER.warning") as mock_warning:
await set_state(async_callback, deprecated_state)
mock_warning.assert_called_once_with(message)
async_callback.assert_called_once_with(**expected_args)

# Reset the mock callback function
async_callback.reset_mock()

0 comments on commit bb41434

Please sign in to comment.