Skip to content

Commit

Permalink
Allow omitted rule constraints to match any value (#101)
Browse files Browse the repository at this point in the history
The definition of umodbus.server.route gives default values of None to the arguments, suggesting they can be omitted. However, if you actually provide None, it will fail later when evaluating DataRule.match.

This change makes it possible to omit any rule constraint to match on any value.
  • Loading branch information
rgov committed Jul 27, 2020
1 parent 82f0872 commit 63c7679
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 9 deletions.
1 change: 1 addition & 0 deletions dev_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
-r requirements.txt

mock==3.0.5;python_version<"3.3"
pytest==5.3.1;python_version>="3.5"
pytest==4.6.6;python_version<"3.5"
pytest-cov==2.8.1
Expand Down
36 changes: 36 additions & 0 deletions tests/unit/test_route.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pytest

from umodbus.route import DataRule


endpoint = lambda slave_id, function_code, address: 0


def test_basic_route():
rule = DataRule(endpoint, slave_ids=[1], function_codes=[1], addresses=[1])
assert rule.match(slave_id=1, function_code=1, address=1)
assert not rule.match(slave_id=0, function_code=1, address=1)
assert not rule.match(slave_id=1, function_code=0, address=1)
assert not rule.match(slave_id=1, function_code=1, address=0)


def test_other_iterables():
# Other iterable types should work, not just lists
rule = DataRule(endpoint,
slave_ids=set([1]), function_codes=[1], addresses=[1])
assert rule.match(slave_id=1, function_code=1, address=1)


def test_wildcard_slave_id():
rule = DataRule(endpoint, slave_ids=None, function_codes=[1], addresses=[1])
assert rule.match(slave_id=1, function_code=1, address=1)


def test_wildcard_function_code():
rule = DataRule(endpoint, slave_ids=[1], function_codes=None, addresses=[1])
assert rule.match(slave_id=1, function_code=1, address=1)


def test_wildcard_address():
rule = DataRule(endpoint, slave_ids=[1], function_codes=[1], addresses=None)
assert rule.match(slave_id=1, function_code=1, address=1)
11 changes: 5 additions & 6 deletions umodbus/route.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ def __init__(self, endpoint, slave_ids, function_codes, addresses):
self.addresses = addresses

def match(self, slave_id, function_code, address):
if slave_id in self.slave_ids and\
function_code in self.function_codes and \
address in self.addresses:
return True

return False
# A constraint of None matches any value
matches = lambda values, v: values is None or v in values
return matches(self.slave_ids, slave_id) and \
matches(self.function_codes, function_code) and \
matches(self.addresses, address)
8 changes: 5 additions & 3 deletions umodbus/server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ def route(self, slave_ids=None, function_codes=None, addresses=None):
def read_single_bit_values(slave_id, address):
return random.choise([0, 1])
:param slave_ids: A list or set with slave id's.
:param function_codes: A list or set with function codes.
:param addresses: A list or set with addresses.
Any argument can be omitted to match any value.
:param slave_ids: A list (or iterable) of slave ids.
:param function_codes: A list (or iterable) of function codes.
:param addresses: A list (or iterable) of addresses.
"""
def inner(f):
self.route_map.add_rule(f, slave_ids, function_codes, addresses)
Expand Down

0 comments on commit 63c7679

Please sign in to comment.