use mavinspect::parser::Inspector;
use mavinspect::protocol::{Filter, Fingerprint, Microservices};
fn default_dialect_paths() -> Vec<&'static str> {
vec![
"./message_definitions/standard",
"./message_definitions/extra",
]
}
fn extra_dialect_paths() -> Vec<&'static str> {
vec!["./message_definitions/extra"]
}
#[test]
fn filter_by_empty_filters() {
let inspector = Inspector::builder()
.set_sources(&default_dialect_paths())
.set_include(&["common"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
let filtered_protocol = protocol.filtered(&Filter::default());
let common = filtered_protocol
.get_dialect_by_canonical_name("common")
.unwrap();
assert!(common
.microservices()
.contains(Microservices::HEARTBEAT | Microservices::COMMAND));
assert!(common.contains_enum_with_name("MAV_CMD"));
assert!(common.contains_command_with_name("MAV_CMD_NAV_LAND"));
assert!(common
.get_enum_by_name("MAV_CMD")
.unwrap()
.has_entry_with_name("MAV_CMD_NAV_LAND"));
assert!(common.contains_enum_with_name("PRECISION_LAND_MODE"));
assert!(common.contains_message_with_name("COMMAND_INT"));
assert!(common.contains_message_with_name("COMMAND_LONG"));
assert!(common.contains_message_with_name("COMMAND_ACK"));
assert!(common.contains_message_with_name("COMMAND_CANCEL"));
let minimal = filtered_protocol
.get_dialect_by_canonical_name("common")
.unwrap();
assert!(minimal.microservices().contains(Microservices::HEARTBEAT));
assert!(common.contains_message_with_name("HEARTBEAT"));
}
#[test]
fn filter_by_microservices_and_messages() {
let inspector = Inspector::builder()
.set_sources(&default_dialect_paths())
.set_include(&["common", "MAVInspect_test", "minimal", "standard"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
use mavinspect::protocol::{Filter, Microservices};
let filtered_protocol = protocol.filtered(
&Filter::by_microservices(Microservices::HEARTBEAT | Microservices::COMMAND).with_messages(
&[
"PROTOCOL_VERSION",
"CLONE",
"DEFAULT",
],
),
);
let common = filtered_protocol
.get_dialect_by_canonical_name("common")
.unwrap();
assert!(common.contains_message_with_name("HEARTBEAT"));
assert!(common.contains_message_with_name("PROTOCOL_VERSION"));
let mav_inspect_test = filtered_protocol
.get_dialect_by_canonical_name("mav_inspect_test")
.unwrap();
assert!(mav_inspect_test.contains_message_with_name("CLONE"));
assert!(mav_inspect_test.contains_message_with_name("DEFAULT"));
assert!(mav_inspect_test.contains_enum_with_name("CLONE"));
assert!(mav_inspect_test.contains_enum_with_name("DEFAULT"));
assert!(!mav_inspect_test.contains_enum_with_name("COPY"));
assert!(!mav_inspect_test.contains_enum_with_name("FROM"));
}
#[test]
fn filter_by_all_options() {
let inspector = Inspector::builder()
.set_sources(&default_dialect_paths())
.set_include(&["common"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
use mavinspect::protocol::{Filter, Microservices};
let filtered_protocol = protocol.filtered(
&Filter::by_microservices(Microservices::HEARTBEAT | Microservices::MISSION)
.with_messages(&["FILE_TRANSFER_PROTOCOL"])
.with_enums(&["GIMBAL_DEVICE_CAP_FLAGS"])
.with_commands(&["MAV_CMD_SET_*"]),
);
let common = filtered_protocol
.get_dialect_by_canonical_name("common")
.unwrap();
assert!(common.contains_message_with_name("HEARTBEAT"));
assert!(common.contains_message_with_name("FILE_TRANSFER_PROTOCOL"));
assert!(!common.contains_message_with_name("COMMAND_INT"));
assert!(!common.contains_message_with_name("PROTOCOL_VERSION"));
assert!(!common.contains_message_with_name("CAMERA_TRIGGER"));
assert!(common.contains_enum_with_name("GIMBAL_DEVICE_CAP_FLAGS"));
assert!(common.contains_enum_with_name("MAV_CMD"));
assert!(common.contains_command_with_name("MAV_CMD_SET_MESSAGE_INTERVAL"));
assert!(common.contains_command_with_name("MAV_CMD_DO_SET_MISSION_CURRENT"));
assert!(common.contains_command_with_name("MAV_CMD_NAV_WAYPOINT"));
assert!(!common.contains_command_with_name("MAV_CMD_INJECT_FAILURE"));
assert!(!common.contains_command_with_name("MAV_CMD_GET_HOME_POSITION"));
}
#[test]
fn filter_by_microservices_common_heartbeat() {
let inspector = Inspector::builder()
.set_sources(&default_dialect_paths())
.set_include(&["common"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
let filtered_protocol = protocol.filtered(&Filter::by_microservices(Microservices::HEARTBEAT));
let dialect = filtered_protocol
.get_dialect_by_canonical_name("common")
.unwrap();
let microservices = dialect.microservices();
assert!(microservices.contains(Microservices::HEARTBEAT));
assert!(!microservices.contains(Microservices::COMMAND));
assert!(!microservices.contains(Microservices::FTP));
}
#[test]
fn filter_by_microservices_commands() {
let inspector = Inspector::builder()
.set_sources(&default_dialect_paths())
.set_include(&["common"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
let filtered_protocol = protocol.filtered(&Filter::by_microservices(Microservices::COMMAND));
let dialect = filtered_protocol
.get_dialect_by_canonical_name("common")
.unwrap();
let microservices = dialect.microservices();
assert!(microservices.contains(Microservices::COMMAND));
assert!(dialect.contains_enum_with_name("MAV_CMD"));
assert!(dialect.contains_command_with_name("MAV_CMD_NAV_LAND"));
assert!(dialect
.get_enum_by_name("MAV_CMD")
.unwrap()
.has_entry_with_name("MAV_CMD_NAV_LAND"));
assert!(dialect.contains_enum_with_name("PRECISION_LAND_MODE"));
assert!(!microservices.contains(Microservices::PING));
assert!(!microservices.contains(Microservices::HEARTBEAT));
assert!(!microservices.contains(Microservices::MISSION));
assert!(!microservices.contains(Microservices::FTP));
}
#[test]
fn filter_by_microservices_mission() {
let inspector = Inspector::builder()
.set_sources(&default_dialect_paths())
.set_include(&["common"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
let filtered_protocol = protocol.filtered(&Filter::by_microservices(Microservices::MISSION));
let dialect = filtered_protocol
.get_dialect_by_canonical_name("common")
.unwrap();
let microservices = dialect.microservices();
assert!(microservices.contains(Microservices::MISSION));
assert!(!microservices.contains(Microservices::COMMAND));
assert!(dialect.contains_enum_with_name("MAV_CMD"));
assert!(dialect.contains_command_with_name("MAV_CMD_NAV_LAND"));
assert!(!dialect.contains_command_with_name("MAV_CMD_REQUEST_MESSAGE"));
assert!(!microservices.contains(Microservices::FTP));
}
#[test]
fn filter_by_microservices_arm_auth() {
let inspector = Inspector::builder()
.set_sources(&default_dialect_paths())
.set_include(&["common"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
let filtered_protocol = protocol.filtered(&Filter::by_microservices(Microservices::ARM_AUTH));
let dialect = filtered_protocol
.get_dialect_by_canonical_name("common")
.unwrap();
let microservices = dialect.microservices();
assert!(microservices.contains(Microservices::ARM_AUTH));
assert!(microservices.contains(Microservices::COMMAND));
assert!(dialect.contains_enum_with_name("MAV_CMD"));
assert!(dialect.contains_command_with_name("MAV_CMD_ARM_AUTHORIZATION_REQUEST"));
assert!(!dialect.contains_command_with_name("MAV_CMD_REQUEST_MESSAGE"));
assert!(!microservices.contains(Microservices::FTP));
let dialect = filtered_protocol
.get_dialect_by_canonical_name("minimal")
.unwrap();
let microservices = dialect.microservices();
assert!(!microservices.contains(Microservices::ARM_AUTH));
}
#[test]
fn filter_by_microservices_explicit_enums() {
let inspector = Inspector::builder()
.set_sources(&default_dialect_paths())
.set_include(&["common"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
let filtered_protocol =
protocol.filtered(&Filter::by_microservices(Microservices::COMPONENT_METADATA));
let dialect = filtered_protocol
.get_dialect_by_canonical_name("common")
.unwrap();
let microservices = dialect.microservices();
assert!(microservices.contains(Microservices::COMPONENT_METADATA));
assert!(microservices.contains(Microservices::COMMAND));
assert!(dialect.contains_enum_with_name("MAV_CMD"));
assert!(dialect.contains_enum_with_name("COMP_METADATA_TYPE"));
assert!(dialect.contains_command_with_name("MAV_CMD_REQUEST_MESSAGE"));
assert!(!dialect.contains_command_with_name("MAV_CMD_NAV_LAND"));
assert!(!microservices.contains(Microservices::FTP));
}
#[test]
fn filter_by_microservices_diverse() {
let inspector = Inspector::builder()
.set_sources(&default_dialect_paths())
.set_include(&["common"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
let filtered_protocol = protocol.filtered(&Filter::by_microservices(
Microservices::COMMAND | Microservices::PING | Microservices::HEARTBEAT,
));
let dialect = filtered_protocol
.get_dialect_by_canonical_name("common")
.unwrap();
let microservices = dialect.microservices();
assert!(microservices.contains(Microservices::HEARTBEAT));
assert!(microservices.contains(Microservices::COMMAND));
assert!(microservices.contains(Microservices::PING));
assert!(!microservices.contains(Microservices::MISSION));
assert!(!microservices.contains(Microservices::FTP));
}
#[test]
fn filter_check_fingerprints() {
let inspector = Inspector::builder()
.set_sources(&default_dialect_paths())
.set_include(&["common"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
let dialect = protocol.get_dialect_by_canonical_name("common").unwrap();
let filtered_protocol = protocol.filtered(&Filter::by_microservices(Microservices::GIMBAL_V1));
let filtered_dialect = filtered_protocol
.get_dialect_by_canonical_name("common")
.unwrap();
assert!(dialect.contains_enum_with_name("MAV_CMD"));
assert!(filtered_dialect.contains_enum_with_name("MAV_CMD"));
let mav_cmd = dialect.get_enum_by_name("MAV_CMD").unwrap();
let filtered_mav_cmd = filtered_dialect.get_enum_by_name("MAV_CMD").unwrap();
assert_ne!(mav_cmd.entries().len(), filtered_mav_cmd.entries().len());
assert_ne!(mav_cmd.fingerprint(), filtered_mav_cmd.fingerprint());
let message = dialect.get_message_by_name("COMMAND_INT").unwrap();
let filtered_message = filtered_dialect.get_message_by_name("COMMAND_INT").unwrap();
assert_ne!(
message.fingerprint_strict(Some(&dialect)),
filtered_message.fingerprint_strict(Some(&filtered_dialect))
);
}
#[test]
fn fingerprints_are_stable() {
let inspector = Inspector::builder()
.set_sources(&extra_dialect_paths())
.set_include(&["mav_inspect_test"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
let mav_inspect_test = protocol
.get_dialect_by_canonical_name("mav_inspect_test")
.unwrap();
let minimal = protocol.get_dialect_by_canonical_name("minimal").unwrap();
assert_eq!(
mav_inspect_test.fingerprint(),
Fingerprint::from(7598630947800471218)
);
assert_eq!(
minimal.fingerprint(),
Fingerprint::from(4941508700730382907)
);
assert_eq!(
protocol.fingerprint(),
Fingerprint::from(16932730339613938253)
);
}
#[test]
fn enum_entry_prefix_stripping() {
let inspector = Inspector::builder()
.set_sources(&extra_dialect_paths())
.set_include(&["crazy_flight"])
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
let dialect = protocol
.get_dialect_by_canonical_name("crazy_flight")
.unwrap();
let mav_enum = dialect
.get_enum_by_name("CRAZYFLIGHT_INSANITY_LEVEL")
.unwrap();
for entry in mav_enum.entries() {
assert_eq!(
format!("{}_{}", mav_enum.name(), entry.name_stripped()),
entry.name()
);
}
}
#[test]
fn test_dialects_filtering_by_name() {
let inspector = Inspector::builder()
.set_sources(&default_dialect_paths())
.build()
.unwrap();
let protocol = inspector.parse().unwrap();
let protocol = protocol.with_dialects_included(&["common"], true, None);
assert!(protocol.contains_dialect_with_canonical_name("common"));
assert!(protocol.contains_dialect_with_canonical_name("standard"));
assert!(protocol.contains_dialect_with_canonical_name("minimal"));
assert!(!protocol.contains_dialect_with_canonical_name("development"));
assert!(!protocol.contains_dialect_with_canonical_name("all"));
assert!(!protocol.contains_dialect_with_canonical_name("crazy_flight"));
assert!(!protocol.contains_dialect_with_canonical_name("mav_inspect_test"));
let protocol = protocol.with_dialects_included(&["common"], false, None);
assert!(protocol.contains_dialect_with_canonical_name("common"));
assert!(!protocol.contains_dialect_with_canonical_name("standard"));
assert!(!protocol.contains_dialect_with_canonical_name("minimal"));
}