diff options
author | Bert Belder <bertbelder@gmail.com> | 2020-05-24 22:28:19 +0200 |
---|---|---|
committer | Bert Belder <bertbelder@gmail.com> | 2020-05-25 04:26:33 +0200 |
commit | 131f2a5f0cdcdbebe3e17c447869f92c99a7c051 (patch) | |
tree | 3c16600a1e649e9e29bc269ff1504fb2b57e825b /cli/tests/integration_tests.rs | |
parent | ee0b5bb89ec33acc5dafb876de1f9fda5bcfa236 (diff) |
fix: BorrowMutError when evaluating expression in inspector console (#5822)
Note that this does not fix the 'Uncaught ReferenceError' issue that
happens when 'eager evaluation' is enabled in the inspector.
Fixes: #5807
Diffstat (limited to 'cli/tests/integration_tests.rs')
-rw-r--r-- | cli/tests/integration_tests.rs | 137 |
1 files changed, 120 insertions, 17 deletions
diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 983011d64..a9d3ebd6c 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -2215,11 +2215,9 @@ fn inspect_flag_with_unique_port(flag_prefix: &str) -> String { } fn extract_ws_url_from_stderr( - stderr: &mut std::process::ChildStderr, + stderr_lines: &mut impl std::iter::Iterator<Item = String>, ) -> url::Url { - let mut stderr = std::io::BufReader::new(stderr); - let mut stderr_first_line = String::from(""); - let _ = stderr.read_line(&mut stderr_first_line).unwrap(); + let stderr_first_line = stderr_lines.next().unwrap(); assert!(stderr_first_line.starts_with("Debugger listening on ")); let v: Vec<_> = stderr_first_line.match_indices("ws:").collect(); assert_eq!(v.len(), 1); @@ -2238,8 +2236,12 @@ async fn inspector_connect() { .stderr(std::process::Stdio::piped()) .spawn() .unwrap(); - let ws_url = extract_ws_url_from_stderr(child.stderr.as_mut().unwrap()); - println!("ws_url {}", ws_url); + + let stderr = child.stderr.as_mut().unwrap(); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + let ws_url = extract_ws_url_from_stderr(&mut stderr_lines); + // We use tokio_tungstenite as a websocket client because warp (which is // a dependency of Deno) uses it. let (_socket, response) = tokio_tungstenite::connect_async(ws_url) @@ -2252,6 +2254,7 @@ async fn inspector_connect() { enum TestStep { StdOut(&'static str), + StdErr(&'static str), WsRecv(&'static str), WsSend(&'static str), } @@ -2269,7 +2272,10 @@ async fn inspector_break_on_first_line() { .unwrap(); let stderr = child.stderr.as_mut().unwrap(); - let ws_url = extract_ws_url_from_stderr(stderr); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + let ws_url = extract_ws_url_from_stderr(&mut stderr_lines); + let (socket, response) = tokio_tungstenite::connect_async(ws_url) .await .expect("Can't connect"); @@ -2313,6 +2319,7 @@ async fn inspector_break_on_first_line() { StdOut(s) => assert_eq!(&stdout_lines.next().unwrap(), s), WsRecv(s) => assert!(socket_rx.next().await.unwrap().starts_with(s)), WsSend(s) => socket_tx.send(s.into()).await.unwrap(), + _ => unreachable!(), } } @@ -2330,7 +2337,12 @@ async fn inspector_pause() { .stderr(std::process::Stdio::piped()) .spawn() .unwrap(); - let ws_url = extract_ws_url_from_stderr(child.stderr.as_mut().unwrap()); + + let stderr = child.stderr.as_mut().unwrap(); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + let ws_url = extract_ws_url_from_stderr(&mut stderr_lines); + // We use tokio_tungstenite as a websocket client because warp (which is // a dependency of Deno) uses it. let (mut socket, _) = tokio_tungstenite::connect_async(ws_url) @@ -2386,8 +2398,12 @@ async fn inspector_port_collision() { .stderr(std::process::Stdio::piped()) .spawn() .unwrap(); - let ws_url_1 = extract_ws_url_from_stderr(child1.stderr.as_mut().unwrap()); - println!("ws_url {}", ws_url_1); + + let stderr_1 = child1.stderr.as_mut().unwrap(); + let mut stderr_lines_1 = std::io::BufReader::new(stderr_1) + .lines() + .map(|r| r.unwrap()); + let _ = extract_ws_url_from_stderr(&mut stderr_lines_1); let mut child2 = util::deno_cmd() .arg("run") @@ -2426,7 +2442,10 @@ async fn inspector_does_not_hang() { .unwrap(); let stderr = child.stderr.as_mut().unwrap(); - let ws_url = extract_ws_url_from_stderr(stderr); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + let ws_url = extract_ws_url_from_stderr(&mut stderr_lines); + let (socket, response) = tokio_tungstenite::connect_async(ws_url) .await .expect("Can't connect"); @@ -2505,16 +2524,100 @@ async fn inspector_without_brk_runs_code() { .stderr(std::process::Stdio::piped()) .spawn() .unwrap(); - extract_ws_url_from_stderr(child.stderr.as_mut().unwrap()); + + let stderr = child.stderr.as_mut().unwrap(); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + let _ = extract_ws_url_from_stderr(&mut stderr_lines); // Check that inspector actually runs code without waiting for inspector - // connection - let mut stdout = std::io::BufReader::new(child.stdout.as_mut().unwrap()); - let mut stdout_first_line = String::from(""); - let _ = stdout.read_line(&mut stdout_first_line).unwrap(); - assert_eq!(stdout_first_line, "hello\n"); + // connection. + let stdout = child.stdout.as_mut().unwrap(); + let mut stdout_lines = + std::io::BufReader::new(stdout).lines().map(|r| r.unwrap()); + let stdout_first_line = stdout_lines.next().unwrap(); + assert_eq!(stdout_first_line, "hello"); child.kill().unwrap(); + child.wait().unwrap(); +} + +#[tokio::test] +async fn inspector_runtime_evaluate_does_not_crash() { + let mut child = util::deno_cmd() + .arg("repl") + .arg(inspect_flag_with_unique_port("--inspect")) + .stdin(std::process::Stdio::piped()) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) + .spawn() + .unwrap(); + + let stderr = child.stderr.as_mut().unwrap(); + let mut stderr_lines = std::io::BufReader::new(stderr) + .lines() + .map(|r| r.unwrap()) + .filter(|s| s.as_str() != "Debugger session started."); + let ws_url = extract_ws_url_from_stderr(&mut stderr_lines); + + let (socket, response) = tokio_tungstenite::connect_async(ws_url) + .await + .expect("Can't connect"); + assert_eq!(response.status(), 101); // Switching protocols. + + let (mut socket_tx, socket_rx) = socket.split(); + let mut socket_rx = + socket_rx.map(|msg| msg.unwrap().to_string()).filter(|msg| { + let pass = !msg.starts_with(r#"{"method":"Debugger.scriptParsed","#); + futures::future::ready(pass) + }); + + let stdin = child.stdin.take().unwrap(); + + let stdout = child.stdout.as_mut().unwrap(); + let mut stdout_lines = std::io::BufReader::new(stdout) + .lines() + .map(|r| r.unwrap()) + .filter(|s| !s.starts_with("Deno ")); + + use TestStep::*; + let test_steps = vec![ + WsSend(r#"{"id":1,"method":"Runtime.enable"}"#), + WsSend(r#"{"id":2,"method":"Debugger.enable"}"#), + WsRecv( + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#, + ), + WsRecv(r#"{"id":1,"result":{}}"#), + WsRecv(r#"{"id":2,"result":{"debuggerId":"#), + WsSend(r#"{"id":3,"method":"Runtime.runIfWaitingForDebugger"}"#), + WsRecv(r#"{"id":3,"result":{}}"#), + StdOut("exit using ctrl+d or close()"), + WsSend( + r#"{"id":4,"method":"Runtime.compileScript","params":{"expression":"Deno.cwd()","sourceURL":"","persistScript":false,"executionContextId":1}}"#, + ), + WsRecv(r#"{"id":4,"result":{}}"#), + WsSend( + r#"{"id":5,"method":"Runtime.evaluate","params":{"expression":"Deno.cwd()","objectGroup":"console","includeCommandLineAPI":true,"silent":false,"contextId":1,"returnByValue":true,"generatePreview":true,"userGesture":true,"awaitPromise":false,"replMode":true}}"#, + ), + WsRecv(r#"{"id":5,"result":{"result":{"type":"string","value":""#), + WsSend( + r#"{"id":6,"method":"Runtime.evaluate","params":{"expression":"console.error('done');","objectGroup":"console","includeCommandLineAPI":true,"silent":false,"contextId":1,"returnByValue":true,"generatePreview":true,"userGesture":true,"awaitPromise":false,"replMode":true}}"#, + ), + WsRecv(r#"{"id":6,"result":{"result":{"type":"undefined"}}}"#), + StdErr("done"), + ]; + + for step in test_steps { + match step { + StdOut(s) => assert_eq!(&stdout_lines.next().unwrap(), s), + StdErr(s) => assert_eq!(&stderr_lines.next().unwrap(), s), + WsRecv(s) => assert!(socket_rx.next().await.unwrap().starts_with(s)), + WsSend(s) => socket_tx.send(s.into()).await.unwrap(), + } + } + + std::mem::drop(stdin); + child.wait().unwrap(); } #[test] |