Skip to content

TC8 SOME/IP conformance test suite for someipd#60

Open
jorgecasal wants to merge 10 commits intoeclipse-score:mainfrom
etas-contrib:jorgecasal_tc8_conformance_test_infrastructure
Open

TC8 SOME/IP conformance test suite for someipd#60
jorgecasal wants to merge 10 commits intoeclipse-score:mainfrom
etas-contrib:jorgecasal_tc8_conformance_test_infrastructure

Conversation

@jorgecasal
Copy link
Copy Markdown
Contributor

@jorgecasal jorgecasal commented Mar 30, 2026

Summary

Introduces the TC8 SOME/IP conformance test suite for someipd, covering OA TC8 ECU Test Specification. Tests run wire-level via raw SOME/IP sockets over loopback, without gatewayd, using a new --tc8-standalone flag added to someipd.


Documentation

  • docs/architecture/tc8_conformance_testing.rst — new architecture document: standalone mode rationale, port-isolation design, per-target port table, test module structure, and TC8 specification alignment analysis.
  • docs/tc8_conformance/requirements.rst — requirements for SD, message format, event notification, field lifecycle, TCP transport, and robustness, with AUTOSAR PRS traceability IDs.
  • docs/tc8_conformance/test_specification.rst — test-specification document mapping each requirement to one or more test cases.
  • docs/tc8_conformance/traceability.rst — requirement-to-test traceability matrix linking TC8 spec sections to test IDs.
  • docs/architecture/index.rst and docs/requirements/index.rst — updated to include the new documents.

TC8 Conformance Test Directory Structure

New directory tests/tc8_conformance/ with the following layout:

tests/tc8_conformance/
├── BUILD.bazel              # 10 score_py_pytest targets + JSON schema test
├── conftest.py              # shared pytest fixtures (someipd_dut, sockets)
├── helpers/
│   ├── constants.py         # env-var-driven port constants
│   ├── message_builder.py   # SOME/IP header/payload construction
│   ├── sd_helpers.py        # SD entry/option builders
│   ├── sd_malformed.py      # malformed-SD frame builders for robustness tests
│   ├── sd_sender.py         # raw SD send/receive with retry
│   ├── event_helpers.py     # event subscribe / notification helpers
│   ├── field_helpers.py     # field GET/SET/subscribe helpers
│   ├── tcp_helpers.py       # TCP connection management
│   ├── udp_helpers.py       # UDP socket utilities
│   ├── someip_assertions.py # custom pytest assertions on SOME/IP frames
│   └── timing.py            # deadline / jitter measurement utilities
├── config/
│   ├── tc8_someipd_sd.json       # vsomeip config for SD tests
│   ├── tc8_someipd_service.json  # vsomeip config for service/event/field tests
│   ├── tc8_someipd_multi.json    # vsomeip config for multi-service tests
│   └── tc8_someipd_config.schema.json  # JSON Schema for all TC8 configs
└── test_*.py                # one module per TC8 area

Test Framework and Test Cases

All tests use score_py_pytest Bazel targets. Port isolation is achieved via the env attribute — each target receives unique TC8_SD_PORT, TC8_SVC_PORT, and (where needed) TC8_SVC_TCP_PORT values, allowing medium-sized targets to run in parallel. Timing-sensitive and reboot lifecycle targets carry the exclusive tag for serial execution.


someipd Changes

  • --tc8-standalone flag (src/someipd/main.cpp): skips gatewayd IPC and offers the TC8 service/event/field directly, enabling self-contained conformance testing without the full gateway stack.
  • offer_event uses ET_FIELD for field-type events so vsomeip delivers the cached initial value to new subscribers immediately on subscribe.
  • src/someipd/BUILD.bazel: someipd binary deps updated for standalone mode.

CI Workflow

.github/workflows/build_and_test_host.yml — new step Bazel TC8 Conformance Test Targets:

  • Adds a loopback multicast route (224.0.0.0/4 dev lo) required for vsomeip SOME/IP-SD on the GitHub Actions runner.
  • Runs bazel test --test_tag_filters=tc8 --test_env=TC8_HOST_IP=127.0.0.1 //tests/tc8_conformance/....

General Clean-up

  • MODULE.bazel: dependency version bump.
  • tests/integration/BUILD.bazel: minor dependency alignment.

Test Plan

  • bazel test --test_tag_filters=tc8 --test_env=TC8_HOST_IP=127.0.0.1 //tests/tc8_conformance/... passes locally
  • bazel run //:copyright.check passes (all new files have correct headers)
  • CI workflow (build_and_test_host) green on this branch
  • bazel build //docs/... builds without RST errors

Wire-level pytest tests verifying someipd against the OA TC8 ECU Test
Specification v3.0 Chapter 5: service discovery (phases, reboot, timing),
message format, event notification, field lifecycle, and TCP transport.

- someipd --tc8-standalone mode: request/response, field GET/SET, UDP and
  TCP events; offer_event uses ET_FIELD so vsomeip delivers the cached field
  value to new subscribers immediately on subscribe (is_field in JSON config
  is not honoured in programmatic offer_event calls)
- vsomeip config templates for SD timing and service/event/field/TCP tests,
  with JSON Schema validation at lint time
- Architecture doc, requirements, test specification and OA spec traceability
- Bazel port isolation via the env attribute: each target receives unique SD
  and service ports enabling medium targets to run in parallel; timing-sensitive
  and reboot lifecycle targets retain the exclusive tag for serial execution
@jorgecasal jorgecasal requested a review from mikehaller March 30, 2026 13:14
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 30, 2026

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run //:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
2026/03/31 14:37:47 Downloading https://releases.bazel.build/8.3.0/release/bazel-8.3.0-linux-x86_64...
Extracting Bazel installation...
Starting local Bazel server (8.3.0) and connecting to it...
INFO: Invocation ID: 610d3460-a342-4e6e-b9be-9a5d79a18576
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
WARNING: For repository 'score_bazel_platforms', the root module requires module version score_bazel_platforms@0.0.4, but got score_bazel_platforms@0.1.1 in the resolved dependency graph. Please update the version in your MODULE.bazel or set --check_direct_dependencies=off
Computing main repo mapping: 
Computing main repo mapping: 
Loading: 
Loading: 4 packages loaded
Loading: 4 packages loaded
    currently loading: 
Loading: 4 packages loaded
    currently loading: 
Loading: 4 packages loaded
    currently loading: 
Loading: 4 packages loaded
    currently loading: 
Analyzing: target //:license-check (5 packages loaded, 0 targets configured)
Analyzing: target //:license-check (5 packages loaded, 0 targets configured)

Analyzing: target //:license-check (29 packages loaded, 10 targets configured)

Analyzing: target //:license-check (88 packages loaded, 10 targets configured)

Analyzing: target //:license-check (91 packages loaded, 10 targets configured)

Analyzing: target //:license-check (97 packages loaded, 11 targets configured)

Analyzing: target //:license-check (158 packages loaded, 2691 targets configured)

Analyzing: target //:license-check (167 packages loaded, 3263 targets configured)

Analyzing: target //:license-check (167 packages loaded, 6808 targets configured)

Analyzing: target //:license-check (173 packages loaded, 7936 targets configured)

Analyzing: target //:license-check (173 packages loaded, 7936 targets configured)

Analyzing: target //:license-check (173 packages loaded, 7936 targets configured)

Analyzing: target //:license-check (174 packages loaded, 8060 targets configured)

Analyzing: target //:license-check (177 packages loaded, 10067 targets configured)

Analyzing: target //:license-check (177 packages loaded, 10067 targets configured)

Analyzing: target //:license-check (178 packages loaded, 10187 targets configured)

Analyzing: target //:license-check (178 packages loaded, 10187 targets configured)

Analyzing: target //:license-check (178 packages loaded, 10187 targets configured)

INFO: Analyzed target //:license-check (179 packages loaded, 11766 targets configured).
[4 / 12] Creating runfiles tree bazel-out/k8-opt-exec-ST-d57f47055a04/bin/external/score_tooling+/dash/tool/formatters/dash_format_converter.runfiles [for tool]; 0s local
[9 / 13] JavaToolchainCompileClasses external/rules_java+/toolchains/platformclasspath_classes; 0s disk-cache, processwrapper-sandbox ... (2 actions running)
INFO: From Generating Dash formatted dependency file ...:
INFO: Successfully converted 2 packages from Cargo.lock to bazel-out/k8-fastbuild/bin/formatted.txt
[11 / 13] JavaToolchainCompileBootClasspath external/rules_java+/toolchains/platformclasspath.jar; 0s disk-cache, processwrapper-sandbox
INFO: Found 1 target...
Target //:license.check.license_check up-to-date:
  bazel-bin/license.check.license_check
  bazel-bin/license.check.license_check.jar
INFO: Elapsed time: 227.499s, Critical Path: 2.26s
INFO: 13 processes: 9 internal, 3 processwrapper-sandbox, 1 worker.
INFO: Build completed successfully, 13 total actions
INFO: Running command line: bazel-bin/license.check.license_check ./formatted.txt <args omitted>
usage: org.eclipse.dash.licenses.cli.Main [-batch <int>] [-cd <url>]
       [-confidence <int>] [-ef <url>] [-excludeSources <sources>] [-help] [-lic
       <url>] [-project <shortname>] [-repo <url>] [-review] [-summary <file>]
       [-timeout <seconds>] [-token <token>]

@jorgecasal jorgecasal changed the title Add TC8 SOME/IP conformance test suite for someipd RFC: TC8 SOME/IP conformance test suite for someipd Mar 30, 2026
@jorgecasal jorgecasal added documentation Improvements or additions to documentation github_actions Pull requests that update GitHub Actions code python Pull requests that update python code labels Mar 30, 2026
@github-actions
Copy link
Copy Markdown

The created documentation from the pull request is available at: docu-html

- Raise check-added-large-files limit from 50 KB to 125 KB to
  accommodate large but legitimate TC8 test modules and the RST
  test specification document
- Add REUSE.toml annotation for tests/tc8_conformance/config/*.json
  so the four vsomeip JSON config files pass reuse-lint-file
- Prepend Apache-2.0 SPDX comment headers to the two TC8 README.md
  files that were missing copyright notices
TC8 conformance tests require special setup (multicast route, env vars)
and already run in a dedicated step; avoid double-execution via -tc8 filter.
@jorgecasal jorgecasal added the enhancement New feature or request label Mar 30, 2026
@jorgecasal jorgecasal force-pushed the jorgecasal_tc8_conformance_test_infrastructure branch from c507e28 to 63d628d Compare March 30, 2026 14:16
@jorgecasal jorgecasal force-pushed the jorgecasal_tc8_conformance_test_infrastructure branch from 63d628d to 8420326 Compare March 30, 2026 14:17
@mikehaller
Copy link
Copy Markdown
Contributor

Documentation overall looks very good, reviewed the current state at https://eclipse-score.github.io/inc_someip_gateway/pr-60/architecture/tc8_conformance_testing.html - not in detail, but general sections and impression. Nice!

On my local checkout, running the tests works with the expected failures:

  • Executed 10 out of 10 tests: 10 fail locally
  • 3 failed, 2 skipped in 59.50s
$ time bazel test --test_tag_filters=tc8 --test_env=TC8_HOST_IP=127.0.0.1 //tests/tc8_conformance/...

Result:

FAILED ../score_tooling+/python_basics/score_pytest::TestSDClientStopSubscribe::test_ets_084_stop_subscribe_ceases_events - AssertionError: ETS_084: Prerequisite failed — no SubscribeAck received
FAILED ../score_tooling+/python_basics/score_pytest::TestSDClientReboot::test_ets_081_reboot_flag_set_after_first_restart - AssertionError: ETS_081: No SD messages captured after restart
FAILED ../score_tooling+/python_basics/score_pytest::TestSDClientReboot::test_ets_082_reboot_flag_set_after_second_restart - AssertionError: ETS_082: No SD messages captured after second restart

real 6m16.073s

@mikehaller
Copy link
Copy Markdown
Contributor

I missed setting up the multicast... now the tests run fine locally as well, can confirm.

# Set up the multicast route locally
$ sudo ip route add 224.0.0.0/4 dev lo

# Re-run the tests
$ time bazel test --test_tag_filters=tc8 --test_env=TC8_HOST_IP=127.0.0.1 //tests/tc8_conformance/...
INFO: Analyzed 13 targets (0 packages loaded, 0 targets configured).
INFO: Found 3 targets and 10 test targets...
INFO: Elapsed time: 214.786s, Critical Path: 182.28s
INFO: 11 processes: 2 action cache hit, 1 internal, 10 linux-sandbox.
INFO: Build completed successfully, 11 total actions
//tests/tc8_conformance:tc8_event_notification                           PASSED in 24.6s
//tests/tc8_conformance:tc8_field_conformance                            PASSED in 3.8s
//tests/tc8_conformance:tc8_message_format                               PASSED in 42.4s
//tests/tc8_conformance:tc8_multi_service                                PASSED in 10.0s
//tests/tc8_conformance:tc8_sd_client                                    PASSED in 19.0s
//tests/tc8_conformance:tc8_sd_format                                    PASSED in 49.3s
//tests/tc8_conformance:tc8_sd_phases_timing                             PASSED in 7.2s
//tests/tc8_conformance:tc8_sd_reboot                                    PASSED in 4.1s
//tests/tc8_conformance:tc8_sd_robustness                                PASSED in 5.6s
//tests/tc8_conformance:tc8_service_discovery                            PASSED in 181.6s

Executed 10 out of 10 tests: 10 tests pass.
There were tests whose specified size is too big. Use the --test_verbose_timeout_warnings command line option to see which ones these are.

real    3m34.876s
user    0m0.203s
sys     0m0.305s

Copy link
Copy Markdown
Contributor

@mikehaller mikehaller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the TC8 Conformity Tests is a complete new part for someip gateway, I'll approve the current state of the PR. It's a very good step forward.

There is one issue regarding the main.cpp where I didn't fully grasp the plans and hence would accept it if it's just temporary.

bazel test //tests/... --test_tag_filters=tc8

# Use a real network interface
TC8_HOST_IP=<your-host-ip> bazel test //tests/tc8_conformance/...
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this host or device under test ip?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, it's for choosing a different host interface (e.g. localhost vs. eth0)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You got it right, nevertheless let me provide a bit more information. In the protocol conformance tests, the DUT (someipd) runs on the same machine as the test framework, so they share the same IP. TC8_HOST_IP is the host's network interface IP, where it's used both to bind the test's raw sockets (for sending/receiving SOME/IP packets) and to configure someipd via the __TC8_HOST_IP__ placeholder in the vsomeip JSON templates.

In short, host IP = DUT IP here, because they're co-located. The variable name reflects the test framework's perspective (the machine under test), not a remote DUT. Happy to rename it to something clearer like TC8_DUT_IP if you think that better matches TC8 terminology.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume the previous state of main.cpp also was just a hardcoded dummy service, and extending it with TC8 specifics as part of the pull request doesn't make a big difference.

In the longer run, would it make sense to have the TC8-enabled version of someipd main.cpp as a separate application?

I ask because someipd is supposed to be an in-vehicle component and mixing production code and test code together like this may not be ideal. If it's just temporary until the other PR's converge, i'll pull back my comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your assumption is correct, main.cpp was already a hardcoded placeholder with no production logic, so the TC8 additions don't mix test code into real production code. That said, your longer-term concern is valid: once someipd grows its real implementation, the TC8-specific flags should move to a separate binary. We'll have to track that as a follow-up.

@jorgecasal jorgecasal changed the title RFC: TC8 SOME/IP conformance test suite for someipd TC8 SOME/IP conformance test suite for someipd Mar 31, 2026
MODULE.bazel Outdated
Copy link
Copy Markdown
Contributor Author

@jorgecasal jorgecasal Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: score_docs_as_code version bump required for full traceability

While verifying the TC8 requirements → test specification → code implementation traceability linkage introduced in this PR, a bug was found in score_docs_as_code that silently prevented all testcase need objects from being created (see eclipse-score/docs-as-code#440 (comment) for the detailed root cause).

The fix has been merged in eclipse-score/docs-as-code#440, but is not yet available in a published release. Our MODULE.bazel currently pins:

bazel_dep(name = "score_docs_as_code", version = "2.3.0", dev_dependency = True)

@jorgecasal jorgecasal self-assigned this Mar 31, 2026
- Use local json_schema_validator rule instead of @score_communication
- Add integrity hashes to download_archive deps for reproducible builds
- Add component descriptions for gatewayd and someipd in architecture docs
@jorgecasal jorgecasal force-pushed the jorgecasal_tc8_conformance_test_infrastructure branch from 4393f39 to 2dfcff0 Compare March 31, 2026 14:37
@jorgecasal jorgecasal marked this pull request as ready for review March 31, 2026 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request github_actions Pull requests that update GitHub Actions code python Pull requests that update python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants