diff --git a/src/tools/interop/idt/README.md b/src/tools/interop/idt/README.md index 8786f70676032a..b069f9682775af 100644 --- a/src/tools/interop/idt/README.md +++ b/src/tools/interop/idt/README.md @@ -192,8 +192,8 @@ Follow the Linux installation steps above, but do not use Docker. > **_IMPORTANT_** > `idt_` commands are shell aliases helpful for administrative commands. -> `idt` invokes the `idt` python package. -> Output from `idt` will always be colorized while output from subprocesses is white. +> `idt` invokes the `idt` python package. +> Output from `idt` will always be colorized while output from subprocesses is generally not. RPi users, as needed: diff --git a/src/tools/interop/idt/capture/config.py b/src/tools/interop/idt/capture/config.py index d1ef279c34c251..ebcd13f8bbe2b5 100644 --- a/src/tools/interop/idt/capture/config.py +++ b/src/tools/interop/idt/capture/config.py @@ -18,3 +18,4 @@ import logging log_level = logging.INFO +async_timeout = 45.0 diff --git a/src/tools/interop/idt/capture/ecosystem/play_services/analysis.py b/src/tools/interop/idt/capture/ecosystem/play_services/analysis.py index fcd2a35c361b0b..63a20da23ef876 100644 --- a/src/tools/interop/idt/capture/ecosystem/play_services/analysis.py +++ b/src/tools/interop/idt/capture/ecosystem/play_services/analysis.py @@ -17,8 +17,8 @@ import os -from capture.file_utils import add_border, create_standard_log_name -from capture.log_format import print_and_write +from capture.utils.artifact import create_standard_log_name +from capture.utils.log import print_and_write, add_border from capture.platform.android import Android diff --git a/src/tools/interop/idt/capture/ecosystem/play_services/play_services.py b/src/tools/interop/idt/capture/ecosystem/play_services/play_services.py index 0862479351475b..76d0b94eb264c7 100644 --- a/src/tools/interop/idt/capture/ecosystem/play_services/play_services.py +++ b/src/tools/interop/idt/capture/ecosystem/play_services/play_services.py @@ -19,9 +19,8 @@ import os from typing import Dict -from capture import log_format from capture.base import EcosystemCapture, UnsupportedCapturePlatformException -from capture.file_utils import create_standard_log_name +from capture.utils.artifact import create_standard_log_name from capture.platform.android import Android from . import config @@ -30,13 +29,17 @@ from .prober import PlayServicesProber +from capture.utils import log + +logger = log.get_logger(__file__) + class PlayServices(EcosystemCapture): """ Implementation of capture and analysis for Play Services """ def __init__(self, platform: Android, artifact_dir: str) -> None: - self.logger = log_format.get_logger(__file__) + self.logger = logger self.artifact_dir = artifact_dir if not isinstance(platform, Android): diff --git a/src/tools/interop/idt/capture/ecosystem/play_services/prober.py b/src/tools/interop/idt/capture/ecosystem/play_services/prober.py index 972a78b1914f94..37722597715610 100644 --- a/src/tools/interop/idt/capture/ecosystem/play_services/prober.py +++ b/src/tools/interop/idt/capture/ecosystem/play_services/prober.py @@ -17,8 +17,7 @@ import os -from capture import log_format -from capture.shell_utils import Bash +from capture.utils.shell import Bash class PlayServicesProber: diff --git a/src/tools/interop/idt/capture/ecosystem/play_services_user/play_services_user.py b/src/tools/interop/idt/capture/ecosystem/play_services_user/play_services_user.py index 120e4c26bae520..a661227cc15fa0 100644 --- a/src/tools/interop/idt/capture/ecosystem/play_services_user/play_services_user.py +++ b/src/tools/interop/idt/capture/ecosystem/play_services_user/play_services_user.py @@ -18,8 +18,8 @@ import os from capture.base import EcosystemCapture, UnsupportedCapturePlatformException -from capture.file_utils import create_standard_log_name -from capture.log_format import print_and_write +from capture.utils.artifact import create_standard_log_name +from capture.utils.log import print_and_write from capture.platform.android.android import Android diff --git a/src/tools/interop/idt/capture/factory.py b/src/tools/interop/idt/capture/factory.py index 1a95683a2383ea..661d4f5abc66c7 100644 --- a/src/tools/interop/idt/capture/factory.py +++ b/src/tools/interop/idt/capture/factory.py @@ -22,21 +22,19 @@ import typing import capture -from capture import log_format +from capture.utils import log +from capture.utils.async_control import get_timeout from capture.base import EcosystemCapture, PlatformLogStreamer, UnsupportedCapturePlatformException -from capture.file_utils import safe_mkdir -from capture.log_format import border_print +from capture.utils.artifact import safe_mkdir +from capture.utils.log import border_print -_CONFIG_TIMEOUT = 45.0 _PLATFORM_MAP: typing.Dict[str, PlatformLogStreamer] = {} _ECOSYSTEM_MAP: typing.Dict[str, PlatformLogStreamer] = {} _ERROR_REPORT: typing.Dict[str, list[str]] = {} -logger = log_format.get_logger(__file__) +from capture.utils import log -def _get_timeout(): - return asyncio.get_running_loop().time() + _CONFIG_TIMEOUT - +logger = log.get_logger(__file__) class PlatformFactory: @@ -82,7 +80,7 @@ async def get_ecosystem_impl( @staticmethod async def init_ecosystems(platform, ecosystem, artifact_dir): - async with asyncio.timeout_at(_get_timeout()): + async with asyncio.timeout_at(get_timeout()): platform = await PlatformFactory.get_platform_impl( platform, artifact_dir) ecosystems_to_load = EcosystemFactory.list_available_ecosystems() \ @@ -90,7 +88,7 @@ async def init_ecosystems(platform, ecosystem, artifact_dir): else [ecosystem] for ecosystem in ecosystems_to_load: try: - async with asyncio.timeout_at(_get_timeout()): + async with asyncio.timeout_at(get_timeout()): await EcosystemFactory.get_ecosystem_impl( ecosystem, platform, artifact_dir) except UnsupportedCapturePlatformException: @@ -116,7 +114,7 @@ async def handle_capture(attr): for ecosystem in _ECOSYSTEM_MAP: try: border_print(f"{attr} for {ecosystem}") - async with asyncio.timeout_at(_get_timeout()): + async with asyncio.timeout_at(get_timeout()): await getattr(_ECOSYSTEM_MAP[ecosystem], attr)() except TimeoutError: logger.error(f"timeout {attr} {ecosystem}") diff --git a/src/tools/interop/idt/capture/loader.py b/src/tools/interop/idt/capture/loader.py index e0709e1c289b24..a765bed8bcbc12 100644 --- a/src/tools/interop/idt/capture/loader.py +++ b/src/tools/interop/idt/capture/loader.py @@ -21,9 +21,9 @@ import traceback from typing import Any -from capture import log_format +from capture.utils import log -logger = log_format.get_logger(__file__) +logger = log.get_logger(__file__) class CaptureImplsLoader: diff --git a/src/tools/interop/idt/capture/pcap/pcap.py b/src/tools/interop/idt/capture/pcap/pcap.py index 45028027c642d3..2fea8d498ce825 100644 --- a/src/tools/interop/idt/capture/pcap/pcap.py +++ b/src/tools/interop/idt/capture/pcap/pcap.py @@ -18,15 +18,18 @@ import os import time -from capture import log_format -from capture.file_utils import create_standard_log_name -from capture.shell_utils import Bash +from capture.utils.artifact import create_standard_log_name +from capture.utils.shell import Bash + +from capture.utils import log + +logger = log.get_logger(__file__) class PacketCaptureRunner: def __init__(self, artifact_dir: str, interface: str) -> None: - self.logger = log_format.get_logger(__file__) + self.logger = logger self.artifact_dir = artifact_dir self.output_path = str( os.path.join( diff --git a/src/tools/interop/idt/capture/platform/android/android.py b/src/tools/interop/idt/capture/platform/android/android.py index ab537e9ba1dcc3..114a496afbd965 100644 --- a/src/tools/interop/idt/capture/platform/android/android.py +++ b/src/tools/interop/idt/capture/platform/android/android.py @@ -20,14 +20,15 @@ import traceback import typing -from capture import log_format from capture.base import PlatformLogStreamer -from capture.shell_utils import Bash +from capture.utils.shell import Bash from . import config from . import streams from .capabilities import Capabilities -logger = log_format.get_logger(__file__) +from capture.utils import log + +logger = log.get_logger(__file__) class Android(PlatformLogStreamer): diff --git a/src/tools/interop/idt/capture/platform/android/capabilities.py b/src/tools/interop/idt/capture/platform/android/capabilities.py index b713b5c49e1a1a..1587f565623552 100644 --- a/src/tools/interop/idt/capture/platform/android/capabilities.py +++ b/src/tools/interop/idt/capture/platform/android/capabilities.py @@ -1,12 +1,13 @@ from typing import TYPE_CHECKING -from capture import log_format -from capture.shell_utils import Bash +from capture.utils.shell import Bash if TYPE_CHECKING: from capture.platform.android import Android -logger = log_format.get_logger(__file__) +from capture.utils import log + +logger = log.get_logger(__file__) class Capabilities: diff --git a/src/tools/interop/idt/capture/platform/android/streams/logcat/logcat.py b/src/tools/interop/idt/capture/platform/android/streams/logcat/logcat.py index 1adc035c6ed44c..d34f34d9115420 100644 --- a/src/tools/interop/idt/capture/platform/android/streams/logcat/logcat.py +++ b/src/tools/interop/idt/capture/platform/android/streams/logcat/logcat.py @@ -15,7 +15,7 @@ # limitations under the License. # -from capture.file_utils import create_standard_log_name +from capture.utils.artifact import create_standard_log_name from typing import TYPE_CHECKING from ..base import AndroidStream diff --git a/src/tools/interop/idt/capture/platform/android/streams/android_pcap/__init__.py b/src/tools/interop/idt/capture/platform/android/streams/pcap/__init__.py similarity index 94% rename from src/tools/interop/idt/capture/platform/android/streams/android_pcap/__init__.py rename to src/tools/interop/idt/capture/platform/android/streams/pcap/__init__.py index cbd2cc919831ec..846210798129ff 100644 --- a/src/tools/interop/idt/capture/platform/android/streams/android_pcap/__init__.py +++ b/src/tools/interop/idt/capture/platform/android/streams/pcap/__init__.py @@ -15,6 +15,6 @@ # limitations under the License. # -from .android_pcap import AndroidPcap +from .pcap import AndroidPcap __all__ = ["AndroidPcap"] diff --git a/src/tools/interop/idt/capture/platform/android/streams/android_pcap/build_tcpdump_64.sh b/src/tools/interop/idt/capture/platform/android/streams/pcap/build_tcpdump_64.sh similarity index 96% rename from src/tools/interop/idt/capture/platform/android/streams/android_pcap/build_tcpdump_64.sh rename to src/tools/interop/idt/capture/platform/android/streams/pcap/build_tcpdump_64.sh index 914da032c6f477..e93b4dad9794dc 100755 --- a/src/tools/interop/idt/capture/platform/android/streams/android_pcap/build_tcpdump_64.sh +++ b/src/tools/interop/idt/capture/platform/android/streams/pcap/build_tcpdump_64.sh @@ -37,7 +37,7 @@ export CFLAGS=-static export CPPFLAGS=-static export LDFLAGS=-static -./configure --host=arm-linux # --disable-ipv6 +./configure --host=arm-linux make aarch64-linux-gnu-strip tcpdump diff --git a/src/tools/interop/idt/capture/platform/android/streams/android_pcap/android_pcap.py b/src/tools/interop/idt/capture/platform/android/streams/pcap/pcap.py similarity index 91% rename from src/tools/interop/idt/capture/platform/android/streams/android_pcap/android_pcap.py rename to src/tools/interop/idt/capture/platform/android/streams/pcap/pcap.py index 83ee4a64068392..7a22d5b023ca63 100644 --- a/src/tools/interop/idt/capture/platform/android/streams/android_pcap/android_pcap.py +++ b/src/tools/interop/idt/capture/platform/android/streams/pcap/pcap.py @@ -18,9 +18,8 @@ import asyncio import os -from capture import log_format -from capture.file_utils import create_standard_log_name, safe_mkdir -from capture.shell_utils import Bash +from capture.utils.artifact import create_standard_log_name, safe_mkdir +from capture.utils.shell import Bash from typing import TYPE_CHECKING from ... import config from ..base import AndroidStream @@ -28,7 +27,9 @@ if TYPE_CHECKING: from capture.platform.android import Android -logger = log_format.get_logger(__file__) +from capture.utils import log + +logger = log.get_logger(__file__) class AndroidPcap(AndroidStream): @@ -53,9 +54,8 @@ async def pull_packet_capture(self) -> None: self.pcap_pull = False async def start(self): - safe_mkdir(self.build_dir) if self.platform.capabilities.has_tcpdump: - self.logger.info("tcpdump already available on this phone; using!") + self.logger.info("tcpdump already available; using!") self.pcap_proc.start_command() self.pcap_pull = True return @@ -63,6 +63,7 @@ async def start(self): self.logger.critical("Android TCP Dump build and push disabled in configs!") return if not os.path.exists(os.path.join(self.build_dir, "tcpdump")): + safe_mkdir(self.build_dir) self.logger.warning("tcpdump bin not found, attempting to build, please wait a few moments!") build_script = os.path.join(os.path.dirname(__file__), "build_tcpdump_64.sh") Bash(f"{build_script} 2>&1 >> BUILD_LOG.txt", sync=True, cwd=self.build_dir).start_command() @@ -74,6 +75,7 @@ async def start(self): self.platform.run_adb_command("chmod +x /sdcard/Movies/tcpdump") else: self.logger.info("tcpdump already in the expected location, not pushing!") + self.logger.info("Starting Android pcap command") self.pcap_proc.start_command() self.pcap_pull = True diff --git a/src/tools/interop/idt/capture/platform/android/streams/screen/screen.py b/src/tools/interop/idt/capture/platform/android/streams/screen/screen.py index fd61551752052a..149c2499bea5e8 100644 --- a/src/tools/interop/idt/capture/platform/android/streams/screen/screen.py +++ b/src/tools/interop/idt/capture/platform/android/streams/screen/screen.py @@ -18,15 +18,17 @@ import asyncio import os -from capture import log_format -from capture.file_utils import create_standard_log_name +from capture.utils import log +from capture.utils.artifact import create_standard_log_name from typing import TYPE_CHECKING from ..base import AndroidStream if TYPE_CHECKING: from capture.platform.android import Android -logger = log_format.get_logger(__file__) +from capture.utils import log + +logger = log.get_logger(__file__) class ScreenRecorder(AndroidStream): diff --git a/src/tools/interop/idt/capture/utils/__init__.py b/src/tools/interop/idt/capture/utils/__init__.py new file mode 100644 index 00000000000000..af291fc35e5e75 --- /dev/null +++ b/src/tools/interop/idt/capture/utils/__init__.py @@ -0,0 +1,25 @@ +# +# Copyright (c) 2023 Project CHIP Authors +# All rights reserved. +# +# 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. +# + +from . import artifact, async_control, log, shell + +__all__ = [ + 'artifact', + 'async_control', + 'log', + 'shell', +] diff --git a/src/tools/interop/idt/capture/file_utils.py b/src/tools/interop/idt/capture/utils/artifact.py similarity index 88% rename from src/tools/interop/idt/capture/file_utils.py rename to src/tools/interop/idt/capture/utils/artifact.py index f89e3bd5b861cd..f6b6e3d8321020 100644 --- a/src/tools/interop/idt/capture/file_utils.py +++ b/src/tools/interop/idt/capture/utils/artifact.py @@ -20,11 +20,6 @@ from pathlib import Path -def add_border(to_print: str) -> str: - """Add star borders to important strings""" - return '\n' + '*' * len(to_print) + '\n' + to_print - - def create_file_timestamp() -> str: """Conventional file timestamp suffix""" return time.strftime("%Y%m%d_%H%M%S") diff --git a/src/tools/interop/idt/capture/utils/async_control.py b/src/tools/interop/idt/capture/utils/async_control.py new file mode 100644 index 00000000000000..d0e6f666b6a416 --- /dev/null +++ b/src/tools/interop/idt/capture/utils/async_control.py @@ -0,0 +1,24 @@ +# +# Copyright (c) 2023 Project CHIP Authors +# All rights reserved. +# +# 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 asyncio + +from capture import config + + +def get_timeout(): + return asyncio.get_running_loop().time() + config.async_timeout diff --git a/src/tools/interop/idt/capture/log_format.py b/src/tools/interop/idt/capture/utils/log.py similarity index 93% rename from src/tools/interop/idt/capture/log_format.py rename to src/tools/interop/idt/capture/utils/log.py index a552ddebb7805d..aae9b5fa56d74d 100644 --- a/src/tools/interop/idt/capture/log_format.py +++ b/src/tools/interop/idt/capture/utils/log.py @@ -18,7 +18,7 @@ import logging from typing import TextIO -from . import config +from capture import config _CONFIG_LEVEL = config.log_level @@ -74,3 +74,8 @@ def border_print(to_print: str, important: bool = False) -> None: def print_and_write(to_print: str, file: TextIO) -> None: print(f"\x1b[32;1m{to_print}\x1b[0m") file.write(to_print) + + +def add_border(to_print: str) -> str: + """Add star borders to important strings""" + return '\n' + '*' * len(to_print) + '\n' + to_print diff --git a/src/tools/interop/idt/capture/shell_utils.py b/src/tools/interop/idt/capture/utils/shell.py similarity index 97% rename from src/tools/interop/idt/capture/shell_utils.py rename to src/tools/interop/idt/capture/utils/shell.py index 6365d9e9996aaf..97eb9431b488e9 100644 --- a/src/tools/interop/idt/capture/shell_utils.py +++ b/src/tools/interop/idt/capture/utils/shell.py @@ -18,10 +18,11 @@ import shlex import subprocess -from capture import log_format from mobly.utils import stop_standing_subprocess -logger = log_format.get_logger(__file__) +from capture.utils import log + +logger = log.get_logger(__file__) class Bash: diff --git a/src/tools/interop/idt/discovery/__init__.py b/src/tools/interop/idt/discovery/__init__.py index f9a1aa665a86d8..b83e5dfe0e1f50 100644 --- a/src/tools/interop/idt/discovery/__init__.py +++ b/src/tools/interop/idt/discovery/__init__.py @@ -14,8 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from .matter_ble import MatterBleScanner -from .matter_dnssd import MatterDnssdListener +from .ble import MatterBleScanner +from .dnssd import MatterDnssdListener __all__ = [ 'MatterBleScanner', diff --git a/src/tools/interop/idt/discovery/matter_ble.py b/src/tools/interop/idt/discovery/ble.py similarity index 100% rename from src/tools/interop/idt/discovery/matter_ble.py rename to src/tools/interop/idt/discovery/ble.py diff --git a/src/tools/interop/idt/discovery/matter_dnssd.py b/src/tools/interop/idt/discovery/dnssd.py similarity index 100% rename from src/tools/interop/idt/discovery/matter_dnssd.py rename to src/tools/interop/idt/discovery/dnssd.py diff --git a/src/tools/interop/idt/idt.py b/src/tools/interop/idt/idt.py index 8d0e50ae7c3fc7..61efee7d437dde 100644 --- a/src/tools/interop/idt/idt.py +++ b/src/tools/interop/idt/idt.py @@ -17,22 +17,33 @@ import argparse import asyncio -import logging import os import shutil import sys from pathlib import Path from capture import EcosystemController, EcosystemFactory, PacketCaptureRunner, PlatformFactory -from capture.file_utils import create_file_timestamp, safe_mkdir -from capture.log_format import border_print +from capture.utils.artifact import create_file_timestamp, safe_mkdir +from capture.utils.log import border_print from discovery import MatterBleScanner, MatterDnssdListener +splash = '''\x1b[0m +\x1b[32;1m┌────────┬\x1b[34;1m──────┐\x1b[35;1m┌──────────┐ +\x1b[32;1m│░░░░░░░░│\x1b[34;1m░░░░░░└\x1b[35;1m┤░░░░░░░░░░│ +\x1b[32;1m└──┐░░┌──┤\x1b[34;1m░░┌┐░░░├\x1b[35;1m───┐░░┌───┘ +\x1b[32;1m │░░│ │\x1b[34;1m░░│└┐░░│\x1b[35;1m │░░│ +\x1b[32;1m │░░│ │\x1b[34;1m░░│┌┘░░│\x1b[35;1m │░░│ +\x1b[32;1m┌──┘░░└──┤\x1b[34;1m░░└┘░░░│\x1b[35;1m │░░│ +\x1b[32;1m│░░░░░░░░│\x1b[34;1m░░░░░░┌┘\x1b[35;1m │░░│ +\x1b[32;1m└────────┴\x1b[34;1m──────┘ \x1b[35;1m └──┘ +\x1b[32;1mInterop \x1b[34;1mDebugging \x1b[35;1mTool +\x1b[0m''' + class InteropDebuggingTool: def __init__(self) -> None: - + print(splash) self.artifact_dir = None create_artifact_dir = True if len(sys.argv) == 1: