Skip to content

Commit

Permalink
[CI] Implement IM tests for Kotlin API (#29717)
Browse files Browse the repository at this point in the history
  • Loading branch information
yufengwangca authored and pull[bot] committed Dec 20, 2023
1 parent 7c15694 commit 3459029
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 1 deletion.
53 changes: 52 additions & 1 deletion .github/workflows/java-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ jobs:
--target linux-x64-java-matter-controller \
build \
"
- name: Build Kotlin Matter Controller
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-kotlin-matter-controller \
build \
"
- name: Run Discover Commissionables Test
run: |
scripts/run_in_python_env.sh out/venv \
Expand Down Expand Up @@ -202,7 +209,51 @@ jobs:
--tool-cluster "pairing" \
--tool-args "code --nodeid 1 --setup-payload 34970112332 --discover-once 1 --use-only-onnetwork-discovery 0 -t 1000" \
--factoryreset \
'
'
- name: Run Kotlin IM Invoke Test
run: |
scripts/run_in_python_env.sh out/venv \
'./scripts/tests/run_kotlin_test.py \
--app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app \
--app-args "--discriminator 3840 --interface-id -1" \
--tool-path out/linux-x64-kotlin-matter-controller \
--tool-cluster "im" \
--tool-args "onnetwork-long-im-invoke --nodeid 1 --setup-pin-code 20202021 --discriminator 3840 -t 1000" \
--factoryreset \
'
- name: Run Kotlin IM Read Test
run: |
scripts/run_in_python_env.sh out/venv \
'./scripts/tests/run_kotlin_test.py \
--app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app \
--app-args "--discriminator 3840 --interface-id -1" \
--tool-path out/linux-x64-kotlin-matter-controller \
--tool-cluster "im" \
--tool-args "onnetwork-long-im-read --nodeid 1 --setup-pin-code 20202021 --discriminator 3840 -t 1000" \
--factoryreset \
'
- name: Run Kotlin IM Write Test
run: |
scripts/run_in_python_env.sh out/venv \
'./scripts/tests/run_kotlin_test.py \
--app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app \
--app-args "--discriminator 3840 --interface-id -1" \
--tool-path out/linux-x64-kotlin-matter-controller \
--tool-cluster "im" \
--tool-args "onnetwork-long-im-write --nodeid 1 --setup-pin-code 20202021 --discriminator 3840 -t 1000" \
--factoryreset \
'
- name: Run Kotlin IM Subscribe Test
run: |
scripts/run_in_python_env.sh out/venv \
'./scripts/tests/run_kotlin_test.py \
--app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app \
--app-args "--discriminator 3840 --interface-id -1" \
--tool-path out/linux-x64-kotlin-matter-controller \
--tool-cluster "im" \
--tool-args "onnetwork-long-im-subscribe --nodeid 1 --setup-pin-code 20202021 --discriminator 3840 -t 1000" \
--factoryreset \
'
- name: Uploading core files
uses: actions/upload-artifact@v3
if: ${{ failure() && !env.ACT }}
Expand Down
125 changes: 125 additions & 0 deletions scripts/tests/run_kotlin_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/usr/bin/env -S python3 -B

# Copyright (c) 2023 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
import os
import queue
import re
import shlex
import signal
import subprocess
import sys

import click
import coloredlogs
from colorama import Fore, Style
from java.base import DumpProgramOutputToQueue
from java.im_test import IMTest


@click.command()
@click.option("--app", type=click.Path(exists=True), default=None,
help='Path to local application to use, omit to use external apps.')
@click.option("--app-args", type=str, default='',
help='The extra arguments passed to the device.')
@click.option("--tool-path", type=click.Path(exists=True), default=None,
help='Path to java-matter-controller.')
@click.option("--tool-cluster", type=str, default='pairing',
help='The cluster name passed to the java-matter-controller.')
@click.option("--tool-args", type=str, default='',
help='The arguments passed to the java-matter-controller.')
@click.option("--factoryreset", is_flag=True,
help='Remove app configs (/tmp/chip*) before running the tests.')
def main(app: str, app_args: str, tool_path: str, tool_cluster: str, tool_args: str, factoryreset: bool):
logging.info("Execute: {script_command}")

if factoryreset:
# Remove native app config
retcode = subprocess.call("rm -rf /tmp/chip*", shell=True)
if retcode != 0:
raise Exception("Failed to remove /tmp/chip* for factory reset.")

print("Contents of test directory: %s" % os.getcwd())
print(subprocess.check_output(["ls -l"], shell=True).decode('utf-8'))

# Remove native app KVS if that was used
kvs_match = re.search(r"--KVS (?P<kvs_path>[^ ]+)", app_args)
if kvs_match:
kvs_path_to_remove = kvs_match.group("kvs_path")
retcode = subprocess.call("rm -f %s" % kvs_path_to_remove, shell=True)
print("Trying to remove KVS path %s" % kvs_path_to_remove)
if retcode != 0:
raise Exception("Failed to remove %s for factory reset." % kvs_path_to_remove)

coloredlogs.install(level='INFO')

log_queue = queue.Queue()
log_cooking_threads = []

if tool_path:
if not os.path.exists(tool_path):
if tool_path is None:
raise FileNotFoundError(f"{tool_path} not found")

app_process = None
if app:
if not os.path.exists(app):
if app is None:
raise FileNotFoundError(f"{app} not found")
app_args = [app] + shlex.split(app_args)
logging.info(f"Execute: {app_args}")
app_process = subprocess.Popen(
app_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0)
DumpProgramOutputToQueue(
log_cooking_threads, Fore.GREEN + "APP " + Style.RESET_ALL, app_process, log_queue)

command = ['java',
f'-Djava.library.path={tool_path}/lib/jni',
'-cp',
':'.join([
f'{tool_path}/lib/*',
f'{tool_path}/lib/third_party/connectedhomeip/src/controller/java/*',
f'{tool_path}/bin/kotlin-matter-controller',
]),
'com.matter.controller.MainKt']

if tool_cluster == 'im':
logging.info("Testing IM")

test = IMTest(log_cooking_threads, log_queue, command, tool_args)
try:
test.RunTest()
except Exception as e:
logging.error(e)
sys.exit(1)

app_exit_code = 0
if app_process:
logging.warning("Stopping app with SIGINT")
app_process.send_signal(signal.SIGINT.value)
app_exit_code = app_process.wait()

# There are some logs not cooked, so we wait until we have processed all logs.
# This procedure should be very fast since the related processes are finished.
for thread in log_cooking_threads:
thread.join()

# We expect app should exit with 0
sys.exit(app_exit_code)


if __name__ == '__main__':
main()

0 comments on commit 3459029

Please sign in to comment.