Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
patman15 committed Nov 8, 2024
1 parent 6e6cd75 commit ea16f06
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 102 deletions.
2 changes: 1 addition & 1 deletion tests/test_const.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ async def test_critical_constants() -> None:
"""Test general constants are not altered for debugging."""

assert UPDATE_INTERVAL == 30 # ensure that update interval is 30 seconds
assert len(BMS_TYPES) == 7 # check number of BMS types
assert len(BMS_TYPES) == 8 # check number of BMS types
155 changes: 54 additions & 101 deletions tests/test_redodo_bms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from uuid import UUID

from bleak.backends.characteristic import BleakGATTCharacteristic
from bleak.exc import BleakError
from bleak.uuids import normalize_uuid_str
from custom_components.bms_ble.plugins.redodo_bms import BMS

Expand Down Expand Up @@ -49,62 +48,6 @@ async def write_gatt_char(
)


# class MockWrongCRCBleakClient(MockRedodoBleakClient):
# """Emulate a E&J technology BMS BleakClient that replies with wrong CRC"""

# def _response(
# self, char_specifier: BleakGATTCharacteristic | int | str | UUID, data: Buffer
# ) -> bytearray:
# if isinstance(char_specifier, str) and normalize_uuid_str(
# char_specifier
# ) != normalize_uuid_str("fff3"):
# return bytearray()
# cmd: int = int(bytearray(data)[5])
# if cmd == 0x60:
# return bytearray(
# b"\x12\x12\x3A\x05\x03\x60\x00\x0A\x02\x13\x00\x00\x71\xC5\x45\x8E\x3D\x00\x01\xCE"
# b"\x02\x22\x0D\x0A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
# ) # wrong CRC [0x01CE != 0x02CD] in line 1
# if cmd == 0x61:
# return bytearray(
# b"\x12\x12\x3A\x05\x03\x61\x00\x0C\x00\x12\x00\x12\x6D\x60\x0B\x7E\x8F\xDB\x18\x20"
# b"\x04\x22\x02\x91\x0D\x0A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
# ) # wrong CRC [0x02 != 0x03] in line 2
# if cmd == 0x62:
# return bytearray(
# b"\x12\x13\x3A\x05\x03\x62\x00\x1D\x0E\x0E\xD7\x0E\xD6\x0E\xD6\x0E\xD5\x0E\xD5\x0E"
# b"\x12\x23\xD6\x0E\xD1\x0E\xD2\x0E\xD5\x0E\xD6\x0E\xD4\x0E\xD8\x0E\xD7\x0E\xDB\x0E"
# b"\x03\x33\x08\x0D\x0A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
# ) # wrong CRC [0x0E != 0x0D] in line 2
# return bytearray()


# class MockInvalidBleakClient(MockRedodoBleakClient):
# """Emulate a E&J technology BMS BleakClient replying garbage."""

# def _response(
# self, char_specifier: BleakGATTCharacteristic | int | str | UUID, data: Buffer
# ) -> bytearray:
# if isinstance(char_specifier, str) and normalize_uuid_str(
# char_specifier
# ) != normalize_uuid_str("6e400002-b5a3-f393-e0a9-e50e24dcca9e"):
# return bytearray()
# cmd: int = int(bytearray(data)[3:5], 16)
# if cmd == 0x02:
# return bytearray(
# b"X0082310080000101C00000880F540F3C0F510FD70F310F2C0F340F3A0FED0FED0000000000000000000000000000000248424242F0000000000000000001ABX"
# ) # correct message, wrong SOI
# if cmd == 0x10:
# return bytearray(
# b":009031001D0000001400080016F4~"
# ) # incorrect message, wrong length (1E != 1D)
# return bytearray()

# async def disconnect(self) -> bool:
# """Mock disconnect to raise BleakError."""
# raise BleakError


async def test_update(monkeypatch, reconnect_fixture) -> None:
"""Test Redodo technology BMS data update."""

Expand Down Expand Up @@ -134,6 +77,10 @@ async def test_update(monkeypatch, reconnect_fixture) -> None:
"delta_voltage": 0.01,
"power": -38.108,
"battery_charging": False,
"battery_level": 65,
"cycle_capacity": 68.89,
"temperature": 23,
"cycles": 3,
}

# query again to check already connected state
Expand All @@ -143,58 +90,64 @@ async def test_update(monkeypatch, reconnect_fixture) -> None:
await bms.disconnect()


@pytest.fixture(name="wrong_response", params=[
b"x009031001E0000001400080016F4~", # wrong SOI
b":009031001E0000001400080016F4x", # wrong EOI
b":009031001D0000001400080016F4~", # wrong length
])
@pytest.fixture(
name="wrong_response",
params=[
bytearray(
b"\x00\x00\x65\x01\x93\x55\xaa\x00\x46\x66\x00\x00\xbc\x67\x00\x00\xf5\x0c\xf7\x0c"
b"\xfc\x0c\xfb\x0c\xf8\x0c\xf2\x0c\xfa\x0c\xf5\x0c\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x65\xfa\xff\xff\x17\x00\x16\x00\x17\x00\x00\x00"
b"\x00\x00\xe9\x1a\x04\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x64\x00\x00\x00\x03\x00\x00\x00"
b"\x5f\x01\x00\x00\xff" # wrong CRC
),
bytearray(
b"\x00\x01\x65\x01\x93\x55\xaa\x00\x46\x66\x00\x00\xbc\x67\x00\x00\xf5\x0c\xf7\x0c"
b"\xfc\x0c\xfb\x0c\xf8\x0c\xf2\x0c\xfa\x0c\xf5\x0c\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x65\xfa\xff\xff\x17\x00\x16\x00\x17\x00\x00\x00"
b"\x00\x00\xe9\x1a\x04\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x64\x00\x00\x00\x03\x00\x00\x00"
b"\x5f\x01\x00\x00\xbc" # wrong SOF
),
bytearray(
b"\x00\x00\x65\x01\x93\x55\xaa\x00\x46\x66\x00\x00\xbc\x67\x00\x00\xf5\x0c\xf7\x0c"
b"\xfc\x0c\xfb\x0c\xf8\x0c\xf2\x0c\xfa\x0c\xf5\x0c\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x65\xfa\xff\xff\x17\x00\x16\x00\x17\x00\x00\x00"
b"\x00\x00\xe9\x1a\x04\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x64\x00\x00\x00\x03\x00\x00\x00"
b"\x5f\x01\x00\xbc" # wrong length
),
bytearray(b"\x00"), # much too short
],
)
def response(request):
"""Return all possible BMS variants."""
return request.param

# async def test_invalid_response(monkeypatch, wrong_response) -> None:
# """Test data up date with BMS returning invalid data."""

# monkeypatch.setattr(
# "custom_components.bms_ble.plugins.redodo_bms.BAT_TIMEOUT",
# 0.1,
# )

# monkeypatch.setattr(
# "tests.test_redodo_bms.MockRedodoBleakClient._response",
# lambda _s,_c_,d: wrong_response,
# )

# monkeypatch.setattr(
# "custom_components.bms_ble.plugins.basebms.BleakClient",
# MockEJBleakClient,
# )

# bms = BMS(generate_ble_device("cc:cc:cc:cc:cc:cc", "MockBLEDevice", None, -73))
async def test_invalid_response(monkeypatch, wrong_response) -> None:
"""Test data up date with BMS returning invalid data."""

# result = {}
# with pytest.raises(TimeoutError):
# result = await bms.async_update()

# assert not result
# await bms.disconnect()


# async def test_wrong_crc(monkeypatch, dev_name) -> None:
# """Test data update with BMS returning invalid data."""
monkeypatch.setattr(
"custom_components.bms_ble.plugins.redodo_bms.BAT_TIMEOUT",
0.1,
)

# monkeypatch.setattr(
# "custom_components.bms_ble.plugins.dpwrcore_bms.BAT_TIMEOUT",
# 0.1,
# )
monkeypatch.setattr(
"tests.test_redodo_bms.MockRedodoBleakClient._response",
lambda _s, _c_, d: wrong_response,
)

# monkeypatch.setattr(
# "custom_components.bms_ble.plugins.basebms.BleakClient",
# MockWrongCRCBleakClient,
# )
monkeypatch.setattr(
"custom_components.bms_ble.plugins.basebms.BleakClient",
MockRedodoBleakClient,
)

# bms = BMS(generate_ble_device("cc:cc:cc:cc:cc:cc", dev_name, None, -73))
bms = BMS(generate_ble_device("cc:cc:cc:cc:cc:cc", "MockBLEDevice", None, -73))

# assert await bms.async_update() == {}
result = {}
with pytest.raises(TimeoutError):
result = await bms.async_update()

# await bms.disconnect()
assert not result
await bms.disconnect()

0 comments on commit ea16f06

Please sign in to comment.