Re-enable randomized concurrent edits test
This commit is contained in:
parent
30e2e2014d
commit
cdb268e656
5 changed files with 102 additions and 112 deletions
|
@ -2414,27 +2414,18 @@ impl Buffer {
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
impl Buffer {
|
impl Buffer {
|
||||||
pub fn randomly_edit<T>(
|
pub fn randomly_edit<T>(&mut self, rng: &mut T, old_range_count: usize)
|
||||||
&mut self,
|
|
||||||
rng: &mut T,
|
|
||||||
old_range_count: usize,
|
|
||||||
_: &mut ModelContext<Self>,
|
|
||||||
) -> (Vec<Range<usize>>, String)
|
|
||||||
where
|
where
|
||||||
T: rand::Rng,
|
T: rand::Rng,
|
||||||
{
|
{
|
||||||
self.buffer.randomly_edit(rng, old_range_count)
|
self.buffer.randomly_edit(rng, old_range_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn randomly_mutate<T>(
|
pub fn randomly_mutate<T>(&mut self, rng: &mut T)
|
||||||
&mut self,
|
|
||||||
rng: &mut T,
|
|
||||||
_: &mut ModelContext<Self>,
|
|
||||||
) -> (Vec<Range<usize>>, String)
|
|
||||||
where
|
where
|
||||||
T: rand::Rng,
|
T: rand::Rng,
|
||||||
{
|
{
|
||||||
self.buffer.randomly_mutate(rng)
|
self.buffer.randomly_mutate(rng);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2450,7 +2441,7 @@ impl TextBuffer {
|
||||||
&mut self,
|
&mut self,
|
||||||
rng: &mut T,
|
rng: &mut T,
|
||||||
old_range_count: usize,
|
old_range_count: usize,
|
||||||
) -> (Vec<Range<usize>>, String)
|
) -> (Vec<Range<usize>>, String, Operation)
|
||||||
where
|
where
|
||||||
T: rand::Rng,
|
T: rand::Rng,
|
||||||
{
|
{
|
||||||
|
@ -2472,17 +2463,17 @@ impl TextBuffer {
|
||||||
old_ranges,
|
old_ranges,
|
||||||
new_text
|
new_text
|
||||||
);
|
);
|
||||||
self.edit(old_ranges.iter().cloned(), new_text.as_str());
|
let op = self.edit(old_ranges.iter().cloned(), new_text.as_str());
|
||||||
(old_ranges, new_text)
|
(old_ranges, new_text, Operation::Edit(op))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn randomly_mutate<T>(&mut self, rng: &mut T) -> (Vec<Range<usize>>, String)
|
pub fn randomly_mutate<T>(&mut self, rng: &mut T) -> Vec<Operation>
|
||||||
where
|
where
|
||||||
T: rand::Rng,
|
T: rand::Rng,
|
||||||
{
|
{
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
|
||||||
let (old_ranges, new_text) = self.randomly_edit(rng, 5);
|
let mut ops = vec![self.randomly_edit(rng, 5).2];
|
||||||
|
|
||||||
// Randomly add, remove or mutate selection sets.
|
// Randomly add, remove or mutate selection sets.
|
||||||
let replica_selection_sets = &self
|
let replica_selection_sets = &self
|
||||||
|
@ -2492,7 +2483,7 @@ impl TextBuffer {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let set_id = replica_selection_sets.choose(rng);
|
let set_id = replica_selection_sets.choose(rng);
|
||||||
if set_id.is_some() && rng.gen_bool(1.0 / 6.0) {
|
if set_id.is_some() && rng.gen_bool(1.0 / 6.0) {
|
||||||
self.remove_selection_set(*set_id.unwrap()).unwrap();
|
ops.push(self.remove_selection_set(*set_id.unwrap()).unwrap());
|
||||||
} else {
|
} else {
|
||||||
let mut ranges = Vec::new();
|
let mut ranges = Vec::new();
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
|
@ -2500,20 +2491,22 @@ impl TextBuffer {
|
||||||
}
|
}
|
||||||
let new_selections = self.selections_from_ranges(ranges).unwrap();
|
let new_selections = self.selections_from_ranges(ranges).unwrap();
|
||||||
|
|
||||||
if set_id.is_none() || rng.gen_bool(1.0 / 5.0) {
|
let op = if set_id.is_none() || rng.gen_bool(1.0 / 5.0) {
|
||||||
self.add_selection_set(new_selections);
|
self.add_selection_set(new_selections)
|
||||||
} else {
|
} else {
|
||||||
self.update_selection_set(*set_id.unwrap(), new_selections)
|
self.update_selection_set(*set_id.unwrap(), new_selections)
|
||||||
.unwrap();
|
.unwrap()
|
||||||
}
|
};
|
||||||
|
ops.push(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
(old_ranges, new_text)
|
ops
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn randomly_undo_redo(&mut self, rng: &mut impl rand::Rng) {
|
pub fn randomly_undo_redo(&mut self, rng: &mut impl rand::Rng) -> Vec<Operation> {
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
|
||||||
|
let mut ops = Vec::new();
|
||||||
for _ in 0..rng.gen_range(1..=5) {
|
for _ in 0..rng.gen_range(1..=5) {
|
||||||
if let Some(transaction) = self.history.undo_stack.choose(rng).cloned() {
|
if let Some(transaction) = self.history.undo_stack.choose(rng).cloned() {
|
||||||
log::info!(
|
log::info!(
|
||||||
|
@ -2521,9 +2514,10 @@ impl TextBuffer {
|
||||||
self.replica_id,
|
self.replica_id,
|
||||||
transaction
|
transaction
|
||||||
);
|
);
|
||||||
self.undo_or_redo(transaction).unwrap();
|
ops.push(self.undo_or_redo(transaction).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ops
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selections_from_ranges<I>(&self, ranges: I) -> Result<Vec<Selection>>
|
fn selections_from_ranges<I>(&self, ranges: I) -> Result<Vec<Selection>>
|
||||||
|
|
|
@ -6,7 +6,6 @@ use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
env,
|
env,
|
||||||
iter::Iterator,
|
iter::Iterator,
|
||||||
mem,
|
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
@ -104,7 +103,7 @@ fn test_random_edits(mut rng: StdRng) {
|
||||||
);
|
);
|
||||||
|
|
||||||
for _i in 0..operations {
|
for _i in 0..operations {
|
||||||
let (old_ranges, new_text) = buffer.randomly_mutate(&mut rng);
|
let (old_ranges, new_text, _) = buffer.randomly_edit(&mut rng, 5);
|
||||||
for old_range in old_ranges.iter().rev() {
|
for old_range in old_ranges.iter().rev() {
|
||||||
reference_string.replace_range(old_range.clone(), &new_text);
|
reference_string.replace_range(old_range.clone(), &new_text);
|
||||||
}
|
}
|
||||||
|
@ -571,92 +570,89 @@ fn test_concurrent_edits() {
|
||||||
assert_eq!(buffer3.text(), "a12c34e56");
|
assert_eq!(buffer3.text(), "a12c34e56");
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[gpui::test(iterations = 100)]
|
#[gpui::test(iterations = 100)]
|
||||||
// fn test_random_concurrent_edits(cx: &mut gpui::MutableAppContext, mut rng: StdRng) {
|
fn test_random_concurrent_edits(mut rng: StdRng) {
|
||||||
// let peers = env::var("PEERS")
|
let peers = env::var("PEERS")
|
||||||
// .map(|i| i.parse().expect("invalid `PEERS` variable"))
|
.map(|i| i.parse().expect("invalid `PEERS` variable"))
|
||||||
// .unwrap_or(5);
|
.unwrap_or(5);
|
||||||
// let operations = env::var("OPERATIONS")
|
let operations = env::var("OPERATIONS")
|
||||||
// .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
||||||
// .unwrap_or(10);
|
.unwrap_or(10);
|
||||||
|
|
||||||
// let base_text_len = rng.gen_range(0..10);
|
let base_text_len = rng.gen_range(0..10);
|
||||||
// let base_text = RandomCharIter::new(&mut rng)
|
let base_text = RandomCharIter::new(&mut rng)
|
||||||
// .take(base_text_len)
|
.take(base_text_len)
|
||||||
// .collect::<String>();
|
.collect::<String>();
|
||||||
// let mut replica_ids = Vec::new();
|
let mut replica_ids = Vec::new();
|
||||||
// let mut buffers = Vec::new();
|
let mut buffers = Vec::new();
|
||||||
// let mut network = Network::new(rng.clone());
|
let mut network = Network::new(rng.clone());
|
||||||
|
|
||||||
// for i in 0..peers {
|
for i in 0..peers {
|
||||||
// let buffer = cx.add_model(|cx| {
|
let mut buffer = TextBuffer::new(i as ReplicaId, 0, History::new(base_text.clone().into()));
|
||||||
// let mut buf = Buffer::new(i as ReplicaId, base_text.as_str(), cx);
|
buffer.history.group_interval = Duration::from_millis(rng.gen_range(0..=200));
|
||||||
// buf.history.group_interval = Duration::from_millis(rng.gen_range(0..=200));
|
buffers.push(buffer);
|
||||||
// buf
|
replica_ids.push(i as u16);
|
||||||
// });
|
network.add_peer(i as u16);
|
||||||
// buffers.push(buffer);
|
}
|
||||||
// replica_ids.push(i as u16);
|
|
||||||
// network.add_peer(i as u16);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// log::info!("initial text: {:?}", base_text);
|
log::info!("initial text: {:?}", base_text);
|
||||||
|
|
||||||
// let mut mutation_count = operations;
|
let mut mutation_count = operations;
|
||||||
// loop {
|
loop {
|
||||||
// let replica_index = rng.gen_range(0..peers);
|
let replica_index = rng.gen_range(0..peers);
|
||||||
// let replica_id = replica_ids[replica_index];
|
let replica_id = replica_ids[replica_index];
|
||||||
// buffers[replica_index].update(cx, |buffer, cx| match rng.gen_range(0..=100) {
|
let buffer = &mut buffers[replica_index];
|
||||||
// 0..=50 if mutation_count != 0 => {
|
match rng.gen_range(0..=100) {
|
||||||
// buffer.randomly_mutate(&mut rng, cx);
|
0..=50 if mutation_count != 0 => {
|
||||||
// network.broadcast(buffer.replica_id, mem::take(&mut buffer.operations));
|
let ops = buffer.randomly_mutate(&mut rng);
|
||||||
// log::info!("buffer {} text: {:?}", buffer.replica_id, buffer.text());
|
network.broadcast(buffer.replica_id, ops);
|
||||||
// mutation_count -= 1;
|
log::info!("buffer {} text: {:?}", buffer.replica_id, buffer.text());
|
||||||
// }
|
mutation_count -= 1;
|
||||||
// 51..=70 if mutation_count != 0 => {
|
}
|
||||||
// buffer.randomly_undo_redo(&mut rng, cx);
|
51..=70 if mutation_count != 0 => {
|
||||||
// network.broadcast(buffer.replica_id, mem::take(&mut buffer.operations));
|
let ops = buffer.randomly_undo_redo(&mut rng);
|
||||||
// mutation_count -= 1;
|
network.broadcast(buffer.replica_id, ops);
|
||||||
// }
|
mutation_count -= 1;
|
||||||
// 71..=100 if network.has_unreceived(replica_id) => {
|
}
|
||||||
// let ops = network.receive(replica_id);
|
71..=100 if network.has_unreceived(replica_id) => {
|
||||||
// if !ops.is_empty() {
|
let ops = network.receive(replica_id);
|
||||||
// log::info!(
|
if !ops.is_empty() {
|
||||||
// "peer {} applying {} ops from the network.",
|
log::info!(
|
||||||
// replica_id,
|
"peer {} applying {} ops from the network.",
|
||||||
// ops.len()
|
replica_id,
|
||||||
// );
|
ops.len()
|
||||||
// buffer.apply_ops(ops, cx).unwrap();
|
);
|
||||||
// }
|
buffer.apply_ops(ops).unwrap();
|
||||||
// }
|
}
|
||||||
// _ => {}
|
}
|
||||||
// });
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
// if mutation_count == 0 && network.is_idle() {
|
if mutation_count == 0 && network.is_idle() {
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// let first_buffer = buffers[0].read(cx);
|
let first_buffer = &buffers[0];
|
||||||
// for buffer in &buffers[1..] {
|
for buffer in &buffers[1..] {
|
||||||
// let buffer = buffer.read(cx);
|
assert_eq!(
|
||||||
// assert_eq!(
|
buffer.text(),
|
||||||
// buffer.text(),
|
first_buffer.text(),
|
||||||
// first_buffer.text(),
|
"Replica {} text != Replica 0 text",
|
||||||
// "Replica {} text != Replica 0 text",
|
buffer.replica_id
|
||||||
// buffer.replica_id
|
);
|
||||||
// );
|
assert_eq!(
|
||||||
// assert_eq!(
|
buffer.selection_sets().collect::<HashMap<_, _>>(),
|
||||||
// buffer.selection_sets().collect::<HashMap<_, _>>(),
|
first_buffer.selection_sets().collect::<HashMap<_, _>>()
|
||||||
// first_buffer.selection_sets().collect::<HashMap<_, _>>()
|
);
|
||||||
// );
|
assert_eq!(
|
||||||
// assert_eq!(
|
buffer.all_selection_ranges().collect::<HashMap<_, _>>(),
|
||||||
// buffer.all_selection_ranges().collect::<HashMap<_, _>>(),
|
first_buffer
|
||||||
// first_buffer
|
.all_selection_ranges()
|
||||||
// .all_selection_ranges()
|
.collect::<HashMap<_, _>>()
|
||||||
// .collect::<HashMap<_, _>>()
|
);
|
||||||
// );
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Envelope<T: Clone> {
|
struct Envelope<T: Clone> {
|
||||||
|
|
|
@ -436,7 +436,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
buffer.update(&mut cx, |buffer, cx| buffer.randomly_edit(&mut rng, 5, cx));
|
buffer.update(&mut cx, |buffer, cx| buffer.randomly_edit(&mut rng, 5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use buffer::{Anchor, Buffer, Point, ToOffset, AnchorRangeExt, HighlightId, TextSummary};
|
use buffer::{Anchor, AnchorRangeExt, Buffer, HighlightId, Point, TextSummary, ToOffset};
|
||||||
use gpui::{AppContext, ModelHandle};
|
use gpui::{AppContext, ModelHandle};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -1334,7 +1334,7 @@ mod tests {
|
||||||
let edits = buffer.update(cx, |buffer, cx| {
|
let edits = buffer.update(cx, |buffer, cx| {
|
||||||
let start_version = buffer.version.clone();
|
let start_version = buffer.version.clone();
|
||||||
let edit_count = rng.gen_range(1..=5);
|
let edit_count = rng.gen_range(1..=5);
|
||||||
buffer.randomly_edit(&mut rng, edit_count, cx);
|
buffer.randomly_edit(&mut rng, edit_count);
|
||||||
buffer.edits_since(start_version).collect::<Vec<_>>()
|
buffer.edits_since(start_version).collect::<Vec<_>>()
|
||||||
});
|
});
|
||||||
log::info!("editing {:?}", edits);
|
log::info!("editing {:?}", edits);
|
||||||
|
|
|
@ -990,7 +990,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
buffer.update(&mut cx, |buffer, cx| buffer.randomly_mutate(&mut rng, cx));
|
buffer.update(&mut cx, |buffer, cx| buffer.randomly_mutate(&mut rng));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue