Skip to content

Commit 06397cc

Browse files
shaoltan-amazonaustina-csa
authored andcommitted
Update Matter Casting automation test script to use the simplified Linux tv-casting-app build command in the workflow yaml file. (project-chip#34037)
* Update Matter Casting automation test script to use the simplified Linux tv-casting-app build command in the workflow yaml file. * Fix Linux tv-casting-app build issue by adding to args.gni file. * Fix Linux tv-casting-app build issue by removing unneeded comparison condition that always return true in simple-app-helper.cpp:392. * Addressed PR comments from @andy31415. * Fix lint and unit tests issues. * Addressed PR comment from @andy31415. * Addressed PR comment from @andy31415.
1 parent 594b555 commit 06397cc

File tree

8 files changed

+60
-41
lines changed

8 files changed

+60
-41
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
- name: Build Linux tv-casting-app
6262
run: |
6363
./scripts/run_in_build_env.sh \
64-
"scripts/examples/gn_build_example.sh examples/tv-casting-app/linux/ out/tv-casting-app"
64+
"scripts/examples/gn_build_example.sh examples/tv-casting-app/linux/ out/tv-casting-app chip_casting_simplified=true"
6565
6666
- name: Test casting from Linux tv-casting-app to Linux tv-app
6767
run: |

examples/tv-casting-app/linux/args.gni

+2
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ chip_enable_rotating_device_id = true
3232

3333
chip_max_discovered_ip_addresses = 20
3434

35+
enable_rtti = true
36+
3537
matter_enable_tracing_support = true

examples/tv-casting-app/linux/simple-app-helper.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ CHIP_ERROR CommandHandler(int argc, char ** argv)
389389
unsigned long index = static_cast<unsigned long>(strtol(argv[1], &eptr, 10));
390390
std::vector<matter::casting::memory::Strong<matter::casting::core::CastingPlayer>> castingPlayers =
391391
matter::casting::core::CastingPlayerDiscovery::GetInstance()->GetCastingPlayers();
392-
VerifyOrReturnValue(0 <= index && index < castingPlayers.size(), CHIP_ERROR_INVALID_ARGUMENT,
392+
VerifyOrReturnValue(index < castingPlayers.size(), CHIP_ERROR_INVALID_ARGUMENT,
393393
ChipLogError(AppServer, "Invalid casting player index provided: %lu", index));
394394
targetCastingPlayer = castingPlayers.at(index);
395395

scripts/build/build/targets.py

+1
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ def BuildHostTarget():
189189
target.AppendModifier('evse-test-event', enable_test_event_triggers=['EVSE']).OnlyIfRe('-energy-management')
190190
target.AppendModifier('enable-dnssd-tests', enable_dnssd_tests=True).OnlyIfRe('-tests')
191191
target.AppendModifier('disable-dnssd-tests', enable_dnssd_tests=False).OnlyIfRe('-tests')
192+
target.AppendModifier('chip-casting-simplified', chip_casting_simplified=True).OnlyIfRe('-tv-casting-app')
192193

193194
return target
194195

scripts/build/builders/host.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE,
313313
use_coverage=False, use_dmalloc=False, minmdns_address_policy=None,
314314
minmdns_high_verbosity=False, imgui_ui=False, crypto_library: HostCryptoLibrary = None,
315315
enable_test_event_triggers=None,
316-
enable_dnssd_tests: Optional[bool] = None
316+
enable_dnssd_tests: Optional[bool] = None,
317+
chip_casting_simplified: Optional[bool] = None
317318
):
318319
super(HostBuilder, self).__init__(
319320
root=os.path.join(root, 'examples', app.ExamplePath()),
@@ -428,6 +429,9 @@ def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE,
428429
else:
429430
self.extra_gn_options.append('chip_enable_dnssd_tests=false')
430431

432+
if chip_casting_simplified is not None:
433+
self.extra_gn_options.append(f'chip_casting_simplified={str(chip_casting_simplified).lower()}')
434+
431435
if self.board == HostBoard.ARM64:
432436
if not use_clang:
433437
raise Exception("Cross compile only supported using clang")

scripts/build/testdata/all_targets_linux_x64.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ efr32-{brd2704b,brd4316a,brd4317a,brd4318a,brd4319a,brd4186a,brd4187a,brd2601b,b
99
esp32-{m5stack,c3devkit,devkitc,qemu}-{all-clusters,all-clusters-minimal,energy-management,ota-provider,ota-requestor,shell,light,lock,bridge,temperature-measurement,ota-requestor,tests}[-rpc][-ipv6only][-tracing]
1010
genio-lighting-app
1111
linux-fake-tests[-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-coverage][-dmalloc][-clang]
12-
linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests]
12+
linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests][-chip-casting-simplified]
1313
linux-x64-efr32-test-runner[-clang]
1414
imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release]
1515
infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm]

scripts/tests/linux/tv_casting_test_sequences.py

+20-25
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
"""
2020
In this file, we define the test sequences with the relevant steps that will be used in the `scripts/tests/run_tv_casting_test.py`
21-
for validating the casting experience between the Linux tv-casting-app and the Linux tv-app.
21+
test script for validating the casting experience between the Linux tv-casting-app and the Linux tv-app.
2222
2323
At the beginning of each test sequence we need to indicate the start up of the tv-app using the `START_APP` string as the `input_cmd`
2424
followed by the same for the tv-casting-app. On the other hand, at the end of each test sequence we need to ensure that each app will
@@ -71,11 +71,8 @@
7171
PRODUCT_ID = 0x8001 # Test product id
7272
DEVICE_TYPE_CASTING_VIDEO_PLAYER = 0x23 # Device type library 10.3: Casting Video Player
7373

74-
TEST_TV_CASTING_APP_DEVICE_NAME = 'Test TV casting app' # Test device name for identifying the tv-casting-app
75-
76-
# Values to verify the subscription state against from the `ReportDataMessage` in the Linux tv-casting-app output.
77-
CLUSTER_MEDIA_PLAYBACK = '0x506' # Application Cluster Spec 6.10.3 Cluster ID: Media Playback
78-
ATTRIBUTE_CURRENT_PLAYBACK_STATE = '0x0000_0000' # Application Cluster Spec 6.10.6 Attribute ID: Current State of Playback
74+
# Value to verify the subscription state against in the Linux tv-casting-app output.
75+
ATTRIBUTE_CURRENT_PLAYBACK_STATE = 0x0000_0000 # Application Cluster Spec 6.10.6 Attribute ID: Current State of Playback
7976

8077
test_sequences = [
8178
Sequence(
@@ -93,27 +90,24 @@
9390
# Validate that the server is properly initialized in the tv-casting-app output.
9491
Step(app=App.TV_CASTING_APP, timeout_sec=APP_MAX_START_WAIT_SEC, output_msg=['Server initialization complete']),
9592

96-
# Validate that there is a valid discovered commissioner with {VENDOR_ID}, {PRODUCT_ID}, and {DEVICE_TYPE_CASTING_VIDEO_PLAYER} in the tv-casting-app output.
97-
Step(app=App.TV_CASTING_APP, output_msg=['Discovered Commissioner #0', f'Vendor ID: {VENDOR_ID}', f'Product ID: {PRODUCT_ID}',
93+
# Validate that there is a valid discovered casting player with {PRODUCT_ID}, {VENDOR_ID}, and {DEVICE_TYPE_CASTING_VIDEO_PLAYER} in the tv-casting-app output.
94+
Step(app=App.TV_CASTING_APP, output_msg=['Discovered CastingPlayer #0', f'Product ID: {PRODUCT_ID}', f'Vendor ID: {VENDOR_ID}',
9895
f'Device Type: {DEVICE_TYPE_CASTING_VIDEO_PLAYER}', 'Supports Commissioner Generated Passcode: true']),
9996

100-
# Validate that we are ready to send `cast request` command to the tv-casting-app subprocess.
101-
Step(app=App.TV_CASTING_APP, output_msg=['Example: cast request 0']),
102-
10397
# Send `cast request {valid_discovered_commissioner_number}\n` command to the tv-casting-app subprocess.
10498
Step(app=App.TV_CASTING_APP, input_cmd='cast request 0\n'),
10599

106-
# Validate that the `Identification Declaration` message block in the tv-casting-app output has the expected values for `device Name`, `vendor id`, and `product id`.
107-
Step(app=App.TV_CASTING_APP, output_msg=['Identification Declaration Start', f'device Name: {TEST_TV_CASTING_APP_DEVICE_NAME}',
108-
f'vendor id: {VENDOR_ID}', f'product id: {PRODUCT_ID}', 'Identification Declaration End']),
100+
# Validate that the tv-casting-app begins the commissioning process.
101+
Step(app=App.TV_CASTING_APP, output_msg=[
102+
'CastingPlayer::VerifyOrEstablishConnection() calling OpenBasicCommissioningWindow()']),
109103

110-
# Validate that the `Identification Declaration` message block in the tv-app output has the expected values for `device Name`, `vendor id`, and `product id`.
111-
Step(app=App.TV_APP, output_msg=['Identification Declaration Start', f'device Name: {TEST_TV_CASTING_APP_DEVICE_NAME}',
112-
f'vendor id: {VENDOR_ID}', f'product id: {PRODUCT_ID}', 'Identification Declaration End']),
104+
# Validate that the `IdentificationDeclaration` message sent from the tv-casting-app to the tv-app will contain the {VENDOR_ID} of the target content app.
105+
Step(app=App.TV_CASTING_APP, output_msg=['IdentificationDeclarationOptions::TargetAppInfos list:']),
106+
Step(app=App.TV_CASTING_APP, output_msg=[f'TargetAppInfo 1, Vendor ID: {VENDOR_ID}']),
113107

114108
# Validate that we received the cast request from the tv-casting-app on the tv-app output.
115109
Step(app=App.TV_APP,
116-
output_msg=['PROMPT USER: Test TV casting app is requesting permission to cast to this TV, approve?']),
110+
output_msg=['------PROMPT USER: Test TV casting app is requesting permission to cast to this TV, approve?']),
117111

118112
# Validate that we received the instructions on the tv-app output for sending the `controller ux ok` command.
119113
Step(app=App.TV_APP, output_msg=['Via Shell Enter: controller ux ok|cancel']),
@@ -124,23 +118,24 @@
124118
# Validate that pairing succeeded between the tv-casting-app and the tv-app.
125119
Step(app=App.TV_APP, output_msg=['Secure Pairing Success']),
126120

127-
# Validate that commissioning succeeded in the tv-casting-app output.
128-
Step(app=App.TV_CASTING_APP, output_msg=['Commissioning completed successfully']),
121+
# Validate that the connection succeeded in the tv-casting-app output.
122+
Step(app=App.TV_CASTING_APP, output_msg=['Successfully connected to CastingPlayer']),
129123

130124
# Validate that commissioning succeeded in the tv-app output.
131125
Step(app=App.TV_APP, output_msg=['------PROMPT USER: commissioning success']),
132126

133-
# Validate the subscription state by looking at the `Cluster` and `Attribute` values in the `ReportDataMessage` block in the tv-casting-app output.
134-
Step(app=App.TV_CASTING_APP, output_msg=[
135-
'ReportDataMessage =', f'Cluster = {CLUSTER_MEDIA_PLAYBACK}', f'Attribute = {ATTRIBUTE_CURRENT_PLAYBACK_STATE}', 'InteractionModelRevision =', '}']),
127+
# Validate that we are able to read the application VendorID value and that it matches {VENDOR_ID}.
128+
Step(app=App.TV_CASTING_APP, output_msg=[f'Read VendorID value: {VENDOR_ID}']),
129+
130+
# Validate that we are able to subscribe to the media playback cluster by reading the CurrentState value and that it matches {ATTRIBUTE_CURRENT_PLAYBACK_STATE}.
131+
Step(app=App.TV_CASTING_APP, output_msg=[f'Read CurrentState value: {ATTRIBUTE_CURRENT_PLAYBACK_STATE}']),
136132

137133
# Validate the LaunchURL in the tv-app output.
138134
Step(app=App.TV_APP,
139135
output_msg=['ContentLauncherManager::HandleLaunchUrl TEST CASE ContentURL=https://www.test.com/videoid DisplayString=Test video']),
140136

141137
# Validate the LaunchURL in the tv-casting-app output.
142-
Step(app=App.TV_CASTING_APP, output_msg=['InvokeResponseMessage =',
143-
'exampleData', 'InteractionModelRevision =', '},']),
138+
Step(app=App.TV_CASTING_APP, output_msg=['LaunchURL Success with response.data: exampleData']),
144139

145140
# Signal to stop the tv-casting-app as we finished validation.
146141
Step(app=App.TV_CASTING_APP, input_cmd=STOP_APP),

scripts/tests/run_tv_casting_test.py

+29-12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17+
import glob
1718
import logging
1819
import os
1920
import signal
@@ -63,6 +64,19 @@ def __exit__(self, exception_type, exception_value, traceback):
6364
self.process.wait()
6465

6566

67+
def remove_cached_files(cached_file_pattern: str):
68+
"""Remove any cached files that match the provided pattern."""
69+
70+
cached_files = glob.glob(cached_file_pattern) # Returns a list of paths that match the pattern.
71+
72+
for cached_file in cached_files:
73+
try:
74+
os.remove(cached_file)
75+
except OSError as e:
76+
logging.error(f'Failed to remove cached file `{cached_file}` with error: `{e.strerror}`')
77+
raise # Re-raise the OSError to propagate it up.
78+
79+
6680
def dump_temporary_logs_to_console(log_file_path: str):
6781
"""Dump log file to the console; log file will be removed once the function exits."""
6882
"""Write the entire content of `log_file_path` to the console."""
@@ -86,7 +100,7 @@ def handle_casting_failure(test_sequence_name: str, log_file_paths: List[str]):
86100
sys.exit(1)
87101

88102

89-
def stop_app(test_sequence_name: str, app_name: str, app: subprocess.Popen):
103+
def stop_app(test_sequence_name: str, app_name: str, app: subprocess.Popen) -> bool:
90104
"""Stop the given `app` subprocess."""
91105

92106
app.terminate()
@@ -115,7 +129,7 @@ def parse_output_msg_in_subprocess(
115129
log_paths: List[str],
116130
test_sequence_name: str,
117131
test_sequence_step: Step
118-
):
132+
) -> bool:
119133
"""Parse the output of a given `app` subprocess and validate its output against the expected `output_msg` in the given `Step`."""
120134

121135
if not test_sequence_step.output_msg:
@@ -168,25 +182,22 @@ def send_input_cmd_to_subprocess(
168182
tv_app_info: Tuple[subprocess.Popen, TextIO],
169183
test_sequence_name: str,
170184
test_sequence_step: Step
171-
):
185+
) -> bool:
172186
"""Send a given input command (`input_cmd`) from the `Step` to its given `app` subprocess."""
173187

174188
if not test_sequence_step.input_cmd:
175189
logging.error(f'{test_sequence_name} - No input command provided in the test sequence step.')
176190
return False
177191

178192
app_subprocess, app_log_file = (tv_casting_app_info if test_sequence_step.app == App.TV_CASTING_APP else tv_app_info)
193+
app_name = test_sequence_step.app.value
179194

180-
app_subprocess.stdin.write(test_sequence_step.input_cmd)
195+
input_cmd = test_sequence_step.input_cmd
196+
app_subprocess.stdin.write(input_cmd)
181197
app_subprocess.stdin.flush()
182198

183-
# Read in the next line which should be the `input_cmd` that was issued.
184-
next_line = app_subprocess.stdout.readline()
185-
app_log_file.write(next_line)
186-
app_log_file.flush()
187-
next_line = next_line.rstrip('\n')
188-
189-
logging.info(f'{test_sequence_name} - Sent `{next_line}` to the {test_sequence_step.app.value} subprocess.')
199+
input_cmd = input_cmd.rstrip('\n')
200+
logging.info(f'{test_sequence_name} - Sent `{input_cmd}` to the {app_name} subprocess.')
190201

191202
return True
192203

@@ -338,7 +349,13 @@ def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path):
338349
if __name__ == '__main__':
339350

340351
# Start with a clean slate by removing any previously cached entries.
341-
os.system('rm -f /tmp/chip_*')
352+
try:
353+
cached_file_pattern = '/tmp/chip_*'
354+
remove_cached_files(cached_file_pattern)
355+
except OSError:
356+
logging.error(
357+
f'Error while removing cached files with file pattern: {cached_file_pattern}')
358+
sys.exit(1)
342359

343360
# Test casting (discovery and commissioning) between the Linux tv-casting-app and the tv-app.
344361
test_casting_fn()

0 commit comments

Comments
 (0)