Skip to content
Draft
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
17 changes: 16 additions & 1 deletion score/mw/com/example/com-api-example/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,33 @@ load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_test")
rust_binary(
name = "com-api-example",
srcs = ["basic-consumer-producer.rs"],
data = [
"etc/config.json",
"etc/logging.json",
],
env = {
"MW_LOG_CONFIG_FILE": "score/mw/com/example/com-api-example/etc/logging.json",
},
features = ["link_std_cpp_lib"],
visibility = ["//visibility:public"],
deps = [
"//score/mw/com/example/com-api-example/com-api-gen",
"//score/mw/com/impl/rust/com-api/com-api",
"@score_baselibs_rust//src/log/score_log",
"@score_logging//score/mw/log/rust/score_log_bridge",
],
)

rust_test(
name = "com-api-example-test",
crate = ":com-api-example",
data = ["etc/config.json"],
data = [
"etc/config.json",
"etc/logging.json",
],
env = {
"MW_LOG_CONFIG_FILE": "score/mw/com/example/com-api-example/etc/logging.json",
},
tags = ["manual"],
deps = [
":com-api-example",
Expand Down
55 changes: 35 additions & 20 deletions score/mw/com/example/com-api-example/basic-consumer-producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use com_api::{
};

use com_api_gen::{Exhaust, Tire, VehicleInterface};
use score_log as log;
use score_log_bridge::ScoreLogBridgeBuilder;

// Type aliases for generated consumer and offered producer types for the Vehicle interface
// VehicleConsumer is the consumer type generated for the Vehicle interface, parameterized by the runtime R
Expand Down Expand Up @@ -97,7 +99,7 @@ impl<R: Runtime> VehicleMonitor<R> {
let uninit_sample = self.producer.left_tire.allocate()?;
let sample = uninit_sample.write(tire);
sample.send()?;
println!("Tire data sent");
log::info!("Tire data sent");
Ok(())
}
}
Expand Down Expand Up @@ -153,30 +155,30 @@ fn create_producer<R: Runtime>(

// Run the example with the specified runtime
fn run_with_runtime<R: Runtime>(name: &str, runtime: &R) {
println!("\n=== Running with {name} runtime ===");
log::info!("Running with {} runtime", name);

let service_id = InstanceSpecifier::new("/Vehicle/Service1/Instance")
.expect("Failed to create InstanceSpecifier");
let producer = create_producer(runtime, service_id.clone());
let consumer = create_consumer(runtime, service_id);
let monitor = VehicleMonitor::new(consumer, producer).unwrap();
let tire_pressure = 5.0;
println!("Setting tire pressure to {tire_pressure}");
log::info!("Setting tire pressure to {}", tire_pressure);
for i in 0..5 {
monitor
.write_tire_data(Tire {
pressure: tire_pressure + i as f32,
})
.unwrap();
let tire_data = monitor.read_tire_data().unwrap();
println!("{tire_data}");
log::info!("Received tire data: {}", tire_data);
}
//unoffer returns producer back, so if needed it can be used further
match monitor.producer.unoffer() {
Ok(_) => println!("Successfully unoffered the service"),
Err(e) => eprintln!("Failed to unoffer: {:?}", e),
Ok(_) => log::info!("Successfully unoffered the service"),
Err(e) => log::error!("Failed to unoffer: {:?}", e),
}
println!("=== {name} runtime completed ===\n");
log::info!("runtime execution completed");
}

// Initialize Lola runtime builder with configuration
Expand All @@ -188,7 +190,22 @@ fn init_lola_runtime_builder() -> LolaRuntimeBuilderImpl {
lola_runtime_builder
}

fn init_logging() {
// Try to load logging config from environment variable.
let config_path = std::env::var("MW_LOG_CONFIG_FILE")
.expect("config file not set in environment variable MW_LOG_CONFIG_FILE");

// Initialize ScoreLogBridge as a default logger.
ScoreLogBridgeBuilder::new()
.show_module(false)
.show_file(true)
.show_line(false)
.config(config_path.into())
.set_as_default_logger();
}

fn main() {
init_logging();
let lola_runtime_builder = init_lola_runtime_builder();
let lola_runtime = lola_runtime_builder.build().unwrap();
run_with_runtime("Lola", &lola_runtime);
Expand All @@ -202,7 +219,8 @@ mod test {

#[test]
fn integration_test() {
println!("Starting integration test with Lola runtime");
init_logging();
log::info!("Starting integration test with Lola runtime");
let lola_runtime_builder = init_lola_runtime_builder();
let lola_runtime = lola_runtime_builder.build().unwrap();
run_with_runtime("Lola", &lola_runtime);
Expand Down Expand Up @@ -320,10 +338,7 @@ mod test {
pressure: 1.0 + i as f32,
});
sample.send().unwrap();
println!(
"[SENDER] Sent sample with pressure: {:.2} psi",
1.0 + i as f32
);
log::info!("Sent tire data: {:.2}", 1.0 + i as f32);
tokio::time::sleep(tokio::time::Duration::from_millis(2000)).await;
}
offered_producer
Expand All @@ -332,25 +347,25 @@ mod test {
//receiver function which use async receive to get data, it waits for new data and process it once it arrives,
//it will receive data 10 times and print the received samples
async fn async_data_processor_fn<R: Runtime>(subscribed: impl Subscription<Tire, R>) {
println!("[RECEIVER] Async data processor started");
log::info!("Async data processor started");
let mut buffer = SampleContainer::new(5);
for _ in 0..5 {
buffer = match subscribed.receive(buffer, 2, 3).await {
Ok(returned_buf) => {
let count = returned_buf.sample_count();
if count > 0 {
println!("[RECEIVER] Received {} samples", count);
log::info!("[RECEIVER] Received {} samples", count);
let mut buf = returned_buf;
while let Some(sample) = buf.pop_front() {
println!("[RECEIVER] Sample: {:.2} psi", sample.pressure);
log::info!("[RECEIVER] Sample: {:.2} psi", sample.pressure);
}
buf
} else {
returned_buf
}
}
Err(e) => {
println!("[RECEIVER] Error receiving data: {:?}", e);
log::error!("[RECEIVER] Error receiving data: {:?}", e);
SampleContainer::new(5)
}
}
Expand All @@ -361,7 +376,7 @@ mod test {
// Use the tokio multi-threaded runtime to run async sender and receiver concurrently on separate threads
#[tokio::test(flavor = "multi_thread")]
async fn receive_and_send_using_multi_thread() {
println!("Starting async subscription test with Lola runtime");
log::info!("Starting async subscription test with Lola runtime");
let service_id = InstanceSpecifier::new("/Vehicle/Service3/Instance")
.expect("Failed to create InstanceSpecifier");
let service_id_clone = service_id.clone();
Expand Down Expand Up @@ -390,10 +405,10 @@ mod test {
let producer = sender_join_handle.await.expect("Error returned from task");

match producer.unoffer() {
Ok(_) => println!("Successfully unoffered the service"),
Err(e) => eprintln!("Failed to unoffer: {:?}", e),
Ok(_) => log::info!("Successfully unoffered the service"),
Err(e) => log::error!("Failed to unoffer: {:?}", e),
}

println!("=== Async subscription test with Lola runtime completed ===\n");
log::info!("=== Async subscription test with Lola runtime completed ===\n");
}
}
8 changes: 8 additions & 0 deletions score/mw/com/example/com-api-example/etc/logging.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"ecuId": "com-api",
"appId": "EAPP",
"appDesc": "Example_Application",
"logMode": "kFile",
"logLevel": "kInfo",
"logLevelThresholdConsole": "kInfo"
}
1 change: 1 addition & 0 deletions score/mw/com/impl/rust/com-api/com-api-concept/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ rust_library(
],
deps = [
"@score_baselibs_rust//src/containers",
"@score_baselibs_rust//src/log/score_log",
],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,18 @@ use containers::fixed_capacity::FixedCapacityQueue;
use core::fmt::Debug;
use core::future::Future;
use core::ops::{Deref, DerefMut};
use score_log::ScoreDebug;
use std::path::Path;

/// Error enumeration for different failure cases in the Consumer/Producer/Runtime APIs.
#[derive(Debug)]
///
/// Both `Debug` and `ScoreDebug` are derived because `score_log` macros require `ScoreDebug`,
/// while `Debug` is needed for standard Rust formatting. There is currently no blanket
/// `impl<T: Debug> ScoreDebug for T` in `score_log_fmt`, so both must be explicitly derived
/// for any type used across both contexts.
// TODO: Need to explore if we can somehow avoid deriving both Debug and ScoreDebug for all types.
// Maybe we can add a blanket impl for ScoreDebug for all Debug types in score_log_fmt?
#[derive(Debug, ScoreDebug)]
pub enum Error {
/// TODO: To be replaced, dummy value for "something went wrong"
Fail,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ rust_library(
"//score/mw/com/impl/rust:mw_com",
"//score/mw/com/impl/rust/com-api/com-api-concept",
"//score/mw/com/impl/rust/com-api/com-api-ffi-lola:bridge_ffi_rs",
"@score_baselibs_rust//src/log/score_log",
"@score_communication_crate_index//:futures",
],
)
Expand Down
Loading
Loading