Skip to content

Commit 49df59b

Browse files
Fix timeout error caused by extract_value_from_string function, increased timeout values to prevent flaky test, and addressed PR comments from @sharadb-amazon.
1 parent 58bcfa0 commit 49df59b

File tree

2 files changed

+33
-21
lines changed

2 files changed

+33
-21
lines changed

.github/workflows/examples-linux-tv-casting-app.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
run: |
6868
./scripts/run_in_build_env.sh \
6969
"python3 ./scripts/tests/run_tv_casting_test.py"
70-
timeout-minutes: 1
70+
timeout-minutes: 2 # Comment this out to debug if GitHub Action times out.
7171

7272
- name: Uploading Size Reports
7373
uses: ./.github/actions/upload-size-reports

scripts/tests/run_tv_casting_test.py

+32-20
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
TV_APP_MAX_START_WAIT_SEC = 2
3232

3333
# The maximum amount of time to commission the Linux tv-casting-app and the tv-app before timeout.
34-
COMMISSIONING_STAGE_MAX_WAIT_SEC = 10
34+
COMMISSIONING_STAGE_MAX_WAIT_SEC = 15
3535

3636
# The maximum amount of time to test that the launchURL is sent from the Linux tv-casting-app and received on the tv-app before timeout.
3737
TEST_LAUNCHURL_MAX_WAIT_SEC = 10
@@ -98,31 +98,42 @@ def handle_casting_failure(casting_state: str, log_file_paths: List[str]):
9898
sys.exit(1)
9999

100100

101-
def extract_value_from_string(line: str) -> str:
101+
def extract_value_from_string(line: str, value_name: str, casting_state: str, log_paths) -> str:
102102
"""Extract and return value from given input string.
103103
104104
The string is expected to be in the following format as it is received
105105
from the Linux tv-casting-app output:
106106
\x1b[0;34m[1715206773402] [20056:2842184] [DMG] Cluster = 0x506,\x1b[0m
107107
The substring to be extracted here is '0x506'.
108108
Or:
109+
\x1b[0;32m[1714582264602] [77989:2286038] [SVR] Discovered Commissioner #0\x1b[0m
110+
The integer value to be extracted here is '0'.
111+
Or:
109112
\x1b[0;34m[1713741926895] [7276:9521344] [DIS] Vendor ID: 65521\x1b[0m
110-
The integer value to be extracted here is 65521.
113+
The integer value to be extracted here is '65521'.
111114
Or:
112115
\x1b[0;34m[1714583616179] [7029:2386956] [SVR] device Name: Test TV casting app\x1b[0m
113116
The substring to be extracted here is 'Test TV casting app'.
114117
"""
115-
if '=' in line:
116-
value = line.split('=')[-1].strip().replace(',\x1b[0m', '')
118+
if ':' in line:
119+
if '=' in line:
120+
delimiter = '='
121+
elif '#' in line:
122+
delimiter = '#'
123+
else:
124+
delimiter = ':'
125+
126+
value = line.split(delimiter)[-1].strip().replace('\x1b[0m', '').rstrip(',')
117127
else:
118-
value = line.split(':')[-1].strip().replace('\x1b[0m', '')
128+
logging.error(f'Could not extract {value_name} from the following line: {line}')
129+
handle_casting_failure(casting_state, log_paths)
119130

120131
return value
121132

122133

123134
def validate_value(casting_state: str, expected_value: Union[str, int], log_paths: List[str], line: str, value_name: str) -> Optional[str]:
124135
"""Validate a value in a string against an expected value during a given casting state."""
125-
value = extract_value_from_string(line)
136+
value = extract_value_from_string(line, value_name, casting_state, log_paths)
126137

127138
if isinstance(expected_value, int):
128139
value = int(value)
@@ -187,7 +198,7 @@ def initiate_cast_request_success(tv_casting_app_info: Tuple[subprocess.Popen, T
187198
return True
188199

189200

190-
def extract_device_info_from_tv_casting_app(tv_casting_app_info: Tuple[subprocess.Popen, TextIO]) -> Tuple[Optional[str], Optional[int], Optional[int]]:
201+
def extract_device_info_from_tv_casting_app(tv_casting_app_info: Tuple[subprocess.Popen, TextIO], casting_state: str, log_paths: List[str]) -> Tuple[Optional[str], Optional[int], Optional[int]]:
191202
"""Extract device information from the 'Identification Declaration' block in the Linux tv-casting-app output."""
192203
tv_casting_app_process, linux_tv_casting_app_log_file = tv_casting_app_info
193204

@@ -200,12 +211,12 @@ def extract_device_info_from_tv_casting_app(tv_casting_app_info: Tuple[subproces
200211
linux_tv_casting_app_log_file.flush()
201212

202213
if 'device Name' in line:
203-
device_name = extract_value_from_string(line)
214+
device_name = extract_value_from_string(line, 'device Name', casting_state, log_paths)
204215
elif 'vendor id' in line:
205-
vendor_id = extract_value_from_string(line)
216+
vendor_id = extract_value_from_string(line, 'vendor id', casting_state, log_paths)
206217
vendor_id = int(vendor_id)
207218
elif 'product id' in line:
208-
product_id = extract_value_from_string(line)
219+
product_id = extract_value_from_string(line, 'product id', casting_state, log_paths)
209220
product_id = int(product_id)
210221

211222
if device_name and vendor_id and product_id:
@@ -337,7 +348,7 @@ def parse_tv_casting_app_for_report_data_msg(tv_casting_app_info: Tuple[subproce
337348
# Check if we exceeded the maximum wait time to parse the Linux tv-casting-app output for `ReportDataMessage` block.
338349
if time.time() - start_wait_time > VERIFY_SUBSCRIPTION_STATE_MAX_WAIT_SEC:
339350
logging.error(
340-
'The relevant `ReportDataMessage` block was not found in the Linux tv-casting-app process within the timeout.')
351+
'The relevant `ReportDataMessage` block for the MediaPlayback:CurrentState subscription was not found in the Linux tv-casting-app process within the timeout.')
341352
report_data_message.clear()
342353
return report_data_message
343354

@@ -354,13 +365,14 @@ def parse_tv_casting_app_for_report_data_msg(tv_casting_app_info: Tuple[subproce
354365
report_data_message.append(tv_casting_line.rstrip('\n'))
355366

356367
if 'Cluster =' in tv_casting_line:
357-
cluster_value = extract_value_from_string(tv_casting_line)
368+
cluster_value = extract_value_from_string(tv_casting_line, 'Cluster value', 'Testing subscription', log_paths)
358369
if cluster_value != CLUSTER_MEDIA_PLAYBACK:
359370
report_data_message.clear()
360371
continue_parsing = False
361372

362373
elif 'Attribute =' in tv_casting_line:
363-
attribute_value = extract_value_from_string(tv_casting_line)
374+
attribute_value = extract_value_from_string(
375+
tv_casting_line, 'Attribute value', 'Testing subscription', log_paths)
364376
if attribute_value != ATTRIBUTE_CURRENT_PLAYBACK_STATE:
365377
report_data_message.clear()
366378
continue_parsing = False
@@ -459,11 +471,11 @@ def test_discovery_fn(tv_casting_app_info: Tuple[subprocess.Popen, TextIO], log_
459471
linux_tv_casting_app_log_file.flush()
460472

461473
# Fail fast if "No commissioner discovered" string found.
462-
if "No commissioner discovered" in line:
474+
if 'No commissioner discovered' in line:
463475
logging.error(line.rstrip('\n'))
464476
handle_casting_failure('Discovery', log_paths)
465477

466-
elif "Discovered Commissioner" in line:
478+
elif 'Discovered Commissioner' in line:
467479
valid_discovered_commissioner = line.rstrip('\n')
468480

469481
elif valid_discovered_commissioner:
@@ -497,7 +509,8 @@ def test_commissioning_fn(valid_discovered_commissioner_number, tv_casting_app_i
497509
handle_casting_failure('Commissioning', log_paths)
498510

499511
# Extract the values from the 'Identification Declaration' block in the tv-casting-app output that we want to validate against.
500-
expected_device_name, expected_vendor_id, expected_product_id = extract_device_info_from_tv_casting_app(tv_casting_app_info)
512+
expected_device_name, expected_vendor_id, expected_product_id = extract_device_info_from_tv_casting_app(
513+
tv_casting_app_info, 'Commissioning', log_paths)
501514

502515
if not validate_identification_declaration_message_on_tv_app(tv_app_info, expected_device_name, expected_vendor_id, expected_product_id, log_paths):
503516
handle_casting_failure('Commissioning', log_paths)
@@ -580,9 +593,8 @@ def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path):
580593
handle_casting_failure('Discovery', log_paths)
581594

582595
# We need the valid discovered commissioner number to continue with commissioning.
583-
# Example string: \x1b[0;32m[1714582264602] [77989:2286038] [SVR] Discovered Commissioner #0\x1b[0m
584-
# The value '0' will be extracted from the string.
585-
valid_discovered_commissioner_number = valid_discovered_commissioner.split('#')[-1].replace('\x1b[0m', '')
596+
valid_discovered_commissioner_number = extract_value_from_string(
597+
valid_discovered_commissioner, 'Discovered Commissioner number', 'Commissioning', log_paths)
586598

587599
test_commissioning_fn(valid_discovered_commissioner_number, tv_casting_app_info, tv_app_info, log_paths)
588600
test_subscription_fn(tv_casting_app_info, log_paths)

0 commit comments

Comments
 (0)