Skip to content

Commit e5f7e97

Browse files
committed
Test coverage datastore 100%.
1 parent 039e89e commit e5f7e97

File tree

13 files changed

+803
-393
lines changed

13 files changed

+803
-393
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/datastore/test_context.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"""Test framers."""
2+
import pytest
3+
4+
from pymodbus.datastore import (
5+
ModbusBaseDeviceContext,
6+
ModbusDeviceContext,
7+
ModbusServerContext,
8+
)
9+
from pymodbus.exceptions import NoSuchIdException
10+
11+
12+
class TestContextDataStore:
13+
"""Unittest for the pymodbus.datastore.remote module."""
14+
15+
def test_datastore_base_device(self):
16+
"""Test ModbusDeviceContext."""
17+
dev = ModbusBaseDeviceContext()
18+
dev.getValues(0x01, 0x01)
19+
dev.setValues(0x05, 0x01, None)
20+
21+
def test_datastore_device(self):
22+
"""Test ModbusDeviceContext."""
23+
dev = ModbusDeviceContext()
24+
str(dev)
25+
dev.reset()
26+
27+
def test_datastore_device_Values(self):
28+
"""Test ModbusDeviceContext."""
29+
dev = ModbusDeviceContext()
30+
dev.getValues(0x01, 0x05)
31+
dev.setValues(0x05, 0x05, [17])
32+
33+
def test_datastore_device_register(self):
34+
"""Test ModbusDeviceContext."""
35+
dev = ModbusDeviceContext()
36+
dev.register(0x17, "representation")
37+
38+
def test_datastore_server(self):
39+
"""Test ModbusServerContext."""
40+
dev = ModbusServerContext()
41+
str(dev)
42+
dev = ModbusServerContext(single=False)
43+
44+
def test_datastore_server_iter(self):
45+
"""Test ModbusServerContext."""
46+
dev = ModbusServerContext()
47+
_ = list(dev)
48+
49+
def test_datastore_server_contains(self):
50+
"""Test ModbusServerContext."""
51+
dev = ModbusServerContext()
52+
assert 0 in dev
53+
dev2 = ModbusServerContext()
54+
dev2.single = False
55+
assert 0 in dev2
56+
57+
def test_datastore_server_set(self):
58+
"""Test ModbusServerContext."""
59+
dev = ModbusDeviceContext()
60+
srv = ModbusServerContext()
61+
srv[1] = dev
62+
srv.single = False
63+
srv[2] = dev
64+
del srv[2]
65+
with pytest.raises(NoSuchIdException):
66+
srv[2000] = dev
67+
with pytest.raises(NoSuchIdException):
68+
del srv[2000]
69+
70+
def xtest_datastore_server_get(self):
71+
"""Test ModbusServerContext."""
72+
srv = ModbusServerContext()
73+
assert srv[0] == {}
74+
srv.single = False
75+
with pytest.raises(NoSuchIdException):
76+
_ = srv[200]
77+
78+
def test_datastore_server_ids(self):
79+
"""Test ModbusServerContext."""
80+
srv = ModbusServerContext()
81+
assert isinstance(srv.device_ids(), list)

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)