zwave-js-server-python/test/model/test_driver.py

393 lines
12 KiB
Python

"""Test the driver model."""
import json
import pytest
from zwave_js_server.const import LogLevel
from zwave_js_server.event import Event
from zwave_js_server.model import (
driver as driver_pkg,
log_config as log_config_pkg,
log_message as log_message_pkg,
)
from .. import load_fixture
def test_from_state(client, log_config):
"""Test from_state method."""
ws_msgs = load_fixture("basic_dump.txt").strip().split("\n")
driver = driver_pkg.Driver(
client, json.loads(ws_msgs[0])["result"]["state"], log_config
)
assert driver == driver_pkg.Driver(
client, json.loads(ws_msgs[0])["result"]["state"], log_config
)
assert driver != driver.controller.home_id
assert hash(driver) == hash(driver.controller.home_id)
for msg in ws_msgs[1:]:
msg = json.loads(msg)
assert msg["type"] == "event"
event = Event(type=msg["event"]["event"], data=msg["event"])
driver.receive_event(event)
assert len(driver.controller.nodes) == 8
async def test_update_log_config(driver, uuid4, mock_command):
"""Test update log config."""
# Update log level
ack_commands = mock_command(
{"command": "driver.update_log_config", "config": {"level": "error"}},
{"success": True},
)
assert (
await driver.async_update_log_config(
log_config_pkg.LogConfig(level=LogLevel.ERROR)
)
is None
)
assert len(ack_commands) == 1
assert ack_commands[0] == {
"command": "driver.update_log_config",
"config": {"level": "error"},
"messageId": uuid4,
}
# Update all parameters
ack_commands = mock_command(
{
"command": "driver.update_log_config",
"config": {
"enabled": True,
"level": "error",
"logToFile": True,
"filename": "/test.txt",
"forceConsole": True,
},
},
{"success": True},
)
assert (
await driver.async_update_log_config(
log_config_pkg.LogConfig(
enabled=True,
level=LogLevel.ERROR,
log_to_file=True,
filename="/test.txt",
force_console=True,
)
)
is None
)
assert len(ack_commands) == 2
assert ack_commands[1] == {
"command": "driver.update_log_config",
"config": {
"enabled": True,
"level": "error",
"logToFile": True,
"filename": "/test.txt",
"forceConsole": True,
},
"messageId": uuid4,
}
async def test_get_log_config(driver, uuid4, mock_command):
"""Test set value."""
ack_commands = mock_command(
{"command": "driver.get_log_config"},
{
"success": True,
"config": {
"enabled": True,
"level": "error",
"logToFile": False,
"filename": "/test.txt",
"forceConsole": False,
},
},
)
log_config = await driver.async_get_log_config()
assert len(ack_commands) == 1
assert ack_commands[0] == {"command": "driver.get_log_config", "messageId": uuid4}
assert log_config.enabled
assert log_config.level == LogLevel.ERROR
assert log_config.log_to_file is False
assert log_config.filename == "/test.txt"
assert log_config.force_console is False
async def test_listening_logs(client, driver, uuid4, mock_command):
"""Test listening to logs helpers."""
# Test that start listening to logs command is sent
ack_commands = mock_command(
{"command": "start_listening_logs"},
{"success": True},
)
await client.async_start_listening_logs()
assert len(ack_commands) == 1
assert ack_commands[0] == {
"command": "start_listening_logs",
"messageId": uuid4,
}
# Test that stop listening to logs command is sent
ack_commands = mock_command(
{"command": "stop_listening_logs"},
{"success": True},
)
await client.async_stop_listening_logs()
assert len(ack_commands) == 2
assert ack_commands[1] == {
"command": "stop_listening_logs",
"messageId": uuid4,
}
# Test receiving a log message event
event = Event(
type="logging",
data={
"source": "driver",
"event": "logging",
"formattedMessage": [
"2021-04-18T18:03:34.051Z CNTRLR [Node 005] [~] \n",
"test",
],
"level": "debug",
"primaryTags": "[Node 005] [~] [Notification]",
"secondaryTags": "[Endpoint 0]",
"message": "Home Security[Motion sensor status]\n: 8 => 0",
"direction": " ",
"label": "CNTRLR",
"timestamp": "2021-04-18T18:03:34.051Z",
"multiline": True,
"secondaryTagPadding": -1,
"context": {
"source": "controller",
"type": "node",
"nodeId": 5,
"header": "Notification",
"direction": "none",
"change": "notification",
"endpoint": 0,
},
},
)
driver.receive_event(event)
assert "log_message" in event.data
assert isinstance(event.data["log_message"], log_message_pkg.LogMessage)
log_message = event.data["log_message"]
assert log_message.message == ["Home Security[Motion sensor status]", ": 8 => 0"]
assert log_message.formatted_message == [
"2021-04-18T18:03:34.051Z CNTRLR [Node 005] [~] ",
"test",
]
assert log_message.direction == " "
assert log_message.primary_tags == "[Node 005] [~] [Notification]"
assert log_message.secondary_tags == "[Endpoint 0]"
assert log_message.level == "debug"
assert log_message.label == "CNTRLR"
assert log_message.multiline
assert log_message.secondary_tag_padding == -1
assert log_message.timestamp == "2021-04-18T18:03:34.051Z"
context = log_message.context
assert context.change == "notification"
assert context.direction == "none"
assert context.endpoint == 0
assert context.header == "Notification"
assert context.node_id == 5
assert context.source == "controller"
assert context.type == "node"
assert context.internal is None
assert context.property_ is None
assert context.property_key is None
assert context.command_class is None
async def test_statistics(driver, uuid4, mock_command):
"""Test statistics commands."""
# Test that enable_statistics command is sent
ack_commands = mock_command(
{
"command": "driver.enable_statistics",
"applicationName": "test_name",
"applicationVersion": "test_version",
},
{"success": True},
)
await driver.async_enable_statistics("test_name", "test_version")
assert len(ack_commands) == 1
assert ack_commands[0] == {
"command": "driver.enable_statistics",
"applicationName": "test_name",
"applicationVersion": "test_version",
"messageId": uuid4,
}
# Test that disable_statistics command is sent
ack_commands = mock_command(
{"command": "driver.disable_statistics"},
{"success": True},
)
await driver.async_disable_statistics()
assert len(ack_commands) == 2
assert ack_commands[1] == {
"command": "driver.disable_statistics",
"messageId": uuid4,
}
# Test that is statistics_enabled command is sent
ack_commands = mock_command(
{"command": "driver.is_statistics_enabled"},
{"success": True, "statisticsEnabled": True},
)
assert await driver.async_is_statistics_enabled()
assert len(ack_commands) == 3
assert ack_commands[2] == {
"command": "driver.is_statistics_enabled",
"messageId": uuid4,
}
async def test_log_config_updated(driver):
"""Test the log_config_updated event."""
# Modify current log config in an update and assert that it changed
assert driver.log_config.level != LogLevel.SILLY
log_config = driver.log_config.to_dict()
log_config["level"] = "silly"
event = Event(
"log config updated",
data={"source": "driver", "event": "log config updated", "config": log_config},
)
driver.receive_event(event)
assert driver.log_config.level == LogLevel.SILLY
async def test_check_for_config_updates(driver, uuid4, mock_command):
"""Test driver.check_for_config_updates command."""
ack_commands = mock_command(
{"command": "driver.check_for_config_updates"},
{"updateAvailable": False, "installedVersion": "1.0.0"},
)
check_config_updates = await driver.async_check_for_config_updates()
assert check_config_updates.installed_version == "1.0.0"
assert check_config_updates.update_available is False
assert check_config_updates.new_version is None
assert len(ack_commands) == 1
assert ack_commands[0] == {
"command": "driver.check_for_config_updates",
"messageId": uuid4,
}
async def test_install_config_update(driver, uuid4, mock_command):
"""Test driver.install_config_update command."""
ack_commands = mock_command(
{"command": "driver.install_config_update"},
{"success": False},
)
assert not await driver.async_install_config_update()
assert len(ack_commands) == 1
assert ack_commands[0] == {
"command": "driver.install_config_update",
"messageId": uuid4,
}
async def test_set_preferred_scales(driver, uuid4, mock_command):
"""Test driver.set_preferred_scales command."""
ack_commands = mock_command({"command": "driver.set_preferred_scales"}, {})
assert not await driver.async_set_preferred_scales({1: 1})
assert len(ack_commands) == 1
assert ack_commands[0] == {
"command": "driver.set_preferred_scales",
"scales": {1: 1},
"messageId": uuid4,
}
async def test_hard_reset(driver, uuid4, mock_command):
"""Test driver hard reset command."""
ack_commands = mock_command({"command": "driver.hard_reset"}, {})
assert not await driver.async_hard_reset()
assert len(ack_commands) == 1
assert ack_commands[0] == {
"command": "driver.hard_reset",
"messageId": uuid4,
}
async def test_try_soft_reset(driver, uuid4, mock_command):
"""Test driver try soft reset command."""
ack_commands = mock_command({"command": "driver.try_soft_reset"}, {})
assert not await driver.async_try_soft_reset()
assert len(ack_commands) == 1
assert ack_commands[0] == {
"command": "driver.try_soft_reset",
"messageId": uuid4,
}
async def test_soft_reset(driver, uuid4, mock_command):
"""Test driver soft reset command."""
ack_commands = mock_command({"command": "driver.soft_reset"}, {})
assert not await driver.async_soft_reset()
assert len(ack_commands) == 1
assert ack_commands[0] == {
"command": "driver.soft_reset",
"messageId": uuid4,
}
async def test_shutdown(driver, uuid4, mock_command):
"""Test driver shutdown command."""
ack_commands = mock_command({"command": "driver.shutdown"}, {"success": True})
assert await driver.async_shutdown()
assert len(ack_commands) == 1
assert ack_commands[0] == {
"command": "driver.shutdown",
"messageId": uuid4,
}
async def test_unknown_event(driver):
"""Test that an unknown event type causes an exception."""
with pytest.raises(KeyError):
assert driver.receive_event(Event("unknown_event", {"source": "driver"}))
async def test_all_nodes_ready_event(driver):
"""Test that the all nodes ready event is succesfully validated by pydantic."""
event = Event("all nodes ready", {"source": "driver", "event": "all nodes ready"})
driver.receive_event(event)