Skip to content
Closed
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
5 changes: 5 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ common --//score/datarouter/build_configuration_flags:enable_dynamic_configurati
common --//score/datarouter/build_configuration_flags:file_transfer=False
common --//score/datarouter/build_configuration_flags:use_local_vlan=True

# TODO: Remove once score_baselibs fixes deprecated StringLiteral and
# ignored-attributes warnings (string_comparison_adaptor.h, text_format.h, etc.)
build --copt=-Wno-deprecated-declarations
build --copt=-Wno-ignored-attributes

# Base QNX config (shared flags)
common:qnx --credential_helper=*.qnx.com=%workspace%/scripts/internal/qnx_creds.py
common:qnx --credential_helper_timeout="60s"
Expand Down
16 changes: 16 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,19 @@ bazel_dep(name = "score_communication", version = "0.2.1")
# Rust dependencies

bazel_dep(name = "score_baselibs_rust", version = "0.1.0")

bazel_dep(name = "score_itf", version = "0.4.0", dev_dependency = True)

# OCI / Docker image rules for integration tests
bazel_dep(name = "rules_oci", version = "2.2.7", dev_dependency = True)
bazel_dep(name = "rules_pkg", version = "1.2.0", dev_dependency = True)

oci = use_extension("@rules_oci//oci:extensions.bzl", "oci", dev_dependency = True)
oci.pull(
name = "ubuntu_24_04",
digest = "sha256:2e863c44b718727c860746568e1d54afd13b2fa71b160f5cd9058fc436217b30",
image = "ubuntu",
platforms = ["linux/amd64"],
tag = "24.04",
)
use_repo(oci, "ubuntu_24_04", "ubuntu_24_04_linux_amd64")
208 changes: 204 additions & 4 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions score/datarouter/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,20 @@ filegroup(
"//platform/aas/tools/sctf:__subpackages__",
"//pqr/abc/abc-lmn/config/project/cpu/pas/datarouter:__pkg__",
"//score/datarouter/test:__subpackages__",
"//score/test/integration:__subpackages__",
],
)

filegroup(
name = "integration_config_files",
srcs = [
"etc/log-channels.json",
"etc/logging.json",
"etc/raw-channels.json",
],
visibility = ["//score/test/integration:__subpackages__"],
)

cc_library(
name = "datarouter_options",
srcs = [
Expand Down
2 changes: 1 addition & 1 deletion score/datarouter/build_configuration_flags/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ config_setting(
":enable_nonverbose_dlt": "True",
},
visibility = [
"@score_logging//score/datarouter:__subpackages__",
"//visibility:public",
],
)

Expand Down
1 change: 1 addition & 0 deletions score/datarouter/dlt_filetransfer_trigger_lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ cc_library(
"//platform/aas/pas/datarouterconf/src/services:__pkg__",
"//platform/aas/test/pas:__subpackages__",
"//score/datarouter/test:__subpackages__",
"//score/test/integration:__subpackages__",
"@score_baselibs//score/logging:__pkg__",
],
deps = [
Expand Down
1 change: 1 addition & 0 deletions score/mw/log/legacy_non_verbose_api/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ cc_library(
visibility = [
"//platform/aas/ara/log:__subpackages__",
"//score/mw/log:__subpackages__",
"//score/test/integration:__subpackages__",
"@score_baselibs//score/mw/log:__subpackages__",
"@score_logging//score/datarouter:__subpackages__",
],
Expand Down
52 changes: 52 additions & 0 deletions score/test/integration/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
load("@rules_pkg//pkg:tar.bzl", "pkg_tar")
load("@rules_python//python:defs.bzl", "py_library")
load("@score_itf//bazel:py_itf_plugin.bzl", "py_itf_plugin")

pkg_tar(
name = "dlt_pkg",
srcs = ["@score_itf//third_party/dlt:dlt-receive"],
visibility = ["//score/test/integration:__subpackages__"],
)

pkg_tar(
name = "datarouter_bin_pkg",
srcs = ["//score/datarouter"],
package_dir = "opt/datarouter/bin",
)

pkg_tar(
name = "datarouter_conf_pkg",
srcs = ["//score/datarouter:integration_config_files"],
package_dir = "opt/datarouter",
strip_prefix = "/score/datarouter",
)

pkg_tar(
name = "datarouter_pkg",
visibility = ["//score/test/integration:__subpackages__"],
deps = [
":datarouter_bin_pkg",
":datarouter_conf_pkg",
],
)

py_library(
name = "dlt_parser",
srcs = ["dlt_parser.py"],
imports = ["."],
visibility = ["//score/test/integration:__subpackages__"],
)

py_library(
name = "logging_plugin_lib",
srcs = ["logging_plugin.py"],
imports = ["."],
deps = ["@score_itf//score/itf/plugins:docker"],
)

py_itf_plugin(
name = "logging_plugin",
enabled_plugins = ["logging_plugin"],
py_library = ":logging_plugin_lib",
visibility = ["//score/test/integration:__subpackages__"],
)
80 changes: 80 additions & 0 deletions score/test/integration/defs.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# *******************************************************************************
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

load("@rules_oci//oci:defs.bzl", "oci_image", "oci_load")
load("@score_itf//:defs.bzl", "py_itf_test")

def _extend_list_in_kwargs(kwargs, key, values):
kwargs[key] = kwargs.get(key, []) + values
return kwargs

def py_logging_itf_test(name, srcs, filesystem, **kwargs):
"""Integration test macro for score_logging using Docker + DLT plugins.
Builds a per-test Docker image from the given filesystem tar layers
(which must include the test app binaries/configs) combined with the
shared base layers (DLT daemon, datarouter).
Args:
name: Test target name.
srcs: Python test source files.
filesystem: A pkg_tar target containing the test-specific binaries
and configuration files.
**kwargs: Forwarded to py_itf_test (e.g. deps, data, tags, timeout).
"""
image_name = "_image_{}".format(name)
image_loader = "_image_{}_loader".format(name)
repo_tag = "{}:latest".format(name)

oci_image(
name = image_name,
base = "@ubuntu_24_04",
tars = [
"//score/test/integration:dlt_pkg",
"//score/test/integration:datarouter_pkg",
filesystem,
],
)

oci_load(
name = image_loader,
image = image_name,
repo_tags = [repo_tag],
)

_extend_list_in_kwargs(kwargs, "data", [image_loader])
_extend_list_in_kwargs(kwargs, "args", [
"--docker-image-bootstrap=$(location {})".format(image_loader),
"--docker-image={}".format(repo_tag),
])

if "tags" not in kwargs:
kwargs["tags"] = []
if "integration" not in kwargs["tags"]:
kwargs["tags"] = kwargs["tags"] + ["integration"]

if "size" not in kwargs:
kwargs["size"] = "enormous"

if "timeout" not in kwargs:
kwargs["timeout"] = "short"

py_itf_test(
name = name,
srcs = srcs,
plugins = [
"@score_itf//score/itf/plugins:docker_plugin",
"@score_itf//score/itf/plugins:dlt_plugin",
"//score/test/integration:logging_plugin",
],
env = {"DOCKER_HOST": ""},
**kwargs
)
91 changes: 91 additions & 0 deletions score/test/integration/dlt_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# *******************************************************************************
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

"""Structured parser for ``dlt-receive -a`` text output.
DLT text lines produced by ``dlt-receive -a`` have the form::
<timestamp> <ecuid> <apid> <ctid> <type> <subtype> <mode> <noar> <payload ...>
Field positions can vary (some fields may be absent in non-extended
headers), but the *apid* and *ctid* fields always appear as a
whitespace-separated pair. DLT pads short IDs to 4 characters with
``-`` (e.g. ``TAP`` → ``TAP-``).
This module provides helpers that work on the *text* output captured by
``dlt-receive -a --stdout-flush`` (which is what ``dlt_on_target``
returns via ``receiver.get_output()``).
"""

from collections import defaultdict
from dataclasses import dataclass, field


@dataclass
class DltMessage:
"""A single parsed DLT message."""

apid: str
ctid: str
payload: str
raw_line: str


def parse_messages(dlt_output: str, app_id: str) -> list[DltMessage]:
"""Parse DLT text output and return messages matching *app_id*.
Args:
dlt_output: Full text output from ``dlt-receive -a``.
app_id: Application ID to filter on (without padding).
Returns:
List of :class:`DltMessage` instances whose *apid* matches *app_id*.
"""
messages: list[DltMessage] = []
for line in dlt_output.splitlines():
parts = line.split()
for i, part in enumerate(parts):
if part.rstrip("-") == app_id and i + 1 < len(parts):
ctid = parts[i + 1].rstrip("-")
# Everything after apid and ctid is the payload
payload = " ".join(parts[i + 2 :]) if i + 2 < len(parts) else ""
messages.append(
DltMessage(
apid=app_id,
ctid=ctid,
payload=payload,
raw_line=line,
)
)
break
return messages


def count_messages_by_context(
dlt_output: str,
app_id: str,
context_ids: set[str] | None = None,
) -> tuple[dict[str, int], int]:
"""Count messages per context ID for a given application.
Args:
dlt_output: Full text output from ``dlt-receive -a``.
app_id: Application ID to filter on.
context_ids: Optional set of context IDs to include in the
per-context breakdown. Messages with other context IDs are
still included in the total count.
Returns:
A ``(counts, total)`` tuple where *counts* maps context ID to
message count and *total* is the overall number of messages from
*app_id*.
"""
counts: dict[str, int] = defaultdict(int)
total = 0
for msg in parse_messages(dlt_output, app_id):
total += 1
if context_ids is None or msg.ctid in context_ids:
counts[msg.ctid] += 1
return dict(counts), total
52 changes: 52 additions & 0 deletions score/test/integration/filetransfer/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# *******************************************************************************
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

load("@rules_cc//cc:defs.bzl", "cc_binary")
load("@rules_pkg//pkg:tar.bzl", "pkg_tar")
load("//score/test/integration:defs.bzl", "py_logging_itf_test")

cc_binary(
name = "filetransfer_app",
srcs = ["filetransfer_app.cpp"],
deps = [
"//score/datarouter/dlt_filetransfer_trigger_lib",
"//score/mw/log",
],
)

pkg_tar(
name = "filetransfer_bin_pkg",
srcs = [":filetransfer_app"],
package_dir = "opt/test_apps/filetransfer/bin",
)

pkg_tar(
name = "filetransfer_config_pkg",
srcs = ["etc/logging.json"],
package_dir = "opt/test_apps/filetransfer/etc",
)

pkg_tar(
name = "filetransfer_filesystem",
deps = [
":filetransfer_bin_pkg",
":filetransfer_config_pkg",
],
)

py_logging_itf_test(
name = "test_filetransfer",
srcs = ["test_filetransfer.py"],
filesystem = ":filetransfer_filesystem",
deps = ["//score/test/integration:dlt_parser"],
)
6 changes: 6 additions & 0 deletions score/test/integration/filetransfer/etc/logging.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"appId": "FTEA",
"appDesc": "File Transfer Example App",
"logMode": "kRemote",
"logLevel": "kVerbose"
}
Loading
Loading