Skip to content

Commit

Permalink
chore: Fix flaky semantic tokens caching test (#23831)
Browse files Browse the repository at this point in the history
The stderr stream from the LSP is consumed by a separate thread, so it
may not have processed the part we care about yet. Instead, wait until
you see the measure for the request you care about.
  • Loading branch information
nathanwhit committed May 15, 2024
1 parent 76234c6 commit 3cea44a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
6 changes: 3 additions & 3 deletions tests/integration/lsp_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12740,7 +12740,7 @@ fn lsp_semantic_token_caching() {

assert_eq!(
client
.perf()
.perf_wait_for_measure("lsp.semantic_tokens_range")
.measure_count("tsc.request.getEncodedSemanticClassifications"),
1,
);
Expand All @@ -12755,7 +12755,7 @@ fn lsp_semantic_token_caching() {

assert_eq!(
client
.perf()
.perf_wait_for_measure("lsp.semantic_tokens_full")
.measure_count("tsc.request.getEncodedSemanticClassifications"),
2,
);
Expand All @@ -12775,7 +12775,7 @@ fn lsp_semantic_token_caching() {
// make sure we actually used the cache
assert_eq!(
client
.perf()
.perf_wait_for_measure("lsp.semantic_tokens_range")
.measure_count("tsc.request.getEncodedSemanticClassifications"),
2,
);
Expand Down
40 changes: 30 additions & 10 deletions tests/util/server/src/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,15 +689,33 @@ impl Perf {
rx,
}
}
fn drain(&mut self) {
while let Ok(record) = self.rx.try_recv() {
if let PerfRecord::Measure(measure) = &record {
*self
.measures_counts
.entry(measure.name.clone())
.or_default() += 1;
fn drain_until(&mut self, f: impl Fn(&PerfRecord) -> bool) {
let timeout_time =
Instant::now().checked_add(Duration::from_secs(5)).unwrap();
let mut found = false;
loop {
while let Ok(record) = self.rx.try_recv() {
if let PerfRecord::Measure(measure) = &record {
*self
.measures_counts
.entry(measure.name.clone())
.or_default() += 1;
}
if f(&record) {
found = true;
}
self.records.push(record);
}

if found {
break;
}

std::thread::sleep(Duration::from_millis(20));

if Instant::now() > timeout_time {
panic!("timed out waiting for perf record");
}
self.records.push(record);
}
}
pub fn measures(&self) -> impl IntoIterator<Item = &PerfMeasure> {
Expand Down Expand Up @@ -757,12 +775,14 @@ impl LspClient {
self.reader.pending_len()
}

pub fn perf(&mut self) -> &Perf {
/// Collects performance records until a measure with the given name is
/// emitted.
pub fn perf_wait_for_measure(&mut self, name: &str) -> &Perf {
let perf = self
.perf
.as_mut()
.expect("must setup with client_builder.collect_perf()");
perf.drain();
perf.drain_until(|record| matches!(record, PerfRecord::Measure(measure) if measure.name == name));
perf
}

Expand Down

0 comments on commit 3cea44a

Please sign in to comment.