Skip to content

Commit 4e258b4

Browse files
committed
Integrate orchestration and persistency rust
1 parent 1b00f6e commit 4e258b4

File tree

19 files changed

+644
-34
lines changed

19 files changed

+644
-34
lines changed

.github/workflows/build_and_test_on_every_pr._yml renamed to .github/workflows/build_and_test_on_every_pr.yml

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,11 @@ jobs:
4444
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
4545
sudo udevadm control --reload-rules
4646
sudo udevadm trigger --name-match=kvm
47-
- name: Bazel execute itf qnx_qemu tests
48-
env:
49-
SCORE_QNX_USER: ${{ secrets.SCORE_QNX_USER }}
50-
SCORE_QNX_PASSWORD: ${{ secrets.SCORE_QNX_PASSWORD }}
47+
- name: Bazel execute showcase examples
5148
run: |
52-
cd qnx_qemu
53-
bazel test --config=qemu-integration --test_output=streamed --credential_helper=*.qnx.com=${{ github.workspace }}/.github/tools/qnx_credential_helper.py -- \
54-
//:test_ssh_qemu \
55-
//:test_scrample_qemu \
56-
49+
set -e
50+
bazel build --config bl-x86_64-linux //feature_showcase:all_examples
51+
while read -r target; do
52+
bazel run --config bl-x86_64-linux "$target"
53+
done < ci/showcase_targets_run.txt
54+

.github/workflows/release_verification.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ jobs:
5656
bazel test --config=qemu-integration --test_output=streamed --credential_helper=*.qnx.com=${{ github.workspace }}/.github/tools/qnx_credential_helper.py -- \
5757
//:test_ssh_qemu \
5858
//:test_scrample_qemu \
59+
- name: Bazel execute showcase examples
60+
run: |
61+
bazel build --config bl-x86_64-linux //feature_showcase:all_examples
5962
release_verification:
6063
runs-on: ubuntu-latest
6164
needs: [test_target]

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ _logs
77

88
# Ruff
99
.ruff_cache
10+
target/

MODULE.bazel

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ include("//:score_modules.MODULE.bazel")
2222
# for building documentation, verifying traceability etc.
2323
bazel_dep(name = "score_platform", version = "0.3.0")
2424
bazel_dep(name = "score_bazel_platforms", version = "0.0.2")
25+
bazel_dep(name = "score_crates", version = "0.0.3")
2526

2627
# QNX toolchain
2728
bazel_dep(name = "score_toolchains_qnx", version = "0.0.2")
@@ -35,8 +36,8 @@ use_repo(toolchains_qnx, "toolchains_qnx_sdp")
3536
use_repo(toolchains_qnx, "toolchains_qnx_qcc")
3637

3738
#gcc toolchain for baselibs
38-
bazel_dep(name = "score_toolchains_gcc", version = "0.5", dev_dependency=False)
39-
gcc = use_extension("@score_toolchains_gcc//extentions:gcc.bzl", "gcc", dev_dependency=False)
39+
bazel_dep(name = "score_toolchains_gcc", version = "0.5", dev_dependency = False)
40+
gcc = use_extension("@score_toolchains_gcc//extentions:gcc.bzl", "gcc", dev_dependency = False)
4041
gcc.toolchain(
4142
url = "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/0.0.1/x86_64-unknown-linux-gnu_gcc12.tar.gz",
4243
sha256 = "457f5f20f57528033cb840d708b507050d711ae93e009388847e113b11bf3600",
@@ -56,26 +57,17 @@ gcc.warning_flags(
5657
use_repo(gcc, "gcc_toolchain", "gcc_toolchain_gcc")
5758
register_toolchains("@gcc_toolchain//:all")
5859

59-
# LLVM Toolchains
60-
bazel_dep(name = "toolchains_llvm", version = "1.2.0") # persistency module uses 1.2.0 and does not work with 1.4.0 yet
61-
llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm")
62-
llvm.toolchain(
63-
cxx_standard = {"": "c++17"},
64-
llvm_version = "19.1.0",
65-
)
66-
use_repo(llvm, "llvm_toolchain")
67-
use_repo(llvm, "llvm_toolchain_llvm")
68-
69-
register_toolchains("@llvm_toolchain//:all")
70-
71-
## needed additions to build
72-
bazel_dep(name = "testing-utils")
60+
bazel_dep(name = "score_test_scenarios", version = "0.3.0")
7361
git_override(
74-
module_name = "testing-utils",
75-
commit = "a847c7464cfa47e000141631d1223b92560d2e58", # tag v0.2.0
76-
remote = "https://github.com/qorix-group/testing_tools.git",
62+
module_name = "score_test_scenarios",
63+
commit = "a2f9cded3deb636f5dc800bf7a47131487119721", # tag v0.3.0
64+
remote = "https://github.com/eclipse-score/testing_tools.git",
7765
)
7866

67+
# Needed for feature integration tests
68+
bazel_dep(name = "rules_rust", version = "0.61.0")
69+
bazel_dep(name = "score_itf", version = "0.1.0")
70+
7971
# # TODO: What is this for?
8072
archive_override(
8173
module_name = "rules_boost",

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ bazel build \
3030

3131
> Note: Python tests for `@score_persistency` cannot be built from this integration workspace due to Bazel external repository visibility limitations. The pip extension and Python dependencies must be accessed within their defining module.
3232
33+
### Orchestration and `kyron` - async runtime for Rust
34+
35+
```bash
36+
bazel build @score_orchestrator//src/...
37+
```
38+
39+
## Feature showcase examples
40+
The examples that are aiming to showcase features provided by S-CORE are located in `feature_showcase` folder.
41+
You can run them currently for host platform using `--config bl-x86_64-linux`.
42+
43+
Execute `bazel query //feature_showcase/...` to obtain list of targets that You can run.
44+
3345
## ⚠️ Observed Issues
3446

3547
### communication: score/mw/com/requirements

ci/showcase_targets_run.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
//feature_showcase/rust:kyron_example
2+
//feature_showcase/rust:orch_per_example
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2025 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+
load("@rules_rust//rust:defs.bzl", "rust_binary")
15+
16+
rust_binary(
17+
name = "rust_test_scenarios",
18+
srcs = glob(["src/**/*.rs"]),
19+
tags = [
20+
"manual",
21+
],
22+
deps = [
23+
"@score_orchestrator//src/kyron:libkyron",
24+
"@score_orchestrator//src/kyron-foundation:libkyron_foundation",
25+
"@score_orchestrator//src/orchestration:liborchestration",
26+
"@score_persistency//src/rust/rust_kvs:rust_kvs",
27+
"@score_test_scenarios//test_scenarios_rust:test_scenarios_rust",
28+
"@score_crates//:tracing",
29+
"@score_crates//:serde",
30+
"@score_crates//:serde_json",
31+
]
32+
)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// Copyright (c) 2025 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+
pub mod runtime_helper;
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
//
2+
// Copyright (c) 2025 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+
use kyron::core::types::UniqueWorkerId;
14+
use kyron::prelude::ThreadParameters as AsyncRtThreadParameters;
15+
use kyron::runtime::*;
16+
use kyron::scheduler::SchedulerType;
17+
use serde::{de, Deserialize, Deserializer};
18+
use serde_json::Value;
19+
use tracing::debug;
20+
21+
fn deserialize_scheduler_type<'de, D>(deserializer: D) -> Result<Option<SchedulerType>, D::Error>
22+
where
23+
D: Deserializer<'de>,
24+
{
25+
let value_opt: Option<String> = Option::deserialize(deserializer)?;
26+
if let Some(value_str) = value_opt {
27+
let value = match value_str.as_str() {
28+
"fifo" => SchedulerType::Fifo,
29+
"round_robin" => SchedulerType::RoundRobin,
30+
"other" => SchedulerType::Other,
31+
_ => return Err(de::Error::custom("Unknown scheduler type")),
32+
};
33+
return Ok(Some(value));
34+
}
35+
36+
Ok(None)
37+
}
38+
39+
/// Thread parameters.
40+
#[derive(Deserialize, Debug, Clone)]
41+
pub struct ThreadParameters {
42+
pub thread_priority: Option<u8>,
43+
pub thread_affinity: Option<Vec<usize>>,
44+
pub thread_stack_size: Option<u64>,
45+
#[serde(default, deserialize_with = "deserialize_scheduler_type")]
46+
pub thread_scheduler: Option<SchedulerType>,
47+
}
48+
49+
/// Dedicated worker configuration.
50+
#[derive(Deserialize, Debug, Clone)]
51+
pub struct DedicatedWorkerConfig {
52+
pub id: String,
53+
#[serde(flatten)]
54+
pub thread_parameters: ThreadParameters,
55+
}
56+
57+
/// Execution engine configuration.
58+
#[derive(Deserialize, Debug, Clone)]
59+
pub struct ExecEngineConfig {
60+
pub task_queue_size: u32,
61+
pub workers: usize,
62+
#[serde(flatten)]
63+
pub thread_parameters: ThreadParameters,
64+
pub dedicated_workers: Option<Vec<DedicatedWorkerConfig>>,
65+
}
66+
67+
fn deserialize_exec_engines<'de, D>(deserializer: D) -> Result<Vec<ExecEngineConfig>, D::Error>
68+
where
69+
D: Deserializer<'de>,
70+
{
71+
#[derive(Deserialize)]
72+
#[serde(untagged)]
73+
enum RuntimeConfig {
74+
Object(ExecEngineConfig),
75+
Array(Vec<ExecEngineConfig>),
76+
}
77+
78+
let exec_engines = match RuntimeConfig::deserialize(deserializer)? {
79+
RuntimeConfig::Object(exec_engine_config) => vec![exec_engine_config],
80+
RuntimeConfig::Array(exec_engine_configs) => exec_engine_configs,
81+
};
82+
Ok(exec_engines)
83+
}
84+
85+
#[derive(Deserialize, Debug)]
86+
#[serde(transparent)]
87+
pub struct Runtime {
88+
#[serde(deserialize_with = "deserialize_exec_engines")]
89+
exec_engines: Vec<ExecEngineConfig>,
90+
}
91+
92+
impl Runtime {
93+
/// Parse `Runtime` from JSON string.
94+
/// JSON is expected to contain `runtime` field.
95+
pub fn from_json(json_str: &str) -> Result<Self, String> {
96+
let v: Value = serde_json::from_str(json_str).map_err(|e| e.to_string())?;
97+
serde_json::from_value(v["runtime"].clone()).map_err(|e| e.to_string())
98+
}
99+
100+
pub fn exec_engines(&self) -> &Vec<ExecEngineConfig> {
101+
&self.exec_engines
102+
}
103+
104+
pub fn build(&self) -> kyron::runtime::Runtime {
105+
debug!("Creating kyron::Runtime with {} execution engines", self.exec_engines.len());
106+
107+
let mut async_rt_builder = kyron::runtime::RuntimeBuilder::new();
108+
for exec_engine in self.exec_engines.as_slice() {
109+
debug!("Creating ExecutionEngine with: {:?}", exec_engine);
110+
111+
let mut exec_engine_builder = ExecutionEngineBuilder::new()
112+
.task_queue_size(exec_engine.task_queue_size)
113+
.workers(exec_engine.workers);
114+
115+
// Set thread parameters.
116+
{
117+
let thread_params = &exec_engine.thread_parameters;
118+
if let Some(thread_priority) = thread_params.thread_priority {
119+
exec_engine_builder = exec_engine_builder.thread_priority(thread_priority);
120+
}
121+
if let Some(thread_affinity) = &thread_params.thread_affinity {
122+
exec_engine_builder = exec_engine_builder.thread_affinity(thread_affinity);
123+
}
124+
if let Some(thread_stack_size) = thread_params.thread_stack_size {
125+
exec_engine_builder = exec_engine_builder.thread_stack_size(thread_stack_size);
126+
}
127+
if let Some(thread_scheduler) = thread_params.thread_scheduler {
128+
exec_engine_builder = exec_engine_builder.thread_scheduler(thread_scheduler);
129+
}
130+
}
131+
132+
// Set dedicated workers.
133+
if let Some(dedicated_workers) = &exec_engine.dedicated_workers {
134+
for dedicated_worker in dedicated_workers {
135+
// Create thread parameters object.
136+
let mut async_rt_thread_params = AsyncRtThreadParameters::default();
137+
if let Some(thread_priority) = dedicated_worker.thread_parameters.thread_priority {
138+
async_rt_thread_params = async_rt_thread_params.priority(thread_priority);
139+
}
140+
if let Some(thread_affinity) = &dedicated_worker.thread_parameters.thread_affinity {
141+
async_rt_thread_params = async_rt_thread_params.affinity(thread_affinity);
142+
}
143+
if let Some(thread_stack_size) = dedicated_worker.thread_parameters.thread_stack_size {
144+
async_rt_thread_params = async_rt_thread_params.stack_size(thread_stack_size);
145+
}
146+
if let Some(thread_scheduler) = dedicated_worker.thread_parameters.thread_scheduler {
147+
async_rt_thread_params = async_rt_thread_params.scheduler_type(thread_scheduler);
148+
}
149+
150+
// Create `UniqueWorkerId`.
151+
let unique_worker_id = UniqueWorkerId::from(&dedicated_worker.id);
152+
153+
exec_engine_builder = exec_engine_builder.with_dedicated_worker(unique_worker_id, async_rt_thread_params);
154+
}
155+
}
156+
157+
let (builder, _) = async_rt_builder.with_engine(exec_engine_builder);
158+
async_rt_builder = builder;
159+
}
160+
161+
async_rt_builder.build().expect("Failed to build async runtime")
162+
}
163+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// Copyright (c) 2025 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+
mod internals;
15+
mod tests;
16+
17+
use test_scenarios_rust::cli::run_cli_app;
18+
use test_scenarios_rust::test_context::TestContext;
19+
20+
use crate::tests::root_scenario_group;
21+
22+
fn main() -> Result<(), String> {
23+
let raw_arguments: Vec<String> = std::env::args().collect();
24+
25+
// Root group.
26+
let root_group = root_scenario_group();
27+
28+
// Run.
29+
let test_context = TestContext::new(root_group);
30+
run_cli_app(&raw_arguments, &test_context)
31+
}

0 commit comments

Comments
 (0)