Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d4d2e1c
feat: add TimeDaemon CIT with pip hub infrastructure
gordon9901 Jul 9, 2026
03ad91c
Update Bazel lockfile
gordon9901 Jul 10, 2026
492fe60
feat: add TimeDaemon CIT with pip hub infrastructure
gordon9901 Jul 10, 2026
1a98719
style: apply clang-format to test scenario sources
gordon9901 Jul 10, 2026
7be7b78
drop premature MIT visibility from shm_ptp_engine
gordon9901 Jul 22, 2026
e8075f5
fix: address PR review comments on TimeDaemon CIT
gordon9901 Jul 30, 2026
df02744
update lock file
gordon9901 Jul 30, 2026
8e61df6
chore: add local clang-tidy config to silence noise
gordon9901 Aug 31, 2026
12dd06f
test(time_daemon/cit): narrow to multi-module integration
gordon9901 Aug 31, 2026
0b23511
test(time_daemon): move pipeline to gtest, drop redundant CIT scenarios
gordon9901 Sep 4, 2026
d562538
Merge branch 'main' into ecarx_time_daemon_cit
gordon9901 Sep 4, 2026
3a84524
merge: resolve MODULE.bazel conflict with origin/main
gordon9901 Sep 10, 2026
8cb00fc
merge: resolve MODULE.bazel.lock conflict with origin/main
gordon9901 Sep 11, 2026
048caf1
Merge branch 'main' into ecarx_time_daemon_cit
gordon9901 Sep 11, 2026
2a34095
Merge branch 'main' into ecarx_time_daemon_cit
gordon9901 Sep 16, 2026
4840af5
Merge branch 'main' into ecarx_time_daemon_cit
gordon9901 Sep 21, 2026
9afab04
Merge branch 'main' into ecarx_time_daemon_cit
gordon9901 Sep 28, 2026
f511a0e
Merge branch 'main' into ecarx_time_daemon_cit
gordon9901 Oct 8, 2026
8616d77
Merge branch 'main' into ecarx_time_daemon_cit
gordon9901 Oct 9, 2026
dda4004
Merge branch 'main' into ecarx_time_daemon_cit
gordon9901 Oct 16, 2026
8947f59
Merge branch 'main' into ecarx_time_daemon_cit
gordon9901 Oct 22, 2026
e712cec
Merge branch 'main' into ecarx_time_daemon_cit
gordon9901 Oct 28, 2026
5cd04a8
Merge remote-tracking branch 'origin/main' into ecarx_time_daemon_cit
gordon9901 Oct 28, 2026
5ec6122
Merge remote-tracking branch 'origin/main' into ecarx_time_daemon_cit
gordon9901 Oct 30, 2026
758e584
Merge remote-tracking branch 'origin/main' into ecarx_time_daemon_cit
gordon9901 Nov 2, 2026
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
30 changes: 30 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# *******************************************************************************
# Copyright (c) 2026 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
# *******************************************************************************
# Local clang-tidy overrides for the score_time module.
#
# The S-CORE baseline from @score_cpp_policies//clang_tidy:.clang-tidy is
# applied first; settings here are layered on top per clang-tidy's standard
# merge rules. Only module-specific suppressions belong here — do not remove
# baseline checks.

# Only analyze headers inside the score/ source tree. Without this,
# clang-tidy picks up warnings from externally provided headers
# (e.g. toolchain redacted_dates.h) that we cannot fix.
HeaderFilterRegex: 'score/'

# Suppress the builtin-macro-redefined diagnostic emitted by the LLVM
# toolchain's redacted_dates.h (which redefines __DATE__/__TIME__ for
# deterministic builds). This is injected by the toolchain via -include
# and is not user code, so suppressing it here is appropriate.
Checks: >-
-clang-diagnostic-builtin-macro-redefined
2 changes: 2 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ exports_files(
[
# Used by the @score_tooling coverage reporter to locate the workspace root.
"MODULE.bazel",
# Local clang-tidy overrides, layered on top of the S-CORE baseline.
".clang-tidy",
],
)

Expand Down
26 changes: 25 additions & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,31 @@ pip.parse(
python_version = PYTHON_VERSION,
requirements_lock = "//third_party/codeql:requirements_lock.txt",
)
use_repo(pip, codeql_coding_standards_pip_hub = "time_codeql_coding_standards_pip_hub")

# To regenerate the lock file after editing requirements.txt:
# bazel run //score/time_daemon/tests/component_tests:requirements.update
pip.parse(
hub_name = "pip_time_daemon_venv",
python_version = PYTHON_VERSION,
requirements_lock = "//score/time_daemon/tests/component_tests:requirements.txt.lock",
)
use_repo(
pip,
"pip_time_daemon_venv",
codeql_coding_standards_pip_hub = "time_codeql_coding_standards_pip_hub",
)

bazel_dep(name = "rules_cc", version = "0.2.17", dev_dependency = True)
Comment thread
gordon9901 marked this conversation as resolved.
Resolved

## Component Integration Test framework

bazel_dep(name = "score_test_scenarios", version = "0.4.1", dev_dependency = True)
git_override(
module_name = "score_test_scenarios",
Comment thread
gordon9901 marked this conversation as resolved.
Resolved
commit = "fec712d490ff5d46fae91332bafac4777b300026", # tag v0.4.1
remote = "https://github.com/eclipse-score/testing_tools.git",
)

## Integration Test Framework dependencies

bazel_dep(name = "score_itf", version = "0.6.0")
Expand Down
5 changes: 4 additions & 1 deletion MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion score/time_daemon/src/application/svt/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ load("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER
"svt_handler.h",
],
features = COMPILER_WARNING_FEATURES,
visibility = ["//score/time_daemon/src/application:__pkg__"],
visibility = [
"//score/time_daemon/src/application:__pkg__",
],
deps = [
"//score/time_daemon/src/application:timebase_handler",
"//score/time_daemon/src/application/job_runner",
Expand Down
16 changes: 16 additions & 0 deletions score/time_daemon/src/verification_machine/svt/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ cc_unit_test_suites_for_host_and_qnx(
name = "unit_test_suite",
cc_unit_tests = [
":svt_verification_machine_test",
":svt_verification_machine_pipeline_integration_test",
],
test_suites_from_sub_packages = ["//score/time_daemon/src/verification_machine/svt/validators:unit_test_suite"],
visibility = ["//score/time_daemon:__subpackages__"],
Expand All @@ -76,3 +77,18 @@ cc_test(
"@score_baselibs//score/mw/log:console_only_backend",
],
)

cc_test(
name = "svt_verification_machine_pipeline_integration_test",
srcs = [
"svt_verification_machine_pipeline_integration_test.cpp",
],
deps = [
"//score/time_daemon/src/common/data_types:ptp_time_info",
"//score/time_daemon/src/ptp_machine/stub:gptp_stub_machine",
"//score/time_daemon/src/verification_machine/svt:svt_verification_machine",
"@googletest//:gtest",
"@googletest//:gtest_main",
"@score_baselibs//score/mw/log:console_only_backend",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/********************************************************************************
* Copyright (c) 2026 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
********************************************************************************/
#include "score/time_daemon/src/common/data_types/ptp_time_info.h"
#include "score/time_daemon/src/ptp_machine/stub/factory.h"
#include "score/time_daemon/src/verification_machine/svt/factory.h"

#include <gtest/gtest.h>

#include <chrono>
#include <future>

namespace score
{
namespace td
{

// Verifies that PtpTimeInfo published by GPTPStubMachine flows correctly through
// SvtVerificationMachine (SynchronizationValidator -> TimeoutValidator -> TimeJumpsValidator)
// and emerges with the expected status fields intact.
class VerificationPipelineIntegrationTest : public ::testing::Test
{
protected:
void SetUp() override
{
ptp_machine_ = CreateGPTPStubMachine("verif_pipeline_ptp");
verifier_ = CreateSvtVerificationMachine("verif_pipeline");

// Wire PTP machine output into the verification pipeline.
ptp_machine_->SetPublishCallback([this](const PtpTimeInfo& data) {
verifier_->OnMessage(data);
});

// Capture the first data point that exits the verification pipeline.
verifier_->SetPublishCallback([this](const PtpTimeInfo& data) {
try
{
verified_promise_.set_value(data);
}
catch (const std::future_error&)
{
// Capture only the first verified data point.
}
});
}

void TearDown() override
{
ptp_machine_->Stop();
}

std::shared_ptr<GPTPStubMachine> ptp_machine_;
std::shared_ptr<SvtVerificationMachine> verifier_;
std::promise<PtpTimeInfo> verified_promise_;
};

TEST_F(VerificationPipelineIntegrationTest, DataFlowsThroughPipeline)
{
ASSERT_TRUE(verifier_->Init());
ASSERT_TRUE(ptp_machine_->Init());
ptp_machine_->Start();

auto verified_future = verified_promise_.get_future();
ASSERT_EQ(verified_future.wait_for(std::chrono::seconds(5)), std::future_status::ready);

const auto data = verified_future.get();

// The stub always produces synchronized/correct data on its first publish;
// all three validators must let it through without flagging an anomaly.
EXPECT_TRUE(data.status.is_synchronized);
EXPECT_TRUE(data.status.is_correct);
EXPECT_FALSE(data.status.is_timeout);
EXPECT_FALSE(data.status.is_time_jump_future);
EXPECT_FALSE(data.status.is_time_jump_past);
EXPECT_GT(data.ptp_assumed_time.count(), 0);
}

} // namespace td
} // namespace score
45 changes: 45 additions & 0 deletions score/time_daemon/tests/component_tests/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# *******************************************************************************
# Copyright (c) 2026 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("@pip_time_daemon_venv//:requirements.bzl", "all_requirements")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
load("@score_tooling//python_basics:defs.bzl", "score_virtualenv")

# To regenerate requirements.txt.lock after editing requirements.txt, run:
# bazel run //score/time_daemon/tests/component_tests:requirements.update
compile_pip_requirements(
name = "requirements",
srcs = [
"requirements.txt",
"@score_tooling//python_basics:requirements.in",
],
requirements_txt = "requirements.txt.lock",
tags = ["manual"],
)

score_virtualenv(
name = "python_tc_venv",
reqs = all_requirements,
venv_name = ".python_tc_venv",
)

# NOTE: The time_daemon_cit pytest target is intentionally absent.
#
# Previous CIT scenarios (lifecycle, shm_roundtrip, pipeline) exercised
# component-internal behaviour inside a single process — those belong in
# gtest-based unit/component integration tests under src/.
#
# The CIT framework (Python driver + test_scenarios binary) is reserved
# for testing the TimeDaemon as an external binary, with true IPC between
# processes. Re-enable score_py_pytest here once a real process-level
# integration scenario is added.
73 changes: 73 additions & 0 deletions score/time_daemon/tests/component_tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!-- ----------------------------------------------------------------------------
Copyright (c) 2026 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
----------------------------------------------------------------------------- -->

# TimeDaemon Component Integration Tests (CIT)

## Scope

Component integration tests verify the TimeDaemon running as an **external
process** — its startup, runtime behaviour, IPC interfaces, and shutdown —
exercised from outside the binary. They are NOT a replacement for unit tests or
for in-process component integration tests.

| Layer | Tool | Where it lives | What it covers |
|-------|------|----------------|----------------|
| Unit | gtest / gmock | `score/time_daemon/src/**/*_test.cpp` | Individual classes, white-box |
| Component integration (in-process) | gtest / gmock | `score/time_daemon/src/**/*_integration_test.cpp` | Multiple production objects wired together inside one process (e.g. GPTPStubMachine → SvtVerificationMachine) |
| **CIT (this layer)** | **pytest + scenario binary** | `score/time_daemon/tests/component_tests/` | **TimeDaemon running as a real binary, single- or multi-process interaction** |
| Module integration | pytest + ITF | `score/tests/module_integration_tests/` | TimeSlave ↔ TimeDaemon across components |
| System | pytest + ITF + QEMU / Docker | `score/tests/gptp_pipeline/` | Multi-binary end-to-end across OS targets |

**Rule of thumb** — if a scenario can be written by instantiating production
objects directly and linking them with gtest (i.e. everything happens inside one
test process), it belongs in the gtest layer under `src/`. CIT is reserved for
tests that must launch the real TimeDaemon executable (or multiple binaries) and
interact with it from outside, via its real IPC/SHM interfaces.

## Architecture

```
pytest (Python) test runner, assertions, reporting
│
▼ subprocess + structured-log parsing
scenario / daemon binary real TimeDaemon (or helper) process
│
▼ IPC / SHM / command line
TimeDaemon production code running in its own process
```

- Python side lives under `tests/` and subclasses `testing_utils.Scenario`
(see `tests/cit_scenario.py`).
- Each pytest class declares a `scenario_name` fixture that selects which
scenario/binary to run; results come back as exit code + structured log lines
parsed by `testing_utils.LogContainer`.
- The `conftest.py` provides CLI options for building and running C++ scenario
binaries (e.g. `--cpp-target-name`, `--build-scenarios`).

## Status

The Python driver scaffolding (`conftest.py`, `cit_scenario.py`, `result_code.py`,
requirements, virtualenv) is in place. Active CIT scenarios will be added here
once the TimeDaemon binary can be launched standalone for process-level
integration testing.

In-process multi-module integration scenarios live in gtest under `src/` (e.g.
`svt_verification_machine_pipeline_integration_test.cpp`).

## Running

When scenario targets exist, run with:

```bash
bazel test //score/time_daemon/tests/component_tests:<target_name>
```
Loading
Loading