tests.rs

  1use super::*;
  2use clock::ReplicaId;
  3use rand::prelude::*;
  4use std::{
  5    cmp::Ordering,
  6    env,
  7    iter::Iterator,
  8    time::{Duration, Instant},
  9};
 10
 11#[test]
 12fn test_edit() {
 13    let mut buffer = Buffer::new(0, 0, History::new("abc".into()));
 14    assert_eq!(buffer.text(), "abc");
 15    buffer.edit(vec![3..3], "def");
 16    assert_eq!(buffer.text(), "abcdef");
 17    buffer.edit(vec![0..0], "ghi");
 18    assert_eq!(buffer.text(), "ghiabcdef");
 19    buffer.edit(vec![5..5], "jkl");
 20    assert_eq!(buffer.text(), "ghiabjklcdef");
 21    buffer.edit(vec![6..7], "");
 22    assert_eq!(buffer.text(), "ghiabjlcdef");
 23    buffer.edit(vec![4..9], "mno");
 24    assert_eq!(buffer.text(), "ghiamnoef");
 25}
 26
 27#[gpui::test(iterations = 100)]
 28fn test_random_edits(mut rng: StdRng) {
 29    let operations = env::var("OPERATIONS")
 30        .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
 31        .unwrap_or(10);
 32
 33    let reference_string_len = rng.gen_range(0..3);
 34    let mut reference_string = RandomCharIter::new(&mut rng)
 35        .take(reference_string_len)
 36        .collect::<String>();
 37    let mut buffer = Buffer::new(0, 0, History::new(reference_string.clone().into()));
 38    buffer.history.group_interval = Duration::from_millis(rng.gen_range(0..=200));
 39    let mut buffer_versions = Vec::new();
 40    log::info!(
 41        "buffer text {:?}, version: {:?}",
 42        buffer.text(),
 43        buffer.version()
 44    );
 45
 46    for _i in 0..operations {
 47        let (old_ranges, new_text, _) = buffer.randomly_edit(&mut rng, 5);
 48        for old_range in old_ranges.iter().rev() {
 49            reference_string.replace_range(old_range.clone(), &new_text);
 50        }
 51        assert_eq!(buffer.text(), reference_string);
 52        log::info!(
 53            "buffer text {:?}, version: {:?}",
 54            buffer.text(),
 55            buffer.version()
 56        );
 57
 58        if rng.gen_bool(0.25) {
 59            buffer.randomly_undo_redo(&mut rng);
 60            reference_string = buffer.text();
 61            log::info!(
 62                "buffer text {:?}, version: {:?}",
 63                buffer.text(),
 64                buffer.version()
 65            );
 66        }
 67
 68        let range = buffer.random_byte_range(0, &mut rng);
 69        assert_eq!(
 70            buffer.text_summary_for_range(range.clone()),
 71            TextSummary::from(&reference_string[range])
 72        );
 73
 74        if rng.gen_bool(0.3) {
 75            buffer_versions.push(buffer.clone());
 76        }
 77    }
 78
 79    for mut old_buffer in buffer_versions {
 80        let edits = buffer
 81            .edits_since(old_buffer.version.clone())
 82            .collect::<Vec<_>>();
 83
 84        log::info!(
 85            "mutating old buffer version {:?}, text: {:?}, edits since: {:?}",
 86            old_buffer.version(),
 87            old_buffer.text(),
 88            edits,
 89        );
 90
 91        let mut delta = 0_isize;
 92        for edit in edits {
 93            let old_start = (edit.old_bytes.start as isize + delta) as usize;
 94            let new_text: String = buffer.text_for_range(edit.new_bytes.clone()).collect();
 95            old_buffer.edit(Some(old_start..old_start + edit.deleted_bytes()), new_text);
 96            delta += edit.delta();
 97        }
 98        assert_eq!(old_buffer.text(), buffer.text());
 99    }
100}
101
102#[test]
103fn test_line_len() {
104    let mut buffer = Buffer::new(0, 0, History::new("".into()));
105    buffer.edit(vec![0..0], "abcd\nefg\nhij");
106    buffer.edit(vec![12..12], "kl\nmno");
107    buffer.edit(vec![18..18], "\npqrs\n");
108    buffer.edit(vec![18..21], "\nPQ");
109
110    assert_eq!(buffer.line_len(0), 4);
111    assert_eq!(buffer.line_len(1), 3);
112    assert_eq!(buffer.line_len(2), 5);
113    assert_eq!(buffer.line_len(3), 3);
114    assert_eq!(buffer.line_len(4), 4);
115    assert_eq!(buffer.line_len(5), 0);
116}
117
118#[test]
119fn test_text_summary_for_range() {
120    let buffer = Buffer::new(0, 0, History::new("ab\nefg\nhklm\nnopqrs\ntuvwxyz".into()));
121    assert_eq!(
122        buffer.text_summary_for_range(1..3),
123        TextSummary {
124            bytes: 2,
125            lines: Point::new(1, 0),
126            first_line_chars: 1,
127            last_line_chars: 0,
128            longest_row: 0,
129            longest_row_chars: 1,
130        }
131    );
132    assert_eq!(
133        buffer.text_summary_for_range(1..12),
134        TextSummary {
135            bytes: 11,
136            lines: Point::new(3, 0),
137            first_line_chars: 1,
138            last_line_chars: 0,
139            longest_row: 2,
140            longest_row_chars: 4,
141        }
142    );
143    assert_eq!(
144        buffer.text_summary_for_range(0..20),
145        TextSummary {
146            bytes: 20,
147            lines: Point::new(4, 1),
148            first_line_chars: 2,
149            last_line_chars: 1,
150            longest_row: 3,
151            longest_row_chars: 6,
152        }
153    );
154    assert_eq!(
155        buffer.text_summary_for_range(0..22),
156        TextSummary {
157            bytes: 22,
158            lines: Point::new(4, 3),
159            first_line_chars: 2,
160            last_line_chars: 3,
161            longest_row: 3,
162            longest_row_chars: 6,
163        }
164    );
165    assert_eq!(
166        buffer.text_summary_for_range(7..22),
167        TextSummary {
168            bytes: 15,
169            lines: Point::new(2, 3),
170            first_line_chars: 4,
171            last_line_chars: 3,
172            longest_row: 1,
173            longest_row_chars: 6,
174        }
175    );
176}
177
178#[test]
179fn test_chars_at() {
180    let mut buffer = Buffer::new(0, 0, History::new("".into()));
181    buffer.edit(vec![0..0], "abcd\nefgh\nij");
182    buffer.edit(vec![12..12], "kl\nmno");
183    buffer.edit(vec![18..18], "\npqrs");
184    buffer.edit(vec![18..21], "\nPQ");
185
186    let chars = buffer.chars_at(Point::new(0, 0));
187    assert_eq!(chars.collect::<String>(), "abcd\nefgh\nijkl\nmno\nPQrs");
188
189    let chars = buffer.chars_at(Point::new(1, 0));
190    assert_eq!(chars.collect::<String>(), "efgh\nijkl\nmno\nPQrs");
191
192    let chars = buffer.chars_at(Point::new(2, 0));
193    assert_eq!(chars.collect::<String>(), "ijkl\nmno\nPQrs");
194
195    let chars = buffer.chars_at(Point::new(3, 0));
196    assert_eq!(chars.collect::<String>(), "mno\nPQrs");
197
198    let chars = buffer.chars_at(Point::new(4, 0));
199    assert_eq!(chars.collect::<String>(), "PQrs");
200
201    // Regression test:
202    let mut buffer = Buffer::new(0, 0, History::new("".into()));
203    buffer.edit(vec![0..0], "[workspace]\nmembers = [\n    \"xray_core\",\n    \"xray_server\",\n    \"xray_cli\",\n    \"xray_wasm\",\n]\n");
204    buffer.edit(vec![60..60], "\n");
205
206    let chars = buffer.chars_at(Point::new(6, 0));
207    assert_eq!(chars.collect::<String>(), "    \"xray_wasm\",\n]\n");
208}
209
210#[test]
211fn test_anchors() {
212    let mut buffer = Buffer::new(0, 0, History::new("".into()));
213    buffer.edit(vec![0..0], "abc");
214    let left_anchor = buffer.anchor_before(2);
215    let right_anchor = buffer.anchor_after(2);
216
217    buffer.edit(vec![1..1], "def\n");
218    assert_eq!(buffer.text(), "adef\nbc");
219    assert_eq!(left_anchor.to_offset(&buffer), 6);
220    assert_eq!(right_anchor.to_offset(&buffer), 6);
221    assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 });
222    assert_eq!(right_anchor.to_point(&buffer), Point { row: 1, column: 1 });
223
224    buffer.edit(vec![2..3], "");
225    assert_eq!(buffer.text(), "adf\nbc");
226    assert_eq!(left_anchor.to_offset(&buffer), 5);
227    assert_eq!(right_anchor.to_offset(&buffer), 5);
228    assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 });
229    assert_eq!(right_anchor.to_point(&buffer), Point { row: 1, column: 1 });
230
231    buffer.edit(vec![5..5], "ghi\n");
232    assert_eq!(buffer.text(), "adf\nbghi\nc");
233    assert_eq!(left_anchor.to_offset(&buffer), 5);
234    assert_eq!(right_anchor.to_offset(&buffer), 9);
235    assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 });
236    assert_eq!(right_anchor.to_point(&buffer), Point { row: 2, column: 0 });
237
238    buffer.edit(vec![7..9], "");
239    assert_eq!(buffer.text(), "adf\nbghc");
240    assert_eq!(left_anchor.to_offset(&buffer), 5);
241    assert_eq!(right_anchor.to_offset(&buffer), 7);
242    assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 },);
243    assert_eq!(right_anchor.to_point(&buffer), Point { row: 1, column: 3 });
244
245    // Ensure anchoring to a point is equivalent to anchoring to an offset.
246    assert_eq!(
247        buffer.anchor_before(Point { row: 0, column: 0 }),
248        buffer.anchor_before(0)
249    );
250    assert_eq!(
251        buffer.anchor_before(Point { row: 0, column: 1 }),
252        buffer.anchor_before(1)
253    );
254    assert_eq!(
255        buffer.anchor_before(Point { row: 0, column: 2 }),
256        buffer.anchor_before(2)
257    );
258    assert_eq!(
259        buffer.anchor_before(Point { row: 0, column: 3 }),
260        buffer.anchor_before(3)
261    );
262    assert_eq!(
263        buffer.anchor_before(Point { row: 1, column: 0 }),
264        buffer.anchor_before(4)
265    );
266    assert_eq!(
267        buffer.anchor_before(Point { row: 1, column: 1 }),
268        buffer.anchor_before(5)
269    );
270    assert_eq!(
271        buffer.anchor_before(Point { row: 1, column: 2 }),
272        buffer.anchor_before(6)
273    );
274    assert_eq!(
275        buffer.anchor_before(Point { row: 1, column: 3 }),
276        buffer.anchor_before(7)
277    );
278    assert_eq!(
279        buffer.anchor_before(Point { row: 1, column: 4 }),
280        buffer.anchor_before(8)
281    );
282
283    // Comparison between anchors.
284    let anchor_at_offset_0 = buffer.anchor_before(0);
285    let anchor_at_offset_1 = buffer.anchor_before(1);
286    let anchor_at_offset_2 = buffer.anchor_before(2);
287
288    assert_eq!(
289        anchor_at_offset_0
290            .cmp(&anchor_at_offset_0, &buffer)
291            .unwrap(),
292        Ordering::Equal
293    );
294    assert_eq!(
295        anchor_at_offset_1
296            .cmp(&anchor_at_offset_1, &buffer)
297            .unwrap(),
298        Ordering::Equal
299    );
300    assert_eq!(
301        anchor_at_offset_2
302            .cmp(&anchor_at_offset_2, &buffer)
303            .unwrap(),
304        Ordering::Equal
305    );
306
307    assert_eq!(
308        anchor_at_offset_0
309            .cmp(&anchor_at_offset_1, &buffer)
310            .unwrap(),
311        Ordering::Less
312    );
313    assert_eq!(
314        anchor_at_offset_1
315            .cmp(&anchor_at_offset_2, &buffer)
316            .unwrap(),
317        Ordering::Less
318    );
319    assert_eq!(
320        anchor_at_offset_0
321            .cmp(&anchor_at_offset_2, &buffer)
322            .unwrap(),
323        Ordering::Less
324    );
325
326    assert_eq!(
327        anchor_at_offset_1
328            .cmp(&anchor_at_offset_0, &buffer)
329            .unwrap(),
330        Ordering::Greater
331    );
332    assert_eq!(
333        anchor_at_offset_2
334            .cmp(&anchor_at_offset_1, &buffer)
335            .unwrap(),
336        Ordering::Greater
337    );
338    assert_eq!(
339        anchor_at_offset_2
340            .cmp(&anchor_at_offset_0, &buffer)
341            .unwrap(),
342        Ordering::Greater
343    );
344}
345
346#[test]
347fn test_anchors_at_start_and_end() {
348    let mut buffer = Buffer::new(0, 0, History::new("".into()));
349    let before_start_anchor = buffer.anchor_before(0);
350    let after_end_anchor = buffer.anchor_after(0);
351
352    buffer.edit(vec![0..0], "abc");
353    assert_eq!(buffer.text(), "abc");
354    assert_eq!(before_start_anchor.to_offset(&buffer), 0);
355    assert_eq!(after_end_anchor.to_offset(&buffer), 3);
356
357    let after_start_anchor = buffer.anchor_after(0);
358    let before_end_anchor = buffer.anchor_before(3);
359
360    buffer.edit(vec![3..3], "def");
361    buffer.edit(vec![0..0], "ghi");
362    assert_eq!(buffer.text(), "ghiabcdef");
363    assert_eq!(before_start_anchor.to_offset(&buffer), 0);
364    assert_eq!(after_start_anchor.to_offset(&buffer), 3);
365    assert_eq!(before_end_anchor.to_offset(&buffer), 6);
366    assert_eq!(after_end_anchor.to_offset(&buffer), 9);
367}
368
369#[test]
370fn test_undo_redo() {
371    let mut buffer = Buffer::new(0, 0, History::new("1234".into()));
372    // Set group interval to zero so as to not group edits in the undo stack.
373    buffer.history.group_interval = Duration::from_secs(0);
374
375    buffer.edit(vec![1..1], "abx");
376    buffer.edit(vec![3..4], "yzef");
377    buffer.edit(vec![3..5], "cd");
378    assert_eq!(buffer.text(), "1abcdef234");
379
380    let transactions = buffer.history.undo_stack.clone();
381    assert_eq!(transactions.len(), 3);
382
383    buffer.undo_or_redo(transactions[0].clone()).unwrap();
384    assert_eq!(buffer.text(), "1cdef234");
385    buffer.undo_or_redo(transactions[0].clone()).unwrap();
386    assert_eq!(buffer.text(), "1abcdef234");
387
388    buffer.undo_or_redo(transactions[1].clone()).unwrap();
389    assert_eq!(buffer.text(), "1abcdx234");
390    buffer.undo_or_redo(transactions[2].clone()).unwrap();
391    assert_eq!(buffer.text(), "1abx234");
392    buffer.undo_or_redo(transactions[1].clone()).unwrap();
393    assert_eq!(buffer.text(), "1abyzef234");
394    buffer.undo_or_redo(transactions[2].clone()).unwrap();
395    assert_eq!(buffer.text(), "1abcdef234");
396
397    buffer.undo_or_redo(transactions[2].clone()).unwrap();
398    assert_eq!(buffer.text(), "1abyzef234");
399    buffer.undo_or_redo(transactions[0].clone()).unwrap();
400    assert_eq!(buffer.text(), "1yzef234");
401    buffer.undo_or_redo(transactions[1].clone()).unwrap();
402    assert_eq!(buffer.text(), "1234");
403}
404
405#[test]
406fn test_history() {
407    let mut now = Instant::now();
408    let mut buffer = Buffer::new(0, 0, History::new("123456".into()));
409
410    let set_id = if let Operation::UpdateSelections { set_id, .. } =
411        buffer.add_selection_set(buffer.selections_from_ranges(vec![4..4]).unwrap())
412    {
413        set_id
414    } else {
415        unreachable!()
416    };
417    buffer.start_transaction_at(Some(set_id), now).unwrap();
418    buffer.edit(vec![2..4], "cd");
419    buffer.end_transaction_at(Some(set_id), now).unwrap();
420    assert_eq!(buffer.text(), "12cd56");
421    assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![4..4]);
422
423    buffer.start_transaction_at(Some(set_id), now).unwrap();
424    buffer
425        .update_selection_set(set_id, buffer.selections_from_ranges(vec![1..3]).unwrap())
426        .unwrap();
427    buffer.edit(vec![4..5], "e");
428    buffer.end_transaction_at(Some(set_id), now).unwrap();
429    assert_eq!(buffer.text(), "12cde6");
430    assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![1..3]);
431
432    now += buffer.history.group_interval + Duration::from_millis(1);
433    buffer.start_transaction_at(Some(set_id), now).unwrap();
434    buffer
435        .update_selection_set(set_id, buffer.selections_from_ranges(vec![2..2]).unwrap())
436        .unwrap();
437    buffer.edit(vec![0..1], "a");
438    buffer.edit(vec![1..1], "b");
439    buffer.end_transaction_at(Some(set_id), now).unwrap();
440    assert_eq!(buffer.text(), "ab2cde6");
441    assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![3..3]);
442
443    // Last transaction happened past the group interval, undo it on its
444    // own.
445    buffer.undo();
446    assert_eq!(buffer.text(), "12cde6");
447    assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![1..3]);
448
449    // First two transactions happened within the group interval, undo them
450    // together.
451    buffer.undo();
452    assert_eq!(buffer.text(), "123456");
453    assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![4..4]);
454
455    // Redo the first two transactions together.
456    buffer.redo();
457    assert_eq!(buffer.text(), "12cde6");
458    assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![1..3]);
459
460    // Redo the last transaction on its own.
461    buffer.redo();
462    assert_eq!(buffer.text(), "ab2cde6");
463    assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![3..3]);
464
465    buffer.start_transaction_at(None, now).unwrap();
466    assert!(buffer.end_transaction_at(None, now).is_none());
467    buffer.undo();
468    assert_eq!(buffer.text(), "12cde6");
469}
470
471#[test]
472fn test_concurrent_edits() {
473    let text = "abcdef";
474
475    let mut buffer1 = Buffer::new(1, 0, History::new(text.into()));
476    let mut buffer2 = Buffer::new(2, 0, History::new(text.into()));
477    let mut buffer3 = Buffer::new(3, 0, History::new(text.into()));
478
479    let buf1_op = buffer1.edit(vec![1..2], "12");
480    assert_eq!(buffer1.text(), "a12cdef");
481    let buf2_op = buffer2.edit(vec![3..4], "34");
482    assert_eq!(buffer2.text(), "abc34ef");
483    let buf3_op = buffer3.edit(vec![5..6], "56");
484    assert_eq!(buffer3.text(), "abcde56");
485
486    buffer1.apply_op(Operation::Edit(buf2_op.clone())).unwrap();
487    buffer1.apply_op(Operation::Edit(buf3_op.clone())).unwrap();
488    buffer2.apply_op(Operation::Edit(buf1_op.clone())).unwrap();
489    buffer2.apply_op(Operation::Edit(buf3_op.clone())).unwrap();
490    buffer3.apply_op(Operation::Edit(buf1_op.clone())).unwrap();
491    buffer3.apply_op(Operation::Edit(buf2_op.clone())).unwrap();
492
493    assert_eq!(buffer1.text(), "a12c34e56");
494    assert_eq!(buffer2.text(), "a12c34e56");
495    assert_eq!(buffer3.text(), "a12c34e56");
496}
497
498#[gpui::test(iterations = 100)]
499fn test_random_concurrent_edits(mut rng: StdRng) {
500    let peers = env::var("PEERS")
501        .map(|i| i.parse().expect("invalid `PEERS` variable"))
502        .unwrap_or(5);
503    let operations = env::var("OPERATIONS")
504        .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
505        .unwrap_or(10);
506
507    let base_text_len = rng.gen_range(0..10);
508    let base_text = RandomCharIter::new(&mut rng)
509        .take(base_text_len)
510        .collect::<String>();
511    let mut replica_ids = Vec::new();
512    let mut buffers = Vec::new();
513    let mut network = Network::new(rng.clone());
514
515    for i in 0..peers {
516        let mut buffer = Buffer::new(i as ReplicaId, 0, History::new(base_text.clone().into()));
517        buffer.history.group_interval = Duration::from_millis(rng.gen_range(0..=200));
518        buffers.push(buffer);
519        replica_ids.push(i as u16);
520        network.add_peer(i as u16);
521    }
522
523    log::info!("initial text: {:?}", base_text);
524
525    let mut mutation_count = operations;
526    loop {
527        let replica_index = rng.gen_range(0..peers);
528        let replica_id = replica_ids[replica_index];
529        let buffer = &mut buffers[replica_index];
530        match rng.gen_range(0..=100) {
531            0..=50 if mutation_count != 0 => {
532                let ops = buffer.randomly_mutate(&mut rng);
533                network.broadcast(buffer.replica_id, ops);
534                log::info!("buffer {} text: {:?}", buffer.replica_id, buffer.text());
535                mutation_count -= 1;
536            }
537            51..=70 if mutation_count != 0 => {
538                let ops = buffer.randomly_undo_redo(&mut rng);
539                network.broadcast(buffer.replica_id, ops);
540                mutation_count -= 1;
541            }
542            71..=100 if network.has_unreceived(replica_id) => {
543                let ops = network.receive(replica_id);
544                if !ops.is_empty() {
545                    log::info!(
546                        "peer {} applying {} ops from the network.",
547                        replica_id,
548                        ops.len()
549                    );
550                    buffer.apply_ops(ops).unwrap();
551                }
552            }
553            _ => {}
554        }
555
556        if mutation_count == 0 && network.is_idle() {
557            break;
558        }
559    }
560
561    let first_buffer = &buffers[0];
562    for buffer in &buffers[1..] {
563        assert_eq!(
564            buffer.text(),
565            first_buffer.text(),
566            "Replica {} text != Replica 0 text",
567            buffer.replica_id
568        );
569        assert_eq!(
570            buffer.selection_sets().collect::<HashMap<_, _>>(),
571            first_buffer.selection_sets().collect::<HashMap<_, _>>()
572        );
573        assert_eq!(
574            buffer.all_selection_ranges().collect::<HashMap<_, _>>(),
575            first_buffer
576                .all_selection_ranges()
577                .collect::<HashMap<_, _>>()
578        );
579    }
580}
581
582#[derive(Clone)]
583struct Envelope<T: Clone> {
584    message: T,
585    sender: ReplicaId,
586}
587
588struct Network<T: Clone, R: rand::Rng> {
589    inboxes: std::collections::BTreeMap<ReplicaId, Vec<Envelope<T>>>,
590    all_messages: Vec<T>,
591    rng: R,
592}
593
594impl<T: Clone, R: rand::Rng> Network<T, R> {
595    fn new(rng: R) -> Self {
596        Network {
597            inboxes: Default::default(),
598            all_messages: Vec::new(),
599            rng,
600        }
601    }
602
603    fn add_peer(&mut self, id: ReplicaId) {
604        self.inboxes.insert(id, Vec::new());
605    }
606
607    fn is_idle(&self) -> bool {
608        self.inboxes.values().all(|i| i.is_empty())
609    }
610
611    fn broadcast(&mut self, sender: ReplicaId, messages: Vec<T>) {
612        for (replica, inbox) in self.inboxes.iter_mut() {
613            if *replica != sender {
614                for message in &messages {
615                    let min_index = inbox
616                        .iter()
617                        .enumerate()
618                        .rev()
619                        .find_map(|(index, envelope)| {
620                            if sender == envelope.sender {
621                                Some(index + 1)
622                            } else {
623                                None
624                            }
625                        })
626                        .unwrap_or(0);
627
628                    // Insert one or more duplicates of this message *after* the previous
629                    // message delivered by this replica.
630                    for _ in 0..self.rng.gen_range(1..4) {
631                        let insertion_index = self.rng.gen_range(min_index..inbox.len() + 1);
632                        inbox.insert(
633                            insertion_index,
634                            Envelope {
635                                message: message.clone(),
636                                sender,
637                            },
638                        );
639                    }
640                }
641            }
642        }
643        self.all_messages.extend(messages);
644    }
645
646    fn has_unreceived(&self, receiver: ReplicaId) -> bool {
647        !self.inboxes[&receiver].is_empty()
648    }
649
650    fn receive(&mut self, receiver: ReplicaId) -> Vec<T> {
651        let inbox = self.inboxes.get_mut(&receiver).unwrap();
652        let count = self.rng.gen_range(0..inbox.len() + 1);
653        inbox
654            .drain(0..count)
655            .map(|envelope| envelope.message)
656            .collect()
657    }
658}