2025-01-01 04:12:39 +09:00
|
|
|
// Copyright 2018-2025 the Deno authors. MIT license.
|
2024-02-12 17:13:14 -07:00
|
|
|
|
2023-05-22 13:35:59 -06:00
|
|
|
use std::io::BufRead;
|
|
|
|
use std::io::BufReader;
|
|
|
|
use std::time::Duration;
|
|
|
|
use std::time::Instant;
|
2024-12-31 12:13:39 -05:00
|
|
|
|
2023-01-13 02:59:13 +01:00
|
|
|
use test_util as util;
|
|
|
|
|
2023-05-22 13:35:59 -06:00
|
|
|
util::unit_test_factory!(
|
|
|
|
js_unit_test,
|
2024-02-09 13:33:05 -07:00
|
|
|
"../tests/unit",
|
2023-05-22 13:35:59 -06:00
|
|
|
"*.ts",
|
|
|
|
[
|
|
|
|
abort_controller_test,
|
|
|
|
blob_test,
|
|
|
|
body_test,
|
|
|
|
broadcast_channel_test,
|
|
|
|
build_test,
|
|
|
|
cache_api_test,
|
|
|
|
chmod_test,
|
|
|
|
chown_test,
|
|
|
|
command_test,
|
|
|
|
console_test,
|
|
|
|
copy_file_test,
|
|
|
|
custom_event_test,
|
2023-11-01 11:57:55 -07:00
|
|
|
cron_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
dir_test,
|
|
|
|
dom_exception_test,
|
|
|
|
error_stack_test,
|
|
|
|
error_test,
|
|
|
|
esnext_test,
|
2024-03-25 22:31:13 +08:00
|
|
|
event_source_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
event_target_test,
|
|
|
|
event_test,
|
|
|
|
fetch_test,
|
|
|
|
ffi_test,
|
|
|
|
file_test,
|
|
|
|
filereader_test,
|
|
|
|
files_test,
|
|
|
|
fs_events_test,
|
|
|
|
get_random_values_test,
|
|
|
|
globals_test,
|
|
|
|
headers_test,
|
|
|
|
http_test,
|
2024-01-22 12:08:01 +01:00
|
|
|
image_bitmap_test,
|
2023-12-06 22:20:28 +09:00
|
|
|
image_data_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
internals_test,
|
|
|
|
intl_test,
|
2023-09-27 02:21:06 +02:00
|
|
|
jupyter_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
kv_test,
|
2023-08-29 11:24:44 -07:00
|
|
|
kv_queue_test_no_db_close,
|
2023-12-05 23:46:47 +05:30
|
|
|
kv_queue_test,
|
2023-06-13 17:49:57 -07:00
|
|
|
kv_queue_undelivered_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
link_test,
|
2024-12-23 08:45:47 +01:00
|
|
|
lint_selectors_test,
|
2024-12-21 00:58:03 +01:00
|
|
|
lint_plugin_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
make_temp_test,
|
|
|
|
message_channel_test,
|
|
|
|
mkdir_test,
|
|
|
|
navigator_test,
|
|
|
|
net_test,
|
|
|
|
network_interfaces_test,
|
|
|
|
os_test,
|
2024-01-31 22:39:56 +01:00
|
|
|
ops_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
path_from_url_test,
|
|
|
|
performance_test,
|
|
|
|
permissions_test,
|
|
|
|
process_test,
|
|
|
|
progressevent_test,
|
|
|
|
promise_hooks_test,
|
2024-12-20 13:48:48 +01:00
|
|
|
quic_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
read_dir_test,
|
|
|
|
read_file_test,
|
|
|
|
read_link_test,
|
|
|
|
read_text_file_test,
|
|
|
|
real_path_test,
|
|
|
|
ref_unref_test,
|
|
|
|
remove_test,
|
|
|
|
rename_test,
|
|
|
|
request_test,
|
|
|
|
response_test,
|
|
|
|
serve_test,
|
|
|
|
signal_test,
|
|
|
|
stat_test,
|
|
|
|
stdio_test,
|
feat(ext/web): resourceForReadableStream (#20180)
Extracted from fast streams work.
This is a resource wrapper for `ReadableStream`, allowing us to treat
all `ReadableStream` instances as resources, and remove special paths in
both `fetch` and `serve`.
Performance with a ReadableStream response yields ~18% improvement:
```
return new Response(new ReadableStream({
start(controller) {
controller.enqueue(new Uint8Array([104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]));
controller.close();
}
})
```
This patch:
```
12:36 $ third_party/prebuilt/mac/wrk http://localhost:8080
Running 10s test @ http://localhost:8080
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 99.96us 100.03us 6.65ms 98.84%
Req/Sec 47.73k 2.43k 51.02k 89.11%
959308 requests in 10.10s, 117.10MB read
Requests/sec: 94978.71
Transfer/sec: 11.59MB
```
main:
```
Running 10s test @ http://localhost:8080
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 163.03us 685.51us 19.73ms 99.27%
Req/Sec 39.50k 3.98k 66.11k 95.52%
789582 requests in 10.10s, 82.83MB read
Requests/sec: 78182.65
Transfer/sec: 8.20MB
```
2023-08-17 07:52:37 -06:00
|
|
|
streams_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
structured_clone_test,
|
2024-02-06 14:57:25 +01:00
|
|
|
symbol_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
symlink_test,
|
|
|
|
test_util,
|
|
|
|
testing_test,
|
|
|
|
text_encoding_test,
|
|
|
|
timers_test,
|
|
|
|
tls_test,
|
refactor(ext/tls): Implement required functionality for later SNI support (#23686)
Precursor to #23236
This implements the SNI features, but uses private symbols to avoid
exposing the functionality at this time. Note that to properly test this
feature, we need to add a way for `connectTls` to specify a hostname.
This is something that should be pushed into that API at a later time as
well.
```ts
Deno.test(
{ permissions: { net: true, read: true } },
async function listenResolver() {
let sniRequests = [];
const listener = Deno.listenTls({
hostname: "localhost",
port: 0,
[resolverSymbol]: (sni: string) => {
sniRequests.push(sni);
return {
cert,
key,
};
},
});
{
const conn = await Deno.connectTls({
hostname: "localhost",
[serverNameSymbol]: "server-1",
port: listener.addr.port,
});
const [_handshake, serverConn] = await Promise.all([
conn.handshake(),
listener.accept(),
]);
conn.close();
serverConn.close();
}
{
const conn = await Deno.connectTls({
hostname: "localhost",
[serverNameSymbol]: "server-2",
port: listener.addr.port,
});
const [_handshake, serverConn] = await Promise.all([
conn.handshake(),
listener.accept(),
]);
conn.close();
serverConn.close();
}
assertEquals(sniRequests, ["server-1", "server-2"]);
listener.close();
},
);
```
---------
Signed-off-by: Matt Mastracci <matthew@mastracci.com>
2024-05-09 10:54:47 -06:00
|
|
|
tls_sni_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
truncate_test,
|
|
|
|
tty_color_test,
|
|
|
|
tty_test,
|
|
|
|
umask_test,
|
|
|
|
url_search_params_test,
|
|
|
|
url_test,
|
|
|
|
urlpattern_test,
|
|
|
|
utime_test,
|
|
|
|
version_test,
|
|
|
|
wasm_test,
|
|
|
|
webcrypto_test,
|
2023-12-09 01:19:16 +01:00
|
|
|
webgpu_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
websocket_test,
|
|
|
|
webstorage_test,
|
|
|
|
worker_permissions_test,
|
2024-02-08 13:09:47 -07:00
|
|
|
worker_test,
|
2023-05-22 13:35:59 -06:00
|
|
|
write_file_test,
|
|
|
|
write_text_file_test,
|
|
|
|
]
|
|
|
|
);
|
2023-01-13 02:59:13 +01:00
|
|
|
|
2023-05-22 13:35:59 -06:00
|
|
|
fn js_unit_test(test: String) {
|
2023-01-13 02:59:13 +01:00
|
|
|
let _g = util::http_server();
|
|
|
|
|
2024-09-04 13:21:02 +01:00
|
|
|
let mut deno = util::deno_cmd()
|
2023-01-13 02:59:13 +01:00
|
|
|
.current_dir(util::root_path())
|
|
|
|
.arg("test")
|
2024-02-07 09:51:28 -07:00
|
|
|
.arg("--config")
|
2024-02-12 13:46:50 -07:00
|
|
|
.arg(util::deno_config_path())
|
2024-02-07 09:51:28 -07:00
|
|
|
.arg("--no-lock")
|
2024-09-04 13:21:02 +01:00
|
|
|
// TODO(bartlomieju): would be better if we could apply this unstable
|
|
|
|
// flag to particular files, but there's many of them that rely on unstable
|
2024-09-12 10:46:48 +10:00
|
|
|
// net APIs (`reusePort` in `listen` and `listenTls`; `listenDatagram`)
|
2024-09-04 13:21:02 +01:00
|
|
|
.arg("--unstable-net")
|
2024-02-08 13:09:47 -07:00
|
|
|
.arg("--location=http://127.0.0.1:4545/")
|
2023-10-30 11:49:19 -06:00
|
|
|
.arg("--no-prompt");
|
|
|
|
|
2024-09-04 13:21:02 +01:00
|
|
|
if test == "broadcast_channel_test" {
|
|
|
|
deno = deno.arg("--unstable-broadcast-channel");
|
|
|
|
}
|
|
|
|
|
|
|
|
if test == "cron_test" {
|
|
|
|
deno = deno.arg("--unstable-cron");
|
|
|
|
}
|
|
|
|
|
|
|
|
if test.contains("kv_") {
|
|
|
|
deno = deno.arg("--unstable-kv");
|
|
|
|
}
|
|
|
|
|
|
|
|
if test == "worker_permissions_test" || test == "worker_test" {
|
|
|
|
deno = deno.arg("--unstable-worker-options");
|
|
|
|
}
|
|
|
|
|
2024-09-27 16:07:20 +02:00
|
|
|
// Some tests require the root CA cert file to be loaded.
|
|
|
|
if test == "websocket_test" {
|
|
|
|
deno = deno.arg(format!(
|
|
|
|
"--cert={}",
|
|
|
|
util::testdata_path()
|
|
|
|
.join("tls")
|
|
|
|
.join("RootCA.pem")
|
|
|
|
.to_string_lossy()
|
|
|
|
));
|
|
|
|
};
|
|
|
|
|
|
|
|
if test == "tls_sni_test" {
|
|
|
|
// TODO(lucacasonato): fix the SNI in the certs so that this is not needed
|
2024-09-04 13:21:02 +01:00
|
|
|
deno = deno.arg("--unsafely-ignore-certificate-errors");
|
|
|
|
}
|
2023-10-30 11:49:19 -06:00
|
|
|
|
|
|
|
let mut deno = deno
|
2023-01-13 02:59:13 +01:00
|
|
|
.arg("-A")
|
feat(lint): add JavaScript plugin support (#27203)
This commit adds an unstable lint plugin API.
Plugins are specified in the `deno.json` file under
`lint.plugins` option like so:
```
{
"lint": {
"plugins": [
"./plugins/my-plugin.ts",
"jsr:@deno/lint-plugin1",
"npm:@deno/lint-plugin2"
]
}
}
```
The API is considered unstable and might be subject
to changes in the future.
Plugin API was modelled after ESLint API for the
most part, but there are no guarantees for compatibility.
The AST format exposed to plugins is closely modelled
after the AST that `typescript-eslint` uses.
Lint plugins use the visitor pattern and can add
diagnostics like so:
```
export default {
name: "lint-plugin",
rules: {
"plugin-rule": {
create(context) {
return {
Identifier(node) {
if (node.name === "a") {
context.report({
node,
message: "should be b",
fix(fixer) {
return fixer.replaceText(node, "_b");
},
});
}
},
};
},
},
},
} satisfies Deno.lint.Plugin;
```
Besides reporting errors (diagnostics) plugins can provide
automatic fixes that use text replacement to apply changes.
---------
Co-authored-by: Marvin Hagemeister <marvin@deno.com>
Co-authored-by: David Sherret <dsherret@gmail.com>
2025-02-05 16:59:24 +01:00
|
|
|
.arg(util::tests_path().join("unit").join(format!("{test}.ts")));
|
|
|
|
|
|
|
|
// update the snapshots if when `UPDATE=1`
|
|
|
|
if std::env::var_os("UPDATE") == Some("1".into()) {
|
|
|
|
deno = deno.arg("--").arg("--update");
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut deno = deno.piped_output().spawn().expect("failed to spawn script");
|
2023-01-13 02:59:13 +01:00
|
|
|
|
2023-05-22 13:35:59 -06:00
|
|
|
let now = Instant::now();
|
|
|
|
let stdout = deno.stdout.take().unwrap();
|
|
|
|
let test_name = test.clone();
|
|
|
|
let stdout = std::thread::spawn(move || {
|
|
|
|
let reader = BufReader::new(stdout);
|
|
|
|
for line in reader.lines() {
|
|
|
|
if let Ok(line) = line {
|
|
|
|
println!("[{test_name} {:0>6.2}] {line}", now.elapsed().as_secs_f32());
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
let now = Instant::now();
|
|
|
|
let stderr = deno.stderr.take().unwrap();
|
|
|
|
let test_name = test.clone();
|
|
|
|
let stderr = std::thread::spawn(move || {
|
|
|
|
let reader = BufReader::new(stderr);
|
|
|
|
for line in reader.lines() {
|
|
|
|
if let Ok(line) = line {
|
|
|
|
eprintln!("[{test_name} {:0>6.2}] {line}", now.elapsed().as_secs_f32());
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-01-02 16:56:52 +01:00
|
|
|
const PER_TEST_TIMEOUT: Duration = Duration::from_secs(3 * 60);
|
2023-05-22 13:35:59 -06:00
|
|
|
|
|
|
|
let now = Instant::now();
|
|
|
|
let status = loop {
|
|
|
|
if now.elapsed() > PER_TEST_TIMEOUT {
|
|
|
|
// Last-ditch kill
|
|
|
|
_ = deno.kill();
|
|
|
|
panic!("Test {test} failed to complete in time");
|
|
|
|
}
|
|
|
|
if let Some(status) = deno
|
|
|
|
.try_wait()
|
|
|
|
.expect("failed to wait for the child process")
|
|
|
|
{
|
|
|
|
break status;
|
|
|
|
}
|
|
|
|
std::thread::sleep(Duration::from_millis(100));
|
|
|
|
};
|
|
|
|
|
2023-03-22 12:00:07 -06:00
|
|
|
#[cfg(unix)]
|
|
|
|
assert_eq!(
|
|
|
|
std::os::unix::process::ExitStatusExt::signal(&status),
|
|
|
|
None,
|
|
|
|
"Deno should not have died with a signal"
|
|
|
|
);
|
|
|
|
assert_eq!(Some(0), status.code(), "Deno should have exited cleanly");
|
2023-05-22 13:35:59 -06:00
|
|
|
|
|
|
|
stdout.join().unwrap();
|
|
|
|
stderr.join().unwrap();
|
|
|
|
|
2023-01-13 02:59:13 +01:00
|
|
|
assert!(status.success());
|
|
|
|
}
|