add tests for the api
This commit is contained in:
@@ -75,6 +75,7 @@ impl TelemetryRegistry {
|
||||
cancellation_token,
|
||||
uuid: response_uuid,
|
||||
client: stored_client,
|
||||
data_type,
|
||||
}
|
||||
}
|
||||
inner(self.client.clone(), name.into(), data_type).await
|
||||
@@ -96,6 +97,7 @@ pub struct GenericTelemetryHandle {
|
||||
cancellation_token: CancellationToken,
|
||||
uuid: Arc<RwLock<Uuid>>,
|
||||
client: Arc<Client>,
|
||||
data_type: DataType,
|
||||
}
|
||||
|
||||
impl GenericTelemetryHandle {
|
||||
@@ -104,6 +106,12 @@ impl GenericTelemetryHandle {
|
||||
value: DataValue,
|
||||
timestamp: DateTime<Utc>,
|
||||
) -> Result<(), MessageError> {
|
||||
if value.to_data_type() != self.data_type {
|
||||
return Err(MessageError::IncorrectDataType {
|
||||
expected: self.data_type,
|
||||
actual: value.to_data_type(),
|
||||
});
|
||||
}
|
||||
let Ok(lock) = self.uuid.try_read() else {
|
||||
return Ok(());
|
||||
};
|
||||
@@ -165,4 +173,292 @@ impl<T: Into<DataValue>> TelemetryHandle<T> {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {}
|
||||
mod tests {
|
||||
use crate::client::error::MessageError;
|
||||
use crate::client::telemetry::TelemetryRegistry;
|
||||
use crate::client::tests::create_test_client;
|
||||
use crate::client::Callback;
|
||||
use crate::messages::payload::RequestMessagePayload;
|
||||
use crate::messages::telemetry_definition::{
|
||||
TelemetryDefinitionRequest, TelemetryDefinitionResponse,
|
||||
};
|
||||
use crate::messages::telemetry_entry::TelemetryEntry;
|
||||
use crate::messages::ResponseMessage;
|
||||
use api_core::data_type::DataType;
|
||||
use api_core::data_value::DataValue;
|
||||
use futures_util::FutureExt;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::task::yield_now;
|
||||
use tokio::time::timeout;
|
||||
use tokio::try_join;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[tokio::test]
|
||||
async fn generic() {
|
||||
// if _c drops then we are disconnected
|
||||
let (mut rx, _c, client) = create_test_client();
|
||||
|
||||
let tlm = TelemetryRegistry::new(Arc::new(client));
|
||||
let tlm_handle = tlm.register_generic("generic", DataType::Float32);
|
||||
|
||||
let tlm_uuid = Uuid::new_v4();
|
||||
|
||||
let expected_rx = async {
|
||||
let msg = rx.recv().await.unwrap();
|
||||
let Callback::Once(responder) = msg.callback else {
|
||||
panic!("Expected Once Callback");
|
||||
};
|
||||
assert!(msg.msg.response.is_none());
|
||||
let RequestMessagePayload::TelemetryDefinitionRequest(TelemetryDefinitionRequest {
|
||||
name,
|
||||
data_type,
|
||||
}) = msg.msg.payload
|
||||
else {
|
||||
panic!("Expected Telemetry Definition Request")
|
||||
};
|
||||
assert_eq!(name, "generic".to_string());
|
||||
assert_eq!(data_type, DataType::Float32);
|
||||
responder
|
||||
.send(ResponseMessage {
|
||||
uuid: Uuid::new_v4(),
|
||||
response: Some(msg.msg.uuid),
|
||||
payload: TelemetryDefinitionResponse { uuid: tlm_uuid }.into(),
|
||||
})
|
||||
.unwrap();
|
||||
};
|
||||
|
||||
let (tlm_handle, _) = try_join!(
|
||||
timeout(Duration::from_secs(1), tlm_handle),
|
||||
timeout(Duration::from_secs(1), expected_rx),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(*tlm_handle.uuid.try_read().unwrap(), tlm_uuid);
|
||||
|
||||
// This should NOT block if there is space in the queue
|
||||
tlm_handle
|
||||
.publish_now(0.0f32.into())
|
||||
.now_or_never()
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
let tlm_msg = timeout(Duration::from_secs(1), rx.recv())
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert!(matches!(tlm_msg.callback, Callback::None));
|
||||
match tlm_msg.msg.payload {
|
||||
RequestMessagePayload::TelemetryEntry(TelemetryEntry { uuid, value, .. }) => {
|
||||
assert_eq!(uuid, tlm_uuid);
|
||||
assert_eq!(value, DataValue::Float32(0.0f32));
|
||||
}
|
||||
_ => panic!("Expected Telemetry Entry"),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn mismatched_type() {
|
||||
let (mut rx, _, client) = create_test_client();
|
||||
|
||||
let tlm = TelemetryRegistry::new(Arc::new(client));
|
||||
let tlm_handle = tlm.register_generic("generic", DataType::Float32);
|
||||
|
||||
let tlm_uuid = Uuid::new_v4();
|
||||
|
||||
let expected_rx = async {
|
||||
let msg = rx.recv().await.unwrap();
|
||||
let Callback::Once(responder) = msg.callback else {
|
||||
panic!("Expected Once Callback");
|
||||
};
|
||||
assert!(msg.msg.response.is_none());
|
||||
let RequestMessagePayload::TelemetryDefinitionRequest(TelemetryDefinitionRequest {
|
||||
name,
|
||||
data_type,
|
||||
}) = msg.msg.payload
|
||||
else {
|
||||
panic!("Expected Telemetry Definition Request")
|
||||
};
|
||||
assert_eq!(name, "generic".to_string());
|
||||
assert_eq!(data_type, DataType::Float32);
|
||||
responder
|
||||
.send(ResponseMessage {
|
||||
uuid: Uuid::new_v4(),
|
||||
response: Some(msg.msg.uuid),
|
||||
payload: TelemetryDefinitionResponse { uuid: tlm_uuid }.into(),
|
||||
})
|
||||
.unwrap();
|
||||
};
|
||||
|
||||
let (tlm_handle, _) = try_join!(
|
||||
timeout(Duration::from_secs(1), tlm_handle),
|
||||
timeout(Duration::from_secs(1), expected_rx),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(*tlm_handle.uuid.try_read().unwrap(), tlm_uuid);
|
||||
|
||||
match timeout(
|
||||
Duration::from_secs(1),
|
||||
tlm_handle.publish_now(0.0f64.into()),
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
{
|
||||
Err(MessageError::IncorrectDataType { expected, actual }) => {
|
||||
assert_eq!(expected, DataType::Float32);
|
||||
assert_eq!(actual, DataType::Float64);
|
||||
}
|
||||
_ => panic!("Error Expected"),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn typed() {
|
||||
// if _c drops then we are disconnected
|
||||
let (mut rx, _c, client) = create_test_client();
|
||||
|
||||
let tlm = TelemetryRegistry::new(Arc::new(client));
|
||||
let tlm_handle = tlm.register::<f32>("typed");
|
||||
|
||||
let tlm_uuid = Uuid::new_v4();
|
||||
|
||||
let expected_rx = async {
|
||||
let msg = rx.recv().await.unwrap();
|
||||
let Callback::Once(responder) = msg.callback else {
|
||||
panic!("Expected Once Callback");
|
||||
};
|
||||
assert!(msg.msg.response.is_none());
|
||||
let RequestMessagePayload::TelemetryDefinitionRequest(TelemetryDefinitionRequest {
|
||||
name,
|
||||
data_type,
|
||||
}) = msg.msg.payload
|
||||
else {
|
||||
panic!("Expected Telemetry Definition Request")
|
||||
};
|
||||
assert_eq!(name, "typed".to_string());
|
||||
assert_eq!(data_type, DataType::Float32);
|
||||
responder
|
||||
.send(ResponseMessage {
|
||||
uuid: Uuid::new_v4(),
|
||||
response: Some(msg.msg.uuid),
|
||||
payload: TelemetryDefinitionResponse { uuid: tlm_uuid }.into(),
|
||||
})
|
||||
.unwrap();
|
||||
};
|
||||
|
||||
let (tlm_handle, _) = try_join!(
|
||||
timeout(Duration::from_secs(1), tlm_handle),
|
||||
timeout(Duration::from_secs(1), expected_rx),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(*tlm_handle.as_generic().uuid.try_read().unwrap(), tlm_uuid);
|
||||
|
||||
// This should NOT block if there is space in the queue
|
||||
tlm_handle
|
||||
.publish_now(1.0f32.into())
|
||||
.now_or_never()
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
// This should block as there should not be space in the queue
|
||||
assert!(tlm_handle
|
||||
.publish_now(2.0f32.into())
|
||||
.now_or_never()
|
||||
.is_none());
|
||||
|
||||
let tlm_msg = timeout(Duration::from_secs(1), rx.recv())
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert!(matches!(tlm_msg.callback, Callback::None));
|
||||
match tlm_msg.msg.payload {
|
||||
RequestMessagePayload::TelemetryEntry(TelemetryEntry { uuid, value, .. }) => {
|
||||
assert_eq!(uuid, tlm_uuid);
|
||||
assert_eq!(value, DataValue::Float32(1.0f32));
|
||||
}
|
||||
_ => panic!("Expected Telemetry Entry"),
|
||||
}
|
||||
|
||||
let _make_generic_again = tlm_handle.to_generic();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn reconnect() {
|
||||
// if _c drops then we are disconnected
|
||||
let (mut rx, connected, client) = create_test_client();
|
||||
|
||||
let tlm = TelemetryRegistry::new(Arc::new(client));
|
||||
let tlm_handle = tlm.register_generic("generic", DataType::Float32);
|
||||
|
||||
let tlm_uuid = Uuid::new_v4();
|
||||
|
||||
let expected_rx = async {
|
||||
let msg = rx.recv().await.unwrap();
|
||||
let Callback::Once(responder) = msg.callback else {
|
||||
panic!("Expected Once Callback");
|
||||
};
|
||||
assert!(msg.msg.response.is_none());
|
||||
let RequestMessagePayload::TelemetryDefinitionRequest(TelemetryDefinitionRequest {
|
||||
name,
|
||||
data_type,
|
||||
}) = msg.msg.payload
|
||||
else {
|
||||
panic!("Expected Telemetry Definition Request")
|
||||
};
|
||||
assert_eq!(name, "generic".to_string());
|
||||
assert_eq!(data_type, DataType::Float32);
|
||||
responder
|
||||
.send(ResponseMessage {
|
||||
uuid: Uuid::new_v4(),
|
||||
response: Some(msg.msg.uuid),
|
||||
payload: TelemetryDefinitionResponse { uuid: tlm_uuid }.into(),
|
||||
})
|
||||
.unwrap();
|
||||
};
|
||||
|
||||
let (tlm_handle, _) = try_join!(
|
||||
timeout(Duration::from_secs(1), tlm_handle),
|
||||
timeout(Duration::from_secs(1), expected_rx),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(*tlm_handle.uuid.try_read().unwrap(), tlm_uuid);
|
||||
|
||||
// Notify Disconnect
|
||||
connected.send_replace(false);
|
||||
// Notify Reconnect
|
||||
connected.send_replace(true);
|
||||
|
||||
{
|
||||
let new_tlm_uuid = Uuid::new_v4();
|
||||
|
||||
let msg = rx.recv().await.unwrap();
|
||||
let Callback::Once(responder) = msg.callback else {
|
||||
panic!("Expected Once Callback");
|
||||
};
|
||||
assert!(msg.msg.response.is_none());
|
||||
let RequestMessagePayload::TelemetryDefinitionRequest(TelemetryDefinitionRequest {
|
||||
name,
|
||||
data_type,
|
||||
}) = msg.msg.payload
|
||||
else {
|
||||
panic!("Expected Telemetry Definition Request")
|
||||
};
|
||||
assert_eq!(name, "generic".to_string());
|
||||
assert_eq!(data_type, DataType::Float32);
|
||||
responder
|
||||
.send(ResponseMessage {
|
||||
uuid: Uuid::new_v4(),
|
||||
response: Some(msg.msg.uuid),
|
||||
payload: TelemetryDefinitionResponse { uuid: new_tlm_uuid }.into(),
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
// Yield to the executor so that the UUIDs can be updated
|
||||
yield_now().await;
|
||||
|
||||
assert_eq!(*tlm_handle.uuid.try_read().unwrap(), new_tlm_uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user