use super::cov_wire_test_support::*;
use super::*;
use bacnet_objects::trend::TrendLogMultipleObject;
use bacnet_types::constructed::BACnetDeviceObjectPropertyReference;
use bacnet_types::enums::ObjectType;
use bacnet_types::error::RemoteError;
const LDOP: PropertyIdentifier = PropertyIdentifier::LOG_DEVICE_OBJECT_PROPERTY;
const AV1_PV: [u8; 7] = [0x0C, 0x00, 0x80, 0x00, 0x01, 0x19, 0x55];
const EMPTY: [u8; 7] = [0x0C, 0x00, 0x3F, 0xFF, 0xFF, 0x19, 0x55];
fn tlm1() -> ObjectIdentifier {
ObjectIdentifier::new(ObjectType::TREND_LOG_MULTIPLE, 1).unwrap()
}
async fn write_local(h: &Harness, index: Option<u32>, value: PropertyValue) -> Result<(), Error> {
h.server
.write_local(
&tlm1(),
LDOP,
index,
value,
None,
crate::LocalCommandSource::ServerDevice,
)
.await
}
async fn read(h: &Harness, property: PropertyIdentifier, index: Option<u32>) -> PropertyValue {
h.server
.database()
.read()
.await
.get(&tlm1())
.unwrap()
.read_property(property, index)
.unwrap()
}
async fn total(h: &Harness) -> PropertyValue {
read(h, PropertyIdentifier::TOTAL_RECORD_COUNT, None).await
}
fn assert_refused(result: Result<(), Error>, class: ErrorClass, code: ErrorCode) {
assert!(
matches!(result, Err(Error::Remote(RemoteError::Error { class: c, code: e }))
if c == class && e == code),
"expected {class:?} / {code:?}, got {result:?}"
);
}
#[tokio::test(start_paused = true)]
async fn write_local_of_index_0_resizes_the_reference_array() {
let h = Harness::start_with(ServerConfig::default(), |db| {
let mut tlm = TrendLogMultipleObject::new(1, "TLM-1", 8).unwrap();
tlm.add_property_reference(BACnetDeviceObjectPropertyReference::new_local(
av1(),
PropertyIdentifier::PRESENT_VALUE.to_raw(),
))
.unwrap();
db.add(Box::new(tlm)).unwrap();
})
.await;
assert_eq!(total(&h).await, PropertyValue::Unsigned(0));
write_local(&h, Some(0), PropertyValue::Unsigned(3))
.await
.unwrap();
assert_eq!(read(&h, LDOP, Some(0)).await, PropertyValue::Unsigned(3));
assert_eq!(
read(&h, LDOP, None).await,
PropertyValue::List(vec![
PropertyValue::ApplicationData(AV1_PV.to_vec()),
PropertyValue::ApplicationData(EMPTY.to_vec()),
PropertyValue::ApplicationData(EMPTY.to_vec()),
])
);
assert_eq!(total(&h).await, PropertyValue::Unsigned(1));
write_local(&h, Some(0), PropertyValue::Unsigned(3))
.await
.unwrap();
assert_eq!(total(&h).await, PropertyValue::Unsigned(1));
write_local(&h, Some(0), PropertyValue::Unsigned(1))
.await
.unwrap();
assert_eq!(
read(&h, LDOP, None).await,
PropertyValue::List(vec![PropertyValue::ApplicationData(AV1_PV.to_vec())])
);
assert_eq!(total(&h).await, PropertyValue::Unsigned(2));
assert_refused(
write_local(&h, Some(0), PropertyValue::Unsigned(65)).await,
ErrorClass::RESOURCES,
ErrorCode::NO_SPACE_TO_WRITE_PROPERTY,
);
assert_refused(
write_local(&h, Some(0), PropertyValue::Real(2.0)).await,
ErrorClass::PROPERTY,
ErrorCode::INVALID_DATA_TYPE,
);
assert_eq!(read(&h, LDOP, Some(0)).await, PropertyValue::Unsigned(1));
assert_eq!(total(&h).await, PropertyValue::Unsigned(2));
}