Fix --int-arg, --bool-arg, etc options parsing (#35249)
* Fix --int-arg, --bool-arg, etc options parsing
* Update CI arguments
* Convert to YAML
* Support mixed arguments type: multi and append
* Restyled by isort
---------
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/src/python_testing/TC_ACE_1_4.py b/src/python_testing/TC_ACE_1_4.py
index 9344b0b..4d6e00e 100644
--- a/src/python_testing/TC_ACE_1_4.py
+++ b/src/python_testing/TC_ACE_1_4.py
@@ -22,18 +22,20 @@
# test-runner-runs:
# run1:
# app: ${ALL_CLUSTERS_APP}
-# factoryreset: true
-# quiet: true
# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json
# script-args: >
# --storage-path admin_storage.json
# --commissioning-method on-network
# --discriminator 1234
# --passcode 20202021
-# --int-arg PIXIT.ACE.APPENDPOINT:1 PIXIT.ACE.APPDEVTYPEID:0x0100
-# --string-arg PIXIT.ACE.APPCLUSTER:OnOff PIXIT.ACE.APPATTRIBUTE:OnOff
+# --int-arg PIXIT.ACE.APPENDPOINT:1
+# --int-arg PIXIT.ACE.APPDEVTYPEID:0x0100
+# --string-arg PIXIT.ACE.APPCLUSTER:OnOff
+# --string-arg PIXIT.ACE.APPATTRIBUTE:OnOff
# --trace-to json:${TRACE_TEST_JSON}.json
# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto
+# factoryreset: true
+# quiet: true
# === END CI TEST ARGUMENTS ===
import sys
@@ -45,8 +47,8 @@
# This test requires several additional command line arguments
# run with
-# --int-arg PIXIT.ACE.ENDPOINT:<endpoint> PIXIT.ACE.APPDEVTYPE:<device_type_id>
-# --string-arg PIXIT.ACE.APPCLUSTER:<cluster_name> PIXIT.ACE.APPATTRIBUTE:<attribute_name>
+# --int-arg PIXIT.ACE.ENDPOINT:<endpoint> --int-arg PIXIT.ACE.APPDEVTYPE:<device_type_id>
+# --string-arg PIXIT.ACE.APPCLUSTER:<cluster_name> --string-arg PIXIT.ACE.APPATTRIBUTE:<attribute_name>
def str_to_cluster(str):
diff --git a/src/python_testing/TC_EWATERHTR_2_1.py b/src/python_testing/TC_EWATERHTR_2_1.py
index e9ae195..8ee466a 100644
--- a/src/python_testing/TC_EWATERHTR_2_1.py
+++ b/src/python_testing/TC_EWATERHTR_2_1.py
@@ -19,12 +19,27 @@
# for details about the block below.
#
# === BEGIN CI TEST ARGUMENTS ===
-# test-runner-runs: run1
-# test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP}
-# test-runner-run/run1/factoryreset: True
-# test-runner-run/run1/quiet: True
-# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x03 --application water-heater
-# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto
+# test-runner-runs:
+# run1:
+# app: ${ENERGY_MANAGEMENT_APP}
+# app-args: >
+# --discriminator 1234
+# --KVS kvs1
+# --trace-to json:${TRACE_APP}.json
+# --enable-key 000102030405060708090a0b0c0d0e0f
+# --featureSet 0x03
+# --application water-heater
+# script-args: >
+# --storage-path admin_storage.json
+# --commissioning-method on-network
+# --discriminator 1234
+# --passcode 20202021
+# --hex-arg enableKey:000102030405060708090a0b0c0d0e0f
+# --endpoint 1
+# --trace-to json:${TRACE_TEST_JSON}.json
+# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto
+# factoryreset: true
+# quiet: true
# === END CI TEST ARGUMENTS ===
import logging
diff --git a/src/python_testing/TC_RVCCLEANM_2_1.py b/src/python_testing/TC_RVCCLEANM_2_1.py
index 8e5013a..c9b8362 100644
--- a/src/python_testing/TC_RVCCLEANM_2_1.py
+++ b/src/python_testing/TC_RVCCLEANM_2_1.py
@@ -19,12 +19,23 @@
# for details about the block below.
#
# === BEGIN CI TEST ARGUMENTS ===
-# test-runner-runs: run1
-# test-runner-run/run1/app: ${CHIP_RVC_APP}
-# test-runner-run/run1/factoryreset: True
-# test-runner-run/run1/quiet: True
-# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json
-# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --int-arg PIXIT.RVCCLEANM.MODE_CHANGE_FAIL:1 PIXIT.RVCCLEANM.MODE_CHANGE_OK:2
+# test-runner-runs:
+# run1:
+# app: ${CHIP_RVC_APP}
+# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json
+# script-args: >
+# --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values
+# --storage-path admin_storage.json
+# --commissioning-method on-network
+# --discriminator 1234
+# --passcode 20202021
+# --int-arg PIXIT.RVCCLEANM.MODE_CHANGE_FAIL:1
+# --int-arg PIXIT.RVCCLEANM.MODE_CHANGE_OK:2
+# --endpoint 1
+# --trace-to json:${TRACE_TEST_JSON}.json
+# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto
+# factoryreset: true
+# quiet: true
# === END CI TEST ARGUMENTS ===
import logging
@@ -35,7 +46,7 @@
# This test requires several additional command line arguments
# run with
-# --int-arg PIXIT.RVCCLEANM.MODE_CHANGE_OK:<mode id> PIXIT.RVCCLEANM.MODE_CHANGE_FAIL:<mode id>
+# --int-arg PIXIT.RVCCLEANM.MODE_CHANGE_OK:<mode id> --int-arg PIXIT.RVCCLEANM.MODE_CHANGE_FAIL:<mode id>
class TC_RVCCLEANM_2_1(MatterBaseTest):
diff --git a/src/python_testing/TC_RVCRUNM_2_1.py b/src/python_testing/TC_RVCRUNM_2_1.py
index 2693cb0..d3da69a 100644
--- a/src/python_testing/TC_RVCRUNM_2_1.py
+++ b/src/python_testing/TC_RVCRUNM_2_1.py
@@ -19,12 +19,23 @@
# for details about the block below.
#
# === BEGIN CI TEST ARGUMENTS ===
-# test-runner-runs: run1
-# test-runner-run/run1/app: ${CHIP_RVC_APP}
-# test-runner-run/run1/factoryreset: True
-# test-runner-run/run1/quiet: True
-# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json
-# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --int-arg PIXIT.RVCRUNM.MODE_CHANGE_OK:0 PIXIT.RVCRUNM.MODE_CHANGE_FAIL:2
+# test-runner-runs:
+# run1:
+# app: ${CHIP_RVC_APP}
+# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json
+# script-args: >
+# --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values
+# --storage-path admin_storage.json
+# --commissioning-method on-network
+# --discriminator 1234
+# --passcode 20202021
+# --endpoint 1
+# --int-arg PIXIT.RVCRUNM.MODE_CHANGE_OK:0
+# --int-arg PIXIT.RVCRUNM.MODE_CHANGE_FAIL:2
+# --trace-to json:${TRACE_TEST_JSON}.json
+# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto
+# factoryreset: true
+# quiet: true
# === END CI TEST ARGUMENTS ===
import logging
@@ -35,7 +46,7 @@
# This test requires several additional command line arguments
# run with
-# --int-arg PIXIT.RVCRUNM.MODE_CHANGE_OK:<mode id> PIXIT.RVCRUNM.MODE_CHANGE_FAIL:<mode id>
+# --int-arg PIXIT.RVCRUNM.MODE_CHANGE_OK:<mode id> --int-arg PIXIT.RVCRUNM.MODE_CHANGE_FAIL:<mode id>
# For running in CI, it is expected that OK=0 and FAIL=2
diff --git a/src/python_testing/TC_RVCRUNM_2_2.py b/src/python_testing/TC_RVCRUNM_2_2.py
index 3a2ce23..0eefcc2 100644
--- a/src/python_testing/TC_RVCRUNM_2_2.py
+++ b/src/python_testing/TC_RVCRUNM_2_2.py
@@ -19,12 +19,23 @@
# for details about the block below.
#
# === BEGIN CI TEST ARGUMENTS ===
-# test-runner-runs: run1
-# test-runner-run/run1/app: ${CHIP_RVC_APP}
-# test-runner-run/run1/factoryreset: True
-# test-runner-run/run1/quiet: True
-# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json
-# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --int-arg PIXIT.RVCRUNM.MODE_A:1 PIXIT.RVCRUNM.MODE_B:2
+# test-runner-runs:
+# run1:
+# app: ${CHIP_RVC_APP}
+# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json
+# script-args: >
+# --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values
+# --storage-path admin_storage.json
+# --commissioning-method on-network
+# --discriminator 1234
+# --passcode 20202021
+# --endpoint 1
+# --int-arg PIXIT.RVCRUNM.MODE_A:1
+# --int-arg PIXIT.RVCRUNM.MODE_B:2
+# --trace-to json:${TRACE_TEST_JSON}.json
+# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto
+# factoryreset: true
+# quiet: true
# === END CI TEST ARGUMENTS ===
import enum
@@ -35,7 +46,7 @@
# This test requires several additional command line arguments.
# Run the test with
-# --int-arg PIXIT.RVCRUNM.MODE_A:<mode id> PIXIT.RVCRUNM.MODE_B:<mode id>
+# --int-arg PIXIT.RVCRUNM.MODE_A:<mode id> --int-arg PIXIT.RVCRUNM.MODE_B:<mode id>
class RvcStatusEnum(enum.IntEnum):
diff --git a/src/python_testing/TestMatterTestingSupport.py b/src/python_testing/TestMatterTestingSupport.py
index d2a259f..08c3e83 100644
--- a/src/python_testing/TestMatterTestingSupport.py
+++ b/src/python_testing/TestMatterTestingSupport.py
@@ -24,7 +24,7 @@
from chip.clusters.Types import Nullable, NullValue
from chip.tlv import uint
from matter_testing_support import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main,
- get_wait_seconds_from_set_time, type_matches, utc_time_in_matter_epoch)
+ get_wait_seconds_from_set_time, parse_matter_test_args, type_matches, utc_time_in_matter_epoch)
from mobly import asserts, signals
from pics_support import parse_pics, parse_pics_xml
from taglist_and_topology_test_support import (TagProblem, create_device_type_list_for_root, create_device_type_lists,
@@ -629,6 +629,24 @@
self.pics_assert('BINFO.S.A0014', False)
self.pics_assert('PICSDOESNOTEXIST', False)
+ def test_parse_matter_test_args(self):
+ args = [
+ # Verify that values are appended to a single argument
+ "--int-arg", "PIXIT.TEST.DEC:42",
+ "--int-arg", "PIXIT.TEST.HEX:0x1234",
+ # Verify that multiple values can be passed for a single argument
+ "--string-arg", "PIXIT.TEST.STR.MULTI.1:foo", "PIXIT.TEST.STR.MULTI.2:bar",
+ # Verify JSON parsing
+ "--json-arg", "PIXIT.TEST.JSON:{\"key\":\"value\"}",
+ ]
+
+ parsed = parse_matter_test_args(args)
+ asserts.assert_equal(parsed.global_test_params.get("PIXIT.TEST.DEC"), 42)
+ asserts.assert_equal(parsed.global_test_params.get("PIXIT.TEST.HEX"), 0x1234)
+ asserts.assert_equal(parsed.global_test_params.get("PIXIT.TEST.STR.MULTI.1"), "foo")
+ asserts.assert_equal(parsed.global_test_params.get("PIXIT.TEST.STR.MULTI.2"), "bar")
+ asserts.assert_equal(parsed.global_test_params.get("PIXIT.TEST.JSON"), {"key": "value"})
+
if __name__ == "__main__":
default_matter_test_main()
diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py
index 92cde9e..2e153a3 100644
--- a/src/python_testing/matter_testing_support.py
+++ b/src/python_testing/matter_testing_support.py
@@ -38,6 +38,7 @@
from datetime import datetime, timedelta, timezone
from enum import Enum, IntFlag
from functools import partial
+from itertools import chain
from typing import Any, Iterable, List, Optional, Tuple
from chip.tlv import float32, uint
@@ -1842,7 +1843,7 @@
all_global_args = []
argsets = [item for item in (args.int_arg, args.float_arg, args.string_arg, args.json_arg,
args.hex_arg, args.bool_arg) if item is not None]
- for argset in argsets:
+ for argset in chain.from_iterable(argsets):
all_global_args.extend(argset)
config.global_test_params = {}
@@ -1954,17 +1955,17 @@
help='Path to chip-tool credentials file root')
args_group = parser.add_argument_group(title="Config arguments", description="Test configuration global arguments set")
- args_group.add_argument('--int-arg', nargs='*', type=int_named_arg, metavar="NAME:VALUE",
+ args_group.add_argument('--int-arg', nargs='*', action='append', type=int_named_arg, metavar="NAME:VALUE",
help="Add a named test argument for an integer as hex or decimal (e.g. -2 or 0xFFFF_1234)")
- args_group.add_argument('--bool-arg', nargs='*', type=bool_named_arg, metavar="NAME:VALUE",
+ args_group.add_argument('--bool-arg', nargs='*', action='append', type=bool_named_arg, metavar="NAME:VALUE",
help="Add a named test argument for an boolean value (e.g. true/false or 0/1)")
- args_group.add_argument('--float-arg', nargs='*', type=float_named_arg, metavar="NAME:VALUE",
+ args_group.add_argument('--float-arg', nargs='*', action='append', type=float_named_arg, metavar="NAME:VALUE",
help="Add a named test argument for a floating point value (e.g. -2.1 or 6.022e23)")
- args_group.add_argument('--string-arg', nargs='*', type=str_named_arg, metavar="NAME:VALUE",
+ args_group.add_argument('--string-arg', nargs='*', action='append', type=str_named_arg, metavar="NAME:VALUE",
help="Add a named test argument for a string value")
- args_group.add_argument('--json-arg', nargs='*', type=json_named_arg, metavar="NAME:VALUE",
+ args_group.add_argument('--json-arg', nargs='*', action='append', type=json_named_arg, metavar="NAME:VALUE",
help="Add a named test argument for JSON stored as a list or dict")
- args_group.add_argument('--hex-arg', nargs='*', type=bytes_as_hex_named_arg, metavar="NAME:VALUE",
+ args_group.add_argument('--hex-arg', nargs='*', action='append', type=bytes_as_hex_named_arg, metavar="NAME:VALUE",
help="Add a named test argument for an octet string in hex (e.g. 0011cafe or 00:11:CA:FE)")
if not argv: