Skip to content
Open
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
4 changes: 4 additions & 0 deletions bazel_common/score_modules_target_sw.MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ bazel_dep(name = "score_lifecycle_health")
git_override(
module_name = "score_lifecycle_health",
commit = "23e9849437c578ade99b8ccbf5d09c1835737b3f",
patch_strip = 1,
patches = [
"//patches/lifecycle:001-forward-visibility-to-config-combiner.patch",
],
remote = "https://github.com/eclipse-score/lifecycle.git",
)

Expand Down
61 changes: 61 additions & 0 deletions feature_integration_tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,66 @@ bazel test //feature_integration_tests/test_cases:fit_rust
bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit_cpp
```

The Rust side of this lifecycle-only suite uses a dedicated Bazel target,
`//feature_integration_tests/test_scenarios/rust:rust_lifecycle_test_scenarios`,
which still reuses `test_scenarios/rust/src/main.rs`. It is built with the
`lifecycle_only` cfg so only lifecycle scenarios are compiled for that suite,
while the normal `fit` and `fit_rust` targets continue to use the full scenario tree.

To run the lifecycle tests directly with `pytest` and build the scenario binaries on demand:

```sh
python3 -m pytest feature_integration_tests/test_cases/tests/lifecycle/ \
--build-scenarios \
-m rust \
--rust-target-name=//feature_integration_tests/test_scenarios/rust:rust_lifecycle_test_scenarios \
-q -v

python3 -m pytest feature_integration_tests/test_cases/tests/lifecycle/ \
--build-scenarios \
-m cpp \
-q -v
```

The Rust override is required because plain `--build-scenarios` defaults to
`//feature_integration_tests/test_scenarios/rust:rust_test_scenarios`, while the
lifecycle tests need the reduced lifecycle-only Rust target.

#### Sandbox uid/gid and scheduling-policy tests

Some lifecycle daemon tests (e.g. `test_launched_process_uid_gid_matches_config_when_applied`,
`test_launched_process_scheduling_matches_config_when_applied`) verify that `launch_manager`
applies the sandbox `uid`/`gid` and scheduling policy from
`feature_integration_tests/configs/lifecycle_daemon_config.json`. This requires granting
`launch_manager` the `cap_setuid,cap_setgid,cap_sys_nice` file capabilities via `setcap`, which
in turn requires `CAP_SETFCAP` — not available to a non-root test runner by default.

Set `FIT_ENABLE_SETCAP=1` to opt in to a `sudo -n setcap` attempt (backed by a passwordless
sudoers rule scoped to the `setcap` binary, e.g. `<user> ALL=(root) NOPASSWD: /usr/sbin/setcap`,
with no trailing arguments pinned — the target path is a fresh `tmp_path` on every run). Without
it, these tests skip with a message identifying the missing capability grant.

```sh
export FIT_ENABLE_SETCAP=1

python3 -m pytest feature_integration_tests/test_cases/tests/lifecycle/ \
--build-scenarios \
-m cpp \
-k "uid_gid or scheduling" \
-q -v
```

Under `bazel test`, undeclared env vars like `FIT_ENABLE_SETCAP` do not reach the test process
unless passed via `--test_env` (not `--action_env`, which only affects build actions):

```sh
bazel test --config=linux-x86_64 //feature_integration_tests/test_cases:fit_cpp \
--test_env=FIT_ENABLE_SETCAP=1
```

`bazel run` inherits the invoking shell's environment directly, so exporting the variable
beforehand is sufficient there.

## Quick try

Run a quick smoke of the FIT harness (lists scenarios or runs a small subset):
Expand All @@ -62,6 +122,7 @@ Test scenarios can be listed and run directly for debugging:

```sh
bazel run //feature_integration_tests/test_scenarios/rust:rust_test_scenarios -- --list-scenarios
bazel run //feature_integration_tests/test_scenarios/rust:rust_lifecycle_test_scenarios -- --list-scenarios
bazel run --config=linux-x86_64 //feature_integration_tests/test_scenarios/cpp:cpp_test_scenarios -- --list-scenarios
```

Expand Down
10 changes: 10 additions & 0 deletions feature_integration_tests/configs/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************
load("@score_lifecycle_health//:defs.bzl", "launch_manager_config")

exports_files(
[
"dlt_config_qnx_x86_64.json",
"dlt_config_x86_64.json",
"qemu_bridge_config.json",
"lifecycle_daemon_config.json",
],
)

Expand All @@ -31,3 +34,10 @@ filegroup(
],
visibility = ["//visibility:public"],
)

launch_manager_config(
name = "lifecycle_daemon_config",
config = ":lifecycle_daemon_config.json",
flatbuffer_out_dir = "etc",
visibility = ["//visibility:public"],
)
103 changes: 103 additions & 0 deletions feature_integration_tests/configs/lifecycle_daemon_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{
"schema_version": 1,
"defaults": {
"deployment_config": {
"bin_dir": "/tmp/lifecycle_fit/bin",
"ready_timeout": 2.0,
"shutdown_timeout": 2.0,
"ready_recovery_action": {
"restart": {
"number_of_attempts": 0

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.

number_of_attempts: 0 disables retries.

test_supervised_app_recovery (test_process_launching_with_daemon.py:382-420) claims feat_req__lifecycle__retries_configurable against this config. With 0 attempts, recovery is entirely via the switch_run_target branch below, so no retry behaviour is exercised.

}
},
"recovery_action": {
"switch_run_target": {
"run_target": "fallback_run_target"
}
},
"sandbox": {
"uid": 1001,
"gid": 1001,
"scheduling_policy": "SCHED_OTHER",
"scheduling_priority": 0
}
},
"component_properties": {
"application_profile": {
"application_type": "Reporting",
"is_self_terminating": false,
"alive_supervision": {
"reporting_cycle": 0.1,
"min_indications": 1,
"max_indications": 3,
"failed_cycles_tolerance": 1
}
},
"ready_condition": {
"process_state": "Running"
}
}
},
"components": {
"cpp_supervised_app": {
"component_properties": {
"binary_name": "cpp_supervised_app",
"application_profile": {
"application_type": "Reporting_And_Supervised"
},
"process_arguments": [
"-d50"
]
},
"deployment_config": {
"environmental_variables": {
"PROCESSIDENTIFIER": "cpp_supervised_app",
"IDENTIFIER": "cpp_supervised_app"
}
}
},
"rust_supervised_app": {
"component_properties": {
"binary_name": "rust_supervised_app",
"depends_on": [

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.

This dependency serializes startup.

rust_supervised_app depending on cpp_supervised_app means the two apps cannot launch in parallel — yet test_startup_declares_and_launches_multiple_processes (test_process_launching_with_daemon.py:128-157) claims feat_req__lifecycle__parallel_launch_support against this same config.

"cpp_supervised_app"
],
"application_profile": {
"application_type": "Reporting_And_Supervised"
},
"process_arguments": [
"-d50"
]
},
"deployment_config": {
"environmental_variables": {
"PROCESSIDENTIFIER": "rust_supervised_app",
"IDENTIFIER": "rust_supervised_app"
}
}
}
},
"run_targets": {
"Startup": {
"depends_on": [
"cpp_supervised_app",
"rust_supervised_app"
],
"recovery_action": {
"switch_run_target": {
"run_target": "fallback_run_target"
}
}
}
},
"initial_run_target": "Startup",
"alive_supervision": {
"evaluation_cycle": 0.05
},
"fallback_run_target": {
"depends_on": [
"cpp_supervised_app",
"rust_supervised_app"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
{

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.

This entire 109-line config is unreferenced.

It is not in configs/BUILD, not in exports_files, not used by any test, and its cpp_retry_exhaustion_app binary is never staged into bin_dir. It looks written precisely for the retry test that retries_configurable currently claims — so either wire it up and add that test, or delete the file along with the requirement tag on test_supervised_app_recovery.

"schema_version": 1,
"defaults": {
"deployment_config": {
"bin_dir": "/tmp/lifecycle_fit/bin",
"ready_timeout": 2.0,
"shutdown_timeout": 2.0,
"ready_recovery_action": {
"restart": {
"number_of_attempts": 0
}
},
"recovery_action": {
"switch_run_target": {
"run_target": "fallback_run_target"
}
},
"sandbox": {
"uid": 1001,
"gid": 1001,
"scheduling_policy": "SCHED_OTHER",
"scheduling_priority": 0
}
},
"component_properties": {
"application_profile": {
"application_type": "Reporting",
"is_self_terminating": false,
"alive_supervision": {
"reporting_cycle": 0.1,
"min_indications": 1,
"max_indications": 3,
"failed_cycles_tolerance": 1
}
},
"ready_condition": {
"process_state": "Running"
}
}
},
"components": {
"cpp_supervised_app": {
"component_properties": {
"binary_name": "cpp_supervised_app",
"application_profile": {
"application_type": "Reporting_And_Supervised"
},
"process_arguments": [
"-d50"
]
},
"deployment_config": {
"environmental_variables": {
"PROCESSIDENTIFIER": "cpp_supervised_app",
"IDENTIFIER": "cpp_supervised_app"
}
}
},
"cpp_retry_exhaustion_app": {
"component_properties": {
"binary_name": "cpp_retry_exhaustion_app",
"application_profile": {
"application_type": "Reporting"
},
"process_arguments": [
"-h"
]
},
"deployment_config": {
"ready_recovery_action": {
"restart": {
"number_of_attempts": 2
}
},
"recovery_action": {
"switch_run_target": {
"run_target": "fallback_run_target"
}
},
"environmental_variables": {
"PROCESSIDENTIFIER": "cpp_retry_exhaustion_app",
"IDENTIFIER": "cpp_retry_exhaustion_app"
}
}
}
},
"run_targets": {
"Startup": {
"depends_on": [
"cpp_supervised_app",
"cpp_retry_exhaustion_app"
],
"recovery_action": {
"switch_run_target": {
"run_target": "fallback_run_target"
}
}
}
},
"initial_run_target": "Startup",
"alive_supervision": {
"evaluation_cycle": 0.05
},
"fallback_run_target": {
"depends_on": [
"cpp_supervised_app"
]
}
}
Loading
Loading