Skip to content

Commit 2df9dda

Browse files
authored
Test coverage datastore 100%. (#2757)
1 parent 0b7bf25 commit 2df9dda

14 files changed

+728
-404
lines changed

pymodbus/datastore/context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def decode(self, fx):
3131
:param fx: The function we are working with
3232
:returns: one of [d(iscretes),i(nputs),h(olding),c(oils)
3333
"""
34-
return self._fx_mapper[fx]
34+
return self._fx_mapper.get(fx, "x")
3535

3636
async def async_getValues(self, func_code: int, address: int, count: int = 1) -> list[int] | list[bool] | ExcCodes:
3737
"""Get `count` values from datastore.

pymodbus/datastore/remote.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Remote datastore."""
22
from pymodbus.exceptions import NotImplementedException
3-
from pymodbus.logging import Log
3+
from pymodbus.pdu import ExceptionResponse
44

55
from .context import ModbusBaseDeviceContext
66

@@ -25,8 +25,6 @@ def __init__(self, client, device_id=None):
2525
self.device_id = device_id
2626
self.result = None
2727
self.__build_mapping()
28-
if not self.__set_callbacks:
29-
Log.error("Init went wrong.")
3028

3129
def reset(self):
3230
"""Reset all the datastores to their default values."""
@@ -79,6 +77,8 @@ def __build_mapping(self):
7977
"i": lambda a, c: self._client.read_input_registers(
8078
a, count=c, **params
8179
),
80+
"x": lambda a, c: ExceptionResponse(0
81+
),
8282
}
8383
self.__set_callbacks = {
8484
"d5": lambda a, v: self._client.write_coil(
@@ -113,11 +113,10 @@ def __extract_result(self, func_code, result):
113113
114114
TODO make this consistent (values?)
115115
"""
116-
if not result.isError():
117-
if func_code in {"d", "c"}:
118-
return result.bits
119-
if func_code in {"h", "i"}:
120-
return result.registers
121-
else:
122-
return result
123-
return None
116+
if result.isError():
117+
return None
118+
if func_code in {"d", "c"}:
119+
return result.bits
120+
if func_code in {"h", "i"}:
121+
return result.registers
122+
return result

pymodbus/datastore/simulator.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,8 @@ def __init__(
487487
self.action_methods: list[Callable] = []
488488
self.registerType_name_to_id: dict[str, int] = {}
489489
self.registerType_id_to_name: list[str] = []
490-
Setup(self).setup(config, custom_actions)
490+
if config:
491+
Setup(self).setup(config, custom_actions)
491492

492493
# --------------------------------------------
493494
# Simulator server interface
@@ -566,6 +567,8 @@ def loop_validate(self, address, end_address, fx_write):
566567
while i < end_address:
567568
if self.registers[i].type == CellType.NEXT:
568569
i += 1
570+
else:
571+
return False
569572
return True
570573

571574
def validate(self, func_code, address, count=1):
@@ -708,7 +711,7 @@ def action_increment(cls, registers, inx, cell, minval=None, maxval=None):
708711
new_regs = cls.build_registers_from_value(value, False)
709712
reg.value = new_regs[0]
710713
reg2.value = new_regs[1]
711-
elif cell.type == CellType.UINT32:
714+
else: # if cell.type == CellType.UINT32:
712715
tmp_reg = [reg.value, reg2.value]
713716
value = cls.build_value_from_registers(tmp_reg, True)
714717
value += 1
@@ -757,7 +760,7 @@ def action_uptime(cls, registers, inx, cell, **_parameters):
757760
regs = cls.build_registers_from_value(value, False)
758761
registers[inx].value = regs[0]
759762
registers[inx + 1].value = regs[1]
760-
elif cell.type == CellType.UINT32:
763+
else: # if cell.type == CellType.UINT32:
761764
regs = cls.build_registers_from_value(value, True)
762765
registers[inx].value = regs[0]
763766
registers[inx + 1].value = regs[1]

test/CHECK_COVERAGE

Lines changed: 0 additions & 8 deletions
This file was deleted.

test/datastore/test_context.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,12 @@ def test_datastore_server_get(self):
7373
"""Test ModbusServerContext."""
7474
srv = ModbusServerContext()
7575
assert srv[0] == {}
76-
#srv.single = False
77-
#with pytest.raises(NoSuchIdException):
78-
# _ = srv[200]
76+
assert srv[1] == {}
77+
srv = ModbusServerContext(devices={1: {}}, single=False)
78+
assert srv[1] == {}
79+
with pytest.raises(NoSuchIdException):
80+
srv[200]
81+
print("jan")
7982

8083
def test_datastore_server_ids(self):
8184
"""Test ModbusServerContext."""

test/not_updated/test_remote_datastore.py renamed to test/datastore/test_remote_datastore.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ def test_remote_device_context(self):
2121
with pytest.raises(NotImplementedException):
2222
context.reset()
2323

24+
def test_remote_device(self):
25+
"""Test a modbus remote device."""
26+
RemoteDeviceContext(None, device_id=1)
27+
2428
def test_remote_device_set_values(self):
2529
"""Test setting values against a remote device context."""
2630
client = mock.MagicMock()
@@ -29,10 +33,8 @@ def test_remote_device_set_values(self):
2933

3034
context = RemoteDeviceContext(client)
3135
context.setValues(0x0F, 0, [1])
32-
# result = context.setValues(0x10, 1, [1])
3336
context.setValues(0x10, 1, [1])
34-
# assert result.exception_code == 0x02
35-
# assert result.function_code == 0x90
37+
context.setValues(0x05, 1, [1])
3638

3739
async def test_remote_device_async_set_values(self):
3840
"""Test setting values against a remote device context."""
@@ -66,6 +68,11 @@ def test_remote_device_get_values(self):
6668
result = context.getValues(3, 0, 10)
6769
assert result != [10] * 10
6870

71+
result = context.getValues(5, 0, 10)
72+
assert result != [10] * 10
73+
74+
result = context.getValues(17, 0, 10)
75+
6976
async def test_remote_device_async_get_values(self):
7077
"""Test getting values from a remote device context."""
7178
client = mock.MagicMock()
@@ -87,3 +94,10 @@ async def test_remote_device_async_get_values(self):
8794

8895
result = await context.async_getValues(3, 0, 10)
8996
assert result != [10] * 10
97+
98+
def test_remote_device_set_values_wrong(self):
99+
"""Test setting values against a remote device context."""
100+
client = mock.MagicMock()
101+
context = RemoteDeviceContext(client)
102+
with pytest.raises(ValueError, match="setValues*"):
103+
context.setValues(0x01, 0, [1])

test/datastore/test_sequential.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""Test framers."""
2+
3+
from pymodbus.constants import ExcCodes
4+
from pymodbus.datastore import ModbusSequentialDataBlock
5+
6+
7+
class TestCOntextDataStore:
8+
"""Unittest for the pymodbus.datastore.remote module."""
9+
10+
def test_datastore_Sequential(self):
11+
"""Test ModbusDeviceContext."""
12+
ModbusSequentialDataBlock(0x01, [17])
13+
ModbusSequentialDataBlock(0x01, 17)
14+
ModbusSequentialDataBlock(0x01, 17).default(112)
15+
16+
def test_datastore_Sequential_get(self):
17+
"""Test ModbusDeviceContext."""
18+
block = ModbusSequentialDataBlock(0x01, [17])
19+
assert block.getValues(13) == ExcCodes.ILLEGAL_ADDRESS
20+
21+
def test_datastore_Sequential_set(self):
22+
"""Test ModbusDeviceContext."""
23+
block = ModbusSequentialDataBlock(0x01, [17])
24+
block.setValues(1, [19])
25+
block.setValues(1, 19)
26+
assert block.setValues(13, [17]) == ExcCodes.ILLEGAL_ADDRESS
27+
28+
def test_datastore_Sequential_iter(self):
29+
"""Test check frame."""
30+
block = ModbusSequentialDataBlock(0x01, [17])
31+
_ = list(block)

0 commit comments

Comments
 (0)