Skip to content

Commit

Permalink
Fix python evaluation of arithmetic statements with no spaces (#32911)
Browse files Browse the repository at this point in the history
  • Loading branch information
tehampson authored Apr 12, 2024
1 parent d65f300 commit 9d46b23
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 2 deletions.
5 changes: 3 additions & 2 deletions scripts/py_matter_yamltests/matter_yamltests/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,8 @@ def _config_variable_substitution(self, value):
# But some other tests were relying on the fact that the expression was put 'as if' in
# the generated code and was resolved before being sent over the wire. For such
# expressions (e.g 'myVar + 1') we need to compute it before sending it over the wire.
tokens = value.split()
delimiter_regex = "(\ |\(|\)|\+|\-|\*|\/|\%)"
tokens = re.split(delimiter_regex, value)
if len(tokens) == 0:
return value

Expand All @@ -1240,7 +1241,7 @@ def _config_variable_substitution(self, value):
return tokens[0]

tokens = [str(token) for token in tokens]
value = ' '.join(tokens)
value = ''.join(tokens)
# TODO we should move away from eval. That will mean that we will need to do extra
# parsing, but it would be safer then just blindly running eval.
return value if not substitution_occured else eval(value)
Expand Down
89 changes: 89 additions & 0 deletions scripts/py_matter_yamltests/test_yaml_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
<attribute side="server" code="0x0024" type="TestEnum" writable="true" optional="false">test_enum</attribute>
<command source="client" code="1" name="test"></command>
<command source="client" code="2" name="IntTest">
<arg name="arg" type="int8u"/>
</command>
</cluster>
</configurator>
'''
Expand Down Expand Up @@ -175,6 +178,81 @@
value: TestEnum.UnknownEnumValue(0)
'''

_BASIC_ARITHMETIC_ARG_RESULTS = [6, 6, 2, 2, 8, 8, 2, 2, 1]
basic_arithmetic_yaml = '''
name: Test Cluster Tests
config:
nodeId: 0x12344321
cluster: "Test"
endpoint: 1
myVariable: 4
tests:
- label: "Add 2"
command: "IntTest"
arguments:
values:
- name: "arg"
value: myVariable + 2
- label: "Add 2 with no space"
command: "IntTest"
arguments:
values:
- name: "arg"
value: myVariable+2
- label: "Minus 2"
command: "IntTest"
arguments:
values:
- name: "arg"
value: myVariable - 2
- label: "Minus 2 with no space"
command: "IntTest"
arguments:
values:
- name: "arg"
value: myVariable-2
- label: "Multiply by 2"
command: "IntTest"
arguments:
values:
- name: "arg"
value: myVariable * 2
- label: "Multiply by 2 with no space"
command: "IntTest"
arguments:
values:
- name: "arg"
value: myVariable*2
- label: "Divide by 2"
command: "IntTest"
arguments:
values:
- name: "arg"
value: myVariable / 2
- label: "Divide by 2 with no space"
command: "IntTest"
arguments:
values:
- name: "arg"
value: myVariable/2
- label: "Arithmetic with parentheses"
command: "IntTest"
arguments:
values:
- name: "arg"
value: (myVariable +3)/7
'''


def mock_open_with_parameter_content(content):
file_object = mock_open(read_data=content).return_value
Expand Down Expand Up @@ -207,6 +285,17 @@ def test_config(self):
self.assertEqual(test_step.cluster, 'Test')
self.assertEqual(test_step.endpoint, 1)

def test_basic_arithmetic(self):
parser_config = TestParserConfig(None, self._definitions)

yaml_parser = TestParser(basic_arithmetic_yaml, parser_config)
for idx, test_step in enumerate(yaml_parser.tests):
values = test_step.arguments['values']
self.assertEqual(len(values), 1)
value = values[0]
self.assertEqual(value['name'], 'arg')
self.assertEqual(value['value'], _BASIC_ARITHMETIC_ARG_RESULTS[idx])

def test_config_override(self):
config_override = {'nodeId': 12345,
'cluster': 'TestOverride', 'endpoint': 4}
Expand Down

0 comments on commit 9d46b23

Please sign in to comment.