Skip to content

Commit

Permalink
feat(wifi): the wireless onboarding suggestion notification is shown …
Browse files Browse the repository at this point in the history
…when the device is not connected to any network and it hasn't been shown earlier #71

feat(notifications): `actions` of `Notification` object are respected and are actually shown in the notification, their type is inheriting the original `ActionItem` and adds `dismiss_notification` boolean to it
feat(tests): stability fixture saves all the snapshots and writes them to the filesystem if it ever fails
feat(core): setup error handler for event loops, previously errors happening in event loops were silence
refactor: all `asyncio.create_subprocess_exec` calls now redirect their `STDOUT` and `STDERR` to `DEVNULL` or `PIPE` to avoid noise in output
  • Loading branch information
sassanh committed May 6, 2024
1 parent 083aedc commit dbaa13d
Show file tree
Hide file tree
Showing 66 changed files with 665 additions and 363 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/integration_delivery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ jobs:
- images
runs-on: ubuntu-latest
environment:
name: release
name: pypi
url: https://pypi.org/p/${{ needs.build.outputs.name }}
permissions:
id-token: write
Expand Down Expand Up @@ -391,7 +391,9 @@ jobs:
runs-on: ubuntu-latest
environment:
name: release
url: https://pypi.org/p/${{ needs.build.outputs.name }}
url:
https://github.com/${{ github.repository }}/releases/tag/v${{
needs.build.outputs.version }}
permissions:
contents: write
steps:
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# ChangeLog

## Version 0.14.0

- feat(wifi): the wireless onboarding suggestion notification is shown when the
device is not connected to any network and it hasn't been shown earlier #71
- feat(notifications): `actions` of `Notification` object are respected and are
actually shown in the notification, their type is inheriting the original `ActionItem`
and adds `dismiss_notification` boolean to it
- feat(tests): stability fixture saves all the snapshots and writes them to the filesystem
if it ever fails
- feat(core): setup error handler for event loops, previously errors happening in
event loops were silence
- refactor: all `asyncio.create_subprocess_exec` calls now redirect their `STDOUT`
and `STDERR` to `DEVNULL` or `PIPE` to avoid noise in output

## Version 0.13.5

- feat(vscode): add vscode tunnel support: users can download the cli binary, login,
Expand Down
175 changes: 87 additions & 88 deletions poetry.lock

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "ubo-app"
version = "0.13.5"
version = "0.14.0"
description = "Ubo main app, running on device initialization. A platform for running other apps."
authors = ["Sassan Haradji <sassanh@gmail.com>"]
license = "Apache-2.0"
Expand All @@ -18,14 +18,14 @@ priority = "primary"
python = "^3.11"
psutil = "^5.9.8"
ubo-gui = [
{ version = "^0.11.3", markers = "extra=='default'", extras = [
{ version = "^0.11.5", markers = "extra=='default'", extras = [
"default",
] },
{ version = "^0.11.3", markers = "extra=='dev'", extras = [
{ version = "^0.11.5", markers = "extra=='dev'", extras = [
"dev",
] },
]
python-redux = "^0.14.4"
python-redux = "^0.15.2"
pyzbar = "^0.1.9"
sdbus-networkmanager = { version = "^2.0.0", markers = "platform_machine=='aarch64'" }
rpi_ws281x = { version = "^5.0.0", markers = "platform_machine=='aarch64'" }
Expand Down
4 changes: 3 additions & 1 deletion scripts/Dockerfile.test
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
FROM ubo-app-dev

ENTRYPOINT ["/bin/bash", "-c", "poetry install --with dev --extras=dev --verbose && poetry run poe test $@"]
RUN mkdir -p /root/.kivy/mods

ENTRYPOINT ["/bin/bash", "-c", "reset; poetry install --with dev --extras=dev --verbose && poetry run poe test $@"]

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

25 changes: 11 additions & 14 deletions tests/fixtures/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import asyncio
import gc
import json
import logging
import sys
import weakref
Expand Down Expand Up @@ -59,25 +58,21 @@ async def clean_up(self: AppContext) -> None:

if app is not None and self.request.session.testsfailed == 0:
logging.getLogger().debug(
'Memory leak: failed to release app for test.\n'
+ json.dumps(
{
'refcount': sys.getrefcount(app),
'referrers': gc.get_referrers(app),
'ref': app_ref,
},
sort_keys=True,
indent=2,
default=str,
),
'Memory leak: failed to release app for test.',
extra={
'refcount': sys.getrefcount(app),
'referrers': gc.get_referrers(app),
'ref': app_ref,
},
)
gc.collect()
for cell in gc.get_referrers(app):
if type(cell).__name__ == 'cell':
from ubo_app.utils.garbage_collection import examine

logging.getLogger().debug(
'CELL EXAMINATION\n' + json.dumps({'cell': cell}),
'CELL EXAMINATION',
extra={'cell': cell},
)
examine(cell, depth_limit=2)
assert app is None, 'Memory leak: failed to release app for test'
Expand All @@ -93,7 +88,9 @@ async def clean_up(self: AppContext) -> None:


@pytest.fixture()
async def app_context(request: SubRequest) -> AsyncGenerator[AppContext, None]:
async def app_context(
request: SubRequest,
) -> AsyncGenerator[AppContext, None]:
"""Create the application."""
import os

Expand Down
47 changes: 40 additions & 7 deletions tests/fixtures/stability.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,29 @@

from __future__ import annotations

from typing import TYPE_CHECKING, TypeAlias
from typing import TYPE_CHECKING, Protocol

import pytest
from redux_pytest.fixtures.wait_for import AsyncWaiter, WaitFor
from tenacity import stop_after_delay, wait_fixed
from tenacity import RetryError, stop_after_delay, wait_fixed

from tests.fixtures.snapshot import write_image

if TYPE_CHECKING:
from redux_pytest.fixtures import StoreSnapshot
from redux_pytest.fixtures.wait_for import AsyncWaiter, WaitFor

from .snapshot import WindowSnapshot

Stability: TypeAlias = AsyncWaiter

class Stability(Protocol):
"""Fixture for waiting for the screen and store to stabilize."""

async def __call__(
self: Stability,
timeout: float | None = None,
) -> AsyncWaiter:
"""Wait for the screen and store to stabilize."""
...


@pytest.fixture()
Expand All @@ -24,11 +35,19 @@ async def stability(
) -> AsyncWaiter:
"""Wait for the screen and store to stabilize."""

async def wrapper() -> None:
async def wrapper(
timeout: float | None = None,
) -> None:
latest_window_hash = None
latest_store_snapshot = None

@wait_for(run_async=True, wait=wait_fixed(1), stop=stop_after_delay(4))
snapshots = []

@wait_for(
run_async=True,
wait=wait_fixed(1),
stop=stop_after_delay(timeout or 4),
)
def check() -> None:
nonlocal latest_window_hash, latest_store_snapshot

Expand All @@ -41,9 +60,23 @@ def check() -> None:
latest_window_hash = new_hash
latest_store_snapshot = new_snapshot

if not is_window_stable:
from headless_kivy_pi.config import _display

snapshots.append(_display.raw_data.copy())

assert is_window_stable, 'The content of the screen is not stable yet'
assert is_store_stable, 'The content of the store is not stable yet'

await check()
try:
await check()
except RetryError:
for i, snapshot in enumerate(snapshots):
write_image(
window_snapshot.results_dir
/ f'window-unstability_snapshot_{i}.mismatch.png',
snapshot,
)
raise

return wrapper
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"wifi": {
"connections": [],
"current_connection": null,
"has_visited_onboarding": true,
"state": "Disconnected"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@
"wifi": {
"connections": [],
"current_connection": null,
"has_visited_onboarding": true,
"state": "Disconnected"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@
"wifi": {
"connections": [],
"current_connection": null,
"has_visited_onboarding": true,
"state": "Disconnected"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@
"wifi": {
"connections": [],
"current_connection": null,
"has_visited_onboarding": true,
"state": "Disconnected"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@
"wifi": {
"connections": [],
"current_connection": null,
"has_visited_onboarding": true,
"state": "Disconnected"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@
"wifi": {
"connections": [],
"current_connection": null,
"has_visited_onboarding": true,
"state": "Disconnected"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@
"wifi": {
"connections": [],
"current_connection": null,
"has_visited_onboarding": true,
"state": "Disconnected"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@
"wifi": {
"connections": [],
"current_connection": null,
"has_visited_onboarding": true,
"state": "Disconnected"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@
"wifi": {
"connections": [],
"current_connection": null,
"has_visited_onboarding": true,
"state": "Disconnected"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// window-001
f1408407725c92709839ffff687fde751ff2236755ecb02569353434d4e2a57a
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// window-002
79dcd5a068687edebfd31ad2045e32a5ef30850e1dc1b55965d4eb3e6651c54f
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// window-003
db544ca147494bc920b9923822f08f395e7930523461f3a0b3efbbddfa873cdf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// window-004
8f78c4b9f9c2f78498aeee2ed3959b003d02140488adb134adf70fb658ee41e0
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// window-006
8f78c4b9f9c2f78498aeee2ed3959b003d02140488adb134adf70fb658ee41e0
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -12,69 +12,48 @@
"container_ip": null,
"docker_id": null,
"id": "home_assistant",
"ip_addresses": [
"192.168.1.1"
],
"ports": [],
"status": "not_available"
},
"home_bridge": {
"container_ip": null,
"docker_id": null,
"id": "home_bridge",
"ip_addresses": [
"192.168.1.1"
],
"ports": [],
"status": "not_available"
},
"ngrok": {
"container_ip": null,
"docker_id": null,
"id": "ngrok",
"ip_addresses": [
"192.168.1.1"
],
"ports": [],
"status": "not_available"
},
"ollama": {
"container_ip": null,
"docker_id": null,
"id": "ollama",
"ip_addresses": [
"192.168.1.1"
],
"ports": [],
"status": "not_available"
},
"open_webui": {
"container_ip": null,
"docker_id": null,
"id": "open_webui",
"ip_addresses": [
"192.168.1.1"
],
"ports": [],
"status": "not_available"
},
"pi_hole": {
"container_ip": null,
"docker_id": null,
"id": "pi_hole",
"ip_addresses": [
"192.168.1.1"
],
"ports": [],
"status": "not_available"
},
"portainer": {
"container_ip": null,
"docker_id": null,
"id": "portainer",
"ip_addresses": [
"192.168.1.1"
],
"ports": [],
"status": "not_available"
},
Expand All @@ -91,7 +70,8 @@
],
"name": "eth0"
}
]
],
"is_connected": true
},
"lightdm": {
"is_active": true,
Expand Down Expand Up @@ -612,6 +592,7 @@
"wifi": {
"connections": [],
"current_connection": null,
"has_visited_onboarding": true,
"state": "Disconnected"
}
}
Loading

0 comments on commit dbaa13d

Please sign in to comment.