Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing fixes for TC_SWTCH from TE2 #34984

Merged
merged 5 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/all-clusters-app/linux/ButtonEventsSimulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ void ButtonEventsSimulator::Next()
break;
}
case ButtonEventsSimulator::State::kEmitStartOfMultiPress: {
SetButtonPosition(mEndpointId, mPressedButtonId);
EmitInitialPress(mEndpointId, mPressedButtonId);
if (mFeatureMap & static_cast<uint32_t>(Clusters::Switch::Feature::kActionSwitch))
{
Expand Down Expand Up @@ -268,6 +269,7 @@ void ButtonEventsSimulator::Next()
{
EmitShortRelease(mEndpointId, mPressedButtonId);
}
SetButtonPosition(mEndpointId, mIdleButtonId);
StartTimer(mMultiPressReleasedTimeMillis);
break;
}
Expand Down
4 changes: 3 additions & 1 deletion scripts/py_matter_yamltests/matter_yamltests/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,9 @@ async def step_manual(self):
def show_prompt(self,
msg: str,
placeholder: Optional[str] = None,
default_value: Optional[str] = None) -> None:
default_value: Optional[str] = None,
endpoint_id: Optional[int] = None,
tcarmelveilleux marked this conversation as resolved.
Show resolved Hide resolved
) -> None:
"""
This method is called when the step needs to ask the user to perform some action or provide some value.
"""
Expand Down
12 changes: 8 additions & 4 deletions src/python_testing/TC_SWTCH.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@

logger = logging.getLogger(__name__)

SIMULATED_LONG_PRESS_LENGTH_SECONDS = 2.0


def bump_substep(step: str) -> str:
"""Given a string like "5a", bump it to "5b", or "6c" to "6d" """
Expand Down Expand Up @@ -94,7 +96,8 @@ def _send_multi_press_named_pipe_command(self, endpoint_id: int, number_of_press

def _send_long_press_named_pipe_command(self, endpoint_id: int, pressed_position: int, feature_map: int):
command_dict = {"Name": "SimulateLongPress", "EndpointId": endpoint_id,
"ButtonId": pressed_position, "LongPressDelayMillis": 5000, "LongPressDurationMillis": 5500, "FeatureMap": feature_map}
"ButtonId": pressed_position, "LongPressDelayMillis": int(1000 * (SIMULATED_LONG_PRESS_LENGTH_SECONDS - 0.5)),
"LongPressDurationMillis": int(1000 * SIMULATED_LONG_PRESS_LENGTH_SECONDS), "FeatureMap": feature_map}
self._send_named_pipe_command(command_dict)

def _send_latching_switch_named_pipe_command(self, endpoint_id: int, new_position: int):
Expand Down Expand Up @@ -168,7 +171,9 @@ def _ask_for_release(self):
prompt_msg="Release the button."
)
else:
time.sleep(self.keep_pressed_delay/1000)
# This will await for the events to be generated properly. Note that there is a bit of a
# race here for the button simulator, but this race is extremely unlikely to be lost.
time.sleep(SIMULATED_LONG_PRESS_LENGTH_SECONDS + 0.5)

def _await_sequence_of_events(self, event_queue: queue.Queue, endpoint_id: int, sequence: list[ClusterObjects.ClusterEvent], timeout_sec: float):
start_time = time.time()
Expand Down Expand Up @@ -373,7 +378,6 @@ async def test_TC_SWTCH_2_3(self):
self.step(5)
# We're using a long press here with a very long duration (in computer-land). This will let us check the intermediate values.
# This is 1s larger than the subscription ceiling
self.keep_pressed_delay = 6000
self.pressed_position = 1
self._ask_for_keep_pressed(endpoint_id, self.pressed_position, feature_map)
event_listener.wait_for_event_report(cluster.Events.InitialPress)
Expand Down Expand Up @@ -595,7 +599,7 @@ def steps_TC_SWTCH_2_5(self):
@staticmethod
def should_run_SWTCH_2_5(wildcard, endpoint):
msm = has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitchMultiPress)
asf = has_feature(Clusters.Switch, 0x20)
asf = has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kActionSwitch)
return msm(wildcard, endpoint) and not asf(wildcard, endpoint)

@per_endpoint_test(should_run_SWTCH_2_5)
Expand Down
25 changes: 21 additions & 4 deletions src/python_testing/matter_testing_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -1380,11 +1380,21 @@ def wait_for_user_input(self,
Returns:
str: User input or none if input is closed.
"""

# TODO(#31928): Remove any assumptions of test params for endpoint ID.

# Get the endpoint user param instead of `--endpoint-id` result, if available, temporarily.
endpoint_id = self.user_params.get("endpoint", None)
if endpoint_id is None or not isinstance(endpoint_id, int):
endpoint_id = self.matter_test_config.endpoint

if self.runner_hook:
# TODO(#31928): Add endpoint support to hooks.
self.runner_hook.show_prompt(msg=prompt_msg,
placeholder=prompt_msg_placeholder,
default_value=default_value)
logging.info("========= USER PROMPT =========")

logging.info(f"========= USER PROMPT for Endpoint {endpoint_id} =========")
logging.info(f">>> {prompt_msg.rstrip()} (press enter to confirm)")
try:
return input()
Expand Down Expand Up @@ -1881,6 +1891,9 @@ def _has_attribute(wildcard, endpoint, attribute: ClusterObjects.ClusterAttribut
cluster = get_cluster_from_attribute(attribute)
try:
attr_list = wildcard.attributes[endpoint][cluster][cluster.Attributes.AttributeList]
if not isinstance(attr_list, list):
asserts.fail(
f"Failed to read mandatory AttributeList attribute value for cluster {cluster} on endpoint {endpoint}: {attr_list}.")
return attribute.attribute_id in attr_list
except KeyError:
return False
Expand Down Expand Up @@ -1910,9 +1923,13 @@ def has_attribute(attribute: ClusterObjects.ClusterAttributeDescriptor) -> Endpo
return partial(_has_attribute, attribute=attribute)


def _has_feature(wildcard, endpoint, cluster: ClusterObjects.ClusterObjectDescriptor, feature: IntFlag) -> bool:
def _has_feature(wildcard, endpoint: int, cluster: ClusterObjects.ClusterObjectDescriptor, feature: IntFlag) -> bool:
try:
feature_map = wildcard.attributes[endpoint][cluster][cluster.Attributes.FeatureMap]
if not isinstance(feature_map, int):
asserts.fail(
f"Failed to read mandatory FeatureMap attribute value for cluster {cluster} on endpoint {endpoint}: {feature_map}.")

return (feature & feature_map) != 0
except KeyError:
return False
Expand All @@ -1926,8 +1943,8 @@ def has_feature(cluster: ClusterObjects.ClusterObjectDescriptor, feature: IntFla

EP0: cluster A, B, C
EP1: cluster D with feature F0
EP2, cluster D with feature F0
EP3, cluster D without feature F0
EP2: cluster D with feature F0
EP3: cluster D without feature F0

And the following test specification:
@per_endpoint_test(has_feature(Clusters.D.Bitmaps.Feature.F0))
Expand Down
Loading