mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 07:17:55 +03:00
dag: add a test about strip->reinsert->build_higher_level_segment bug
Summary: See the added test. Differential Revision: D35548450 fbshipit-source-id: a1e1d889b88bfcf15030659a0dd4869b7f38ff80
This commit is contained in:
parent
8c7ea28d84
commit
a452ebfe49
@ -352,6 +352,53 @@ impl TestDag {
|
||||
format!("{}{}\n{}", all_str, iddag_state, idmap_state)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
/// Dump Dag segments as ASCII string.
|
||||
pub fn dump_segments_ascii(&self) -> String {
|
||||
use crate::Id;
|
||||
use crate::IdSet;
|
||||
use crate::IdSpan;
|
||||
use std::collections::HashSet;
|
||||
|
||||
let span_iter = |span: IdSpan| IdSet::from_spans(vec![span]).into_iter().rev();
|
||||
let iddag = &self.dag.dag;
|
||||
let all_ids = iddag.all_ids_in_groups(&Group::ALL).unwrap();
|
||||
let max_level = iddag.max_level().unwrap();
|
||||
let mut output = String::new();
|
||||
for level in 0..=max_level {
|
||||
output = format!("{}\n Lv{}:", output.trim_end(), level);
|
||||
for span in all_ids.iter_span_asc() {
|
||||
output += " |";
|
||||
let segments = iddag.segments_in_span_ascending(*span, level).unwrap();
|
||||
let segment_ids: HashSet<Id> = segments
|
||||
.iter()
|
||||
.flat_map(|s| span_iter(s.span().unwrap()))
|
||||
.collect();
|
||||
let segment_highs: HashSet<Id> =
|
||||
segments.iter().map(|s| s.high().unwrap()).collect();
|
||||
for id in span_iter(*span) {
|
||||
let id_str = format!("{:?}", id);
|
||||
if segment_ids.contains(&id) {
|
||||
output += &id_str
|
||||
} else {
|
||||
let space = " ".repeat(id_str.len());
|
||||
output += &space;
|
||||
};
|
||||
output.push(
|
||||
if segment_highs.contains(&id)
|
||||
|| (segment_ids.contains(&(id + 1)) && !segment_ids.contains(&id))
|
||||
{
|
||||
'|'
|
||||
} else {
|
||||
' '
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
output.trim_end().to_string()
|
||||
}
|
||||
|
||||
async fn validate(&self) {
|
||||
// All vertexes should be accessible, and round-trip through IdMap.
|
||||
let mut iter = self.dag.all().await.unwrap().iter().await.unwrap();
|
||||
|
@ -105,3 +105,86 @@ P->C: 1->4, 4->N0
|
||||
// Strip C+F. B is no longer lazy.
|
||||
assert_eq!(strip("C F").await, "<spans [0:1]>\nLv0: RH0-1[]\n1->B");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_reinsert_then_create_higher_level() {
|
||||
// Test re-inserting a stripped "gap" and then creating higher level segments.
|
||||
//
|
||||
// Initial state:
|
||||
//
|
||||
// Lv0: |0|1|2|3|4|5|6|7|8|9|10|
|
||||
// Lv1: |-|---|-|---|---|---|
|
||||
// Lv2: |-----|-|-------|
|
||||
//
|
||||
// Strip 3:
|
||||
//
|
||||
// Lv0: |0|1|2| |4|5|6|7|8|9|10|
|
||||
// Lv1: |-|---| |---|---|---|
|
||||
// Lv2: |-----| |-------|
|
||||
//
|
||||
// Reinsert 3 (Note: 3 no longer has Lv1 and Lv2 segments):
|
||||
//
|
||||
// Lv0: |0|1|2|3|4|5|6|7|8|9|10|
|
||||
// Lv1: |-|---| |---|---|---|
|
||||
// Lv2: |-----| |-------|
|
||||
//
|
||||
// Trigger Lv3 segment creation:
|
||||
//
|
||||
// Lv0: |0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|
|
||||
// Lv1: |-|---| |---|---|---|-----|-----|
|
||||
// Lv2: |-----| |-------|---------|
|
||||
// Lv3: ? |-----------------|
|
||||
|
||||
let mut dag = TestDag::new_with_segment_size(2);
|
||||
|
||||
// Use "Z" as an extra parent to avoid merging flat segments.
|
||||
dag.drawdag("Z", &[]);
|
||||
for i in 1..=10 {
|
||||
let ascii = match i {
|
||||
1 | 3 | 4 => format!("A{i}", i = i),
|
||||
_ => format!("Z-A{i} A{p}-A{i}", p = i - 1, i = i),
|
||||
};
|
||||
dag.drawdag(&ascii, &[]);
|
||||
}
|
||||
dag.flush("").await;
|
||||
|
||||
assert_eq!(
|
||||
dag.dump_segments_ascii(),
|
||||
r#"
|
||||
Lv0: |N0|N1|N2|N3|N4|N5|N6|N7|N8|N9|N10|
|
||||
Lv1: |N0|N1 N2|N3|N4 N5|N6 N7|N8 N9|
|
||||
Lv2: |N0 N1 N2|N3|N4 N5 N6 N7|"#
|
||||
);
|
||||
|
||||
// Strip 3.
|
||||
dag.strip("A3").await;
|
||||
assert_eq!(
|
||||
dag.dump_segments_ascii(),
|
||||
r#"
|
||||
Lv0: |N0|N1|N2| |N4|N5|N6|N7|N8|N9|N10|
|
||||
Lv1: |N0|N1 N2| |N4 N5|N6 N7|N8 N9|
|
||||
Lv2: |N0 N1 N2| |N4 N5 N6 N7|"#
|
||||
);
|
||||
|
||||
// Reinsert 3. Note A3 does not have Lv1 or Lv2 segments.
|
||||
dag.drawdag("A2-A3 Z-A3", &[]);
|
||||
assert_eq!(
|
||||
dag.dump_segments_ascii(),
|
||||
r#"
|
||||
Lv0: |N0|N1|N2|N3|N4|N5|N6|N7|N8|N9|N10|
|
||||
Lv1: |N0|N1 N2| |N4 N5|N6 N7|N8 N9|
|
||||
Lv2: |N0 N1 N2| |N4 N5 N6 N7|"#
|
||||
);
|
||||
|
||||
// Try to create Lv3 segments.
|
||||
dag.drawdag("A10-A11 A3-A11", &[]);
|
||||
for i in 12..=14 {
|
||||
// FIXME: Crash when creating Lv3 segment.
|
||||
// Bug("level 3 segments [RN0-N2[], RN4-N7[N0]] are not sorted or connected!")
|
||||
if i == 14 {
|
||||
break;
|
||||
}
|
||||
let ascii = format!("Z-A{i} A{p}-A{i}", p = i - 1, i = i);
|
||||
dag.drawdag(&ascii, &[]);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user