summaryrefslogtreecommitdiff
path: root/cli/tools/test.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tools/test.rs')
-rw-r--r--cli/tools/test.rs71
1 files changed, 63 insertions, 8 deletions
diff --git a/cli/tools/test.rs b/cli/tools/test.rs
index d7817eb1a..5eb3552ec 100644
--- a/cli/tools/test.rs
+++ b/cli/tools/test.rs
@@ -22,7 +22,6 @@ use crate::graph_util::graph_valid;
use crate::located_script_name;
use crate::lockfile;
use crate::ops;
-use crate::ops::testing::create_stdout_stderr_pipes;
use crate::proc_state::ProcState;
use crate::resolver::ImportMapResolver;
use crate::resolver::JsxResolver;
@@ -41,6 +40,8 @@ use deno_core::serde_json::json;
use deno_core::url::Url;
use deno_core::ModuleSpecifier;
use deno_graph::ModuleKind;
+use deno_runtime::ops::io::Stdio;
+use deno_runtime::ops::io::StdioPipe;
use deno_runtime::permissions::Permissions;
use deno_runtime::tokio_util::run_basic;
use log::Level;
@@ -52,6 +53,7 @@ use serde::Deserialize;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::collections::HashSet;
+use std::io::Read;
use std::io::Write;
use std::num::NonZeroUsize;
use std::path::PathBuf;
@@ -588,17 +590,17 @@ async fn test_specifier(
channel: UnboundedSender<TestEvent>,
options: TestSpecifierOptions,
) -> Result<(), AnyError> {
- let (stdout_writer, stderr_writer) =
- create_stdout_stderr_pipes(channel.clone());
+ let (stdout, stderr) = create_stdout_stderr_pipes(channel.clone());
let mut worker = create_main_worker(
&ps,
specifier.clone(),
permissions,
- vec![ops::testing::init(
- channel.clone(),
- stdout_writer,
- stderr_writer,
- )],
+ vec![ops::testing::init(channel.clone())],
+ Stdio {
+ stdin: StdioPipe::Inherit,
+ stdout: StdioPipe::File(stdout),
+ stderr: StdioPipe::File(stderr),
+ },
);
let mut maybe_coverage_collector = if let Some(ref coverage_dir) =
@@ -1452,3 +1454,56 @@ pub async fn run_tests_with_watch(
Ok(())
}
+
+/// Creates the stdout and stderr pipes and returns the writers for stdout and stderr.
+pub fn create_stdout_stderr_pipes(
+ sender: UnboundedSender<TestEvent>,
+) -> (std::fs::File, std::fs::File) {
+ let (stdout_reader, stdout_writer) = os_pipe::pipe().unwrap();
+ let (stderr_reader, stderr_writer) = os_pipe::pipe().unwrap();
+
+ start_output_redirect_thread(stdout_reader, sender.clone());
+ start_output_redirect_thread(stderr_reader, sender);
+
+ (
+ pipe_writer_to_file(stdout_writer),
+ pipe_writer_to_file(stderr_writer),
+ )
+}
+
+#[cfg(windows)]
+fn pipe_writer_to_file(writer: os_pipe::PipeWriter) -> std::fs::File {
+ use std::os::windows::prelude::FromRawHandle;
+ use std::os::windows::prelude::IntoRawHandle;
+ // SAFETY: Requires consuming ownership of the provided handle
+ unsafe { std::fs::File::from_raw_handle(writer.into_raw_handle()) }
+}
+
+#[cfg(unix)]
+fn pipe_writer_to_file(writer: os_pipe::PipeWriter) -> std::fs::File {
+ use std::os::unix::io::FromRawFd;
+ use std::os::unix::io::IntoRawFd;
+ // SAFETY: Requires consuming ownership of the provided handle
+ unsafe { std::fs::File::from_raw_fd(writer.into_raw_fd()) }
+}
+
+fn start_output_redirect_thread(
+ mut pipe_reader: os_pipe::PipeReader,
+ sender: UnboundedSender<TestEvent>,
+) {
+ tokio::task::spawn_blocking(move || loop {
+ let mut buffer = [0; 512];
+ let size = match pipe_reader.read(&mut buffer) {
+ Ok(0) | Err(_) => break,
+ Ok(size) => size,
+ };
+ if sender
+ .send(TestEvent::Output(TestOutput::Bytes(
+ buffer[0..size].to_vec(),
+ )))
+ .is_err()
+ {
+ break;
+ }
+ });
+}