use std::thread;
use std::time::Duration;
use mqtt_protocol_core::mqtt;
mod common;
#[test]
fn test_send_basic_functionality() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(5);
assert_eq!(tas.max(), 5);
tas.insert_or_update("topic1", 1);
tas.insert_or_update("topic3", 3);
assert_eq!(tas.get(1), Some("topic1"));
assert_eq!(tas.get(3), Some("topic3"));
assert_eq!(tas.get(2), None);
assert_eq!(tas.get_lru_alias(), 2);
tas.insert_or_update("topic2", 2);
assert_eq!(tas.get_lru_alias(), 4);
tas.insert_or_update("topic4", 4);
assert_eq!(tas.get_lru_alias(), 5);
tas.insert_or_update("topic5", 5);
assert_eq!(tas.get_lru_alias(), 1);
tas.insert_or_update("topic10", 1);
assert_eq!(tas.get_lru_alias(), 3); assert_eq!(tas.get(1), Some("topic10"));
assert_eq!(tas.get(3), Some("topic3"));
assert_eq!(tas.get_lru_alias(), 2);
assert_eq!(tas.find_by_topic("topic2"), Some(2));
assert_eq!(tas.get_lru_alias(), 2); assert_eq!(tas.find_by_topic("non exist"), None);
tas.clear();
assert_eq!(tas.get_lru_alias(), 1);
assert_eq!(tas.get(1), None);
assert_eq!(tas.get(2), None);
assert_eq!(tas.get(3), None);
assert_eq!(tas.get(4), None);
assert_eq!(tas.get(5), None);
tas.insert_or_update("topic1", 1);
assert_eq!(tas.get(1), Some("topic1"));
}
#[test]
fn test_recv_functionality() {
common::init_tracing();
let mut tar = mqtt::packet::TopicAliasSend::new(5);
tar.insert_or_update("topic1", 1);
tar.insert_or_update("topic3", 3);
assert_eq!(tar.get(1), Some("topic1"));
assert_eq!(tar.get(3), Some("topic3"));
assert_eq!(tar.get(2), None);
tar.insert_or_update("topic10", 1);
assert_eq!(tar.get(1), Some("topic10"));
tar.clear();
assert_eq!(tar.get(1), None); assert_eq!(tar.get(3), None);
tar.insert_or_update("topic1", 1);
assert_eq!(tar.get(1), Some("topic1"));
}
#[test]
fn test_peek() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(3);
tas.insert_or_update("topic1", 1);
tas.insert_or_update("topic2", 2);
assert_eq!(tas.peek(1), Some("topic1"));
assert_eq!(tas.peek(2), Some("topic2"));
assert_eq!(tas.peek(3), None); assert_eq!(tas.peek(0), None); assert_eq!(tas.peek(999), None);
tas.insert_or_update("topic3", 3);
let lru = tas.get_lru_alias();
assert_eq!(lru, 1); }
#[test]
fn test_alias_update_behavior() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(3);
tas.insert_or_update("topic1", 1);
tas.insert_or_update("topic2", 2);
assert_eq!(tas.find_by_topic("topic1"), Some(1));
assert_eq!(tas.find_by_topic("topic2"), Some(2));
tas.insert_or_update("topic1", 2);
let found_alias = tas.find_by_topic("topic1");
assert!(found_alias == Some(1) || found_alias == Some(2)); assert_eq!(tas.find_by_topic("topic2"), None); assert_eq!(tas.get(1), Some("topic1")); assert_eq!(tas.get(2), Some("topic1")); }
#[test]
fn test_topic_update_behavior() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(3);
tas.insert_or_update("topic1", 1);
tas.insert_or_update("topic2", 2);
tas.insert_or_update("topic2", 1);
assert_eq!(tas.get(1), Some("topic2"));
assert_eq!(tas.get(2), Some("topic2")); let found_alias = tas.find_by_topic("topic2");
assert!(found_alias == Some(1) || found_alias == Some(2)); assert_eq!(tas.find_by_topic("topic1"), None); }
#[test]
fn test_lru_ordering_with_timestamps() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(3);
tas.insert_or_update("topic1", 1);
thread::sleep(Duration::from_millis(1));
tas.insert_or_update("topic2", 2);
thread::sleep(Duration::from_millis(1));
tas.insert_or_update("topic3", 3);
assert_eq!(tas.get_lru_alias(), 1);
tas.get(1);
assert_eq!(tas.get_lru_alias(), 2);
}
#[test]
fn test_edge_cases() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(1);
assert_eq!(tas.max(), 1);
assert_eq!(tas.get_lru_alias(), 1);
tas.insert_or_update("topic1", 1);
assert_eq!(tas.get(1), Some("topic1"));
assert_eq!(tas.get_lru_alias(), 1);
tas.insert_or_update("topic2", 1);
assert_eq!(tas.get(1), Some("topic2"));
assert_eq!(tas.find_by_topic("topic1"), None);
assert_eq!(tas.find_by_topic("topic2"), Some(1));
}
#[test]
fn test_boundary_conditions() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(2);
tas.insert_or_update("topic1", 1);
assert_eq!(tas.get(1), Some("topic1"));
tas.insert_or_update("topic2", 2);
assert_eq!(tas.get(2), Some("topic2"));
assert_eq!(tas.get(0), None); assert_eq!(tas.get(3), None); assert_eq!(tas.peek(0), None);
assert_eq!(tas.peek(3), None);
}
#[test]
fn test_empty_container() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(5);
assert_eq!(tas.get(1), None);
assert_eq!(tas.peek(1), None);
assert_eq!(tas.find_by_topic("nonexistent"), None);
assert_eq!(tas.get_lru_alias(), 1);
tas.clear();
assert_eq!(tas.get_lru_alias(), 1);
}
#[test]
fn test_duplicate_operations() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(3);
tas.insert_or_update("topic1", 1);
tas.insert_or_update("topic1", 1);
tas.insert_or_update("topic1", 1);
assert_eq!(tas.get(1), Some("topic1"));
assert_eq!(tas.find_by_topic("topic1"), Some(1));
assert_eq!(tas.get_lru_alias(), 2); }
#[test]
fn test_large_max_alias() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(1000);
assert_eq!(tas.max(), 1000);
assert_eq!(tas.get_lru_alias(), 1);
tas.insert_or_update("topic1", 1);
tas.insert_or_update("topic500", 500);
tas.insert_or_update("topic1000", 1000);
assert_eq!(tas.get(1), Some("topic1"));
assert_eq!(tas.get(500), Some("topic500"));
assert_eq!(tas.get(1000), Some("topic1000"));
assert_eq!(tas.get_lru_alias(), 2); }
#[test]
#[should_panic(expected = "assertion failed")]
fn test_insert_empty_topic_panic() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(10);
tas.insert_or_update("", 1); }
#[test]
#[should_panic(expected = "assertion failed")]
fn test_insert_invalid_alias_zero_panic() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(10);
tas.insert_or_update("test", 0); }
#[test]
#[should_panic(expected = "assertion failed")]
fn test_insert_invalid_alias_too_high_panic() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(10);
tas.insert_or_update("test", 11); }
#[test]
#[should_panic(expected = "assertion failed")]
fn test_get_lru_alias_zero_max_panic() {
common::init_tracing();
let tas = mqtt::packet::TopicAliasSend::new(0);
tas.get_lru_alias(); }
#[test]
fn test_special_characters_in_topics() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(5);
tas.insert_or_update("topic/with/slashes", 1);
tas.insert_or_update("topic with spaces", 2);
tas.insert_or_update("topic_with_underscores", 3);
tas.insert_or_update("topic-with-dashes", 4);
tas.insert_or_update("topic.with.dots", 5);
assert_eq!(tas.get(1), Some("topic/with/slashes"));
assert_eq!(tas.get(2), Some("topic with spaces"));
assert_eq!(tas.get(3), Some("topic_with_underscores"));
assert_eq!(tas.get(4), Some("topic-with-dashes"));
assert_eq!(tas.get(5), Some("topic.with.dots"));
assert_eq!(tas.find_by_topic("topic/with/slashes"), Some(1));
assert_eq!(tas.find_by_topic("topic with spaces"), Some(2));
assert_eq!(tas.find_by_topic("topic_with_underscores"), Some(3));
assert_eq!(tas.find_by_topic("topic-with-dashes"), Some(4));
assert_eq!(tas.find_by_topic("topic.with.dots"), Some(5));
}
#[test]
fn test_long_topic_names() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(3);
let long_topic = "a".repeat(1000);
let very_long_topic = "b".repeat(10000);
tas.insert_or_update(&long_topic, 1);
tas.insert_or_update(&very_long_topic, 2);
assert_eq!(tas.get(1), Some(long_topic.as_str()));
assert_eq!(tas.get(2), Some(very_long_topic.as_str()));
assert_eq!(tas.find_by_topic(&long_topic), Some(1));
assert_eq!(tas.find_by_topic(&very_long_topic), Some(2));
}
#[test]
fn test_unicode_topics() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(5);
tas.insert_or_update("トピック1", 1);
tas.insert_or_update("主题2", 2);
tas.insert_or_update("موضوع3", 3);
tas.insert_or_update("тема4", 4);
tas.insert_or_update("🎉emoji🎊", 5);
assert_eq!(tas.get(1), Some("トピック1"));
assert_eq!(tas.get(2), Some("主题2"));
assert_eq!(tas.get(3), Some("موضوع3"));
assert_eq!(tas.get(4), Some("тема4"));
assert_eq!(tas.get(5), Some("🎉emoji🎊"));
assert_eq!(tas.find_by_topic("トピック1"), Some(1));
assert_eq!(tas.find_by_topic("主题2"), Some(2));
assert_eq!(tas.find_by_topic("موضوع3"), Some(3));
assert_eq!(tas.find_by_topic("тема4"), Some(4));
assert_eq!(tas.find_by_topic("🎉emoji🎊"), Some(5));
}
#[test]
fn test_same_topic_different_alias_update() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(5);
tas.insert_or_update("topic1", 1);
assert_eq!(tas.find_by_topic("topic1"), Some(1));
assert_eq!(tas.get(1), Some("topic1"));
tas.insert_or_update("topic1", 2);
let found_alias = tas.find_by_topic("topic1");
assert!(found_alias == Some(1) || found_alias == Some(2)); assert_eq!(tas.get(1), Some("topic1")); assert_eq!(tas.get(2), Some("topic1"));
assert_eq!(tas.get_lru_alias(), 3); }
#[test]
fn test_same_alias_different_topic_update() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(5);
tas.insert_or_update("topic1", 1);
assert_eq!(tas.find_by_topic("topic1"), Some(1));
assert_eq!(tas.get(1), Some("topic1"));
tas.insert_or_update("topic2", 1);
assert_eq!(tas.find_by_topic("topic2"), Some(1));
assert_eq!(tas.get(1), Some("topic2"));
assert_eq!(tas.find_by_topic("topic1"), None); }
#[test]
fn test_overwrite_verification_comprehensive() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(10);
tas.insert_or_update("topicA", 1);
tas.insert_or_update("topicB", 2);
tas.insert_or_update("topicC", 3);
assert_eq!(tas.find_by_topic("topicA"), Some(1));
assert_eq!(tas.find_by_topic("topicB"), Some(2));
assert_eq!(tas.find_by_topic("topicC"), Some(3));
assert_eq!(tas.get(1), Some("topicA"));
assert_eq!(tas.get(2), Some("topicB"));
assert_eq!(tas.get(3), Some("topicC"));
tas.insert_or_update("topicA", 5);
let found_alias = tas.find_by_topic("topicA");
assert!(found_alias == Some(1) || found_alias == Some(5)); assert_eq!(tas.get(1), Some("topicA")); assert_eq!(tas.get(5), Some("topicA"));
assert_eq!(tas.find_by_topic("topicB"), Some(2));
assert_eq!(tas.find_by_topic("topicC"), Some(3));
tas.insert_or_update("topicD", 2);
assert_eq!(tas.find_by_topic("topicD"), Some(2));
assert_eq!(tas.get(2), Some("topicD"));
assert_eq!(tas.find_by_topic("topicB"), None);
let found_alias_a = tas.find_by_topic("topicA");
assert!(found_alias_a == Some(1) || found_alias_a == Some(5)); assert_eq!(tas.find_by_topic("topicC"), Some(3));
tas.insert_or_update("topicC", 1);
let found_alias_c = tas.find_by_topic("topicC");
assert!(found_alias_c == Some(1) || found_alias_c == Some(3)); assert_eq!(tas.get(1), Some("topicC"));
assert_eq!(tas.get(3), Some("topicC"));
let found_alias_a_final = tas.find_by_topic("topicA");
assert!(found_alias_a_final == Some(5)); assert_eq!(tas.find_by_topic("topicD"), Some(2));
let found_alias_c_final = tas.find_by_topic("topicC");
assert!(found_alias_c_final == Some(1) || found_alias_c_final == Some(3));
assert_eq!(tas.find_by_topic("topicB"), None);
assert_eq!(tas.get(1), Some("topicC"));
assert_eq!(tas.get(2), Some("topicD"));
assert_eq!(tas.get(3), Some("topicC")); assert_eq!(tas.get(5), Some("topicA"));
}
#[test]
fn test_mqtt_v5_spec_multiple_aliases_same_topic() {
common::init_tracing();
let mut tas = mqtt::packet::TopicAliasSend::new(10);
tas.insert_or_update("topic1", 1);
assert_eq!(tas.find_by_topic("topic1"), Some(1));
assert_eq!(tas.get(1), Some("topic1"));
tas.insert_or_update("topic1", 2);
assert_eq!(tas.get(1), Some("topic1"));
assert_eq!(tas.get(2), Some("topic1"));
let found_alias = tas.find_by_topic("topic1");
assert!(found_alias == Some(1) || found_alias == Some(2));
tas.insert_or_update("topic1", 3);
assert_eq!(tas.get(1), Some("topic1"));
assert_eq!(tas.get(2), Some("topic1"));
assert_eq!(tas.get(3), Some("topic1"));
tas.insert_or_update("topic2", 1);
assert_eq!(tas.get(1), Some("topic2"));
assert_eq!(tas.get(2), Some("topic1"));
assert_eq!(tas.get(3), Some("topic1"));
let found_alias = tas.find_by_topic("topic1");
assert!(found_alias == Some(2) || found_alias == Some(3));
assert_eq!(tas.find_by_topic("topic2"), Some(1));
}