Skip to content

Commit 160f9c6

Browse files
Subramanian-K812Saumya-R
authored andcommitted
Enable cr_checker copyright check via pre-commit hook (eclipse-score#265)
* ci: enable cr_checker copyright check via pre-commit hook * fix: add copyright headers to files missing SPDX block * fix: add missing copyright header to overall_status.rst * fix: remove broken copyright_checker Bazel target * fix: add missing blank line after copyright block in overall_status.rst doc: remove scrample references from ebclfsa documentation + update devcontainer (eclipse-score#269) * chore: Bump devcontainer to v.1.7.0 * doc: remove scrample references in the EB clfsa documentation The scrample code had been removed already but this document was forgotten. upload sarif results to security tab (eclipse-score#260) Co-authored-by: Frank Scholter Peres(MBTI) <145544737+FScholPer@users.noreply.github.com> Integrate Time module (eclipse-score#273) * Integrate Time module * Deploy time examples * Make sure qemu has enought permisisons * Make exmplaes stop after time Bump `score_bazel_cpp_toolchains` to the latest version (eclipse-score#274) The latest version of toolchain provides support for coverage for QNX builds. Signed-off-by: Nikola Radakovic <nikola.ra.radakovic@bmw.de> Add QNX8 aarch64 build support (eclipse-score#241) * Add QNX8 aarch64 build support * review findings * free more space adding launch manager fit test cases adding feature integration test cases for other requirements removing hard fail conditions updated documents adding copilot reivew fixes Fixed restart behavior on the same instance, Hardened shutdown race handling updated the statement clearing self.process after shutdown fixed pytest build environment issues fixxing the python build issues copyright fixes
1 parent b2ae791 commit 160f9c6

36 files changed

Lines changed: 5775 additions & 11 deletions

feature_integration_tests/LIFECYCLE_TESTS_SUMMARY.md

Lines changed: 735 additions & 0 deletions
Large diffs are not rendered by default.

feature_integration_tests/README.md

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,22 @@ This directory contains Feature Integration Tests for the S-CORE project. It inc
1919
- `test_ssh.py` — SSH connectivity tests
2020
- `configs/` — Configuration files for ITF execution (DLT, QEMU bridge, etc.)
2121

22+
## Lifecycle FIT Summary
23+
24+
Lifecycle Feature Integration Tests validate end-to-end integration patterns for the S-CORE lifecycle stack across Rust and C++ scenarios.
25+
26+
- Coverage: 85/92 lifecycle requirements (92%)
27+
- Modes:
28+
- API integration mode (no running daemon required)
29+
- Daemon integration mode (real Launch Manager behavior)
30+
- Main validated areas:
31+
- Process launching and dependency ordering (sequential/parallel)
32+
- Conditional launching and run targets
33+
- Process security/resources/termination
34+
- Monitoring, recovery, control interface, logging, and configuration handling
35+
36+
For full lifecycle requirement mapping and detailed rationale, see `feature_integration_tests/LIFECYCLE_TESTS_SUMMARY.md`.
37+
2238
## Running Tests
2339

2440
### Python Test Cases (scenario-based FIT)
@@ -32,10 +48,61 @@ bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit
3248
To run specific test suites:
3349

3450
```sh
35-
bazel test //feature_integration_tests/test_cases:fit_rust
51+
bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit_rust
3652
bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit_cpp
3753
```
3854

55+
To run daemon integration test suites:
56+
57+
```sh
58+
bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit_daemon_rust
59+
bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit_daemon_cpp
60+
```
61+
62+
To run lifecycle-focused tests only:
63+
64+
```sh
65+
bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit_rust --test_filter="*lifecycle*"
66+
bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit_cpp --test_filter="*lifecycle*"
67+
```
68+
69+
Pytest direct local runs are also supported:
70+
71+
```sh
72+
# All lifecycle tests (rust + cpp)
73+
python3 -m pytest feature_integration_tests/test_cases/tests/lifecycle/ -q -v
74+
75+
# Rust only
76+
python3 -m pytest feature_integration_tests/test_cases/tests/lifecycle/ -q -v -m rust
77+
78+
# C++ only
79+
python3 -m pytest feature_integration_tests/test_cases/tests/lifecycle/ -q -v -m cpp
80+
```
81+
82+
To build scenario executables from pytest before running tests:
83+
84+
```sh
85+
# Default Bazel config: linux-x86_64
86+
python3 -m pytest feature_integration_tests/test_cases/tests/lifecycle/ \
87+
--build-scenarios \
88+
--build-scenarios-timeout=600 \
89+
-q -v
90+
91+
# Explicit Bazel config
92+
python3 -m pytest feature_integration_tests/test_cases/tests/lifecycle/ \
93+
--build-scenarios \
94+
--bazel-config=linux-x86_64 \
95+
--build-scenarios-timeout=600 \
96+
-q -v
97+
98+
# Or via environment override
99+
FIT_BAZEL_CONFIG=linux-x86_64 \
100+
python3 -m pytest feature_integration_tests/test_cases/tests/lifecycle/ \
101+
--build-scenarios \
102+
--build-scenarios-timeout=600 \
103+
-q -v
104+
```
105+
39106
### ITF Tests (QEMU-based)
40107

41108
ITF tests run on a QEMU target and require the `itf-qnx-x86_64` config:

feature_integration_tests/itf/test_lifecycle.py

Whitespace-only changes.

feature_integration_tests/test_cases/BUILD

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# *******************************************************************************
1313
load("@pip_score_venv_test//:requirements.bzl", "all_requirements")
1414
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
15+
load("@score_lifecycle_health//:defs.bzl", "launch_manager_config")
1516
load("@score_tooling//python_basics:defs.bzl", "score_py_pytest")
1617

1718
# In order to update the requirements, change the `requirements.txt` file and run:
@@ -34,6 +35,11 @@ compile_pip_requirements(
3435
],
3536
)
3637

38+
launch_manager_config(
39+
name = "daemon_lifecycle_configs",
40+
config = "//feature_integration_tests/test_cases/configs:daemon_launch_manager_config.json",
41+
)
42+
3743
# Tests targets
3844
score_py_pytest(
3945
name = "fit_rust",
@@ -45,7 +51,9 @@ score_py_pytest(
4551
],
4652
data = [
4753
"conftest.py",
54+
"daemon_helpers.py",
4855
"fit_scenario.py",
56+
"lifecycle_scenario.py",
4957
"persistency_scenario.py",
5058
"test_properties.py",
5159
"//feature_integration_tests/test_scenarios/rust:rust_test_scenarios",
@@ -67,10 +75,65 @@ score_py_pytest(
6775
],
6876
data = [
6977
"conftest.py",
78+
"daemon_helpers.py",
79+
"fit_scenario.py",
80+
"lifecycle_scenario.py",
81+
"persistency_scenario.py",
82+
"test_properties.py",
83+
"//feature_integration_tests/test_scenarios/cpp:cpp_test_scenarios",
84+
],
85+
pytest_config = "//:pyproject.toml",
86+
deps = all_requirements,
87+
)
88+
89+
# Daemon integration tests (Rust)
90+
score_py_pytest(
91+
name = "fit_daemon_rust",
92+
srcs = glob(["tests/**/*.py"]),
93+
args = [
94+
"-m rust",
95+
"--traces=all",
96+
"--rust-target-path=$(rootpath //feature_integration_tests/test_scenarios/rust:rust_test_scenarios)",
97+
"-k with_daemon",
98+
],
99+
data = [
100+
"conftest.py",
101+
"daemon_helpers.py",
102+
"fit_scenario.py",
103+
"lifecycle_scenario.py",
104+
"persistency_scenario.py",
105+
"test_properties.py",
106+
"//feature_integration_tests/test_scenarios/rust:rust_test_scenarios",
107+
"@score_lifecycle_health//examples/rust_supervised_app",
108+
"@score_lifecycle_health//src/launch_manager_daemon:launch_manager",
109+
],
110+
env = {
111+
"RUST_BACKTRACE": "1",
112+
},
113+
pytest_config = "//:pyproject.toml",
114+
deps = all_requirements,
115+
)
116+
117+
# Daemon integration tests (C++)
118+
score_py_pytest(
119+
name = "fit_daemon_cpp",
120+
srcs = glob(["tests/**/*.py"]),
121+
args = [
122+
"-m cpp",
123+
"--traces=all",
124+
"--cpp-target-path=$(rootpath //feature_integration_tests/test_scenarios/cpp:cpp_test_scenarios)",
125+
"-k with_daemon",
126+
],
127+
data = [
128+
"conftest.py",
129+
"daemon_helpers.py",
70130
"fit_scenario.py",
131+
"lifecycle_scenario.py",
71132
"persistency_scenario.py",
72133
"test_properties.py",
73134
"//feature_integration_tests/test_scenarios/cpp:cpp_test_scenarios",
135+
"@score_lifecycle_health//examples/cpp_supervised_app",
136+
"@score_lifecycle_health//src/launch_manager_daemon:launch_manager",
74137
],
75138
pytest_config = "//:pyproject.toml",
76139
deps = all_requirements,
@@ -83,3 +146,11 @@ test_suite(
83146
":fit_rust",
84147
],
85148
)
149+
150+
test_suite(
151+
name = "fit_daemon",
152+
tests = [
153+
":fit_daemon_cpp",
154+
":fit_daemon_rust",
155+
],
156+
)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
13+
14+
exports_files([
15+
"daemon_launch_manager_config.json",
16+
])
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
{
2+
"schema_version": 1,
3+
"defaults": {
4+
"deployment_config": {
5+
"bin_dir": "bin/",
6+
"ready_recovery_action": {
7+
"restart": {
8+
"number_of_attempts": 1,
9+
"delay_before_restart": 0.5
10+
}
11+
}
12+
},
13+
"component_properties": {
14+
"application_profile": {
15+
"application_type": "Reporting",
16+
"is_self_terminating": false,
17+
"alive_supervision": {
18+
"reporting_cycle": 0.1,
19+
"min_indications": 1,
20+
"max_indications": 3,
21+
"failed_cycles_tolerance": 1
22+
}
23+
},
24+
"depends_on": [],
25+
"process_arguments": [],
26+
"ready_condition": {
27+
"process_state": "Running"
28+
}
29+
},
30+
"run_target": {
31+
"transition_timeout": 5,
32+
"recovery_action": {
33+
"switch_run_target": {
34+
"run_target": "fallback_run_target"
35+
}
36+
}
37+
},
38+
"alive_supervision": {
39+
"evaluation_cycle": 0.5
40+
}
41+
},
42+
"components": {
43+
"state_manager": {
44+
"description": "State Manager application",
45+
"component_properties": {
46+
"binary_name": "control_daemon",
47+
"application_profile": {
48+
"application_type": "State_Manager",
49+
"alive_supervision": {
50+
"min_indications": 0
51+
}
52+
},
53+
"depends_on": []
54+
}
55+
},
56+
"cpp_supervised_app": {
57+
"component_properties": {
58+
"binary_name": "cpp_supervised_app",
59+
"application_profile": {
60+
"application_type": "Reporting_And_Supervised"
61+
},
62+
"process_arguments": [
63+
"-d50"
64+
]
65+
},
66+
"deployment_config": {
67+
"environmental_variables": {
68+
"PROCESSIDENTIFIER": "cpp_supervised_app",
69+
"CONFIG_PATH": "etc/hmproc_cpp_supervised_app.bin",
70+
"IDENTIFIER": "cpp_supervised_app"
71+
}
72+
}
73+
},
74+
"rust_supervised_app": {
75+
"component_properties": {
76+
"binary_name": "rust_supervised_app",
77+
"application_profile": {
78+
"application_type": "Reporting_And_Supervised"
79+
},
80+
"process_arguments": [
81+
"-d50"
82+
]
83+
},
84+
"deployment_config": {
85+
"environmental_variables": {
86+
"PROCESSIDENTIFIER": "rust_supervised_app",
87+
"CONFIG_PATH": "etc/hmproc_rust_supervised_app.bin",
88+
"IDENTIFIER": "rust_supervised_app"
89+
}
90+
}
91+
}
92+
},
93+
"run_targets": {
94+
"Startup": {
95+
"description": "Minimal functionality of the system",
96+
"depends_on": [
97+
"cpp_supervised_app",
98+
"rust_supervised_app",
99+
"state_manager"
100+
],
101+
"recovery_action": {
102+
"switch_run_target": {
103+
"run_target": "fallback_run_target"
104+
}
105+
}
106+
}
107+
},
108+
"initial_run_target": "Startup",
109+
"fallback_run_target": {
110+
"description": "Switching off everything",
111+
"depends_on": [
112+
"state_manager"
113+
],
114+
"transition_timeout": 1.5
115+
},
116+
"alive_supervision": {
117+
"evaluation_cycle": 0.5
118+
}
119+
}

feature_integration_tests/test_cases/conftest.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
#
1111
# SPDX-License-Identifier: Apache-2.0
1212
# *******************************************************************************
13+
import os
14+
import subprocess
1315
from pathlib import Path
1416

1517
import pytest
16-
from testing_utils import BazelTools
1718

1819

1920
# Cmdline options
@@ -61,6 +62,12 @@ def pytest_addoption(parser):
6162
default=180.0,
6263
help="Build command timeout in seconds. Default: %(default)s",
6364
)
65+
parser.addoption(
66+
"--bazel-config",
67+
type=str,
68+
default=os.environ.get("FIT_BAZEL_CONFIG", "linux-x86_64"),
69+
help=('Bazel config used when --build-scenarios is enabled (default: env FIT_BAZEL_CONFIG or "linux-x86_64").'),
70+
)
6471
parser.addoption(
6572
"--default-execution-timeout",
6673
type=float,
@@ -88,18 +95,35 @@ def pytest_sessionstart(session):
8895
# Build scenarios.
8996
if session.config.getoption("--build-scenarios"):
9097
build_timeout = session.config.getoption("--build-scenarios-timeout")
98+
bazel_config = session.config.getoption("--bazel-config")
99+
100+
def _build_target(target_name: str) -> None:
101+
command = ["bazel", "build", f"--config={bazel_config}", target_name]
102+
result = subprocess.run(
103+
command,
104+
capture_output=True,
105+
text=True,
106+
check=False,
107+
timeout=build_timeout,
108+
)
109+
if result.returncode != 0:
110+
stderr_tail = "\n".join(result.stderr.strip().splitlines()[-40:])
111+
raise RuntimeError(
112+
"Failed to run build with pytest --build-scenarios.\n"
113+
f"Command: {' '.join(command)}\n"
114+
f"Return code: {result.returncode}\n"
115+
f"stderr (last lines):\n{stderr_tail}"
116+
)
91117

92118
# Build Rust test scenarios.
93-
print("Building Rust test scenarios executable...")
94-
rust_tools = BazelTools(option_prefix="rust", build_timeout=build_timeout)
119+
print(f"Building Rust test scenarios executable with --config={bazel_config}...")
95120
rust_target_name = session.config.getoption("--rust-target-name")
96-
rust_tools.build(rust_target_name)
121+
_build_target(rust_target_name)
97122

98123
# Build C++ test scenarios.
99-
print("Building C++ test scenarios executable...")
100-
cpp_tools = BazelTools(option_prefix="cpp", build_timeout=build_timeout)
124+
print(f"Building C++ test scenarios executable with --config={bazel_config}...")
101125
cpp_target_name = session.config.getoption("--cpp-target-name")
102-
cpp_tools.build(cpp_target_name)
126+
_build_target(cpp_target_name)
103127

104128
except Exception as e:
105129
pytest.exit(str(e), returncode=1)

0 commit comments

Comments
 (0)