|
1 | 1 | //! Test data consumption using low level consumers.
|
2 | 2 |
|
3 | 3 | use std::collections::HashMap;
|
| 4 | +use std::convert::TryInto; |
4 | 5 | use std::sync::atomic::{AtomicUsize, Ordering};
|
5 | 6 | use std::sync::Arc;
|
6 | 7 | use std::thread;
|
@@ -90,6 +91,67 @@ async fn test_produce_consume_seek() {
|
90 | 91 | }
|
91 | 92 | }
|
92 | 93 |
|
| 94 | +// Seeking should allow replaying messages and skipping messages. |
| 95 | +#[tokio::test] |
| 96 | +async fn test_produce_consume_seek_partitions() { |
| 97 | + let _r = env_logger::try_init(); |
| 98 | + |
| 99 | + let topic_name = rand_test_topic(); |
| 100 | + populate_topic(&topic_name, 30, &value_fn, &key_fn, None, None).await; |
| 101 | + |
| 102 | + let consumer = create_base_consumer(&rand_test_group(), None); |
| 103 | + consumer.subscribe(&[topic_name.as_str()]).unwrap(); |
| 104 | + |
| 105 | + let mut partition_offset_map = HashMap::new(); |
| 106 | + for message in consumer.iter().take(30) { |
| 107 | + match message { |
| 108 | + Ok(m) => { |
| 109 | + let offset = partition_offset_map.entry(m.partition()).or_insert(0); |
| 110 | + assert_eq!(m.offset(), *offset); |
| 111 | + *offset += 1; |
| 112 | + } |
| 113 | + Err(e) => panic!("Error receiving message: {:?}", e), |
| 114 | + } |
| 115 | + } |
| 116 | + |
| 117 | + let mut tpl = TopicPartitionList::new(); |
| 118 | + tpl.add_partition_offset(&topic_name, 0, Offset::Beginning) |
| 119 | + .unwrap(); |
| 120 | + tpl.add_partition_offset(&topic_name, 1, Offset::End) |
| 121 | + .unwrap(); |
| 122 | + tpl.add_partition_offset(&topic_name, 2, Offset::Offset(2)) |
| 123 | + .unwrap(); |
| 124 | + |
| 125 | + let r_tpl = consumer.seek_partitions(tpl, None).unwrap(); |
| 126 | + assert_eq!(r_tpl.elements().len(), 3); |
| 127 | + for tpe in r_tpl.elements().iter() { |
| 128 | + assert!(tpe.error().is_ok()); |
| 129 | + } |
| 130 | + |
| 131 | + let msg_cnt_p0 = partition_offset_map.get(&0).unwrap(); |
| 132 | + let msg_cnt_p2 = partition_offset_map.get(&2).unwrap(); |
| 133 | + let total_msgs_to_read = msg_cnt_p0 + (msg_cnt_p2 - 2); |
| 134 | + let mut poffset_map = HashMap::new(); |
| 135 | + for message in consumer.iter().take(total_msgs_to_read.try_into().unwrap()) { |
| 136 | + match message { |
| 137 | + Ok(m) => { |
| 138 | + let offset = poffset_map.entry(m.partition()).or_insert(0); |
| 139 | + if m.partition() == 0 { |
| 140 | + assert_eq!(m.offset(), *offset); |
| 141 | + } else if m.partition() == 2 { |
| 142 | + assert_eq!(m.offset(), *offset + 2); |
| 143 | + } else if m.partition() == 1 { |
| 144 | + panic!("Unexpected message from partition 1") |
| 145 | + } |
| 146 | + *offset += 1; |
| 147 | + } |
| 148 | + Err(e) => panic!("Error receiving message: {:?}", e), |
| 149 | + } |
| 150 | + } |
| 151 | + assert_eq!(msg_cnt_p0, poffset_map.get(&0).unwrap()); |
| 152 | + assert_eq!(msg_cnt_p2 - 2, *poffset_map.get(&2).unwrap()); |
| 153 | +} |
| 154 | + |
93 | 155 | // All produced messages should be consumed.
|
94 | 156 | #[tokio::test]
|
95 | 157 | async fn test_produce_consume_iter() {
|
|
0 commit comments