2021-02-25 00:14:17 -05:00
|
|
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
|
|
|
|
|
|
|
use deno_core::error::AnyError;
|
|
|
|
use deno_core::serde::Deserialize;
|
|
|
|
use deno_core::serde_json;
|
|
|
|
use deno_core::serde_json::json;
|
|
|
|
use deno_core::serde_json::Value;
|
|
|
|
use std::collections::HashMap;
|
2021-03-25 14:17:37 -04:00
|
|
|
use std::path::Path;
|
2021-02-25 00:14:17 -05:00
|
|
|
use std::time::Duration;
|
2021-05-17 16:45:13 -04:00
|
|
|
use test_util::lsp::LspClient;
|
|
|
|
use test_util::lsp::LspResponseError;
|
2021-02-25 00:14:17 -05:00
|
|
|
|
|
|
|
static FIXTURE_DB_TS: &str = include_str!("fixtures/db.ts");
|
|
|
|
static FIXTURE_DB_MESSAGES: &[u8] = include_bytes!("fixtures/db_messages.json");
|
|
|
|
static FIXTURE_INIT_JSON: &[u8] =
|
|
|
|
include_bytes!("fixtures/initialize_params.json");
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
enum FixtureType {
|
|
|
|
#[serde(rename = "action")]
|
|
|
|
Action,
|
|
|
|
#[serde(rename = "change")]
|
|
|
|
Change,
|
|
|
|
#[serde(rename = "completion")]
|
|
|
|
Completion,
|
|
|
|
#[serde(rename = "highlight")]
|
|
|
|
Highlight,
|
|
|
|
#[serde(rename = "hover")]
|
|
|
|
Hover,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
struct FixtureMessage {
|
|
|
|
#[serde(rename = "type")]
|
|
|
|
fixture_type: FixtureType,
|
|
|
|
params: Value,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A benchmark that opens a 8000+ line TypeScript document, adds a function to
|
|
|
|
/// the end of the document and does a level of hovering and gets quick fix
|
|
|
|
/// code actions.
|
2021-03-25 14:17:37 -04:00
|
|
|
fn bench_big_file_edits(deno_exe: &Path) -> Result<Duration, AnyError> {
|
2021-02-25 00:14:17 -05:00
|
|
|
let mut client = LspClient::new(deno_exe)?;
|
|
|
|
|
|
|
|
let params: Value = serde_json::from_slice(FIXTURE_INIT_JSON)?;
|
|
|
|
let (_, response_error): (Option<Value>, Option<LspResponseError>) =
|
|
|
|
client.write_request("initialize", params)?;
|
|
|
|
assert!(response_error.is_none());
|
|
|
|
|
|
|
|
client.write_notification("initialized", json!({}))?;
|
|
|
|
|
|
|
|
client.write_notification(
|
|
|
|
"textDocument/didOpen",
|
|
|
|
json!({
|
|
|
|
"textDocument": {
|
|
|
|
"uri": "file:///fixtures/db.ts",
|
|
|
|
"languageId": "typescript",
|
|
|
|
"version": 1,
|
|
|
|
"text": FIXTURE_DB_TS
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
)?;
|
|
|
|
|
2021-05-11 23:10:06 -04:00
|
|
|
// TODO(@kitsonk) work around https://github.com/denoland/deno/issues/10603
|
|
|
|
// let (id, method, _): (u64, String, Option<Value>) = client.read_request()?;
|
|
|
|
// assert_eq!(method, "workspace/configuration");
|
2021-05-09 21:16:04 -04:00
|
|
|
|
2021-05-11 23:10:06 -04:00
|
|
|
// client.write_response(
|
|
|
|
// id,
|
|
|
|
// json!({
|
|
|
|
// "enable": true
|
|
|
|
// }),
|
|
|
|
// )?;
|
2021-05-09 21:16:04 -04:00
|
|
|
|
2021-05-07 07:05:32 -04:00
|
|
|
let (method, _): (String, Option<Value>) = client.read_notification()?;
|
|
|
|
assert_eq!(method, "textDocument/publishDiagnostics");
|
|
|
|
let (method, _): (String, Option<Value>) = client.read_notification()?;
|
|
|
|
assert_eq!(method, "textDocument/publishDiagnostics");
|
2021-02-25 00:14:17 -05:00
|
|
|
let (method, _): (String, Option<Value>) = client.read_notification()?;
|
|
|
|
assert_eq!(method, "textDocument/publishDiagnostics");
|
|
|
|
|
|
|
|
let messages: Vec<FixtureMessage> =
|
|
|
|
serde_json::from_slice(FIXTURE_DB_MESSAGES)?;
|
|
|
|
|
|
|
|
for msg in messages {
|
|
|
|
match msg.fixture_type {
|
|
|
|
FixtureType::Action => {
|
2021-05-17 16:45:13 -04:00
|
|
|
client.write_request::<_, _, Value>(
|
|
|
|
"textDocument/codeAction",
|
|
|
|
msg.params,
|
|
|
|
)?;
|
2021-02-25 00:14:17 -05:00
|
|
|
}
|
|
|
|
FixtureType::Change => {
|
|
|
|
client.write_notification("textDocument/didChange", msg.params)?;
|
|
|
|
}
|
|
|
|
FixtureType::Completion => {
|
2021-05-17 16:45:13 -04:00
|
|
|
client.write_request::<_, _, Value>(
|
|
|
|
"textDocument/completion",
|
|
|
|
msg.params,
|
|
|
|
)?;
|
2021-02-25 00:14:17 -05:00
|
|
|
}
|
|
|
|
FixtureType::Highlight => {
|
2021-05-17 16:45:13 -04:00
|
|
|
client.write_request::<_, _, Value>(
|
|
|
|
"textDocument/documentHighlight",
|
|
|
|
msg.params,
|
|
|
|
)?;
|
2021-02-25 00:14:17 -05:00
|
|
|
}
|
|
|
|
FixtureType::Hover => {
|
2021-05-17 16:45:13 -04:00
|
|
|
client
|
|
|
|
.write_request::<_, _, Value>("textDocument/hover", msg.params)?;
|
2021-02-25 00:14:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let (_, response_error): (Option<Value>, Option<LspResponseError>) =
|
|
|
|
client.write_request("shutdown", json!(null))?;
|
|
|
|
assert!(response_error.is_none());
|
|
|
|
|
|
|
|
client.write_notification("exit", json!(null))?;
|
|
|
|
|
|
|
|
Ok(client.duration())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A test that starts up the LSP, opens a single line document, and exits.
|
2021-03-25 14:17:37 -04:00
|
|
|
fn bench_startup_shutdown(deno_exe: &Path) -> Result<Duration, AnyError> {
|
2021-02-25 00:14:17 -05:00
|
|
|
let mut client = LspClient::new(deno_exe)?;
|
|
|
|
|
|
|
|
let params: Value = serde_json::from_slice(FIXTURE_INIT_JSON)?;
|
|
|
|
let (_, response_error): (Option<Value>, Option<LspResponseError>) =
|
|
|
|
client.write_request("initialize", params)?;
|
|
|
|
assert!(response_error.is_none());
|
|
|
|
|
|
|
|
client.write_notification("initialized", json!({}))?;
|
|
|
|
|
|
|
|
client.write_notification(
|
|
|
|
"textDocument/didOpen",
|
|
|
|
json!({
|
|
|
|
"textDocument": {
|
|
|
|
"uri": "file:///a/file.ts",
|
|
|
|
"languageId": "typescript",
|
|
|
|
"version": 1,
|
|
|
|
"text": "console.log(Deno.args);\n"
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
)?;
|
|
|
|
|
2021-05-11 23:10:06 -04:00
|
|
|
// TODO(@kitsonk) work around https://github.com/denoland/deno/issues/10603
|
|
|
|
// let (id, method, _): (u64, String, Option<Value>) = client.read_request()?;
|
|
|
|
// assert_eq!(method, "workspace/configuration");
|
2021-05-09 21:16:04 -04:00
|
|
|
|
2021-05-11 23:10:06 -04:00
|
|
|
// client.write_response(
|
|
|
|
// id,
|
|
|
|
// json!({
|
|
|
|
// "enable": true
|
|
|
|
// }),
|
|
|
|
// )?;
|
2021-05-09 21:16:04 -04:00
|
|
|
|
2021-05-07 07:05:32 -04:00
|
|
|
let (method, _): (String, Option<Value>) = client.read_notification()?;
|
|
|
|
assert_eq!(method, "textDocument/publishDiagnostics");
|
|
|
|
let (method, _): (String, Option<Value>) = client.read_notification()?;
|
|
|
|
assert_eq!(method, "textDocument/publishDiagnostics");
|
2021-02-25 00:14:17 -05:00
|
|
|
let (method, _): (String, Option<Value>) = client.read_notification()?;
|
|
|
|
assert_eq!(method, "textDocument/publishDiagnostics");
|
|
|
|
|
|
|
|
let (_, response_error): (Option<Value>, Option<LspResponseError>) =
|
|
|
|
client.write_request("shutdown", json!(null))?;
|
|
|
|
assert!(response_error.is_none());
|
|
|
|
|
|
|
|
client.write_notification("exit", json!(null))?;
|
|
|
|
|
|
|
|
Ok(client.duration())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Generate benchmarks for the LSP server.
|
|
|
|
pub(crate) fn benchmarks(
|
2021-03-25 14:17:37 -04:00
|
|
|
deno_exe: &Path,
|
2021-02-25 00:14:17 -05:00
|
|
|
) -> Result<HashMap<String, u64>, AnyError> {
|
|
|
|
println!("-> Start benchmarking lsp");
|
|
|
|
let mut exec_times = HashMap::new();
|
|
|
|
|
|
|
|
println!(" - Simple Startup/Shutdown ");
|
|
|
|
let mut times = Vec::new();
|
|
|
|
for _ in 0..10 {
|
|
|
|
times.push(bench_startup_shutdown(deno_exe)?);
|
|
|
|
}
|
|
|
|
let mean =
|
|
|
|
(times.iter().sum::<Duration>() / times.len() as u32).as_millis() as u64;
|
|
|
|
println!(" ({} runs, mean: {}ms)", times.len(), mean);
|
|
|
|
exec_times.insert("startup_shutdown".to_string(), mean);
|
|
|
|
|
|
|
|
println!(" - Big Document/Several Edits ");
|
|
|
|
let mut times = Vec::new();
|
|
|
|
for _ in 0..5 {
|
|
|
|
times.push(bench_big_file_edits(deno_exe)?);
|
|
|
|
}
|
|
|
|
let mean =
|
|
|
|
(times.iter().sum::<Duration>() / times.len() as u32).as_millis() as u64;
|
|
|
|
println!(" ({} runs, mean: {}ms)", times.len(), mean);
|
|
|
|
exec_times.insert("big_file_edits".to_string(), mean);
|
|
|
|
|
|
|
|
println!("<- End benchmarking lsp");
|
|
|
|
|
|
|
|
Ok(exec_times)
|
|
|
|
}
|