2024-01-01 14:58:21 -05:00
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2023-01-12 20:59:13 -05:00
2024-05-02 20:43:12 -04:00
use std ::io ::BufReader ;
use std ::io ::Cursor ;
use std ::io ::Read ;
use std ::io ::Write ;
use std ::process ::Command ;
use std ::process ::Stdio ;
use std ::sync ::Arc ;
2023-12-26 08:32:21 -05:00
use bytes ::Bytes ;
2023-08-06 12:25:48 -04:00
use deno_core ::serde_json ::json ;
2023-01-12 20:59:13 -05:00
use deno_core ::url ;
2024-07-17 19:37:31 -04:00
2024-05-02 20:43:12 -04:00
use deno_tls ::rustls ;
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 12:54:47 -04:00
use deno_tls ::rustls ::ClientConnection ;
2024-05-02 20:43:12 -04:00
use deno_tls ::rustls_pemfile ;
use deno_tls ::TlsStream ;
2024-11-06 18:49:32 -05:00
use hickory_client ::serialize ::txt ::Parser ;
2023-08-29 13:03:02 -04:00
use pretty_assertions ::assert_eq ;
2023-01-12 20:59:13 -05:00
use test_util as util ;
2024-02-12 19:13:14 -05:00
use test_util ::itest ;
2023-01-12 20:59:13 -05:00
use test_util ::TempDir ;
use util ::assert_contains ;
2023-06-06 17:07:46 -04:00
use util ::assert_not_contains ;
2023-06-10 11:09:45 -04:00
use util ::PathRef ;
2023-03-30 17:47:53 -04:00
use util ::TestContext ;
2023-03-03 17:27:05 -05:00
use util ::TestContextBuilder ;
2023-01-12 20:59:13 -05:00
2024-05-29 14:38:18 -04:00
const CODE_CACHE_DB_FILE_NAME : & str = " v8_code_cache_v2 " ;
2023-01-12 20:59:13 -05:00
// tests to ensure that when `--location` is set, all code shares the same
// localStorage cache based on the origin of the location URL.
#[ test ]
fn webstorage_location_shares_origin ( ) {
let deno_dir = util ::new_deno_dir ( ) ;
2023-11-17 10:05:42 -05:00
let output = util ::deno_cmd_with_deno_dir ( & deno_dir )
2023-01-12 20:59:13 -05:00
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " --location " )
. arg ( " https://example.com/a.ts " )
. arg ( " run/webstorage/fixture.ts " )
. stdout ( Stdio ::piped ( ) )
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( output . status . success ( ) ) ;
assert_eq! ( output . stdout , b " Storage { length: 0 } \n " ) ;
2023-11-17 10:05:42 -05:00
let output = util ::deno_cmd_with_deno_dir ( & deno_dir )
2023-01-12 20:59:13 -05:00
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " --location " )
. arg ( " https://example.com/b.ts " )
. arg ( " run/webstorage/logger.ts " )
. stdout ( Stdio ::piped ( ) )
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( output . status . success ( ) ) ;
2023-11-19 03:13:38 -05:00
assert_eq! ( output . stdout , b " Storage { hello: \" deno \" , length: 1 } \n " ) ;
2023-01-12 20:59:13 -05:00
}
// test to ensure that when a --config file is set, but no --location, that
// storage persists against unique configuration files.
#[ test ]
fn webstorage_config_file ( ) {
2023-11-17 10:05:42 -05:00
let context = TestContext ::default ( ) ;
2023-01-12 20:59:13 -05:00
2023-11-17 10:05:42 -05:00
context
. new_command ( )
. args (
" run --config run/webstorage/config_a.jsonc run/webstorage/fixture.ts " ,
)
. run ( )
. assert_matches_text ( " Storage { length: 0 } \n " ) ;
2023-01-12 20:59:13 -05:00
2023-11-17 10:05:42 -05:00
context
. new_command ( )
. args ( " run --config run/webstorage/config_b.jsonc run/webstorage/logger.ts " )
. run ( )
. assert_matches_text ( " Storage { length: 0 } \n " ) ;
2023-01-12 20:59:13 -05:00
2023-11-17 10:05:42 -05:00
context
. new_command ( )
. args ( " run --config run/webstorage/config_a.jsonc run/webstorage/logger.ts " )
. run ( )
2023-11-19 03:13:38 -05:00
. assert_matches_text ( " Storage { hello: \" deno \" , length: 1 } \n " ) ;
2023-01-12 20:59:13 -05:00
}
// tests to ensure `--config` does not effect persisted storage when a
// `--location` is provided.
#[ test ]
fn webstorage_location_precedes_config ( ) {
2023-11-17 10:05:42 -05:00
let context = TestContext ::default ( ) ;
2023-01-12 20:59:13 -05:00
2023-11-17 10:05:42 -05:00
context . new_command ( )
. args ( " run --location https://example.com/a.ts --config run/webstorage/config_a.jsonc run/webstorage/fixture.ts " )
. run ( )
. assert_matches_text ( " Storage { length: 0 } \n " ) ;
2023-01-12 20:59:13 -05:00
2023-11-17 10:05:42 -05:00
context . new_command ( )
. args ( " run --location https://example.com/b.ts --config run/webstorage/config_b.jsonc run/webstorage/logger.ts " )
. run ( )
2023-11-19 03:13:38 -05:00
. assert_matches_text ( " Storage { hello: \" deno \" , length: 1 } \n " ) ;
2023-01-12 20:59:13 -05:00
}
// test to ensure that when there isn't a configuration or location, that the
// main module is used to determine how to persist storage data.
#[ test ]
fn webstorage_main_module ( ) {
2023-11-17 10:05:42 -05:00
let context = TestContext ::default ( ) ;
2023-01-12 20:59:13 -05:00
2023-11-17 10:05:42 -05:00
context
. new_command ( )
. args ( " run run/webstorage/fixture.ts " )
. run ( )
. assert_matches_text ( " Storage { length: 0 } \n " ) ;
2023-01-12 20:59:13 -05:00
2023-11-17 10:05:42 -05:00
context
. new_command ( )
. args ( " run run/webstorage/logger.ts " )
. run ( )
. assert_matches_text ( " Storage { length: 0 } \n " ) ;
2023-01-12 20:59:13 -05:00
2023-11-17 10:05:42 -05:00
context
. new_command ( )
. args ( " run run/webstorage/fixture.ts " )
. run ( )
2023-11-19 03:13:38 -05:00
. assert_matches_text ( " Storage { hello: \" deno \" , length: 1 } \n " ) ;
2023-01-12 20:59:13 -05:00
}
#[ test ]
fn _083_legacy_external_source_map ( ) {
let _g = util ::http_server ( ) ;
let deno_dir = TempDir ::new ( ) ;
let module_url = url ::Url ::parse (
" http://localhost:4545/run/083_legacy_external_source_map.ts " ,
)
. unwrap ( ) ;
// Write a faulty old external source map.
let faulty_map_path = deno_dir . path ( ) . join ( " gen/http/localhost_PORT4545/9576bd5febd0587c5c4d88d57cb3ac8ebf2600c529142abe3baa9a751d20c334.js.map " ) ;
2023-06-10 11:09:45 -04:00
faulty_map_path . parent ( ) . create_dir_all ( ) ;
faulty_map_path . write ( r # "{\"version\":3,\"file\":\"\",\"sourceRoot\":\"\",\"sources\":[\"http://localhost:4545/083_legacy_external_source_map.ts\"],\"names\":[],\"mappings\":\";AAAA,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC\"}"# ) ;
2023-01-12 20:59:13 -05:00
let output = Command ::new ( util ::deno_exe_path ( ) )
. env ( " DENO_DIR " , deno_dir . path ( ) )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( module_url . to_string ( ) )
. output ( )
. unwrap ( ) ;
// Before https://github.com/denoland/deno/issues/6965 was fixed, the faulty
// old external source map would cause a panic while formatting the error
// and the exit code would be 101. The external source map should be ignored
// in favor of the inline one.
assert_eq! ( output . status . code ( ) , Some ( 1 ) ) ;
let out = std ::str ::from_utf8 ( & output . stdout ) . unwrap ( ) ;
assert_eq! ( out , " " ) ;
}
itest! ( _089_run_allow_list {
2024-09-10 07:28:59 -04:00
args : " run --allow-run=curl run/089_run_allow_list.ts " ,
2024-08-28 21:11:37 -04:00
envs : vec ! [
( " LD_LIBRARY_PATH " . to_string ( ) , " " . to_string ( ) ) ,
( " DYLD_FALLBACK_LIBRARY_PATH " . to_string ( ) , " " . to_string ( ) )
] ,
2023-01-12 20:59:13 -05:00
output : " run/089_run_allow_list.ts.out " ,
} ) ;
#[ test ]
fn _090_run_permissions_request ( ) {
2023-03-30 17:47:53 -04:00
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/090_run_permissions_request.ts " ] )
. with_pty ( | mut console | {
2023-03-28 17:49:00 -04:00
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests run access to \" ls \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-run \r \n " ,
" ┠─ Run again with --allow-run to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " y " ) ;
console . expect ( " Granted run access to \" ls \" . " ) ;
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests run access to \" cat \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-run \r \n " ,
" ┠─ Run again with --allow-run to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " n " ) ;
console . expect ( " Denied run access to \" cat \" . " ) ;
console . expect ( " granted " ) ;
console . expect ( " denied " ) ;
2023-03-30 17:47:53 -04:00
} ) ;
2023-01-12 20:59:13 -05:00
}
2023-01-24 18:42:44 -05:00
#[ test ]
fn _090_run_permissions_request_sync ( ) {
2023-03-30 17:47:53 -04:00
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/090_run_permissions_request_sync.ts " ] )
. with_pty ( | mut console | {
2023-03-28 17:49:00 -04:00
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests run access to \" ls \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-run \r \n " ,
" ┠─ Run again with --allow-run to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " y " ) ;
console . expect ( " Granted run access to \" ls \" . " ) ;
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests run access to \" cat \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-run \r \n " ,
" ┠─ Run again with --allow-run to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " n " ) ;
console . expect ( " Denied run access to \" cat \" . " ) ;
console . expect ( " granted " ) ;
console . expect ( " denied " ) ;
2023-03-30 17:47:53 -04:00
} ) ;
2023-01-24 18:42:44 -05:00
}
2023-02-22 17:02:10 -05:00
#[ test ]
fn permissions_prompt_allow_all ( ) {
2023-03-30 17:47:53 -04:00
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/permissions_prompt_allow_all.ts " ] )
. with_pty ( | mut console | {
2023-03-28 17:49:00 -04:00
// "run" permissions
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests run access to \" FOO \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-run \r \n " ,
" ┠─ Run again with --allow-run to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " A " ) ;
console . expect ( " ✅ Granted all run access. " ) ;
// "read" permissions
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests read access to \" FOO \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-read \r \n " ,
" ┠─ Run again with --allow-read to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " A " ) ;
console . expect ( " ✅ Granted all read access. " ) ;
// "write" permissions
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests write access to \" FOO \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-write \r \n " ,
" ┠─ Run again with --allow-write to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all write permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " A " ) ;
console . expect ( " ✅ Granted all write access. " ) ;
// "net" permissions
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests net access to \" foo \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-net \r \n " ,
" ┠─ Run again with --allow-net to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
console . write_line_raw ( " A " ) ;
2023-03-28 17:49:00 -04:00
console . expect ( " ✅ Granted all net access. " ) ;
// "env" permissions
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests env access to \" FOO \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-env \r \n " ,
" ┠─ Run again with --allow-env to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
console . write_line_raw ( " A " ) ;
2023-03-28 17:49:00 -04:00
console . expect ( " ✅ Granted all env access. " ) ;
// "sys" permissions
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests sys access to \" loadavg \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-sys \r \n " ,
" ┠─ Run again with --allow-sys to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
console . write_line_raw ( " A " ) ;
2023-03-28 17:49:00 -04:00
console . expect ( " ✅ Granted all sys access. " ) ;
// "ffi" permissions
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests ffi access to \" FOO \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-ffi \r \n " ,
" ┠─ Run again with --allow-ffi to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all ffi permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
console . write_line_raw ( " A " ) ;
2023-03-28 17:49:00 -04:00
console . expect ( " ✅ Granted all ffi access. " )
} ,
) ;
2023-02-22 17:02:10 -05:00
}
#[ test ]
fn permissions_prompt_allow_all_2 ( ) {
2023-03-30 17:47:53 -04:00
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/permissions_prompt_allow_all_2.ts " ] )
. with_pty ( | mut console | {
2023-03-28 17:49:00 -04:00
// "env" permissions
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests env access to \" FOO \" . \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-env \r \n " ,
" ┠─ Run again with --allow-env to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " A " ) ;
console . expect ( " ✅ Granted all env access. " ) ;
// "sys" permissions
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests sys access to \" loadavg \" . \r \n " ,
" ┠─ Requested by `Deno.loadavg()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-sys \r \n " ,
" ┠─ Run again with --allow-sys to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " A " ) ;
console . expect ( " ✅ Granted all sys access. " ) ;
// "read" permissions
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests read access to <CWD>. \r \n " ,
" ┠─ Requested by `Deno.cwd()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-read \r \n " ,
" ┠─ Run again with --allow-read to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " A " ) ;
console . expect ( " ✅ Granted all read access. " ) ;
2023-03-30 17:47:53 -04:00
} ) ;
2023-03-28 17:49:00 -04:00
}
#[ test ]
fn permissions_prompt_allow_all_lowercase_a ( ) {
2023-03-30 17:47:53 -04:00
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/permissions_prompt_allow_all.ts " ] )
. with_pty ( | mut console | {
2023-03-28 17:49:00 -04:00
// "run" permissions
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests run access to \" FOO \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-run \r \n " ,
" ┠─ Run again with --allow-run to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " a " ) ;
console . expect ( " Unrecognized option. " ) ;
2023-03-30 17:47:53 -04:00
} ) ;
2023-02-22 17:02:10 -05:00
}
2024-01-03 18:31:39 -05:00
#[ test ]
fn permission_request_long ( ) {
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/permission_request_long.ts " ] )
. with_pty ( | mut console | {
console . expect ( concat! (
2024-04-19 20:12:03 -04:00
" was larger than the configured maximum length (10240 bytes): denying request. \r \n " ,
2024-01-03 18:31:39 -05:00
" ❌ WARNING: This may indicate that code is trying to bypass or hide permission check requests. \r \n " ,
" ❌ Run again with --allow-read to bypass this check if this is really what you want to do. \r \n " ,
) ) ;
} ) ;
}
2023-08-03 07:19:19 -04:00
#[ test ]
fn permissions_cache ( ) {
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/permissions_cache.ts " ] )
. with_pty ( | mut console | {
console . expect ( concat! (
" prompt \r \n " ,
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests read access to \" foo \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-read \r \n " ,
" ┠─ Run again with --allow-read to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) " ,
2023-08-03 07:19:19 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-08-03 07:19:19 -04:00
console . write_line_raw ( " y " ) ;
console . expect ( " ✅ Granted read access to \" foo \" . " ) ;
console . expect ( " granted " ) ;
console . expect ( " prompt " ) ;
} ) ;
}
2023-11-01 11:21:13 -04:00
itest! ( env_file {
args : " run --env=env --allow-env run/env_file.ts " ,
output : " run/env_file.out " ,
} ) ;
itest! ( env_file_missing {
args : " run --env=missing --allow-env run/env_file.ts " ,
2024-01-21 18:27:14 -05:00
output : " run/env_file_missing.out " ,
2023-11-01 11:21:13 -04:00
} ) ;
2023-01-12 20:59:13 -05:00
itest! ( lock_write_fetch {
args :
2024-09-25 21:50:54 -04:00
" run --quiet --allow-import --allow-read --allow-write --allow-env --allow-run run/lock_write_fetch/main.ts " ,
2023-01-12 20:59:13 -05:00
output : " run/lock_write_fetch/main.out " ,
http_server : true ,
exit_code : 0 ,
} ) ;
2023-08-29 13:03:02 -04:00
#[ test ]
fn lock_redirects ( ) {
let context = TestContextBuilder ::new ( )
. use_temp_cwd ( )
. use_http_server ( )
. add_npm_env_vars ( )
. build ( ) ;
let temp_dir = context . temp_dir ( ) ;
temp_dir . write ( " deno.json " , " {} " ) ; // cause a lockfile to be created
temp_dir . write (
" main.ts " ,
" import 'http://localhost:4546/run/001_hello.js'; " ,
) ;
context
. new_command ( )
2024-09-25 21:50:54 -04:00
. args ( " run --allow-import main.ts " )
2023-08-29 13:03:02 -04:00
. run ( )
. skip_output_check ( ) ;
let initial_lockfile_text = r #" {
2024-08-26 19:01:50 -04:00
" version " : " 4 " ,
2023-08-29 13:03:02 -04:00
" redirects " : {
" http://localhost:4546/run/001_hello.js " : " http://localhost:4545/run/001_hello.js "
} ,
" remote " : {
" http://localhost:4545/run/001_hello.js " : " c479db5ea26965387423ca438bb977d0b4788d5901efcef52f69871e4c1048c5 "
}
}
" #;
assert_eq! ( temp_dir . read_to_string ( " deno.lock " ) , initial_lockfile_text ) ;
context
. new_command ( )
2024-09-25 21:50:54 -04:00
. args ( " run --allow-import main.ts " )
2023-08-29 13:03:02 -04:00
. run ( )
. assert_matches_text ( " Hello World \n " ) ;
assert_eq! ( temp_dir . read_to_string ( " deno.lock " ) , initial_lockfile_text ) ;
// now try changing where the redirect occurs in the lockfile
temp_dir . write ( " deno.lock " , r #" {
2024-08-26 19:01:50 -04:00
" version " : " 4 " ,
2023-08-29 13:03:02 -04:00
" redirects " : {
" http://localhost:4546/run/001_hello.js " : " http://localhost:4545/echo.ts "
} ,
" remote " : {
" http://localhost:4545/run/001_hello.js " : " c479db5ea26965387423ca438bb977d0b4788d5901efcef52f69871e4c1048c5 "
}
}
" #);
// also, add some npm dependency to ensure it doesn't end up in
// the redirects as they're currently stored separately
temp_dir . write (
" main.ts " ,
" import 'http://localhost:4546/run/001_hello.js'; \n import 'npm:@denotest/esm-basic'; \n " ,
) ;
// it should use the echo script instead
context
. new_command ( )
2024-09-25 21:50:54 -04:00
. args ( " run --allow-import main.ts Hi there " )
2023-08-29 13:03:02 -04:00
. run ( )
2024-05-06 21:06:01 -04:00
. assert_matches_text ( concat! (
" Download http://localhost:4545/echo.ts \n " ,
2024-10-18 14:38:57 -04:00
" Download http://localhost:4260/@denotest%2fesm-basic \n " ,
2024-05-07 13:21:56 -04:00
" Download http://localhost:4260/@denotest/esm-basic/1.0.0.tgz \n " ,
2024-05-06 21:06:01 -04:00
" Hi, there " ,
2023-08-29 13:03:02 -04:00
) ) ;
util ::assertions ::assert_wildcard_match (
& temp_dir . read_to_string ( " deno.lock " ) ,
r #" {
2024-08-26 19:01:50 -04:00
" version " : " 4 " ,
" specifiers " : {
2024-08-28 14:17:47 -04:00
" npm:@denotest/esm-basic@* " : " 1.0.0 "
2024-08-26 19:01:50 -04:00
} ,
" npm " : {
" @denotest/esm-basic@1.0.0 " : {
" integrity " : " sha512-[WILDCARD] "
2023-08-29 13:03:02 -04:00
}
2023-09-08 14:34:57 -04:00
} ,
" redirects " : {
" http://localhost:4546/run/001_hello.js " : " http://localhost:4545/echo.ts "
} ,
" remote " : {
" http://localhost:4545/echo.ts " : " 829eb4d67015a695d70b2a33c78b631b29eea1dbac491a6bfcf394af2a2671c2 " ,
" http://localhost:4545/run/001_hello.js " : " c479db5ea26965387423ca438bb977d0b4788d5901efcef52f69871e4c1048c5 "
2023-08-29 13:03:02 -04:00
}
}
" #,
) ;
}
2024-01-22 16:31:12 -05:00
#[ test ]
fn lock_deno_json_package_json_deps ( ) {
let context = TestContextBuilder ::new ( )
. use_temp_cwd ( )
. use_http_server ( )
. add_npm_env_vars ( )
. add_jsr_env_vars ( )
. build ( ) ;
let temp_dir = context . temp_dir ( ) . path ( ) ;
let deno_json = temp_dir . join ( " deno.json " ) ;
let package_json = temp_dir . join ( " package.json " ) ;
// add a jsr and npm dependency
deno_json . write_json ( & json! ( {
2024-10-04 15:55:03 -04:00
" nodeModulesDir " : " auto " ,
2024-01-22 16:31:12 -05:00
" imports " : {
" esm-basic " : " npm:@denotest/esm-basic " ,
2024-04-29 14:09:58 -04:00
" module_graph " : " jsr:@denotest/module-graph@1.4 " ,
2024-01-22 16:31:12 -05:00
}
} ) ) ;
let main_ts = temp_dir . join ( " main.ts " ) ;
main_ts . write ( " import 'esm-basic'; import 'module_graph'; " ) ;
context
. new_command ( )
. args ( " cache main.ts " )
. run ( )
. skip_output_check ( ) ;
let lockfile = temp_dir . join ( " deno.lock " ) ;
2024-01-30 09:26:30 -05:00
let esm_basic_integrity =
get_lockfile_npm_package_integrity ( & lockfile , " @denotest/esm-basic@1.0.0 " ) ;
2024-01-22 16:31:12 -05:00
lockfile . assert_matches_json ( json! ( {
2024-08-26 19:01:50 -04:00
" version " : " 4 " ,
" specifiers " : {
2024-08-28 14:17:47 -04:00
" jsr:@denotest/module-graph@1.4 " : " 1.4.0 " ,
" npm:@denotest/esm-basic@* " : " 1.0.0 "
2024-08-26 19:01:50 -04:00
} ,
" jsr " : {
" @denotest/module-graph@1.4.0 " : {
" integrity " : " 32de0973c5fa55772326fcd504a757f386d2b010db3e13e78f3bcf851e69473d "
}
} ,
" npm " : {
" @denotest/esm-basic@1.0.0 " : {
" integrity " : esm_basic_integrity
2024-01-22 16:31:12 -05:00
}
} ,
" workspace " : {
" dependencies " : [
2024-04-29 14:09:58 -04:00
" jsr:@denotest/module-graph@1.4 " ,
2024-08-28 14:17:47 -04:00
" npm:@denotest/esm-basic@* "
2024-01-22 16:31:12 -05:00
]
}
} ) ) ;
// now remove the npm dependency from the deno.json and move
// it to a package.json that uses an alias
deno_json . write_json ( & json! ( {
2024-10-04 15:55:03 -04:00
" nodeModulesDir " : " auto " ,
2024-01-22 16:31:12 -05:00
" imports " : {
2024-04-29 14:09:58 -04:00
" module_graph " : " jsr:@denotest/module-graph@1.4 " ,
2024-01-22 16:31:12 -05:00
}
} ) ) ;
package_json . write_json ( & json! ( {
" dependencies " : {
" esm-basic " : " npm:@denotest/esm-basic "
}
} ) ) ;
context
. new_command ( )
. args ( " cache main.ts " )
. run ( )
. skip_output_check ( ) ;
main_ts . write ( " import 'module_graph'; " ) ;
context
. new_command ( )
// ensure this doesn't clear out packageJson below
. args ( " cache --no-npm main.ts " )
. run ( )
. skip_output_check ( ) ;
lockfile . assert_matches_json ( json! ( {
2024-08-26 19:01:50 -04:00
" version " : " 4 " ,
" specifiers " : {
2024-08-28 14:17:47 -04:00
" jsr:@denotest/module-graph@1.4 " : " 1.4.0 " ,
" npm:@denotest/esm-basic@* " : " 1.0.0 "
2024-08-26 19:01:50 -04:00
} ,
" jsr " : {
" @denotest/module-graph@1.4.0 " : {
" integrity " : " 32de0973c5fa55772326fcd504a757f386d2b010db3e13e78f3bcf851e69473d "
}
} ,
" npm " : {
" @denotest/esm-basic@1.0.0 " : {
" integrity " : esm_basic_integrity
2024-01-22 16:31:12 -05:00
}
} ,
" workspace " : {
" dependencies " : [
2024-04-29 14:09:58 -04:00
" jsr:@denotest/module-graph@1.4 "
2024-01-22 16:31:12 -05:00
] ,
" packageJson " : {
" dependencies " : [
2024-08-28 14:17:47 -04:00
" npm:@denotest/esm-basic@* "
2024-01-22 16:31:12 -05:00
]
}
}
} ) ) ;
// now remove the package.json
package_json . remove_file ( ) ;
// cache and it will remove the package.json
context
. new_command ( )
. args ( " cache main.ts " )
. run ( )
. skip_output_check ( ) ;
lockfile . assert_matches_json ( json! ( {
2024-08-26 19:01:50 -04:00
" version " : " 4 " ,
" specifiers " : {
2024-08-28 14:17:47 -04:00
" jsr:@denotest/module-graph@1.4 " : " 1.4.0 " ,
2024-08-26 19:01:50 -04:00
} ,
" jsr " : {
" @denotest/module-graph@1.4.0 " : {
" integrity " : " 32de0973c5fa55772326fcd504a757f386d2b010db3e13e78f3bcf851e69473d "
2024-01-22 16:31:12 -05:00
}
} ,
" workspace " : {
" dependencies " : [
2024-04-29 14:09:58 -04:00
" jsr:@denotest/module-graph@1.4 "
2024-01-22 16:31:12 -05:00
]
}
} ) ) ;
// now remove the deps from the deno.json
2024-10-04 15:55:03 -04:00
deno_json . write_json ( & json! ( {
" nodeModulesDir " : " auto "
} ) ) ;
2024-01-22 16:31:12 -05:00
main_ts . write ( " " ) ;
context
. new_command ( )
. args ( " cache main.ts " )
. run ( )
. skip_output_check ( ) ;
lockfile . assert_matches_json ( json! ( {
2024-08-26 19:01:50 -04:00
" version " : " 4 "
2024-01-22 16:31:12 -05:00
} ) ) ;
}
2024-01-30 09:26:30 -05:00
#[ test ]
fn lock_deno_json_package_json_deps_workspace ( ) {
let context = TestContextBuilder ::new ( )
. use_temp_cwd ( )
. use_http_server ( )
. add_npm_env_vars ( )
. add_jsr_env_vars ( )
. build ( ) ;
let temp_dir = context . temp_dir ( ) . path ( ) ;
// deno.json
let deno_json = temp_dir . join ( " deno.json " ) ;
2024-07-03 20:54:33 -04:00
deno_json . write_json ( & json! ( {
2024-08-30 17:58:24 -04:00
" nodeModulesDir " : " auto "
2024-07-03 20:54:33 -04:00
} ) ) ;
2024-01-30 09:26:30 -05:00
// package.json
let package_json = temp_dir . join ( " package.json " ) ;
package_json . write_json ( & json! ( {
" workspaces " : [ " package-a " ] ,
" dependencies " : {
" @denotest/cjs-default-export " : " 1 "
}
} ) ) ;
// main.ts
let main_ts = temp_dir . join ( " main.ts " ) ;
main_ts . write ( " import '@denotest/cjs-default-export'; " ) ;
// package-a/package.json
let a_package = temp_dir . join ( " package-a " ) ;
a_package . create_dir_all ( ) ;
let a_package_json = a_package . join ( " package.json " ) ;
a_package_json . write_json ( & json! ( {
" dependencies " : {
" @denotest/esm-basic " : " 1 "
}
} ) ) ;
// package-a/main.ts
let main_ts = a_package . join ( " main.ts " ) ;
main_ts . write ( " import '@denotest/esm-basic'; " ) ;
context
. new_command ( )
. args ( " run package-a/main.ts " )
. run ( )
. skip_output_check ( ) ;
let lockfile = temp_dir . join ( " deno.lock " ) ;
let esm_basic_integrity =
get_lockfile_npm_package_integrity ( & lockfile , " @denotest/esm-basic@1.0.0 " ) ;
2024-07-03 20:54:33 -04:00
let cjs_default_export_integrity = get_lockfile_npm_package_integrity (
& lockfile ,
" @denotest/cjs-default-export@1.0.0 " ,
) ;
2024-01-30 09:26:30 -05:00
lockfile . assert_matches_json ( json! ( {
2024-08-26 19:01:50 -04:00
" version " : " 4 " ,
" specifiers " : {
2024-08-28 14:17:47 -04:00
" npm:@denotest/cjs-default-export@1 " : " 1.0.0 " ,
" npm:@denotest/esm-basic@1 " : " 1.0.0 "
2024-08-26 19:01:50 -04:00
} ,
" npm " : {
" @denotest/cjs-default-export@1.0.0 " : {
" integrity " : cjs_default_export_integrity
2024-01-30 09:26:30 -05:00
} ,
2024-08-26 19:01:50 -04:00
" @denotest/esm-basic@1.0.0 " : {
" integrity " : esm_basic_integrity
2024-01-30 09:26:30 -05:00
}
} ,
2024-07-03 20:54:33 -04:00
" workspace " : {
" packageJson " : {
" dependencies " : [
" npm:@denotest/cjs-default-export@1 "
]
} ,
" members " : {
" package-a " : {
" packageJson " : {
" dependencies " : [
" npm:@denotest/esm-basic@1 "
]
}
}
}
}
2024-01-30 09:26:30 -05:00
} ) ) ;
// run a command that causes discovery of the root package.json beside the lockfile
context
. new_command ( )
. args ( " run main.ts " )
. run ( )
. skip_output_check ( ) ;
// now we should see the dependencies
let cjs_default_export_integrity = get_lockfile_npm_package_integrity (
& lockfile ,
" @denotest/cjs-default-export@1.0.0 " ,
) ;
let expected_lockfile = json! ( {
2024-08-26 19:01:50 -04:00
" version " : " 4 " ,
" specifiers " : {
2024-08-28 14:17:47 -04:00
" npm:@denotest/cjs-default-export@1 " : " 1.0.0 " ,
" npm:@denotest/esm-basic@1 " : " 1.0.0 "
2024-08-26 19:01:50 -04:00
} ,
" npm " : {
" @denotest/cjs-default-export@1.0.0 " : {
" integrity " : cjs_default_export_integrity
2024-01-30 09:26:30 -05:00
} ,
2024-08-26 19:01:50 -04:00
" @denotest/esm-basic@1.0.0 " : {
" integrity " : esm_basic_integrity
2024-01-30 09:26:30 -05:00
}
} ,
" workspace " : {
" packageJson " : {
" dependencies " : [
" npm:@denotest/cjs-default-export@1 "
]
2024-07-03 20:54:33 -04:00
} ,
" members " : {
" package-a " : {
" packageJson " : {
" dependencies " : [
" npm:@denotest/esm-basic@1 "
]
}
}
2024-01-30 09:26:30 -05:00
}
}
} ) ;
lockfile . assert_matches_json ( expected_lockfile . clone ( ) ) ;
// now run the command again in the package with the nested package.json
context
. new_command ( )
. args ( " run package-a/main.ts " )
. run ( )
. skip_output_check ( ) ;
// the lockfile should stay the same as the above because the package.json
// was found in a different directory
lockfile . assert_matches_json ( expected_lockfile . clone ( ) ) ;
}
fn get_lockfile_npm_package_integrity (
lockfile : & PathRef ,
package_name : & str ,
) -> String {
// todo(dsherret): it would be nice if the test server didn't produce
// different hashes depending on what operating system it's running on
lockfile
. read_json_value ( )
. get ( " npm " )
. unwrap ( )
. get ( package_name )
. unwrap ( )
. get ( " integrity " )
. unwrap ( )
. as_str ( )
. unwrap ( )
. to_string ( )
}
2023-01-12 20:59:13 -05:00
itest! ( error_013_missing_script {
args : " run --reload missing_file_name " ,
exit_code : 1 ,
output : " run/error_013_missing_script.out " ,
} ) ;
2024-09-25 21:50:54 -04:00
// We have an allow-import flag but not allow-read, it should still result in error.
2023-01-12 20:59:13 -05:00
itest! ( error_016_dynamic_import_permissions2 {
2024-09-25 21:50:54 -04:00
args :
" run --reload --allow-import run/error_016_dynamic_import_permissions2.js " ,
2023-01-12 20:59:13 -05:00
output : " run/error_016_dynamic_import_permissions2.out " ,
exit_code : 1 ,
http_server : true ,
} ) ;
2024-11-05 01:39:05 -05:00
itest! ( error_026_remote_import_error {
args : " run --allow-import run/error_026_remote_import_error.ts " ,
output : " run/error_026_remote_import_error.ts.out " ,
2023-01-12 20:59:13 -05:00
exit_code : 1 ,
2024-11-05 01:39:05 -05:00
http_server : true ,
2023-01-12 20:59:13 -05:00
} ) ;
2024-11-05 01:39:05 -05:00
itest! ( error_local_static_import_from_remote_ts {
args : " run --allow-import --reload http://localhost:4545/run/error_local_static_import_from_remote.ts " ,
exit_code : 1 ,
http_server : true ,
output : " run/error_local_static_import_from_remote.ts.out " ,
2023-01-12 20:59:13 -05:00
} ) ;
2024-11-05 01:39:05 -05:00
itest! ( error_local_static_import_from_remote_js {
args : " run --allow-import --reload http://localhost:4545/run/error_local_static_import_from_remote.js " ,
2023-01-12 20:59:13 -05:00
exit_code : 1 ,
2024-11-05 01:39:05 -05:00
http_server : true ,
output : " run/error_local_static_import_from_remote.js.out " ,
2023-01-12 20:59:13 -05:00
} ) ;
2024-11-05 01:39:05 -05:00
itest! ( import_meta {
args : " run --allow-import --quiet --reload --import-map=run/import_meta/importmap.json run/import_meta/main.ts " ,
output : " run/import_meta/main.out " ,
http_server : true ,
2023-01-12 20:59:13 -05:00
} ) ;
2024-11-05 01:39:05 -05:00
itest! ( no_check_remote {
args : " run --allow-import --quiet --reload --no-check=remote run/no_check_remote.ts " ,
output : " run/no_check_remote.ts.enabled.out " ,
http_server : true ,
2023-01-12 20:59:13 -05:00
} ) ;
2024-11-05 01:39:05 -05:00
#[ test ]
fn type_directives_js_main ( ) {
let context = TestContext ::default ( ) ;
let output = context
. new_command ( )
. args ( " run --reload -L debug --check run/type_directives_js_main.js " )
. run ( ) ;
output . assert_matches_text ( " [WILDCARD] - FileFetcher::fetch_no_follow_with_options - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD] " ) ;
let output = context
. new_command ( )
. args ( " run --reload -L debug run/type_directives_js_main.js " )
. run ( ) ;
assert_not_contains! ( output . combined_output ( ) , " type_reference.d.ts " ) ;
}
2023-01-12 20:59:13 -05:00
2024-11-05 01:39:05 -05:00
itest! ( type_directives_redirect {
args : " run --allow-import --reload --check run/type_directives_redirect.ts " ,
output : " run/type_directives_redirect.ts.out " ,
http_server : true ,
2023-01-12 20:59:13 -05:00
} ) ;
2024-11-05 01:39:05 -05:00
itest! ( disallow_http_from_https_js {
args : " run --allow-import --quiet --reload --cert tls/RootCA.pem https://localhost:5545/run/disallow_http_from_https.js " ,
output : " run/disallow_http_from_https_js.out " ,
http_server : true ,
exit_code : 1 ,
2023-01-12 20:59:13 -05:00
} ) ;
2024-11-05 01:39:05 -05:00
itest! ( disallow_http_from_https_ts {
args : " run --allow-import --quiet --reload --cert tls/RootCA.pem https://localhost:5545/run/disallow_http_from_https.ts " ,
output : " run/disallow_http_from_https_ts.out " ,
http_server : true ,
exit_code : 1 ,
2023-01-12 20:59:13 -05:00
} ) ;
2024-11-05 01:39:05 -05:00
itest! ( jsx_import_source_import_map_scoped {
args : " run --allow-import --reload --import-map jsx/import-map-scoped.json --no-lock --config jsx/deno-jsx-import-map.jsonc subdir/jsx_import_source_no_pragma.tsx " ,
output : " run/jsx_import_source_import_map.out " ,
http_server : true ,
2023-01-12 20:59:13 -05:00
} ) ;
2024-11-05 01:39:05 -05:00
itest! ( jsx_import_source_import_map_scoped_dev {
args : " run --allow-import --reload --import-map jsx/import-map-scoped.json --no-lock --config jsx/deno-jsxdev-import-map.jsonc subdir/jsx_import_source_no_pragma.tsx " ,
output : " run/jsx_import_source_import_map_dev.out " ,
http_server : true ,
2023-01-12 20:59:13 -05:00
} ) ;
2024-11-05 01:39:05 -05:00
// FIXME(bartlomieju): disabled, because this test is very flaky on CI
// itest!(local_sources_not_cached_in_memory {
// args: "run --allow-read --allow-write run/no_mem_cache.js",
// output: "run/no_mem_cache.js.out",
// });
2023-01-12 20:59:13 -05:00
#[ test ]
fn no_validate_asm ( ) {
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " run/no_validate_asm.js " )
2023-11-17 10:05:42 -05:00
. piped_output ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( output . status . success ( ) ) ;
assert! ( output . stderr . is_empty ( ) ) ;
assert! ( output . stdout . is_empty ( ) ) ;
}
#[ test ]
fn exec_path ( ) {
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " --allow-read " )
. arg ( " run/exec_path.ts " )
. stdout ( Stdio ::piped ( ) )
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( output . status . success ( ) ) ;
let stdout_str = std ::str ::from_utf8 ( & output . stdout ) . unwrap ( ) . trim ( ) ;
2023-06-10 11:09:45 -04:00
let actual = PathRef ::new ( std ::path ::Path ::new ( stdout_str ) ) . canonicalize ( ) ;
let expected = util ::deno_exe_path ( ) . canonicalize ( ) ;
2023-01-12 20:59:13 -05:00
assert_eq! ( expected , actual ) ;
}
2023-03-23 12:45:43 -04:00
#[ test ]
fn run_from_stdin_defaults_to_ts ( ) {
let source_code = r #"
interface Lollipop {
_ : number ;
}
console . log ( " executing typescript " ) ;
" #;
let mut p = util ::deno_cmd ( )
. arg ( " run " )
. arg ( " --check " )
. arg ( " - " )
. stdin ( std ::process ::Stdio ::piped ( ) )
2023-11-17 10:05:42 -05:00
. stdout_piped ( )
2023-03-23 12:45:43 -04:00
. spawn ( )
. unwrap ( ) ;
let stdin = p . stdin . as_mut ( ) . unwrap ( ) ;
stdin . write_all ( source_code . as_bytes ( ) ) . unwrap ( ) ;
let result = p . wait_with_output ( ) . unwrap ( ) ;
assert! ( result . status . success ( ) ) ;
let stdout_str = std ::str ::from_utf8 ( & result . stdout ) . unwrap ( ) . trim ( ) ;
assert_eq! ( stdout_str , " executing typescript " ) ;
}
#[ test ]
fn run_from_stdin_ext ( ) {
let source_code = r #"
let i = 123 ;
i = " hello "
console . log ( " executing javascript " ) ;
" #;
let mut p = util ::deno_cmd ( )
2023-11-17 22:46:15 -05:00
. args ( " run --ext js --check - " )
2023-03-23 12:45:43 -04:00
. stdin ( std ::process ::Stdio ::piped ( ) )
2023-11-17 10:05:42 -05:00
. stdout_piped ( )
2023-03-23 12:45:43 -04:00
. spawn ( )
. unwrap ( ) ;
let stdin = p . stdin . as_mut ( ) . unwrap ( ) ;
stdin . write_all ( source_code . as_bytes ( ) ) . unwrap ( ) ;
let result = p . wait_with_output ( ) . unwrap ( ) ;
assert! ( result . status . success ( ) ) ;
let stdout_str = std ::str ::from_utf8 ( & result . stdout ) . unwrap ( ) . trim ( ) ;
assert_eq! ( stdout_str , " executing javascript " ) ;
}
2023-01-12 20:59:13 -05:00
#[ cfg(windows) ]
// Clippy suggests to remove the `NoStd` prefix from all variants. I disagree.
#[ allow(clippy::enum_variant_names) ]
enum WinProcConstraints {
NoStdIn ,
NoStdOut ,
NoStdErr ,
}
#[ cfg(windows) ]
fn run_deno_script_constrained (
2023-06-10 11:09:45 -04:00
script_path : test_util ::PathRef ,
2023-01-12 20:59:13 -05:00
constraints : WinProcConstraints ,
) -> Result < ( ) , i64 > {
let file_path = " assets/DenoWinRunner.ps1 " ;
let constraints = match constraints {
WinProcConstraints ::NoStdIn = > " 1 " ,
WinProcConstraints ::NoStdOut = > " 2 " ,
WinProcConstraints ::NoStdErr = > " 4 " ,
} ;
2023-06-10 11:09:45 -04:00
let deno_exe_path = util ::deno_exe_path ( ) . to_string ( ) ;
let deno_script_path = script_path . to_string ( ) ;
2023-01-12 20:59:13 -05:00
let args = vec! [ & deno_exe_path [ .. ] , & deno_script_path [ .. ] , constraints ] ;
util ::run_powershell_script_file ( file_path , args )
}
#[ cfg(windows) ]
#[ test ]
fn should_not_panic_on_no_stdin ( ) {
let output = run_deno_script_constrained (
util ::testdata_path ( ) . join ( " echo.ts " ) ,
WinProcConstraints ::NoStdIn ,
) ;
output . unwrap ( ) ;
}
#[ cfg(windows) ]
#[ test ]
fn should_not_panic_on_no_stdout ( ) {
let output = run_deno_script_constrained (
util ::testdata_path ( ) . join ( " echo.ts " ) ,
WinProcConstraints ::NoStdOut ,
) ;
output . unwrap ( ) ;
}
#[ cfg(windows) ]
#[ test ]
fn should_not_panic_on_no_stderr ( ) {
let output = run_deno_script_constrained (
util ::testdata_path ( ) . join ( " echo.ts " ) ,
WinProcConstraints ::NoStdErr ,
) ;
output . unwrap ( ) ;
}
#[ cfg(not(windows)) ]
#[ test ]
fn should_not_panic_on_undefined_home_environment_variable ( ) {
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " echo.ts " )
. env_remove ( " HOME " )
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( output . status . success ( ) ) ;
}
#[ test ]
fn should_not_panic_on_undefined_deno_dir_environment_variable ( ) {
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " echo.ts " )
. env_remove ( " DENO_DIR " )
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( output . status . success ( ) ) ;
}
#[ cfg(not(windows)) ]
#[ test ]
fn should_not_panic_on_undefined_deno_dir_and_home_environment_variables ( ) {
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " echo.ts " )
. env_remove ( " DENO_DIR " )
. env_remove ( " HOME " )
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( output . status . success ( ) ) ;
}
#[ test ]
2024-09-03 04:36:28 -04:00
fn deno_log ( ) {
// Without DENO_LOG the stderr is empty.
2023-01-12 20:59:13 -05:00
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " run/001_hello.js " )
2023-11-17 10:05:42 -05:00
. stderr_piped ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( output . status . success ( ) ) ;
assert! ( output . stderr . is_empty ( ) ) ;
2024-09-03 04:36:28 -04:00
// With DENO_LOG the stderr is not empty.
2023-01-12 20:59:13 -05:00
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " run/001_hello.js " )
2024-09-03 04:36:28 -04:00
. env ( " DENO_LOG " , " debug " )
2023-11-17 10:05:42 -05:00
. stderr_piped ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( output . status . success ( ) ) ;
assert! ( ! output . stderr . is_empty ( ) ) ;
}
#[ test ]
fn dont_cache_on_check_fail ( ) {
2023-11-17 10:05:42 -05:00
let context = TestContext ::default ( ) ;
let output = context
. new_command ( )
. args ( " run --check=all --reload run/error_003_typescript.ts " )
. split_output ( )
. run ( ) ;
assert! ( ! output . stderr ( ) . is_empty ( ) ) ;
output . skip_stdout_check ( ) ;
output . assert_exit_code ( 1 ) ;
2023-01-12 20:59:13 -05:00
2023-11-17 10:05:42 -05:00
let output = context
. new_command ( )
. args ( " run --check=all run/error_003_typescript.ts " )
. split_output ( )
. run ( ) ;
assert! ( ! output . stderr ( ) . is_empty ( ) ) ;
output . skip_stdout_check ( ) ;
output . assert_exit_code ( 1 ) ;
2023-01-12 20:59:13 -05:00
}
mod permissions {
use test_util as util ;
2023-03-30 17:47:53 -04:00
use util ::TestContext ;
2023-01-12 20:59:13 -05:00
#[ test ]
fn with_allow ( ) {
for permission in & util ::PERMISSION_VARIANTS {
let status = util ::deno_cmd ( )
2024-07-29 12:58:04 -04:00
. current_dir ( util ::testdata_path ( ) )
2023-01-12 20:59:13 -05:00
. arg ( " run " )
2023-01-27 10:43:16 -05:00
. arg ( format! ( " --allow- {permission} " ) )
2023-01-12 20:59:13 -05:00
. arg ( " run/permission_test.ts " )
2023-01-27 10:43:16 -05:00
. arg ( format! ( " {permission} Required " ) )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait ( )
. unwrap ( ) ;
assert! ( status . success ( ) ) ;
}
}
#[ test ]
fn without_allow ( ) {
for permission in & util ::PERMISSION_VARIANTS {
let ( _ , err ) = util ::run_and_collect_output (
false ,
2024-09-10 07:28:59 -04:00
& format! ( " run run/permission_test.ts {permission} Required " ) ,
2023-01-12 20:59:13 -05:00
None ,
None ,
false ,
) ;
assert! ( err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
}
#[ test ]
fn rw_inside_project_dir ( ) {
const PERMISSION_VARIANTS : [ & str ; 2 ] = [ " read " , " write " ] ;
for permission in & PERMISSION_VARIANTS {
let status = util ::deno_cmd ( )
2024-07-29 12:58:04 -04:00
. current_dir ( util ::testdata_path ( ) )
2023-01-12 20:59:13 -05:00
. arg ( " run " )
. arg ( format! (
" --allow-{0}={1} " ,
permission ,
util ::testdata_path ( )
) )
. arg ( " run/complex_permissions_test.ts " )
. arg ( permission )
. arg ( " run/complex_permissions_test.ts " )
. spawn ( )
. unwrap ( )
. wait ( )
. unwrap ( ) ;
assert! ( status . success ( ) ) ;
}
}
#[ test ]
fn rw_outside_test_dir ( ) {
const PERMISSION_VARIANTS : [ & str ; 2 ] = [ " read " , " write " ] ;
for permission in & PERMISSION_VARIANTS {
let ( _ , err ) = util ::run_and_collect_output (
false ,
& format! (
" run --allow-{0}={1} run/complex_permissions_test.ts {0} {2} " ,
permission ,
2023-06-10 11:09:45 -04:00
util ::testdata_path ( ) ,
util ::root_path ( ) . join ( " Cargo.toml " ) ,
2023-01-12 20:59:13 -05:00
) ,
None ,
None ,
false ,
) ;
assert! ( err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
}
#[ test ]
fn rw_inside_test_dir ( ) {
const PERMISSION_VARIANTS : [ & str ; 2 ] = [ " read " , " write " ] ;
for permission in & PERMISSION_VARIANTS {
let status = util ::deno_cmd ( )
2024-07-29 12:58:04 -04:00
. current_dir ( util ::testdata_path ( ) )
2023-01-12 20:59:13 -05:00
. arg ( " run " )
. arg ( format! (
" --allow-{0}={1} " ,
permission ,
2023-06-10 11:09:45 -04:00
util ::testdata_path ( ) ,
2023-01-12 20:59:13 -05:00
) )
. arg ( " run/complex_permissions_test.ts " )
. arg ( permission )
. arg ( " run/complex_permissions_test.ts " )
. spawn ( )
. unwrap ( )
. wait ( )
. unwrap ( ) ;
assert! ( status . success ( ) ) ;
}
}
#[ test ]
fn rw_outside_test_and_js_dir ( ) {
const PERMISSION_VARIANTS : [ & str ; 2 ] = [ " read " , " write " ] ;
2023-06-10 11:09:45 -04:00
let test_dir = util ::testdata_path ( ) ;
let js_dir = util ::root_path ( ) . join ( " js " ) ;
2023-01-12 20:59:13 -05:00
for permission in & PERMISSION_VARIANTS {
let ( _ , err ) = util ::run_and_collect_output (
false ,
& format! (
" run --allow-{0}={1},{2} run/complex_permissions_test.ts {0} {3} " ,
permission ,
test_dir ,
js_dir ,
2023-06-10 11:09:45 -04:00
util ::root_path ( ) . join ( " Cargo.toml " ) ,
2023-01-12 20:59:13 -05:00
) ,
None ,
None ,
false ,
) ;
assert! ( err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
}
#[ test ]
fn rw_inside_test_and_js_dir ( ) {
const PERMISSION_VARIANTS : [ & str ; 2 ] = [ " read " , " write " ] ;
2023-06-10 11:09:45 -04:00
let test_dir = util ::testdata_path ( ) ;
let js_dir = util ::root_path ( ) . join ( " js " ) ;
2023-01-12 20:59:13 -05:00
for permission in & PERMISSION_VARIANTS {
let status = util ::deno_cmd ( )
2024-07-29 12:58:04 -04:00
. current_dir ( util ::testdata_path ( ) )
2023-01-12 20:59:13 -05:00
. arg ( " run " )
2023-01-27 10:43:16 -05:00
. arg ( format! ( " --allow- {permission} = {test_dir} , {js_dir} " ) )
2023-01-12 20:59:13 -05:00
. arg ( " run/complex_permissions_test.ts " )
. arg ( permission )
. arg ( " run/complex_permissions_test.ts " )
. spawn ( )
. unwrap ( )
. wait ( )
. unwrap ( ) ;
assert! ( status . success ( ) ) ;
}
}
#[ test ]
fn rw_relative ( ) {
const PERMISSION_VARIANTS : [ & str ; 2 ] = [ " read " , " write " ] ;
for permission in & PERMISSION_VARIANTS {
let status = util ::deno_cmd ( )
2024-07-29 12:58:04 -04:00
. current_dir ( util ::testdata_path ( ) )
2023-01-12 20:59:13 -05:00
. arg ( " run " )
2023-01-27 10:43:16 -05:00
. arg ( format! ( " --allow- {permission} =. " ) )
2023-01-12 20:59:13 -05:00
. arg ( " run/complex_permissions_test.ts " )
. arg ( permission )
. arg ( " run/complex_permissions_test.ts " )
. spawn ( )
. unwrap ( )
. wait ( )
. unwrap ( ) ;
assert! ( status . success ( ) ) ;
}
}
#[ test ]
fn rw_no_prefix ( ) {
const PERMISSION_VARIANTS : [ & str ; 2 ] = [ " read " , " write " ] ;
for permission in & PERMISSION_VARIANTS {
let status = util ::deno_cmd ( )
2024-07-29 12:58:04 -04:00
. current_dir ( util ::testdata_path ( ) )
2023-01-12 20:59:13 -05:00
. arg ( " run " )
2023-01-27 10:43:16 -05:00
. arg ( format! ( " --allow- {permission} =tls/../ " ) )
2023-01-12 20:59:13 -05:00
. arg ( " run/complex_permissions_test.ts " )
. arg ( permission )
. arg ( " run/complex_permissions_test.ts " )
. spawn ( )
. unwrap ( )
. wait ( )
. unwrap ( ) ;
assert! ( status . success ( ) ) ;
}
}
#[ test ]
fn net_fetch_allow_localhost_4545 ( ) {
2024-05-07 13:21:56 -04:00
// ensure the http server is running for those tests so they run
// deterministically whether the http server is running or not
let _http_guard = util ::http_server ( ) ;
2023-01-12 20:59:13 -05:00
let ( _ , err ) = util ::run_and_collect_output (
true ,
" run --allow-net=localhost:4545 run/complex_permissions_test.ts netFetch http://localhost:4545/ " ,
None ,
None ,
true ,
) ;
assert! ( ! err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn net_fetch_allow_deno_land ( ) {
2024-05-07 13:21:56 -04:00
let _http_guard = util ::http_server ( ) ;
2023-01-12 20:59:13 -05:00
let ( _ , err ) = util ::run_and_collect_output (
false ,
" run --allow-net=deno.land run/complex_permissions_test.ts netFetch http://localhost:4545/ " ,
None ,
None ,
true ,
) ;
assert! ( err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn net_fetch_localhost_4545_fail ( ) {
2024-05-07 13:21:56 -04:00
let _http_guard = util ::http_server ( ) ;
2023-01-12 20:59:13 -05:00
let ( _ , err ) = util ::run_and_collect_output (
false ,
" run --allow-net=localhost:4545 run/complex_permissions_test.ts netFetch http://localhost:4546/ " ,
None ,
None ,
true ,
) ;
assert! ( err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn net_fetch_localhost ( ) {
2024-05-07 13:21:56 -04:00
let _http_guard = util ::http_server ( ) ;
2023-01-12 20:59:13 -05:00
let ( _ , err ) = util ::run_and_collect_output (
true ,
" run --allow-net=localhost run/complex_permissions_test.ts netFetch http://localhost:4545/ http://localhost:4546/ http://localhost:4547/ " ,
None ,
None ,
true ,
) ;
assert! ( ! err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn net_connect_allow_localhost_ip_4555 ( ) {
2024-05-07 13:21:56 -04:00
let _http_guard = util ::http_server ( ) ;
2023-01-12 20:59:13 -05:00
let ( _ , err ) = util ::run_and_collect_output (
true ,
" run --allow-net=127.0.0.1:4545 run/complex_permissions_test.ts netConnect 127.0.0.1:4545 " ,
None ,
None ,
true ,
) ;
assert! ( ! err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn net_connect_allow_deno_land ( ) {
2024-05-07 13:21:56 -04:00
let _http_guard = util ::http_server ( ) ;
2023-01-12 20:59:13 -05:00
let ( _ , err ) = util ::run_and_collect_output (
false ,
" run --allow-net=deno.land run/complex_permissions_test.ts netConnect 127.0.0.1:4546 " ,
None ,
None ,
true ,
) ;
assert! ( err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn net_connect_allow_localhost_ip_4545_fail ( ) {
2024-05-07 13:21:56 -04:00
let _http_guard = util ::http_server ( ) ;
2023-01-12 20:59:13 -05:00
let ( _ , err ) = util ::run_and_collect_output (
false ,
" run --allow-net=127.0.0.1:4545 run/complex_permissions_test.ts netConnect 127.0.0.1:4546 " ,
None ,
None ,
true ,
) ;
assert! ( err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn net_connect_allow_localhost_ip ( ) {
2024-05-07 13:21:56 -04:00
let _http_guard = util ::http_server ( ) ;
2023-01-12 20:59:13 -05:00
let ( _ , err ) = util ::run_and_collect_output (
true ,
" run --allow-net=127.0.0.1 run/complex_permissions_test.ts netConnect 127.0.0.1:4545 127.0.0.1:4546 127.0.0.1:4547 " ,
None ,
None ,
true ,
) ;
assert! ( ! err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn net_listen_allow_localhost_4555 ( ) {
2024-05-07 13:21:56 -04:00
let _http_guard = util ::http_server ( ) ;
2023-01-12 20:59:13 -05:00
let ( _ , err ) = util ::run_and_collect_output (
true ,
2024-05-07 13:21:56 -04:00
" run --allow-net=localhost:4588 run/complex_permissions_test.ts netListen localhost:4588 " ,
2023-01-12 20:59:13 -05:00
None ,
None ,
false ,
) ;
assert! ( ! err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn net_listen_allow_deno_land ( ) {
2024-05-07 13:21:56 -04:00
let _http_guard = util ::http_server ( ) ;
2023-01-12 20:59:13 -05:00
let ( _ , err ) = util ::run_and_collect_output (
false ,
" run --allow-net=deno.land run/complex_permissions_test.ts netListen localhost:4545 " ,
None ,
None ,
false ,
) ;
assert! ( err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn net_listen_allow_localhost_4555_fail ( ) {
2024-05-07 13:21:56 -04:00
let _http_guard = util ::http_server ( ) ;
2023-01-12 20:59:13 -05:00
let ( _ , err ) = util ::run_and_collect_output (
false ,
" run --allow-net=localhost:4555 run/complex_permissions_test.ts netListen localhost:4556 " ,
None ,
None ,
false ,
) ;
assert! ( err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn net_listen_allow_localhost ( ) {
2024-05-07 13:21:56 -04:00
let _http_guard = util ::http_server ( ) ;
2023-06-26 09:10:27 -04:00
// Port 4600 is chosen to not collide with those used by
2023-01-12 20:59:13 -05:00
// target/debug/test_server
let ( _ , err ) = util ::run_and_collect_output (
true ,
" run --allow-net=localhost run/complex_permissions_test.ts netListen localhost:4600 " ,
None ,
None ,
false ,
) ;
assert! ( ! err . contains ( util ::PERMISSION_DENIED_PATTERN ) ) ;
}
#[ test ]
fn _061_permissions_request ( ) {
2023-03-30 17:47:53 -04:00
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/061_permissions_request.ts " ] )
. with_pty ( | mut console | {
2023-03-28 17:49:00 -04:00
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests read access to \" foo \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-read \r \n " ,
" ┠─ Run again with --allow-read to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " y " ) ;
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests read access to \" bar \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-read \r \n " ,
" ┠─ Run again with --allow-read to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " n " ) ;
console . expect ( " granted " ) ;
console . expect ( " prompt " ) ;
console . expect ( " denied " ) ;
2023-03-30 17:47:53 -04:00
} ) ;
2023-01-12 20:59:13 -05:00
}
2023-01-24 18:42:44 -05:00
#[ test ]
fn _061_permissions_request_sync ( ) {
2023-03-30 17:47:53 -04:00
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/061_permissions_request_sync.ts " ] )
. with_pty ( | mut console | {
2023-03-28 17:49:00 -04:00
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests read access to \" foo \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-read \r \n " ,
" ┠─ Run again with --allow-read to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " y " ) ;
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests read access to \" bar \" . \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-read \r \n " ,
" ┠─ Run again with --allow-read to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " n " ) ;
console . expect ( " granted " ) ;
console . expect ( " prompt " ) ;
console . expect ( " denied " ) ;
2023-03-30 17:47:53 -04:00
} ) ;
2023-01-24 18:42:44 -05:00
}
2023-01-12 20:59:13 -05:00
#[ test ]
fn _062_permissions_request_global ( ) {
2023-03-30 17:47:53 -04:00
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/062_permissions_request_global.ts " ] )
. with_pty ( | mut console | {
2023-03-28 17:49:00 -04:00
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests read access. \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-read \r \n " ,
" ┠─ Run again with --allow-read to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " y \n " ) ;
console
. expect ( " PermissionStatus { state: \" granted \" , onchange: null } " ) ;
console
. expect ( " PermissionStatus { state: \" granted \" , onchange: null } " ) ;
console
. expect ( " PermissionStatus { state: \" granted \" , onchange: null } " ) ;
2023-03-30 17:47:53 -04:00
} ) ;
2023-01-12 20:59:13 -05:00
}
2023-01-24 18:42:44 -05:00
#[ test ]
fn _062_permissions_request_global_sync ( ) {
2023-03-30 17:47:53 -04:00
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/062_permissions_request_global_sync.ts " ] )
. with_pty ( | mut console | {
2023-03-28 17:49:00 -04:00
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests read access. \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-read \r \n " ,
" ┠─ Run again with --allow-read to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) " ,
2023-03-28 17:49:00 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-28 17:49:00 -04:00
console . write_line_raw ( " y " ) ;
console
. expect ( " PermissionStatus { state: \" granted \" , onchange: null } " ) ;
console
. expect ( " PermissionStatus { state: \" granted \" , onchange: null } " ) ;
console
. expect ( " PermissionStatus { state: \" granted \" , onchange: null } " ) ;
2023-03-30 17:47:53 -04:00
} ) ;
2023-01-24 18:42:44 -05:00
}
2023-01-12 20:59:13 -05:00
#[ test ]
fn _066_prompt ( ) {
2023-03-30 17:47:53 -04:00
TestContext ::default ( )
. new_command ( )
2024-09-10 07:28:59 -04:00
. args_vec ( [ " run " , " --quiet " , " run/066_prompt.ts " ] )
2023-03-30 17:47:53 -04:00
. with_pty ( | mut console | {
2024-01-11 16:05:55 -05:00
console . expect ( " What is your name? Jane Doe " ) ;
2024-01-01 23:06:05 -05:00
console . write_line_raw ( " " ) ;
console . expect ( " Your name is Jane Doe. " ) ;
2024-01-11 16:05:55 -05:00
2023-03-28 17:49:00 -04:00
console . expect ( " Prompt " ) ;
2024-01-01 23:06:05 -05:00
console . write_line_raw ( " foo " ) ;
console . expect ( " Your input is foo. " ) ;
console . expect ( " Question 0 [y/N] " ) ;
console . write_line_raw ( " Y " ) ;
console . expect ( " Your answer is true " ) ;
console . expect ( " Question 1 [y/N] " ) ;
console . write_line_raw ( " N " ) ;
console . expect ( " Your answer is false " ) ;
console . expect ( " Question 2 [y/N] " ) ;
console . write_line_raw ( " yes " ) ;
console . expect ( " Your answer is false " ) ;
console . expect ( " Confirm [y/N] " ) ;
console . write_line ( " " ) ;
console . expect ( " Your answer is false " ) ;
console . expect ( " What is Windows EOL? " ) ;
console . write_line ( " windows " ) ;
console . expect ( " Your answer is \" windows \" " ) ;
console . expect ( " Hi [Enter] " ) ;
console . write_line ( " " ) ;
console . expect ( " Alert [Enter] " ) ;
console . write_line ( " " ) ;
console . expect ( " The end of test " ) ;
2023-03-30 17:47:53 -04:00
} ) ;
2023-01-12 20:59:13 -05:00
}
}
2024-05-29 12:53:04 -04:00
#[ test ]
#[ cfg(windows) ]
fn process_stdin_read_unblock ( ) {
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " run/process_stdin_unblock.mjs " ] )
. with_pty ( | mut console | {
console . write_raw ( " b " ) ;
console . human_delay ( ) ;
console . write_line_raw ( " s " ) ;
console . expect_all ( & [ " 1 " , " 1 " ] ) ;
} ) ;
}
2023-01-12 20:59:13 -05:00
#[ test ]
fn issue9750 ( ) {
2023-03-30 17:47:53 -04:00
TestContext ::default ( )
. new_command ( )
2024-01-23 11:40:49 -05:00
. args_vec ( [ " run " , " run/issue9750.js " ] )
2023-03-30 17:47:53 -04:00
. with_pty ( | mut console | {
console . expect ( " Enter 'yy': " ) ;
console . write_line_raw ( " yy " ) ;
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests env access. \r \n " ,
" ┠─ Requested by `Deno.permissions.request()` API. \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-env \r \n " ,
" ┠─ Run again with --allow-env to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions) " ,
2023-03-30 17:47:53 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-30 17:47:53 -04:00
console . write_line_raw ( " n " ) ;
console . expect ( " Denied env access. " ) ;
console . expect ( concat! (
2024-08-08 09:39:31 -04:00
" ┏ ⚠️ Deno requests env access to \" SECRET \" . \r \n " ,
" ┠─ Learn more at: https://docs.deno.com/go/--allow-env \r \n " ,
" ┠─ Run again with --allow-env to bypass this prompt. \r \n " ,
" ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions) " ,
2023-03-30 17:47:53 -04:00
) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-03-30 17:47:53 -04:00
console . write_line_raw ( " n " ) ;
console . expect_all ( & [
" Denied env access to \" SECRET \" . " ,
2024-09-10 14:12:24 -04:00
" NotCapable: Requires env access to \" SECRET \" , run again with the --allow-env flag " ,
2023-03-30 17:47:53 -04:00
] ) ;
} ) ;
2023-01-12 20:59:13 -05:00
}
#[ test ]
#[ cfg(unix) ]
fn navigator_language_unix ( ) {
let ( res , _ ) = util ::run_and_collect_output (
true ,
" run navigator_language.ts " ,
None ,
Some ( vec! [ ( " LC_ALL " . to_owned ( ) , " pl_PL " . to_owned ( ) ) ] ) ,
false ,
) ;
assert_eq! ( res , " pl-PL \n " )
}
#[ test ]
fn navigator_language ( ) {
let ( res , _ ) = util ::run_and_collect_output (
true ,
" run navigator_language.ts " ,
None ,
None ,
false ,
) ;
assert! ( ! res . is_empty ( ) )
}
#[ test ]
#[ cfg(unix) ]
fn navigator_languages_unix ( ) {
let ( res , _ ) = util ::run_and_collect_output (
true ,
" run navigator_languages.ts " ,
None ,
Some ( vec! [
( " LC_ALL " . to_owned ( ) , " pl_PL " . to_owned ( ) ) ,
( " NO_COLOR " . to_owned ( ) , " 1 " . to_owned ( ) ) ,
] ) ,
false ,
) ;
assert_eq! ( res , " [ \" pl-PL \" ] \n " )
}
#[ test ]
fn navigator_languages ( ) {
let ( res , _ ) = util ::run_and_collect_output (
true ,
" run navigator_languages.ts " ,
None ,
None ,
false ,
) ;
assert! ( ! res . is_empty ( ) )
}
/// Regression test for https://github.com/denoland/deno/issues/12740.
#[ test ]
fn issue12740 ( ) {
let mod_dir = TempDir ::new ( ) ;
let mod1_path = mod_dir . path ( ) . join ( " mod1.ts " ) ;
let mod2_path = mod_dir . path ( ) . join ( " mod2.ts " ) ;
2023-11-17 10:05:42 -05:00
mod1_path . write ( " " ) ;
let status = util ::deno_cmd ( )
2023-01-12 20:59:13 -05:00
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( & mod1_path )
. stderr ( Stdio ::null ( ) )
. stdout ( Stdio ::null ( ) )
. spawn ( )
. unwrap ( )
. wait ( )
. unwrap ( ) ;
assert! ( status . success ( ) ) ;
2023-11-17 10:05:42 -05:00
mod1_path . write ( " export { foo } from \" ./mod2.ts \" ; " ) ;
mod2_path . write ( " ( " ) ;
let status = util ::deno_cmd ( )
2023-01-12 20:59:13 -05:00
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( & mod1_path )
. stderr ( Stdio ::null ( ) )
. stdout ( Stdio ::null ( ) )
. spawn ( )
. unwrap ( )
. wait ( )
. unwrap ( ) ;
assert! ( ! status . success ( ) ) ;
}
/// Regression test for https://github.com/denoland/deno/issues/12807.
#[ test ]
fn issue12807 ( ) {
let mod_dir = TempDir ::new ( ) ;
let mod1_path = mod_dir . path ( ) . join ( " mod1.ts " ) ;
let mod2_path = mod_dir . path ( ) . join ( " mod2.ts " ) ;
// With a fresh `DENO_DIR`, run a module with a dependency and a type error.
2023-11-17 10:05:42 -05:00
mod1_path . write ( " import './mod2.ts'; Deno.exit('0'); " ) ;
mod2_path . write ( " console.log('Hello, world!'); " ) ;
let status = util ::deno_cmd ( )
2023-01-12 20:59:13 -05:00
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " --check " )
. arg ( & mod1_path )
. stderr ( Stdio ::null ( ) )
. stdout ( Stdio ::null ( ) )
. spawn ( )
. unwrap ( )
. wait ( )
. unwrap ( ) ;
assert! ( ! status . success ( ) ) ;
// Fix the type error and run again.
std ::fs ::write ( & mod1_path , " import './mod2.ts'; Deno.exit(0); " ) . unwrap ( ) ;
2023-11-17 10:05:42 -05:00
let status = util ::deno_cmd ( )
2023-01-12 20:59:13 -05:00
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " --check " )
. arg ( & mod1_path )
. stderr ( Stdio ::null ( ) )
. stdout ( Stdio ::null ( ) )
. spawn ( )
. unwrap ( )
. wait ( )
. unwrap ( ) ;
assert! ( status . success ( ) ) ;
}
2023-03-13 10:03:19 -04:00
#[ test ]
fn package_json_no_node_modules_dir_created ( ) {
// it should not create a node_modules directory
let context = TestContextBuilder ::new ( )
. add_npm_env_vars ( )
. use_temp_cwd ( )
. build ( ) ;
2023-03-15 10:34:23 -04:00
let temp_dir = context . temp_dir ( ) ;
2023-03-13 10:03:19 -04:00
temp_dir . write ( " deno.json " , " {} " ) ;
temp_dir . write ( " package.json " , " {} " ) ;
temp_dir . write ( " main.ts " , " " ) ;
context . new_command ( ) . args ( " run main.ts " ) . run ( ) ;
assert! ( ! temp_dir . path ( ) . join ( " node_modules " ) . exists ( ) ) ;
}
#[ test ]
fn node_modules_dir_no_npm_specifiers_no_dir_created ( ) {
// it should not create a node_modules directory
let context = TestContextBuilder ::new ( )
. add_npm_env_vars ( )
. use_temp_cwd ( )
. build ( ) ;
2023-03-15 10:34:23 -04:00
let temp_dir = context . temp_dir ( ) ;
2023-03-13 10:03:19 -04:00
temp_dir . write ( " deno.json " , " {} " ) ;
temp_dir . write ( " main.ts " , " " ) ;
context
. new_command ( )
. args ( " run --node-modules-dir main.ts " )
. run ( ) ;
assert! ( ! temp_dir . path ( ) . join ( " node_modules " ) . exists ( ) ) ;
}
2023-01-12 20:59:13 -05:00
#[ test ]
fn check_local_then_remote ( ) {
let _http_guard = util ::http_server ( ) ;
let deno_dir = util ::new_deno_dir ( ) ;
let output = util ::deno_cmd_with_deno_dir ( & deno_dir )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
2024-09-25 21:50:54 -04:00
. arg ( " --allow-import " )
2023-01-12 20:59:13 -05:00
. arg ( " --check " )
. arg ( " run/remote_type_error/main.ts " )
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( output . status . success ( ) ) ;
let output = util ::deno_cmd_with_deno_dir ( & deno_dir )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
2024-09-25 21:50:54 -04:00
. arg ( " --allow-import " )
2023-01-12 20:59:13 -05:00
. arg ( " --check=all " )
. arg ( " run/remote_type_error/main.ts " )
. env ( " NO_COLOR " , " 1 " )
2023-11-17 10:05:42 -05:00
. stderr_piped ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( ! output . status . success ( ) ) ;
let stderr = std ::str ::from_utf8 ( & output . stderr ) . unwrap ( ) ;
assert_contains! ( stderr , " Type 'string' is not assignable to type 'number'. " ) ;
}
2024-10-03 08:28:38 -04:00
#[ test ]
fn permission_request_with_no_prompt ( ) {
TestContext ::default ( )
. new_command ( )
. env ( " NO_COLOR " , " 1 " )
. args_vec ( [
" run " ,
" --quiet " ,
" --no-prompt " ,
" run/permission_request_no_prompt.ts " ,
] )
. with_pty ( | mut console | {
console . expect ( " PermissionStatus { state: \" denied \" , onchange: null } " ) ;
} ) ;
}
2023-01-12 20:59:13 -05:00
#[ test ]
fn deno_no_prompt_environment_variable ( ) {
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " run/no_prompt.ts " )
. env ( " DENO_NO_PROMPT " , " 1 " )
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( output . status . success ( ) ) ;
}
#[ test ]
fn running_declaration_files ( ) {
2023-11-17 10:05:42 -05:00
let context = TestContextBuilder ::new ( ) . use_temp_cwd ( ) . build ( ) ;
let temp_dir = context . temp_dir ( ) ;
2023-01-12 20:59:13 -05:00
let files = vec! [ " file.d.ts " , " file.d.cts " , " file.d.mts " ] ;
for file in files {
temp_dir . write ( file , " " ) ;
2023-11-17 10:05:42 -05:00
context
. new_command ( )
2024-11-01 12:27:00 -04:00
// todo(dsherret): investigate why --allow-read is required here
. args_vec ( [ " run " , " --allow-read " , file ] )
2023-11-17 10:05:42 -05:00
. run ( )
. skip_output_check ( )
. assert_exit_code ( 0 ) ;
2023-01-12 20:59:13 -05:00
}
}
2023-05-22 11:54:58 -04:00
#[ cfg(not(target_os = " windows " )) ]
2023-05-11 08:53:45 -04:00
itest! ( spawn_kill_permissions {
2024-01-23 09:33:07 -05:00
args : " run --quiet --allow-run=cat spawn_kill_permissions.ts " ,
2024-08-28 21:11:37 -04:00
envs : vec ! [
( " LD_LIBRARY_PATH " . to_string ( ) , " " . to_string ( ) ) ,
( " DYLD_FALLBACK_LIBRARY_PATH " . to_string ( ) , " " . to_string ( ) )
] ,
2023-05-11 08:53:45 -04:00
output_str : Some ( " " ) ,
} ) ;
2023-01-12 20:59:13 -05:00
#[ test ]
fn cache_test ( ) {
let _g = util ::http_server ( ) ;
let deno_dir = TempDir ::new ( ) ;
let module_url =
url ::Url ::parse ( " http://localhost:4545/run/006_url_imports.ts " ) . unwrap ( ) ;
let output = Command ::new ( util ::deno_exe_path ( ) )
. env ( " DENO_DIR " , deno_dir . path ( ) )
. current_dir ( util ::testdata_path ( ) )
. arg ( " cache " )
2024-09-25 21:50:54 -04:00
. arg ( " --allow-import=localhost:4545 " )
2023-01-12 20:59:13 -05:00
. arg ( " --check=all " )
. arg ( " -L " )
. arg ( " debug " )
. arg ( module_url . to_string ( ) )
. output ( )
. expect ( " Failed to spawn script " ) ;
assert! ( output . status . success ( ) ) ;
let prg = util ::deno_exe_path ( ) ;
let output = Command ::new ( prg )
. env ( " DENO_DIR " , deno_dir . path ( ) )
. env ( " HTTP_PROXY " , " http://nil " )
. env ( " NO_COLOR " , " 1 " )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
2024-09-25 21:50:54 -04:00
. arg ( " --allow-import=localhost:4545 " )
2023-01-12 20:59:13 -05:00
. arg ( module_url . to_string ( ) )
. output ( )
. expect ( " Failed to spawn script " ) ;
let str_output = std ::str ::from_utf8 ( & output . stdout ) . unwrap ( ) ;
let module_output_path =
util ::testdata_path ( ) . join ( " run/006_url_imports.ts.out " ) ;
let mut module_output = String ::new ( ) ;
let mut module_output_file = std ::fs ::File ::open ( module_output_path ) . unwrap ( ) ;
module_output_file
. read_to_string ( & mut module_output )
. unwrap ( ) ;
assert_eq! ( module_output , str_output ) ;
}
#[ test ]
fn cache_invalidation_test ( ) {
let deno_dir = TempDir ::new ( ) ;
let fixture_path = deno_dir . path ( ) . join ( " fixture.ts " ) ;
2023-06-10 11:09:45 -04:00
fixture_path . write ( " console.log( \" 42 \" ); " ) ;
2023-01-12 20:59:13 -05:00
let output = Command ::new ( util ::deno_exe_path ( ) )
. env ( " DENO_DIR " , deno_dir . path ( ) )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
2023-06-10 11:09:45 -04:00
. arg ( & fixture_path )
2023-01-12 20:59:13 -05:00
. output ( )
. expect ( " Failed to spawn script " ) ;
assert! ( output . status . success ( ) ) ;
let actual = std ::str ::from_utf8 ( & output . stdout ) . unwrap ( ) ;
assert_eq! ( actual , " 42 \n " ) ;
2023-06-10 11:09:45 -04:00
fixture_path . write ( " console.log( \" 43 \" ); " ) ;
2023-01-12 20:59:13 -05:00
let output = Command ::new ( util ::deno_exe_path ( ) )
. env ( " DENO_DIR " , deno_dir . path ( ) )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
2023-06-10 11:09:45 -04:00
. arg ( fixture_path )
2023-01-12 20:59:13 -05:00
. output ( )
. expect ( " Failed to spawn script " ) ;
assert! ( output . status . success ( ) ) ;
let actual = std ::str ::from_utf8 ( & output . stdout ) . unwrap ( ) ;
assert_eq! ( actual , " 43 \n " ) ;
}
#[ test ]
fn cache_invalidation_test_no_check ( ) {
let deno_dir = TempDir ::new ( ) ;
let fixture_path = deno_dir . path ( ) . join ( " fixture.ts " ) ;
2023-06-10 11:09:45 -04:00
fixture_path . write ( " console.log( \" 42 \" ); " ) ;
2023-01-12 20:59:13 -05:00
let output = Command ::new ( util ::deno_exe_path ( ) )
. env ( " DENO_DIR " , deno_dir . path ( ) )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " --no-check " )
2023-06-10 11:09:45 -04:00
. arg ( & fixture_path )
2023-01-12 20:59:13 -05:00
. output ( )
. expect ( " Failed to spawn script " ) ;
assert! ( output . status . success ( ) ) ;
let actual = std ::str ::from_utf8 ( & output . stdout ) . unwrap ( ) ;
assert_eq! ( actual , " 42 \n " ) ;
2023-06-10 11:09:45 -04:00
fixture_path . write ( " console.log( \" 43 \" ); " ) ;
2023-01-12 20:59:13 -05:00
let output = Command ::new ( util ::deno_exe_path ( ) )
. env ( " DENO_DIR " , deno_dir . path ( ) )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " --no-check " )
2023-06-10 11:09:45 -04:00
. arg ( fixture_path )
2023-01-12 20:59:13 -05:00
. output ( )
. expect ( " Failed to spawn script " ) ;
assert! ( output . status . success ( ) ) ;
let actual = std ::str ::from_utf8 ( & output . stdout ) . unwrap ( ) ;
assert_eq! ( actual , " 43 \n " ) ;
}
#[ test ]
fn ts_dependency_recompilation ( ) {
let t = TempDir ::new ( ) ;
let ats = t . path ( ) . join ( " a.ts " ) ;
std ::fs ::write (
& ats ,
"
import { foo } from \ " ./b.ts \" ;
function print ( str : string ) : void {
console . log ( str ) ;
}
print ( foo ) ; " ,
)
. unwrap ( ) ;
let bts = t . path ( ) . join ( " b.ts " ) ;
std ::fs ::write (
& bts ,
"
export const foo = \ " foo \" ; " ,
)
. unwrap ( ) ;
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. env ( " NO_COLOR " , " 1 " )
. arg ( " run " )
. arg ( " --check " )
. arg ( & ats )
. output ( )
. expect ( " failed to spawn script " ) ;
let stdout_output = std ::str ::from_utf8 ( & output . stdout ) . unwrap ( ) . trim ( ) ;
let stderr_output = std ::str ::from_utf8 ( & output . stderr ) . unwrap ( ) . trim ( ) ;
assert! ( stdout_output . ends_with ( " foo " ) ) ;
assert! ( stderr_output . starts_with ( " Check " ) ) ;
// Overwrite contents of b.ts and run again
std ::fs ::write (
& bts ,
"
export const foo = 5 ; " ,
)
. expect ( " error writing file " ) ;
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. env ( " NO_COLOR " , " 1 " )
. arg ( " run " )
. arg ( " --check " )
. arg ( & ats )
. output ( )
. expect ( " failed to spawn script " ) ;
let stdout_output = std ::str ::from_utf8 ( & output . stdout ) . unwrap ( ) . trim ( ) ;
let stderr_output = std ::str ::from_utf8 ( & output . stderr ) . unwrap ( ) . trim ( ) ;
// error: TS2345 [ERROR]: Argument of type '5' is not assignable to parameter of type 'string'.
assert! ( stderr_output . contains ( " TS2345 " ) ) ;
assert! ( ! output . status . success ( ) ) ;
assert! ( stdout_output . is_empty ( ) ) ;
}
#[ test ]
fn basic_auth_tokens ( ) {
let _g = util ::http_server ( ) ;
let output = util ::deno_cmd ( )
. current_dir ( util ::root_path ( ) )
. arg ( " run " )
2024-09-25 21:50:54 -04:00
. arg ( " --allow-import " )
2023-01-12 20:59:13 -05:00
. arg ( " http://127.0.0.1:4554/run/001_hello.js " )
2023-11-17 10:05:42 -05:00
. piped_output ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( ! output . status . success ( ) ) ;
let stdout_str = std ::str ::from_utf8 ( & output . stdout ) . unwrap ( ) . trim ( ) ;
assert! ( stdout_str . is_empty ( ) ) ;
let stderr_str = std ::str ::from_utf8 ( & output . stderr ) . unwrap ( ) . trim ( ) ;
2023-01-27 10:43:16 -05:00
eprintln! ( " {stderr_str} " ) ;
2023-01-12 20:59:13 -05:00
assert! ( stderr_str
. contains ( " Module not found \" http://127.0.0.1:4554/run/001_hello.js \" . " ) ) ;
let output = util ::deno_cmd ( )
. current_dir ( util ::root_path ( ) )
. arg ( " run " )
2024-09-25 21:50:54 -04:00
. arg ( " --allow-import " )
2023-01-12 20:59:13 -05:00
. arg ( " http://127.0.0.1:4554/run/001_hello.js " )
. env ( " DENO_AUTH_TOKENS " , " testuser123:testpassabc@127.0.0.1:4554 " )
2023-11-17 10:05:42 -05:00
. piped_output ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
let stderr_str = std ::str ::from_utf8 ( & output . stderr ) . unwrap ( ) . trim ( ) ;
2023-01-27 10:43:16 -05:00
eprintln! ( " {stderr_str} " ) ;
2023-01-12 20:59:13 -05:00
assert! ( output . status . success ( ) ) ;
let stdout_str = std ::str ::from_utf8 ( & output . stdout ) . unwrap ( ) . trim ( ) ;
assert_eq! ( util ::strip_ansi_codes ( stdout_str ) , " Hello World " ) ;
}
#[ tokio::test(flavor = " multi_thread " , worker_threads = 2) ]
async fn test_resolve_dns ( ) {
2024-11-06 18:49:32 -05:00
use hickory_server ::authority ::Catalog ;
use hickory_server ::authority ::ZoneType ;
use hickory_server ::proto ::rr ::Name ;
use hickory_server ::store ::in_memory ::InMemoryAuthority ;
use hickory_server ::ServerFuture ;
2023-01-12 20:59:13 -05:00
use std ::net ::SocketAddr ;
use std ::str ::FromStr ;
use std ::sync ::Arc ;
use std ::time ::Duration ;
use tokio ::net ::TcpListener ;
use tokio ::net ::UdpSocket ;
use tokio ::sync ::oneshot ;
const DNS_PORT : u16 = 4553 ;
// Setup DNS server for testing
async fn run_dns_server ( tx : oneshot ::Sender < ( ) > ) {
let zone_file = std ::fs ::read_to_string (
util ::testdata_path ( ) . join ( " run/resolve_dns.zone.in " ) ,
)
. unwrap ( ) ;
2024-11-06 18:49:32 -05:00
let records = Parser ::new (
& zone_file ,
None ,
Some ( Name ::from_str ( " example.com " ) . unwrap ( ) ) ,
)
. parse ( ) ;
2023-01-12 20:59:13 -05:00
if records . is_err ( ) {
panic! ( " failed to parse: {:?} " , records . err ( ) )
}
let ( origin , records ) = records . unwrap ( ) ;
let authority = Box ::new ( Arc ::new (
InMemoryAuthority ::new ( origin , records , ZoneType ::Primary , false )
. unwrap ( ) ,
) ) ;
let mut catalog : Catalog = Catalog ::new ( ) ;
catalog . upsert ( Name ::root ( ) . into ( ) , authority ) ;
let mut server_fut = ServerFuture ::new ( catalog ) ;
let socket_addr = SocketAddr ::from ( ( [ 127 , 0 , 0 , 1 ] , DNS_PORT ) ) ;
let tcp_listener = TcpListener ::bind ( socket_addr ) . await . unwrap ( ) ;
let udp_socket = UdpSocket ::bind ( socket_addr ) . await . unwrap ( ) ;
server_fut . register_socket ( udp_socket ) ;
server_fut . register_listener ( tcp_listener , Duration ::from_secs ( 2 ) ) ;
// Notifies that the DNS server is ready
tx . send ( ( ) ) . unwrap ( ) ;
server_fut . block_until_done ( ) . await . unwrap ( ) ;
}
let ( ready_tx , ready_rx ) = oneshot ::channel ( ) ;
let dns_server_fut = run_dns_server ( ready_tx ) ;
let handle = tokio ::spawn ( dns_server_fut ) ;
// Waits for the DNS server to be ready
ready_rx . await . unwrap ( ) ;
// Pass: `--allow-net`
{
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. env ( " NO_COLOR " , " 1 " )
. arg ( " run " )
. arg ( " --check " )
. arg ( " --allow-net " )
. arg ( " run/resolve_dns.ts " )
2023-11-17 10:05:42 -05:00
. piped_output ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
let err = String ::from_utf8_lossy ( & output . stderr ) ;
let out = String ::from_utf8_lossy ( & output . stdout ) ;
2023-01-27 10:43:16 -05:00
println! ( " {err} " ) ;
2023-01-12 20:59:13 -05:00
assert! ( output . status . success ( ) ) ;
assert! ( err . starts_with ( " Check file " ) ) ;
let expected = std ::fs ::read_to_string (
util ::testdata_path ( ) . join ( " run/resolve_dns.ts.out " ) ,
)
. unwrap ( ) ;
assert_eq! ( expected , out ) ;
}
// Pass: `--allow-net=127.0.0.1:4553`
{
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. env ( " NO_COLOR " , " 1 " )
. arg ( " run " )
. arg ( " --check " )
. arg ( " --allow-net=127.0.0.1:4553 " )
. arg ( " run/resolve_dns.ts " )
2023-11-17 10:05:42 -05:00
. piped_output ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
let err = String ::from_utf8_lossy ( & output . stderr ) ;
let out = String ::from_utf8_lossy ( & output . stdout ) ;
2023-02-15 11:30:54 -05:00
if ! output . status . success ( ) {
eprintln! ( " stderr: {err} " ) ;
}
2023-01-12 20:59:13 -05:00
assert! ( output . status . success ( ) ) ;
assert! ( err . starts_with ( " Check file " ) ) ;
let expected = std ::fs ::read_to_string (
util ::testdata_path ( ) . join ( " run/resolve_dns.ts.out " ) ,
)
. unwrap ( ) ;
assert_eq! ( expected , out ) ;
}
// Permission error: `--allow-net=deno.land`
{
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. env ( " NO_COLOR " , " 1 " )
. arg ( " run " )
. arg ( " --check " )
. arg ( " --allow-net=deno.land " )
. arg ( " run/resolve_dns.ts " )
2023-11-17 10:05:42 -05:00
. piped_output ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
let err = String ::from_utf8_lossy ( & output . stderr ) ;
let out = String ::from_utf8_lossy ( & output . stdout ) ;
assert! ( ! output . status . success ( ) ) ;
assert! ( err . starts_with ( " Check file " ) ) ;
2024-09-10 14:12:24 -04:00
assert! ( err . contains ( r # "error: Uncaught (in promise) NotCapable: Requires net access to "127.0.0.1:4553""# ) ) ;
2023-01-12 20:59:13 -05:00
assert! ( out . is_empty ( ) ) ;
}
// Permission error: no permission specified
{
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. env ( " NO_COLOR " , " 1 " )
. arg ( " run " )
. arg ( " --check " )
. arg ( " run/resolve_dns.ts " )
2023-11-17 10:05:42 -05:00
. piped_output ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
let err = String ::from_utf8_lossy ( & output . stderr ) ;
let out = String ::from_utf8_lossy ( & output . stdout ) ;
assert! ( ! output . status . success ( ) ) ;
assert! ( err . starts_with ( " Check file " ) ) ;
2024-09-10 14:12:24 -04:00
assert! ( err . contains ( r # "error: Uncaught (in promise) NotCapable: Requires net access to "127.0.0.1:4553""# ) ) ;
2023-01-12 20:59:13 -05:00
assert! ( out . is_empty ( ) ) ;
}
handle . abort ( ) ;
}
#[ tokio::test ]
async fn http2_request_url ( ) {
2023-05-14 17:40:01 -04:00
let mut child = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " --quiet " )
. arg ( " --allow-net " )
. arg ( " --allow-read " )
. arg ( " ./run/http2_request_url.ts " )
. arg ( " 4506 " )
2023-11-17 10:05:42 -05:00
. stdout_piped ( )
2023-05-14 17:40:01 -04:00
. spawn ( )
. unwrap ( ) ;
let stdout = child . stdout . as_mut ( ) . unwrap ( ) ;
let mut buffer = [ 0 ; 5 ] ;
let read = stdout . read ( & mut buffer ) . unwrap ( ) ;
assert_eq! ( read , 5 ) ;
let msg = std ::str ::from_utf8 ( & buffer ) . unwrap ( ) ;
assert_eq! ( msg , " READY " ) ;
let cert = reqwest ::Certificate ::from_pem ( include_bytes! (
" ../testdata/tls/RootCA.crt "
) )
. unwrap ( ) ;
2023-01-12 20:59:13 -05:00
2023-05-14 17:40:01 -04:00
let client = reqwest ::Client ::builder ( )
. add_root_certificate ( cert )
. http2_prior_knowledge ( )
. build ( )
. unwrap ( ) ;
2023-01-12 20:59:13 -05:00
2023-05-14 17:40:01 -04:00
let res = client . get ( " http://127.0.0.1:4506 " ) . send ( ) . await . unwrap ( ) ;
assert_eq! ( 200 , res . status ( ) ) ;
2023-01-12 20:59:13 -05:00
2023-05-14 17:40:01 -04:00
let body = res . text ( ) . await . unwrap ( ) ;
assert_eq! ( body , " http://127.0.0.1:4506/ " ) ;
2023-01-12 20:59:13 -05:00
2023-05-14 17:40:01 -04:00
child . kill ( ) . unwrap ( ) ;
child . wait ( ) . unwrap ( ) ;
2023-01-12 20:59:13 -05:00
}
#[ cfg(not(windows)) ]
#[ test ]
fn set_raw_should_not_panic_on_no_tty ( ) {
let output = util ::deno_cmd ( )
. arg ( " eval " )
. arg ( " Deno.stdin.setRaw(true) " )
// stdin set to piped so it certainly does not refer to TTY
. stdin ( std ::process ::Stdio ::piped ( ) )
// stderr is piped so we can capture output.
2023-11-17 10:05:42 -05:00
. stderr_piped ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( ! output . status . success ( ) ) ;
let stderr = std ::str ::from_utf8 ( & output . stderr ) . unwrap ( ) . trim ( ) ;
assert! ( stderr . contains ( " BadResource " ) ) ;
}
2024-02-18 09:27:44 -05:00
#[ cfg(not(windows)) ]
#[ test ]
fn fsfile_set_raw_should_not_panic_on_no_tty ( ) {
let output = util ::deno_cmd ( )
. arg ( " eval " )
. arg ( " Deno.openSync( \" /dev/stdin \" ).setRaw(true) " )
// stdin set to piped so it certainly does not refer to TTY
. stdin ( std ::process ::Stdio ::piped ( ) )
// stderr is piped so we can capture output.
. stderr_piped ( )
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( ! output . status . success ( ) ) ;
let stderr = std ::str ::from_utf8 ( & output . stderr ) . unwrap ( ) . trim ( ) ;
2024-04-19 20:12:03 -04:00
assert! (
stderr . contains ( " BadResource " ) ,
" stderr did not contain BadResource: {stderr} "
) ;
2024-02-18 09:27:44 -05:00
}
2023-01-12 20:59:13 -05:00
#[ test ]
fn timeout_clear ( ) {
// https://github.com/denoland/deno/issues/7599
use std ::time ::Duration ;
use std ::time ::Instant ;
let source_code = r #"
const handle = setTimeout ( ( ) = > {
console . log ( " timeout finish " ) ;
} , 10000 ) ;
clearTimeout ( handle ) ;
console . log ( " finish " ) ;
" #;
let mut p = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " - " )
. stdin ( std ::process ::Stdio ::piped ( ) )
. spawn ( )
. unwrap ( ) ;
let stdin = p . stdin . as_mut ( ) . unwrap ( ) ;
stdin . write_all ( source_code . as_bytes ( ) ) . unwrap ( ) ;
let start = Instant ::now ( ) ;
let status = p . wait ( ) . unwrap ( ) ;
let end = Instant ::now ( ) ;
assert! ( status . success ( ) ) ;
// check that program did not run for 10 seconds
// for timeout to clear
assert! ( end - start < Duration ::new ( 10 , 0 ) ) ;
}
#[ test ]
fn broken_stdout ( ) {
let ( reader , writer ) = os_pipe ::pipe ( ) . unwrap ( ) ;
// drop the reader to create a broken pipe
drop ( reader ) ;
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " eval " )
. arg ( " console.log(3.14) " )
. stdout ( writer )
2023-11-17 10:05:42 -05:00
. stderr_piped ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( ! output . status . success ( ) ) ;
let stderr = std ::str ::from_utf8 ( output . stderr . as_ref ( ) ) . unwrap ( ) . trim ( ) ;
2023-12-06 19:02:52 -05:00
assert! ( stderr . contains ( " Uncaught (in promise) BrokenPipe " ) ) ;
2023-01-12 20:59:13 -05:00
assert! ( ! stderr . contains ( " panic " ) ) ;
}
2024-08-19 20:21:12 -04:00
#[ test ]
fn broken_stdout_repl ( ) {
let ( reader , writer ) = os_pipe ::pipe ( ) . unwrap ( ) ;
// drop the reader to create a broken pipe
drop ( reader ) ;
let output = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " repl " )
. stdout ( writer )
. stderr_piped ( )
. spawn ( )
. unwrap ( )
. wait_with_output ( )
. unwrap ( ) ;
assert! ( ! output . status . success ( ) ) ;
let stderr = std ::str ::from_utf8 ( output . stderr . as_ref ( ) ) . unwrap ( ) . trim ( ) ;
if cfg! ( windows ) {
assert_contains! ( stderr , " The pipe is being closed. (os error 232) " ) ;
} else {
assert_contains! ( stderr , " Broken pipe (os error 32) " ) ;
}
assert_not_contains! ( stderr , " panic " ) ;
}
2023-04-23 16:55:45 -04:00
#[ tokio::test(flavor = " multi_thread " ) ]
async fn websocketstream_ping ( ) {
2023-01-12 20:59:13 -05:00
let _g = util ::http_server ( ) ;
let script = util ::testdata_path ( ) . join ( " run/websocketstream_ping_test.ts " ) ;
let root_ca = util ::testdata_path ( ) . join ( " tls/RootCA.pem " ) ;
2023-04-23 16:55:45 -04:00
2023-12-27 11:59:57 -05:00
let srv_fn = hyper ::service ::service_fn ( | mut req | async move {
2023-04-23 16:55:45 -04:00
let ( response , upgrade_fut ) =
2023-12-27 11:59:57 -05:00
fastwebsockets ::upgrade ::upgrade ( & mut req ) . unwrap ( ) ;
2023-04-23 16:55:45 -04:00
tokio ::spawn ( async move {
let mut ws = upgrade_fut . await . unwrap ( ) ;
2023-12-27 11:59:57 -05:00
ws . write_frame ( fastwebsockets ::Frame ::text ( b " A " [ .. ] . into ( ) ) )
2023-04-23 16:55:45 -04:00
. await
. unwrap ( ) ;
2023-12-27 11:59:57 -05:00
ws . write_frame ( fastwebsockets ::Frame ::new (
2023-04-23 16:55:45 -04:00
true ,
2023-12-27 11:59:57 -05:00
fastwebsockets ::OpCode ::Ping ,
2023-04-23 16:55:45 -04:00
None ,
2023-08-10 00:29:06 -04:00
vec! [ ] . into ( ) ,
2023-04-23 16:55:45 -04:00
) )
. await
. unwrap ( ) ;
2023-12-27 11:59:57 -05:00
ws . write_frame ( fastwebsockets ::Frame ::text ( b " B " [ .. ] . into ( ) ) )
2023-04-23 16:55:45 -04:00
. await
. unwrap ( ) ;
let message = ws . read_frame ( ) . await . unwrap ( ) ;
2023-12-27 11:59:57 -05:00
assert_eq! ( message . opcode , fastwebsockets ::OpCode ::Pong ) ;
ws . write_frame ( fastwebsockets ::Frame ::text ( b " C " [ .. ] . into ( ) ) )
2023-04-23 16:55:45 -04:00
. await
. unwrap ( ) ;
2023-12-27 11:59:57 -05:00
ws . write_frame ( fastwebsockets ::Frame ::close_raw ( vec! [ ] . into ( ) ) )
2023-04-23 16:55:45 -04:00
. await
. unwrap ( ) ;
} ) ;
Ok ::< _ , std ::convert ::Infallible > ( response )
} ) ;
let child = util ::deno_cmd ( )
2023-01-12 20:59:13 -05:00
. arg ( " test " )
2024-09-09 17:44:29 -04:00
. arg ( " --unstable-net " )
2023-01-12 20:59:13 -05:00
. arg ( " --allow-net " )
. arg ( " --cert " )
. arg ( root_ca )
. arg ( script )
2023-11-17 10:05:42 -05:00
. stdout_piped ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( ) ;
2023-04-23 16:55:45 -04:00
let server = tokio ::net ::TcpListener ::bind ( " 127.0.0.1:4513 " )
. await
2023-01-12 20:59:13 -05:00
. unwrap ( ) ;
2023-04-23 16:55:45 -04:00
tokio ::spawn ( async move {
let ( stream , _ ) = server . accept ( ) . await . unwrap ( ) ;
2023-12-26 08:32:21 -05:00
let io = hyper_util ::rt ::TokioIo ::new ( stream ) ;
2023-12-27 11:59:57 -05:00
let conn_fut = hyper ::server ::conn ::http1 ::Builder ::new ( )
2023-12-26 08:32:21 -05:00
. serve_connection ( io , srv_fn )
2023-04-23 16:55:45 -04:00
. with_upgrades ( ) ;
if let Err ( e ) = conn_fut . await {
eprintln! ( " websocket server error: {e:?} " ) ;
}
} ) ;
2023-01-12 20:59:13 -05:00
2023-04-23 16:55:45 -04:00
let r = child . wait_with_output ( ) . unwrap ( ) ;
assert! ( r . status . success ( ) ) ;
2023-01-12 20:59:13 -05:00
}
2023-04-23 16:55:45 -04:00
struct SpawnExecutor ;
2023-12-27 11:59:57 -05:00
impl < Fut > hyper ::rt ::Executor < Fut > for SpawnExecutor
2023-04-23 16:55:45 -04:00
where
Fut : std ::future ::Future + Send + 'static ,
Fut ::Output : Send + 'static ,
{
fn execute ( & self , fut : Fut ) {
2023-08-23 19:03:05 -04:00
deno_core ::unsync ::spawn ( fut ) ;
2023-04-23 16:55:45 -04:00
}
}
#[ tokio::test ]
async fn websocket_server_multi_field_connection_header ( ) {
2023-01-12 20:59:13 -05:00
let script = util ::testdata_path ( )
. join ( " run/websocket_server_multi_field_connection_header_test.ts " ) ;
let root_ca = util ::testdata_path ( ) . join ( " tls/RootCA.pem " ) ;
let mut child = util ::deno_cmd ( )
. arg ( " run " )
. arg ( " --allow-net " )
. arg ( " --cert " )
. arg ( root_ca )
. arg ( script )
2023-11-17 10:05:42 -05:00
. stdout_piped ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( ) ;
let stdout = child . stdout . as_mut ( ) . unwrap ( ) ;
let mut buffer = [ 0 ; 5 ] ;
let read = stdout . read ( & mut buffer ) . unwrap ( ) ;
assert_eq! ( read , 5 ) ;
let msg = std ::str ::from_utf8 ( & buffer ) . unwrap ( ) ;
assert_eq! ( msg , " READY " ) ;
2023-04-23 16:55:45 -04:00
let stream = tokio ::net ::TcpStream ::connect ( " localhost:4319 " )
. await
. unwrap ( ) ;
2023-12-27 11:59:57 -05:00
let req = http ::Request ::builder ( )
. header ( http ::header ::UPGRADE , " websocket " )
. header ( http ::header ::CONNECTION , " keep-alive, Upgrade " )
2023-04-23 16:55:45 -04:00
. header (
" Sec-WebSocket-Key " ,
2023-12-27 11:59:57 -05:00
fastwebsockets ::handshake ::generate_key ( ) ,
2023-04-23 16:55:45 -04:00
)
. header ( " Sec-WebSocket-Version " , " 13 " )
2023-01-12 20:59:13 -05:00
. uri ( " ws://localhost:4319 " )
2023-12-26 08:32:21 -05:00
. body ( http_body_util ::Empty ::< Bytes > ::new ( ) )
2023-01-12 20:59:13 -05:00
. unwrap ( ) ;
2023-04-23 16:55:45 -04:00
2023-01-12 20:59:13 -05:00
let ( mut socket , _ ) =
2023-12-27 11:59:57 -05:00
fastwebsockets ::handshake ::client ( & SpawnExecutor , req , stream )
2023-04-23 16:55:45 -04:00
. await
2023-01-12 20:59:13 -05:00
. unwrap ( ) ;
2023-04-23 16:55:45 -04:00
let message = socket . read_frame ( ) . await . unwrap ( ) ;
2023-12-27 11:59:57 -05:00
assert_eq! ( message . opcode , fastwebsockets ::OpCode ::Close ) ;
2023-04-23 16:55:45 -04:00
assert! ( message . payload . is_empty ( ) ) ;
socket
2023-12-27 11:59:57 -05:00
. write_frame ( fastwebsockets ::Frame ::close_raw ( vec! [ ] . into ( ) ) )
2023-04-23 16:55:45 -04:00
. await
. unwrap ( ) ;
2023-01-12 20:59:13 -05:00
assert! ( child . wait ( ) . unwrap ( ) . success ( ) ) ;
}
2023-04-23 16:55:45 -04:00
#[ tokio::test ]
async fn websocket_server_idletimeout ( ) {
2024-02-28 17:12:21 -05:00
test_util ::timeout! ( 60 ) ;
2023-01-12 20:59:13 -05:00
let script =
util ::testdata_path ( ) . join ( " run/websocket_server_idletimeout.ts " ) ;
let root_ca = util ::testdata_path ( ) . join ( " tls/RootCA.pem " ) ;
let mut child = util ::deno_cmd ( )
2024-02-28 17:12:21 -05:00
. arg ( " run " )
2023-01-12 20:59:13 -05:00
. arg ( " --allow-net " )
. arg ( " --cert " )
. arg ( root_ca )
2024-07-24 20:26:54 -04:00
. arg ( " --config " )
. arg ( " ./config/deno.json " )
2023-01-12 20:59:13 -05:00
. arg ( script )
2023-11-17 10:05:42 -05:00
. stdout_piped ( )
2023-01-12 20:59:13 -05:00
. spawn ( )
. unwrap ( ) ;
let stdout = child . stdout . as_mut ( ) . unwrap ( ) ;
2024-02-28 17:12:21 -05:00
let mut buf : Vec < u8 > = vec! [ ] ;
while ! String ::from_utf8 ( buf . clone ( ) ) . unwrap ( ) . contains ( " READY " ) {
let mut buffer = [ 0 ; 64 ] ;
let read = stdout . read ( & mut buffer ) . unwrap ( ) ;
buf . extend_from_slice ( & buffer [ 0 .. read ] ) ;
eprintln! ( " buf = {buf:?} " ) ;
}
2023-01-12 20:59:13 -05:00
2023-04-23 16:55:45 -04:00
let stream = tokio ::net ::TcpStream ::connect ( " localhost:4509 " )
. await
. unwrap ( ) ;
2023-12-27 11:59:57 -05:00
let req = http ::Request ::builder ( )
. header ( http ::header ::UPGRADE , " websocket " )
. header ( http ::header ::CONNECTION , " keep-alive, Upgrade " )
2023-04-23 16:55:45 -04:00
. header (
" Sec-WebSocket-Key " ,
2023-12-27 11:59:57 -05:00
fastwebsockets ::handshake ::generate_key ( ) ,
2023-04-23 16:55:45 -04:00
)
. header ( " Sec-WebSocket-Version " , " 13 " )
2023-01-12 20:59:13 -05:00
. uri ( " ws://localhost:4509 " )
2023-12-26 08:32:21 -05:00
. body ( http_body_util ::Empty ::< Bytes > ::new ( ) )
2023-01-12 20:59:13 -05:00
. unwrap ( ) ;
2023-04-23 16:55:45 -04:00
let ( _socket , _ ) =
2023-12-27 11:59:57 -05:00
fastwebsockets ::handshake ::client ( & SpawnExecutor , req , stream )
2023-04-23 16:55:45 -04:00
. await
2023-01-12 20:59:13 -05:00
. unwrap ( ) ;
2024-02-28 17:12:21 -05:00
assert_eq! ( child . wait ( ) . unwrap ( ) . code ( ) , Some ( 123 ) ) ;
2023-01-12 20:59:13 -05:00
}
// Regression test for https://github.com/denoland/deno/issues/16772
#[ test ]
fn file_fetcher_preserves_permissions ( ) {
2023-11-14 11:58:06 -05:00
let context = TestContext ::with_http_server ( ) ;
context
. new_command ( )
. args ( " repl --quiet " )
. with_pty ( | mut console | {
console . write_line (
2024-05-14 15:59:32 -04:00
" const a = await import('http://localhost:4545/run/019_media_types.ts'); " ,
) ;
2023-11-14 11:58:06 -05:00
console . expect ( " Allow? " ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
2023-11-14 11:58:06 -05:00
console . write_line_raw ( " y " ) ;
console . expect_all ( & [ " success " , " true " ] ) ;
} ) ;
2023-01-12 20:59:13 -05:00
}
2023-01-13 10:05:07 -05:00
#[ test ]
fn stdio_streams_are_locked_in_permission_prompt ( ) {
2023-11-17 11:57:11 -05:00
if ! util ::pty ::Pty ::is_supported ( ) {
// Don't deal with the logic below if the with_pty
// block doesn't even run (ex. on Windows CI)
return ;
}
2024-04-02 17:55:06 -04:00
let context = TestContextBuilder ::new ( ) . build ( ) ;
2023-03-28 17:49:00 -04:00
2024-04-02 17:55:06 -04:00
context
. new_command ( )
. args ( " repl " )
. with_pty ( | mut console | {
let malicious_output = r # "**malicious**"# ;
// Start a worker that starts spamming stdout
console . write_line ( r # "new Worker(URL.createObjectURL(new Blob(["setInterval(() => console.log('**malicious**'), 10)"])), { type: "module" });"# ) ;
// The worker is now spamming
console . expect ( malicious_output ) ;
2024-04-19 20:12:03 -04:00
console . write_line ( r # "Deno.readTextFileSync('../Cargo.toml');"# ) ;
2024-04-02 17:55:06 -04:00
// We will get a permission prompt
console . expect ( " Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) > " ) ;
// The worker is blocked, so nothing else should get written here
console . human_delay ( ) ;
console . write_line_raw ( " i " ) ;
// We ensure that nothing gets written here between the permission prompt and this text, despire the delay
let newline = if cfg! ( target_os = " linux " ) {
" ^J "
} else {
" \r \n "
} ;
2024-08-08 09:39:31 -04:00
console . expect_raw_next ( format! ( " i {newline} \u{1b} [1A \u{1b} [0J┗ Unrecognized option. Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) > " ) ) ;
2024-04-02 17:55:06 -04:00
console . human_delay ( ) ;
console . write_line_raw ( " y " ) ;
// We ensure that nothing gets written here between the permission prompt and this text, despire the delay
2024-08-08 09:39:31 -04:00
console . expect_raw_next ( format! ( " y {newline} \x1b [5A \x1b [0J✅ Granted read access to \" " ) ) ;
2023-11-17 11:57:11 -05:00
2024-04-02 17:55:06 -04:00
// Back to spamming!
console . expect ( malicious_output ) ;
} ) ;
2023-01-13 10:05:07 -05:00
}
2023-01-24 09:05:54 -05:00
2023-03-09 19:09:14 -05:00
#[ test ]
2024-02-18 23:51:06 -05:00
fn permission_prompt_escapes_ansi_codes_and_control_chars ( ) {
2023-03-09 19:09:14 -05:00
util ::with_pty ( & [ " repl " ] , | mut console | {
console . write_line (
2023-11-14 11:58:06 -05:00
r # "Deno.permissions.request({ name: "env", variable: "\rDo you like ice cream? y/n" });"#
) ;
2023-09-08 14:34:57 -04:00
// will be uppercase on windows
let env_name = if cfg! ( windows ) {
2024-02-18 23:51:06 -05:00
" \\ rDO YOU LIKE ICE CREAM? Y/N "
2023-09-08 14:34:57 -04:00
} else {
2024-02-18 23:51:06 -05:00
" \\ rDo you like ice cream? y/n "
2023-09-08 14:34:57 -04:00
} ;
console . expect ( format! (
2024-08-08 09:39:31 -04:00
" \u{250f} \u{26a0} \u{fe0f} Deno requests env access to \" {} \" . " ,
2023-09-08 14:34:57 -04:00
env_name
) )
2023-03-09 19:09:14 -05:00
} ) ;
2024-09-04 08:51:24 -04:00
// windows doesn't support backslashes in paths, so just try this on unix
if cfg! ( unix ) {
let context = TestContextBuilder ::default ( ) . use_temp_cwd ( ) . build ( ) ;
context
. new_command ( )
. env ( " PATH " , context . temp_dir ( ) . path ( ) )
. env ( " DYLD_FALLBACK_LIBRARY_PATH " , " " )
. env ( " LD_LIBRARY_PATH " , " " )
. args_vec ( [ " repl " , " --allow-write=. " ] )
. with_pty ( | mut console | {
console . write_line_raw ( r # "const boldANSI = "\u001b[1m";"# ) ;
console . expect ( " undefined " ) ;
console . write_line_raw ( r # "const unboldANSI = "\u001b[22m";"# ) ;
console . expect ( " undefined " ) ;
console . write_line_raw (
r # "Deno.writeTextFileSync(`${boldANSI}cat${unboldANSI}`, "");"# ,
) ;
console . expect ( " undefined " ) ;
console . write_line_raw (
r # "new Deno.Command(`./${boldANSI}cat${unboldANSI}`).spawn();"# ,
) ;
console
. expect ( " \u{250f} \u{26a0} \u{fe0f} Deno requests run access to \" " ) ;
console . expect ( " \\ u{1b}[1mcat \\ u{1b}[22m \" . " ) ; // ensure escaped
} ) ;
}
2023-03-09 19:09:14 -05:00
}
2023-03-08 06:44:54 -05:00
itest! ( extension_import {
args : " run run/extension_import.ts " ,
output : " run/extension_import.ts.out " ,
2023-02-07 14:22:46 -05:00
exit_code : 1 ,
} ) ;
2023-03-08 06:44:54 -05:00
itest! ( extension_dynamic_import {
args : " run run/extension_dynamic_import.ts " ,
output : " run/extension_dynamic_import.ts.out " ,
2023-02-07 14:22:46 -05:00
exit_code : 1 ,
} ) ;
2023-08-01 20:49:09 -04:00
#[ test ]
2023-08-06 21:56:56 -04:00
pub fn vendor_dir_config_file ( ) {
2023-08-01 20:49:09 -04:00
let test_context = TestContextBuilder ::new ( )
. use_http_server ( )
. use_temp_cwd ( )
. build ( ) ;
let temp_dir = test_context . temp_dir ( ) ;
2023-08-06 21:56:56 -04:00
let vendor_dir = temp_dir . path ( ) . join ( " vendor " ) ;
let rm_vendor_dir = | | std ::fs ::remove_dir_all ( & vendor_dir ) . unwrap ( ) ;
2023-08-01 20:49:09 -04:00
2023-08-06 21:56:56 -04:00
temp_dir . write ( " deno.json " , r # "{ "vendor": true }"# ) ;
2023-08-01 20:49:09 -04:00
temp_dir . write (
" main.ts " ,
r #" import { returnsHi } from 'http://localhost:4545/subdir/mod1.ts';
console . log ( returnsHi ( ) ) ; " #,
) ;
2024-09-25 21:50:54 -04:00
let deno_run_cmd = test_context
. new_command ( )
. args ( " run --allow-import --quiet main.ts " ) ;
2023-08-01 20:49:09 -04:00
deno_run_cmd . run ( ) . assert_matches_text ( " Hi \n " ) ;
2023-08-06 21:56:56 -04:00
assert! ( vendor_dir . exists ( ) ) ;
rm_vendor_dir ( ) ;
temp_dir . write ( " deno.json " , r # "{ "vendor": false }"# ) ;
2023-08-01 20:49:09 -04:00
deno_run_cmd . run ( ) . assert_matches_text ( " Hi \n " ) ;
2023-08-06 21:56:56 -04:00
assert! ( ! vendor_dir . exists ( ) ) ;
2023-08-01 20:49:09 -04:00
test_context
. new_command ( )
2024-09-25 21:50:54 -04:00
. args ( " cache --allow-import --quiet --vendor main.ts " )
2023-08-01 20:49:09 -04:00
. run ( ) ;
2023-08-06 21:56:56 -04:00
assert! ( vendor_dir . exists ( ) ) ;
rm_vendor_dir ( ) ;
2023-08-01 20:49:09 -04:00
2023-08-06 21:56:56 -04:00
temp_dir . write ( " deno.json " , r # "{ "vendor": true }"# ) ;
2024-09-25 21:50:54 -04:00
let cache_command = test_context
. new_command ( )
. args ( " cache --allow-import --quiet main.ts " ) ;
2023-08-01 20:49:09 -04:00
cache_command . run ( ) ;
2023-08-06 21:56:56 -04:00
assert! ( vendor_dir . exists ( ) ) ;
let mod1_file = vendor_dir
2023-08-01 20:49:09 -04:00
. join ( " http_localhost_4545 " )
. join ( " subdir " )
. join ( " mod1.ts " ) ;
mod1_file . write ( " export function returnsHi() { return 'bye bye bye'; } " ) ;
2024-05-28 14:58:43 -04:00
// this is fine with a lockfile because users are supposed to be able
// to modify the vendor folder
deno_run_cmd . run ( ) . assert_matches_text ( " bye bye bye \n " ) ;
2023-08-01 20:49:09 -04:00
// try updating by deleting the lockfile
let lockfile = temp_dir . path ( ) . join ( " deno.lock " ) ;
lockfile . remove_file ( ) ;
cache_command . run ( ) ;
2024-05-28 14:58:43 -04:00
// should still run and the lockfile should be recreated
// (though with the checksum from the vendor folder)
2023-08-01 20:49:09 -04:00
deno_run_cmd . run ( ) . assert_matches_text ( " bye bye bye \n " ) ;
assert! ( lockfile . exists ( ) ) ;
2023-08-06 12:25:48 -04:00
// ensure we can add and execute files in directories that have a hash in them
test_context
. new_command ( )
// http_localhost_4545/subdir/#capitals_c75d7/main.js
2024-09-25 21:50:54 -04:00
. args ( " cache --allow-import http://localhost:4545/subdir/CAPITALS/main.js " )
2023-08-06 12:25:48 -04:00
. run ( )
. skip_output_check ( ) ;
assert_eq! (
2023-08-06 21:56:56 -04:00
vendor_dir . join ( " manifest.json " ) . read_json_value ( ) ,
2023-08-06 12:25:48 -04:00
json! ( {
" folders " : {
" http://localhost:4545/subdir/CAPITALS/ " : " http_localhost_4545/subdir/#capitals_c75d7 "
}
} )
) ;
2023-08-06 21:56:56 -04:00
vendor_dir
2023-08-06 12:25:48 -04:00
. join ( " http_localhost_4545/subdir/#capitals_c75d7/hello_there.ts " )
. write ( " console.log('hello there'); " ) ;
test_context
. new_command ( )
// todo(dsherret): seems wrong that we don't auto-discover the config file to get the vendor directory for this
2024-09-25 21:50:54 -04:00
. args ( " run --allow-import --vendor http://localhost:4545/subdir/CAPITALS/hello_there.ts " )
2023-08-06 12:25:48 -04:00
. run ( )
. assert_matches_text ( " hello there \n " ) ;
2023-08-17 12:14:22 -04:00
// now try importing directly from the vendor folder
temp_dir . write (
" main.ts " ,
r #" import { returnsHi } from './vendor/http_localhost_4545/subdir/mod1.ts';
console . log ( returnsHi ( ) ) ; " #,
) ;
deno_run_cmd
. run ( )
. assert_matches_text ( " error: Importing from the vendor directory is not permitted. Use a remote specifier instead or disable vendoring.
at [ WILDCARD ] / main . ts :1 :27
" )
. assert_exit_code ( 1 ) ;
2023-08-01 20:49:09 -04:00
}
2023-09-14 14:08:59 -04:00
2024-01-31 17:18:14 -05:00
// TODO(bartlomieju): temporary disabled
// itest!(warn_on_deprecated_api {
// args: "run -A run/warn_on_deprecated_api/main.js",
// output: "run/warn_on_deprecated_api/main.out",
// http_server: true,
// exit_code: 0,
// });
2024-01-18 18:30:49 -05:00
2024-01-31 17:18:14 -05:00
// itest!(warn_on_deprecated_api_verbose {
// args: "run -A run/warn_on_deprecated_api/main.js",
// output: "run/warn_on_deprecated_api/main.verbose.out",
// envs: vec![("DENO_VERBOSE_WARNINGS".to_string(), "1".to_string())],
// http_server: true,
// exit_code: 0,
// });
2024-01-26 10:41:16 -05:00
2024-01-31 17:18:14 -05:00
// itest!(warn_on_deprecated_api_with_flag {
// args: "run -A --quiet run/warn_on_deprecated_api/main.js",
// output: "run/warn_on_deprecated_api/main_disabled_flag.out",
// http_server: true,
// exit_code: 0,
// });
2024-01-18 18:30:49 -05:00
2024-01-31 17:18:14 -05:00
// itest!(warn_on_deprecated_api_with_env_var {
// args: "run -A run/warn_on_deprecated_api/main.js",
// envs: vec![("DENO_NO_DEPRECATION_WARNINGS".to_string(), "1".to_string())],
// output: "run/warn_on_deprecated_api/main_disabled_env.out",
// http_server: true,
// exit_code: 0,
// });
2024-01-24 17:44:06 -05:00
#[ test ]
fn deno_json_imports_expand ( ) {
let test_context = TestContextBuilder ::for_npm ( ) . use_temp_cwd ( ) . build ( ) ;
let dir = test_context . temp_dir ( ) ;
dir . write (
" deno.json " ,
r #" {
" imports " : {
" basic " : " npm:@denotest/esm-basic "
}
} " #,
) ;
dir . write (
" main.ts " ,
r #"
// import map should resolve
import { setValue , getValue } from " basic " ;
// this entry should have been added automatically
import { hello } from " basic/other.mjs " ;
setValue ( 5 ) ;
console . log ( getValue ( ) ) ;
console . log ( hello ( ) ) ;
" #,
) ;
let output = test_context . new_command ( ) . args ( " run main.ts " ) . run ( ) ;
output . assert_matches_text ( " [WILDCARD]5 \n hello, world! \n " ) ;
}
#[ test ]
fn deno_json_imports_expand_doesnt_overwrite_existing_entries ( ) {
let test_context = TestContextBuilder ::for_npm ( ) . use_temp_cwd ( ) . build ( ) ;
let dir = test_context . temp_dir ( ) ;
dir . write (
" deno.json " ,
r #" {
" imports " : {
" basic " : " npm:@denotest/esm-basic " ,
" basic/ " : " npm:/@denotest/sub-folders/folder_index_js/ "
}
} " #,
) ;
dir . write (
" main.ts " ,
r #"
// import map should resolve
import { setValue , getValue } from " basic " ;
// this entry should map to explicitly specified "basic/" mapping
import { add } from " basic/index.js " ;
setValue ( 5 ) ;
console . log ( getValue ( ) ) ;
console . log ( add ( 3 , 4 ) ) ;
" #,
) ;
let output = test_context . new_command ( ) . args ( " run main.ts " ) . run ( ) ;
output . assert_matches_text ( " [WILDCARD]5 \n 7 \n " ) ;
}
2024-03-15 09:57:24 -04:00
2024-04-17 10:19:55 -04:00
#[ test ]
fn code_cache_test ( ) {
let test_context = TestContextBuilder ::new ( ) . use_temp_cwd ( ) . build ( ) ;
2024-06-18 17:24:18 -04:00
let deno_dir = test_context . deno_dir ( ) ;
2024-04-17 10:19:55 -04:00
let temp_dir = test_context . temp_dir ( ) ;
temp_dir . write ( " main.js " , " console.log('Hello World - A'); " ) ;
// First run with no prior cache.
{
let output = test_context
. new_command ( )
2024-06-18 17:24:18 -04:00
. args ( " run -Ldebug main.js " )
2024-04-17 10:19:55 -04:00
. split_output ( )
. run ( ) ;
output
. assert_stdout_matches_text ( " Hello World - A[WILDCARD] " )
. assert_stderr_matches_text ( " [WILDCARD]Updating V8 code cache for ES module: file:///[WILDCARD]/main.js[WILDCARD] " ) ;
2024-06-18 17:24:18 -04:00
assert_not_contains! ( output . stderr ( ) , " V8 code cache hit " ) ;
2024-04-17 10:19:55 -04:00
// Check that the code cache database exists.
2024-05-29 14:38:18 -04:00
let code_cache_path = deno_dir . path ( ) . join ( CODE_CACHE_DB_FILE_NAME ) ;
2024-04-17 10:19:55 -04:00
assert! ( code_cache_path . exists ( ) ) ;
}
// 2nd run with cache.
{
let output = test_context
. new_command ( )
2024-06-18 17:24:18 -04:00
. args ( " run -Ldebug main.js " )
2024-04-17 10:19:55 -04:00
. split_output ( )
. run ( ) ;
output
. assert_stdout_matches_text ( " Hello World - A[WILDCARD] " )
. assert_stderr_matches_text ( " [WILDCARD]V8 code cache hit for ES module: file:///[WILDCARD]/main.js[WILDCARD] " ) ;
2024-06-18 17:24:18 -04:00
assert_not_contains! ( output . stderr ( ) , " Updating V8 code cache " ) ;
2024-04-17 10:19:55 -04:00
}
// Rerun with --no-code-cache.
{
let output = test_context
. new_command ( )
2024-06-18 17:24:18 -04:00
. args ( " run -Ldebug --no-code-cache main.js " )
2024-04-17 10:19:55 -04:00
. split_output ( )
. run ( ) ;
output
. assert_stdout_matches_text ( " Hello World - A[WILDCARD] " )
. skip_stderr_check ( ) ;
2024-06-18 17:24:18 -04:00
assert_not_contains! ( output . stderr ( ) , " V8 code cache " ) ;
2024-04-17 10:19:55 -04:00
}
// Modify the script, and make sure that the cache is rejected.
temp_dir . write ( " main.js " , " console.log('Hello World - B'); " ) ;
{
let output = test_context
. new_command ( )
2024-06-18 17:24:18 -04:00
. args ( " run -Ldebug main.js " )
2024-04-17 10:19:55 -04:00
. split_output ( )
. run ( ) ;
output
. assert_stdout_matches_text ( " Hello World - B[WILDCARD] " )
. assert_stderr_matches_text ( " [WILDCARD]Updating V8 code cache for ES module: file:///[WILDCARD]/main.js[WILDCARD] " ) ;
2024-06-18 17:24:18 -04:00
assert_not_contains! ( output . stderr ( ) , " V8 code cache hit " ) ;
2024-04-17 10:19:55 -04:00
}
}
#[ test ]
fn code_cache_npm_test ( ) {
2024-06-18 17:24:18 -04:00
let test_context = TestContextBuilder ::for_npm ( ) . use_temp_cwd ( ) . build ( ) ;
let deno_dir = test_context . deno_dir ( ) ;
2024-04-17 10:19:55 -04:00
let temp_dir = test_context . temp_dir ( ) ;
temp_dir . write (
" main.js " ,
" import chalk from \" npm:chalk@5 \" ;console.log(chalk('Hello World')); " ,
) ;
// First run with no prior cache.
{
let output = test_context
. new_command ( )
2024-06-18 17:24:18 -04:00
. args ( " run -Ldebug -A main.js " )
2024-04-17 10:19:55 -04:00
. split_output ( )
. run ( ) ;
output
. assert_stdout_matches_text ( " Hello World[WILDCARD] " )
. assert_stderr_matches_text ( " [WILDCARD]Updating V8 code cache for ES module: file:///[WILDCARD]/main.js[WILDCARD] " )
2024-05-06 21:06:01 -04:00
. assert_stderr_matches_text ( " [WILDCARD]Updating V8 code cache for ES module: file:///[WILDCARD]/chalk/5.[WILDCARD]/source/index.js[WILDCARD] " ) ;
2024-06-18 17:24:18 -04:00
assert_not_contains! ( output . stderr ( ) , " V8 code cache hit " ) ;
2024-04-17 10:19:55 -04:00
// Check that the code cache database exists.
2024-05-29 14:38:18 -04:00
let code_cache_path = deno_dir . path ( ) . join ( CODE_CACHE_DB_FILE_NAME ) ;
2024-04-17 10:19:55 -04:00
assert! ( code_cache_path . exists ( ) ) ;
}
// 2nd run with cache.
{
let output = test_context
. new_command ( )
2024-06-18 17:24:18 -04:00
. args ( " run -Ldebug -A main.js " )
2024-04-17 10:19:55 -04:00
. split_output ( )
. run ( ) ;
output
. assert_stdout_matches_text ( " Hello World[WILDCARD] " )
. assert_stderr_matches_text ( " [WILDCARD]V8 code cache hit for ES module: file:///[WILDCARD]/main.js[WILDCARD] " )
2024-05-06 21:06:01 -04:00
. assert_stderr_matches_text ( " [WILDCARD]V8 code cache hit for ES module: file:///[WILDCARD]/chalk/5.[WILDCARD]/source/index.js[WILDCARD] " ) ;
2024-06-18 17:24:18 -04:00
assert_not_contains! ( output . stderr ( ) , " Updating V8 code cache " ) ;
2024-04-17 10:19:55 -04:00
}
}
#[ test ]
fn code_cache_npm_with_require_test ( ) {
2024-06-18 17:24:18 -04:00
let test_context = TestContextBuilder ::for_npm ( ) . use_temp_cwd ( ) . build ( ) ;
let deno_dir = test_context . deno_dir ( ) ;
2024-04-17 10:19:55 -04:00
let temp_dir = test_context . temp_dir ( ) ;
temp_dir . write (
" main.js " ,
" import fraction from \" npm:autoprefixer \" ;console.log(typeof fraction); " ,
) ;
// First run with no prior cache.
{
let output = test_context
. new_command ( )
2024-06-18 17:24:18 -04:00
. args ( " run -Ldebug -A main.js " )
2024-04-17 10:19:55 -04:00
. split_output ( )
. run ( ) ;
output
. assert_stdout_matches_text ( " function[WILDCARD] " )
. assert_stderr_matches_text ( " [WILDCARD]Updating V8 code cache for ES module: file:///[WILDCARD]/main.js[WILDCARD] " )
2024-05-06 21:06:01 -04:00
. assert_stderr_matches_text ( " [WILDCARD]Updating V8 code cache for ES module: file:///[WILDCARD]/autoprefixer/[WILDCARD]/autoprefixer.js[WILDCARD] " )
. assert_stderr_matches_text ( " [WILDCARD]Updating V8 code cache for script: file:///[WILDCARD]/autoprefixer/[WILDCARD]/autoprefixer.js[WILDCARD] " )
. assert_stderr_matches_text ( " [WILDCARD]Updating V8 code cache for script: file:///[WILDCARD]/browserslist/[WILDCARD]/index.js[WILDCARD] " ) ;
2024-06-18 17:24:18 -04:00
assert_not_contains! ( output . stderr ( ) , " V8 code cache hit " ) ;
2024-04-17 10:19:55 -04:00
// Check that the code cache database exists.
2024-05-29 14:38:18 -04:00
let code_cache_path = deno_dir . path ( ) . join ( CODE_CACHE_DB_FILE_NAME ) ;
2024-04-17 10:19:55 -04:00
assert! ( code_cache_path . exists ( ) ) ;
}
// 2nd run with cache.
{
let output = test_context
. new_command ( )
2024-06-18 17:24:18 -04:00
. args ( " run -Ldebug -A main.js " )
2024-04-17 10:19:55 -04:00
. split_output ( )
. run ( ) ;
output
. assert_stdout_matches_text ( " function[WILDCARD] " )
. assert_stderr_matches_text ( " [WILDCARD]V8 code cache hit for ES module: file:///[WILDCARD]/main.js[WILDCARD] " )
2024-05-06 21:06:01 -04:00
. assert_stderr_matches_text ( " [WILDCARD]V8 code cache hit for ES module: file:///[WILDCARD]/autoprefixer/[WILDCARD]/autoprefixer.js[WILDCARD] " )
. assert_stderr_matches_text ( " [WILDCARD]V8 code cache hit for script: file:///[WILDCARD]/autoprefixer/[WILDCARD]/autoprefixer.js[WILDCARD] " )
. assert_stderr_matches_text ( " [WILDCARD]V8 code cache hit for script: file:///[WILDCARD]/browserslist/[WILDCARD]/index.js[WILDCARD] " ) ;
2024-06-18 17:24:18 -04:00
assert_not_contains! ( output . stderr ( ) , " Updating V8 code cache " ) ;
}
}
#[ test ]
fn code_cache_npm_cjs_wrapper_module_many_exports ( ) {
// The code cache was being invalidated because the CJS wrapper module
// had indeterministic output.
let test_context = TestContextBuilder ::for_npm ( ) . use_temp_cwd ( ) . build ( ) ;
let temp_dir = test_context . temp_dir ( ) ;
temp_dir . write (
" main.js " ,
// this package has a few exports
" import { hello } from \" npm:@denotest/cjs-reexport-collision \" ;hello.sayHello(); " ,
) ;
// First run with no prior cache.
{
let output = test_context
. new_command ( )
. args ( " run -Ldebug -A main.js " )
. split_output ( )
. run ( ) ;
assert_not_contains! ( output . stderr ( ) , " V8 code cache hit " ) ;
assert_contains! ( output . stderr ( ) , " Updating V8 code cache " ) ;
output . skip_stdout_check ( ) ;
}
// 2nd run with cache.
{
let output = test_context
. new_command ( )
. args ( " run -Ldebug -A main.js " )
. split_output ( )
. run ( ) ;
assert_contains! ( output . stderr ( ) , " V8 code cache hit " ) ;
assert_not_contains! ( output . stderr ( ) , " Updating V8 code cache " ) ;
output . skip_stdout_check ( ) ;
// should have two occurrences of this (one for entrypoint and one for wrapper module)
assert_eq! (
output
. stderr ( )
. split ( " V8 code cache hit for ES module " )
. count ( ) ,
3
) ;
2024-04-17 10:19:55 -04:00
}
}
2024-04-27 07:25:18 -04:00
#[ test ]
fn node_process_stdin_unref_with_pty ( ) {
TestContext ::default ( )
. new_command ( )
. args_vec ( [ " run " , " --quiet " , " run/node_process_stdin_unref_with_pty.js " ] )
. with_pty ( | mut console | {
console . expect ( " START \r \n " ) ;
console . write_line ( " foo " ) ;
console . expect ( " foo \r \n " ) ;
console . write_line ( " bar " ) ;
console . expect ( " bar \r \n " ) ;
console . write_line ( " baz " ) ;
console . expect ( " baz \r \n " ) ;
} ) ;
TestContext ::default ( )
. new_command ( )
. args_vec ( [
" run " ,
" --quiet " ,
" run/node_process_stdin_unref_with_pty.js " ,
" --unref " ,
] )
. with_pty ( | mut console | {
// if process.stdin.unref is called, the program immediately ends by skipping reading from stdin.
console . expect ( " START \r \n END \r \n " ) ;
} ) ;
}
2024-05-02 20:43:12 -04:00
#[ tokio::test ]
async fn listen_tls_alpn ( ) {
let mut child = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " --quiet " )
. arg ( " --allow-net " )
. arg ( " --allow-read " )
. arg ( " ./cert/listen_tls_alpn.ts " )
. arg ( " 4504 " )
. stdout_piped ( )
. spawn ( )
. unwrap ( ) ;
let stdout = child . stdout . as_mut ( ) . unwrap ( ) ;
let mut msg = [ 0 ; 5 ] ;
let read = stdout . read ( & mut msg ) . unwrap ( ) ;
assert_eq! ( read , 5 ) ;
assert_eq! ( & msg , b " READY " ) ;
let mut reader = & mut BufReader ::new ( Cursor ::new ( include_bytes! (
" ../testdata/tls/RootCA.crt "
) ) ) ;
2024-07-01 20:09:47 -04:00
let certs = rustls_pemfile ::certs ( & mut reader )
. collect ::< Result < Vec < _ > , _ > > ( )
. unwrap ( ) ;
2024-05-02 20:43:12 -04:00
let mut root_store = rustls ::RootCertStore ::empty ( ) ;
2024-07-01 20:09:47 -04:00
root_store . add_parsable_certificates ( certs ) ;
2024-05-02 20:43:12 -04:00
let mut cfg = rustls ::ClientConfig ::builder ( )
. with_root_certificates ( root_store )
. with_no_client_auth ( ) ;
cfg . alpn_protocols . push ( b " foobar " . to_vec ( ) ) ;
let cfg = Arc ::new ( cfg ) ;
2024-07-01 20:09:47 -04:00
let hostname =
rustls ::pki_types ::ServerName ::try_from ( " localhost " . to_string ( ) ) . unwrap ( ) ;
2024-05-02 20:43:12 -04:00
let tcp_stream = tokio ::net ::TcpStream ::connect ( " localhost:4504 " )
. await
. unwrap ( ) ;
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 12:54:47 -04:00
let mut tls_stream = TlsStream ::new_client_side (
tcp_stream ,
ClientConnection ::new ( cfg , hostname ) . unwrap ( ) ,
None ,
) ;
2024-05-02 20:43:12 -04:00
let handshake = tls_stream . handshake ( ) . await . unwrap ( ) ;
assert_eq! ( handshake . alpn , Some ( b " foobar " . to_vec ( ) ) ) ;
let status = child . wait ( ) . unwrap ( ) ;
assert! ( status . success ( ) ) ;
}
#[ tokio::test ]
async fn listen_tls_alpn_fail ( ) {
let mut child = util ::deno_cmd ( )
. current_dir ( util ::testdata_path ( ) )
. arg ( " run " )
. arg ( " --quiet " )
. arg ( " --allow-net " )
. arg ( " --allow-read " )
2024-07-24 20:26:54 -04:00
. arg ( " --config " )
. arg ( " ../config/deno.json " )
2024-05-02 20:43:12 -04:00
. arg ( " ./cert/listen_tls_alpn_fail.ts " )
. arg ( " 4505 " )
. stdout_piped ( )
. spawn ( )
. unwrap ( ) ;
let stdout = child . stdout . as_mut ( ) . unwrap ( ) ;
let mut msg = [ 0 ; 5 ] ;
let read = stdout . read ( & mut msg ) . unwrap ( ) ;
assert_eq! ( read , 5 ) ;
assert_eq! ( & msg , b " READY " ) ;
let mut reader = & mut BufReader ::new ( Cursor ::new ( include_bytes! (
" ../testdata/tls/RootCA.crt "
) ) ) ;
2024-07-01 20:09:47 -04:00
let certs = rustls_pemfile ::certs ( & mut reader )
. collect ::< Result < Vec < _ > , _ > > ( )
. unwrap ( ) ;
2024-05-02 20:43:12 -04:00
let mut root_store = rustls ::RootCertStore ::empty ( ) ;
2024-07-01 20:09:47 -04:00
root_store . add_parsable_certificates ( certs ) ;
2024-05-02 20:43:12 -04:00
let mut cfg = rustls ::ClientConfig ::builder ( )
. with_root_certificates ( root_store )
. with_no_client_auth ( ) ;
cfg . alpn_protocols . push ( b " boofar " . to_vec ( ) ) ;
let cfg = Arc ::new ( cfg ) ;
2024-07-01 20:09:47 -04:00
let hostname = rustls ::pki_types ::ServerName ::try_from ( " localhost " ) . unwrap ( ) ;
2024-05-02 20:43:12 -04:00
let tcp_stream = tokio ::net ::TcpStream ::connect ( " localhost:4505 " )
. await
. unwrap ( ) ;
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 12:54:47 -04:00
let mut tls_stream = TlsStream ::new_client_side (
tcp_stream ,
ClientConnection ::new ( cfg , hostname ) . unwrap ( ) ,
None ,
) ;
2024-05-02 20:43:12 -04:00
tls_stream . handshake ( ) . await . unwrap_err ( ) ;
let status = child . wait ( ) . unwrap ( ) ;
assert! ( status . success ( ) ) ;
}
2024-08-08 05:41:30 -04:00
// Couldn't get the directory readonly on windows on the CI
// so gave up because this being tested on unix is good enough
#[ cfg(unix) ]
#[ test ]
fn emit_failed_readonly_file_system ( ) {
let context = TestContextBuilder ::default ( ) . use_temp_cwd ( ) . build ( ) ;
context . deno_dir ( ) . path ( ) . canonicalize ( ) . make_dir_readonly ( ) ;
let temp_dir = context . temp_dir ( ) . path ( ) . canonicalize ( ) ;
temp_dir . join ( " main.ts " ) . write ( " import './other.ts'; " ) ;
temp_dir . join ( " other.ts " ) . write ( " console.log('hi'); " ) ;
let output = context
. new_command ( )
. args ( " run --log-level=debug main.ts " )
. run ( ) ;
output . assert_matches_text ( " [WILDCARD]Error saving emit data ([WILDLINE]main.ts)[WILDCARD]Skipped emit cache save of [WILDLINE]other.ts[WILDCARD]hi[WILDCARD] " ) ;
}
2024-09-18 09:51:39 -04:00
2024-10-09 13:49:56 -04:00
// todo(dsherret): waiting on fix in https://github.com/servo/rust-url/issues/505
#[ ignore ]
2024-09-18 09:51:39 -04:00
#[ cfg(windows) ]
#[ test ]
fn handle_invalid_path_error ( ) {
let deno_cmd = util ::deno_cmd_with_deno_dir ( & util ::new_deno_dir ( ) ) ;
let output = deno_cmd . arg ( " run " ) . arg ( " file://asdf " ) . output ( ) . unwrap ( ) ;
2024-09-25 21:50:54 -04:00
assert_contains! (
String ::from_utf8_lossy ( & output . stderr ) ,
" Invalid file path. "
2024-09-18 09:51:39 -04:00
) ;
let deno_cmd = util ::deno_cmd_with_deno_dir ( & util ::new_deno_dir ( ) ) ;
let output = deno_cmd . arg ( " run " ) . arg ( " /a/b " ) . output ( ) . unwrap ( ) ;
2024-09-25 21:50:54 -04:00
assert_contains! ( String ::from_utf8_lossy ( & output . stderr ) , " Module not found " ) ;
2024-09-18 09:51:39 -04:00
let deno_cmd = util ::deno_cmd_with_deno_dir ( & util ::new_deno_dir ( ) ) ;
let output = deno_cmd . arg ( " run " ) . arg ( " //a/b " ) . output ( ) . unwrap ( ) ;
2024-09-25 21:50:54 -04:00
assert_contains! (
String ::from_utf8_lossy ( & output . stderr ) ,
" Invalid file path. "
2024-09-18 09:51:39 -04:00
) ;
let deno_cmd = util ::deno_cmd_with_deno_dir ( & util ::new_deno_dir ( ) ) ;
let output = deno_cmd . arg ( " run " ) . arg ( " ///a/b " ) . output ( ) . unwrap ( ) ;
2024-09-25 21:50:54 -04:00
assert_contains! ( String ::from_utf8_lossy ( & output . stderr ) , " Module not found " ) ;
2024-09-18 09:51:39 -04:00
}