Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

Commit

Permalink
Add Cucumber based integration tests
Browse files Browse the repository at this point in the history
Cucumber has been added as a test dependency.
Several integration tests against a running Databroker have been
implemented using textual scenario descriptions following the
Gherkin syntax.

Signed-off-by: Kai Hudalla <[email protected]>
  • Loading branch information
sophokles73 authored and SebastianSchildt committed Apr 27, 2023
1 parent 1c2d994 commit 3fe7ccc
Show file tree
Hide file tree
Showing 13 changed files with 1,497 additions and 114 deletions.
844 changes: 772 additions & 72 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ members = [
]

[workspace.dependencies]
clap = { version = "3.1.10", default-features = false }
clap = { version = "4.2", default-features = false }
databroker-proto = { path = "kuksa_databroker/databroker-proto" }
# prost has no features
prost = "0.11"
Expand Down
3 changes: 2 additions & 1 deletion kuksa_databroker/createbom/bomutil/maplicensefile.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#! /usr/bin/env python
########################################################################
# Copyright (c) 2022 Robert Bosch GmbH
# Copyright (c) 2022, 2023 Robert Bosch GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -21,6 +21,7 @@

MAP = {
"Apache-2.0": "Apache-2.0.txt.gz",
"BlueOak-1.0.0": "BlueOak-1.0.0.md.gz",
"MIT": "MIT.txt.gz",
"Unlicense": "Unlicense.txt.gz",
"BSL-1.0": "BSL-1.0.txt.gz",
Expand Down
4 changes: 2 additions & 2 deletions kuksa_databroker/createbom/bomutil/quirks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#! /usr/bin/env python
########################################################################
# Copyright (c) 2022 Robert Bosch GmbH
# Copyright (c) 2022, 2023 Robert Bosch GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -27,7 +27,7 @@ def apply_quirks(component):
Use narrow matching (name and complete license string) to catch
changes
'''
if component["name"] == "wasi" \
if component["name"] in {"io-lifetimes", "linux-raw-sys", "rustix", "wasi"} \
and component["license"] == "Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT":
# All licenses are "OR", we already ship Apache-2.0 and MIT. The LLVM exception
# does not apply to us, so lets keep it clean.
Expand Down
Binary file not shown.
121 changes: 120 additions & 1 deletion kuksa_databroker/databroker-proto/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand All @@ -25,6 +25,125 @@ pub mod kuksa {
pub mod val {
pub mod v1 {
tonic::include_proto!("kuksa.val.v1");

use datapoint::Value;
use std::{any::Any, fmt::Display, str::FromStr};

#[derive(Debug)]
pub struct ParsingError {
message: String,
}

impl ParsingError {
pub fn new<T: Into<String>>(message: T) -> Self {
ParsingError {
message: message.into(),
}
}
}

impl Display for ParsingError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.message.fmt(f)
}
}

impl std::error::Error for ParsingError {}

impl FromStr for DataType {
type Err = ParsingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"string" => Ok(DataType::String),
"string[]" => Ok(DataType::StringArray),
"bool" => Ok(DataType::Boolean),
"bool[]" => Ok(DataType::BooleanArray),
"int8" => Ok(DataType::Int8),
"int8[]" => Ok(DataType::Int8Array),
"int16" => Ok(DataType::Int16),
"int16[]" => Ok(DataType::Int16Array),
"int32" => Ok(DataType::Int32),
"int32[]" => Ok(DataType::Int32Array),
"int64" => Ok(DataType::Int64),
"int64[]" => Ok(DataType::Int64Array),
"uint8" => Ok(DataType::Uint8),
"uint8[]" => Ok(DataType::Uint8Array),
"uint16" => Ok(DataType::Uint16),
"uint16[]" => Ok(DataType::Uint16Array),
"uint32" => Ok(DataType::Uint32),
"uint32[]" => Ok(DataType::Uint32Array),
"uint64" => Ok(DataType::Uint64),
"uint64[]" => Ok(DataType::Uint64Array),
"float" => Ok(DataType::Float),
"float[]" => Ok(DataType::FloatArray),
"double" => Ok(DataType::Double),
"double[]" => Ok(DataType::DoubleArray),
"timestamp" => Ok(DataType::Timestamp),
"timestamp[]" => Ok(DataType::TimestampArray),
_ => Err(ParsingError::new(format!("unsupported data type '{s}'"))),
}
}
}

impl Value {
pub fn new<T: Into<DataType>>(
vss_type: T,
value: &str,
) -> Result<Self, ParsingError> {
let dt: DataType = vss_type.into();
match dt {
DataType::String => Ok(Value::String(value.to_string())),
DataType::Boolean => value
.parse::<bool>()
.map(Value::Bool)
.map_err(|e| ParsingError::new(e.to_string())),
DataType::Int8 => value
.parse::<i8>()
.map(|v| Value::Int32(v as i32))
.map_err(|e| ParsingError::new(e.to_string())),
DataType::Int16 => value
.parse::<i16>()
.map(|v| Value::Int32(v as i32))
.map_err(|e| ParsingError::new(e.to_string())),
DataType::Int32 => value
.parse::<i32>()
.map(Value::Int32)
.map_err(|e| ParsingError::new(e.to_string())),
DataType::Int64 => value
.parse::<i64>()
.map(Value::Int64)
.map_err(|e| ParsingError::new(e.to_string())),
DataType::Uint8 => value
.parse::<u8>()
.map(|v| Value::Uint32(v as u32))
.map_err(|e| ParsingError::new(e.to_string())),
DataType::Uint16 => value
.parse::<u16>()
.map(|v| Value::Uint32(v as u32))
.map_err(|e| ParsingError::new(e.to_string())),
DataType::Uint32 => value
.parse::<u32>()
.map(Value::Uint32)
.map_err(|e| ParsingError::new(e.to_string())),
DataType::Uint64 => value
.parse::<u64>()
.map(Value::Uint64)
.map_err(|e| ParsingError::new(e.to_string())),
DataType::Float => value
.parse::<f32>()
.map(Value::Float)
.map_err(|e| ParsingError::new(e.to_string())),
DataType::Double => value
.parse::<f64>()
.map(Value::Double)
.map_err(|e| ParsingError::new(e.to_string())),
_ => Err(ParsingError::new(format!(
"data type '{:?}' not supported for parsing string into typed value",
dt.type_id()
))),
}
}
}
}
}
}
15 changes: 14 additions & 1 deletion kuksa_databroker/databroker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ tracing-subscriber = { version = "0.3.11", default-features = false, features =
"env-filter",
"ansi",
] }
clap = { workspace = true, features = ["std", "env"] }
clap = { workspace = true, features = [
"std",
"env",
"derive",
] }
sqlparser = "0.16.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Expand All @@ -58,10 +62,19 @@ lazy_static = "1.4.0"
[features]
# to enable jemalloc use --features jemalloc
jemalloc = ["dep:jemallocator"]
libtest = []

[build-dependencies]
anyhow = "1.0"
vergen = { version = "7", default-features = false, features = [
"cargo",
"git",
] }

[dev-dependencies]
anyhow = "1.0"
cucumber = { version = "0.19", features = ["libtest"] }

[[test]]
name = "current_values"
harness = false
31 changes: 29 additions & 2 deletions kuksa_databroker/databroker/src/grpc/server.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand All @@ -13,7 +13,8 @@

use std::{convert::TryFrom, future::Future, time::Duration};

use tonic::transport::ServerTlsConfig;
use tokio_stream::wrappers::TcpListenerStream;
use tonic::transport::{Server, ServerTlsConfig};
use tracing::{debug, info, warn};

use databroker_proto::{kuksa, sdv};
Expand Down Expand Up @@ -147,3 +148,29 @@ where

Ok(())
}

pub async fn serve_with_incoming_shutdown<F>(
stream: TcpListenerStream,
broker: broker::DataBroker,
signal: F,
) -> Result<(), Box<dyn std::error::Error>>
where
F: Future<Output = ()>,
{
broker.start_housekeeping_task();

Server::builder()
.http2_keepalive_interval(Some(Duration::from_secs(10)))
.http2_keepalive_timeout(Some(Duration::from_secs(20)))
.add_service(sdv::databroker::v1::broker_server::BrokerServer::new(
broker.clone(),
))
.add_service(sdv::databroker::v1::collector_server::CollectorServer::new(
broker.clone(),
))
.add_service(kuksa::val::v1::val_server::ValServer::new(broker.clone()))
.serve_with_incoming_shutdown(stream, shutdown(broker, signal))
.await?;

Ok(())
}
20 changes: 20 additions & 0 deletions kuksa_databroker/databroker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,23 @@ pub mod permissions;
pub mod query;
pub mod types;
pub mod vss;

use std::fmt::Write;

use tracing::info;
use tracing_subscriber::filter::EnvFilter;

pub fn init_logging() {
let mut output = String::from("Init logging from RUST_LOG");
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|err| {
output.write_fmt(format_args!(" ({err})")).unwrap();
// If no environment variable set, this is the default
EnvFilter::new("info")
});
tracing_subscriber::fmt::Subscriber::builder()
.with_env_filter(filter)
.try_init()
.expect("Unable to install global logging subscriber");

info!("{}", output);
}
Loading

0 comments on commit 3fe7ccc

Please sign in to comment.