Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,11 @@ jobs:
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Bazel execute itf qnx_qemu tests
env:
SCORE_QNX_USER: ${{ secrets.SCORE_QNX_USER }}
SCORE_QNX_PASSWORD: ${{ secrets.SCORE_QNX_PASSWORD }}
- name: Bazel execute showcase examples
run: |
cd qnx_qemu
bazel test --config=qemu-integration --test_output=streamed --credential_helper=*.qnx.com=${{ github.workspace }}/.github/tools/qnx_credential_helper.py -- \
//:test_ssh_qemu \
//:test_scrample_qemu \

set -e
bazel build --config bl-x86_64-linux //feature_showcase:all_examples
while read -r target; do
bazel run --config bl-x86_64-linux "$target"
done < ci/showcase_targets_run.txt

3 changes: 3 additions & 0 deletions .github/workflows/release_verification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ jobs:
bazel test --config=qemu-integration --test_output=streamed --credential_helper=*.qnx.com=${{ github.workspace }}/.github/tools/qnx_credential_helper.py -- \
//:test_ssh_qemu \
//:test_scrample_qemu \
- name: Bazel execute showcase examples
run: |
bazel build --config bl-x86_64-linux //feature_showcase:all_examples
release_verification:
runs-on: ubuntu-latest
needs: [test_target]
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ _logs

# Ruff
.ruff_cache
target/

rust-project.json
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rust-analyzer.linkedProjects": [
"rust-project.json"
]
}
30 changes: 11 additions & 19 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ include("//:score_modules.MODULE.bazel")
# for building documentation, verifying traceability etc.
bazel_dep(name = "score_platform", version = "0.3.0")
bazel_dep(name = "score_bazel_platforms", version = "0.0.2")
bazel_dep(name = "score_crates", version = "0.0.3")

# QNX toolchain
bazel_dep(name = "score_toolchains_qnx", version = "0.0.2")
Expand All @@ -35,8 +36,8 @@ use_repo(toolchains_qnx, "toolchains_qnx_sdp")
use_repo(toolchains_qnx, "toolchains_qnx_qcc")

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

# LLVM Toolchains
bazel_dep(name = "toolchains_llvm", version = "1.2.0") # persistency module uses 1.2.0 and does not work with 1.4.0 yet
llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm")
llvm.toolchain(
cxx_standard = {"": "c++17"},
llvm_version = "19.1.0",
)
use_repo(llvm, "llvm_toolchain")
use_repo(llvm, "llvm_toolchain_llvm")

register_toolchains("@llvm_toolchain//:all")

## needed additions to build
bazel_dep(name = "testing-utils")
bazel_dep(name = "score_test_scenarios", version = "0.3.0")
git_override(
module_name = "testing-utils",
commit = "a847c7464cfa47e000141631d1223b92560d2e58", # tag v0.2.0
remote = "https://github.com/qorix-group/testing_tools.git",
module_name = "score_test_scenarios",
commit = "a2f9cded3deb636f5dc800bf7a47131487119721", # tag v0.3.0
remote = "https://github.com/eclipse-score/testing_tools.git",
)

# Needed for feature integration tests
bazel_dep(name = "rules_rust", version = "0.61.0")
bazel_dep(name = "score_itf", version = "0.1.0")

# # TODO: What is this for?
archive_override(
module_name = "rules_boost",
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ bazel build \

> 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.

### Orchestration and `kyron` - async runtime for Rust

```bash
bazel build @score_orchestrator//src/...
```

## Feature showcase examples
The examples that are aiming to showcase features provided by S-CORE are located in `feature_showcase` folder.
You can run them currently for host platform using `--config bl-x86_64-linux`.

Execute `bazel query //feature_showcase/...` to obtain list of targets that You can run.

## ⚠️ Observed Issues

### communication: score/mw/com/requirements
Expand Down Expand Up @@ -108,6 +120,12 @@ local_path_override(module_name = "score_tooling", path = "../tooling")
- Unify LLVM toolchain versions across modules.
- Introduce integration tests for `@itf` once build succeeds.

## IDE support

### Rust

Use `./generate_rust_analyzer_support.sh` to generate rust_analyzer settings that will let VS Code work.

## 📌 Quick Reference

| Area | Status | Action |
Expand Down
2 changes: 2 additions & 0 deletions ci/showcase_targets_run.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
//feature_showcase/rust:kyron_example
//feature_showcase/rust:orch_per_example
32 changes: 32 additions & 0 deletions feature_integration_tests/rust_test_scenarios/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# *******************************************************************************
# Copyright (c) 2025 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("@rules_rust//rust:defs.bzl", "rust_binary")

rust_binary(
name = "rust_test_scenarios",
srcs = glob(["src/**/*.rs"]),
tags = [
"manual",
],
deps = [
"@score_orchestrator//src/kyron:libkyron",
"@score_orchestrator//src/kyron-foundation:libkyron_foundation",
"@score_orchestrator//src/orchestration:liborchestration",
"@score_persistency//src/rust/rust_kvs:rust_kvs",
"@score_test_scenarios//test_scenarios_rust:test_scenarios_rust",
"@score_crates//:tracing",
"@score_crates//:serde",
"@score_crates//:serde_json",
]
)
13 changes: 13 additions & 0 deletions feature_integration_tests/rust_test_scenarios/src/internals/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// Copyright (c) 2025 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
//
pub mod runtime_helper;
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
//
// Copyright (c) 2025 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
//
use kyron::core::types::UniqueWorkerId;
use kyron::prelude::ThreadParameters as AsyncRtThreadParameters;
use kyron::runtime::*;
use kyron::scheduler::SchedulerType;
use serde::{de, Deserialize, Deserializer};
use serde_json::Value;
use tracing::debug;

fn deserialize_scheduler_type<'de, D>(deserializer: D) -> Result<Option<SchedulerType>, D::Error>
where
D: Deserializer<'de>,
{
let value_opt: Option<String> = Option::deserialize(deserializer)?;
if let Some(value_str) = value_opt {
let value = match value_str.as_str() {
"fifo" => SchedulerType::Fifo,
"round_robin" => SchedulerType::RoundRobin,
"other" => SchedulerType::Other,
_ => return Err(de::Error::custom("Unknown scheduler type")),
};
return Ok(Some(value));
}

Ok(None)
}

/// Thread parameters.
#[derive(Deserialize, Debug, Clone)]
pub struct ThreadParameters {
pub thread_priority: Option<u8>,
pub thread_affinity: Option<Vec<usize>>,
pub thread_stack_size: Option<u64>,
#[serde(default, deserialize_with = "deserialize_scheduler_type")]
pub thread_scheduler: Option<SchedulerType>,
}

/// Dedicated worker configuration.
#[derive(Deserialize, Debug, Clone)]
pub struct DedicatedWorkerConfig {
pub id: String,
#[serde(flatten)]
pub thread_parameters: ThreadParameters,
}

/// Execution engine configuration.
#[derive(Deserialize, Debug, Clone)]
pub struct ExecEngineConfig {
pub task_queue_size: u32,
pub workers: usize,
#[serde(flatten)]
pub thread_parameters: ThreadParameters,
pub dedicated_workers: Option<Vec<DedicatedWorkerConfig>>,
}

fn deserialize_exec_engines<'de, D>(deserializer: D) -> Result<Vec<ExecEngineConfig>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum RuntimeConfig {
Object(ExecEngineConfig),
Array(Vec<ExecEngineConfig>),
}

let exec_engines = match RuntimeConfig::deserialize(deserializer)? {
RuntimeConfig::Object(exec_engine_config) => vec![exec_engine_config],
RuntimeConfig::Array(exec_engine_configs) => exec_engine_configs,
};
Ok(exec_engines)
}

#[derive(Deserialize, Debug)]
#[serde(transparent)]
pub struct Runtime {
#[serde(deserialize_with = "deserialize_exec_engines")]
exec_engines: Vec<ExecEngineConfig>,
}

impl Runtime {
/// Parse `Runtime` from JSON string.
/// JSON is expected to contain `runtime` field.
pub fn from_json(json_str: &str) -> Result<Self, String> {
let v: Value = serde_json::from_str(json_str).map_err(|e| e.to_string())?;
serde_json::from_value(v["runtime"].clone()).map_err(|e| e.to_string())
}

pub fn exec_engines(&self) -> &Vec<ExecEngineConfig> {
&self.exec_engines
}

pub fn build(&self) -> kyron::runtime::Runtime {
debug!("Creating kyron::Runtime with {} execution engines", self.exec_engines.len());

let mut async_rt_builder = kyron::runtime::RuntimeBuilder::new();
for exec_engine in self.exec_engines.as_slice() {
debug!("Creating ExecutionEngine with: {:?}", exec_engine);

let mut exec_engine_builder = ExecutionEngineBuilder::new()
.task_queue_size(exec_engine.task_queue_size)
.workers(exec_engine.workers);

// Set thread parameters.
{
let thread_params = &exec_engine.thread_parameters;
if let Some(thread_priority) = thread_params.thread_priority {
exec_engine_builder = exec_engine_builder.thread_priority(thread_priority);
}
if let Some(thread_affinity) = &thread_params.thread_affinity {
exec_engine_builder = exec_engine_builder.thread_affinity(thread_affinity);
}
if let Some(thread_stack_size) = thread_params.thread_stack_size {
exec_engine_builder = exec_engine_builder.thread_stack_size(thread_stack_size);
}
if let Some(thread_scheduler) = thread_params.thread_scheduler {
exec_engine_builder = exec_engine_builder.thread_scheduler(thread_scheduler);
}
}

// Set dedicated workers.
if let Some(dedicated_workers) = &exec_engine.dedicated_workers {
for dedicated_worker in dedicated_workers {
// Create thread parameters object.
let mut async_rt_thread_params = AsyncRtThreadParameters::default();
if let Some(thread_priority) = dedicated_worker.thread_parameters.thread_priority {
async_rt_thread_params = async_rt_thread_params.priority(thread_priority);
}
if let Some(thread_affinity) = &dedicated_worker.thread_parameters.thread_affinity {
async_rt_thread_params = async_rt_thread_params.affinity(thread_affinity);
}
if let Some(thread_stack_size) = dedicated_worker.thread_parameters.thread_stack_size {
async_rt_thread_params = async_rt_thread_params.stack_size(thread_stack_size);
}
if let Some(thread_scheduler) = dedicated_worker.thread_parameters.thread_scheduler {
async_rt_thread_params = async_rt_thread_params.scheduler_type(thread_scheduler);
}

// Create `UniqueWorkerId`.
let unique_worker_id = UniqueWorkerId::from(&dedicated_worker.id);

exec_engine_builder = exec_engine_builder.with_dedicated_worker(unique_worker_id, async_rt_thread_params);
}
}

let (builder, _) = async_rt_builder.with_engine(exec_engine_builder);
async_rt_builder = builder;
}

async_rt_builder.build().expect("Failed to build async runtime")
}
}
31 changes: 31 additions & 0 deletions feature_integration_tests/rust_test_scenarios/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// Copyright (c) 2025 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
//

mod internals;
mod tests;

use test_scenarios_rust::cli::run_cli_app;
use test_scenarios_rust::test_context::TestContext;

use crate::tests::root_scenario_group;

fn main() -> Result<(), String> {
let raw_arguments: Vec<String> = std::env::args().collect();

// Root group.
let root_group = root_scenario_group();

// Run.
let test_context = TestContext::new(root_group);
run_cli_app(&raw_arguments, &test_context)
}
Loading