Skip to content

Commit b2f16b5

Browse files
alexcrichtonsunfishcode
authored andcommitted
Start to lift restriction of stdio only once (#3)
* Start to lift restriction of stdio only once This commit adds new `{Stdin,Stdout}Stream` traits which take over the job of the stdio streams in `WasiCtxBuilder` and `WasiCtx`. These traits bake in the ability to create a stream at any time to satisfy the API of `wasi:cli`. The TTY functionality is folded into them as while I was at it. The implementation for stdin is relatively trivial since the stdin implementation already handles multiple streams reading it. Built-in impls of the `StdinStream` trait are also provided for helper types in `preview2::pipe` which resulted in the implementation of `MemoryInputPipe` being updated to support `Clone` where all clones read the same original data. * Get tests building * Un-ignore now-passing test * Remove unneeded argument from `WasiCtxBuilder::build` * Fix tests
1 parent b08590e commit b2f16b5

16 files changed

+273
-261
lines changed

Cargo.lock

-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/test-programs/tests/command.rs

+51-54
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use wasmtime::{
88
use wasmtime_wasi::preview2::{
99
command::{add_to_linker, Command},
1010
pipe::MemoryInputPipe,
11-
DirPerms, FilePerms, HostMonotonicClock, HostWallClock, IsATTY, Table, WasiCtx, WasiCtxBuilder,
11+
DirPerms, FilePerms, HostMonotonicClock, HostWallClock, Table, WasiCtx, WasiCtxBuilder,
1212
WasiView,
1313
};
1414

@@ -61,10 +61,10 @@ async fn instantiate(
6161

6262
#[test_log::test(tokio::test(flavor = "multi_thread"))]
6363
async fn hello_stdout() -> Result<()> {
64-
let mut table = Table::new();
64+
let table = Table::new();
6565
let wasi = WasiCtxBuilder::new()
6666
.args(&["gussie", "sparky", "willa"])
67-
.build(&mut table)?;
67+
.build();
6868
let (mut store, command) =
6969
instantiate(get_component("hello_stdout"), CommandCtx { table, wasi }).await?;
7070
command
@@ -76,7 +76,7 @@ async fn hello_stdout() -> Result<()> {
7676

7777
#[test_log::test(tokio::test(flavor = "multi_thread"))]
7878
async fn panic() -> Result<()> {
79-
let mut table = Table::new();
79+
let table = Table::new();
8080
let wasi = WasiCtxBuilder::new()
8181
.args(&[
8282
"diesel",
@@ -88,7 +88,7 @@ async fn panic() -> Result<()> {
8888
"good",
8989
"yesterday",
9090
])
91-
.build(&mut table)?;
91+
.build();
9292
let (mut store, command) =
9393
instantiate(get_component("panic"), CommandCtx { table, wasi }).await?;
9494
let r = command.wasi_cli_run().call_run(&mut store).await;
@@ -99,10 +99,10 @@ async fn panic() -> Result<()> {
9999

100100
#[test_log::test(tokio::test(flavor = "multi_thread"))]
101101
async fn args() -> Result<()> {
102-
let mut table = Table::new();
102+
let table = Table::new();
103103
let wasi = WasiCtxBuilder::new()
104104
.args(&["hello", "this", "", "is an argument", "with 🚩 emoji"])
105-
.build(&mut table)?;
105+
.build();
106106
let (mut store, command) =
107107
instantiate(get_component("args"), CommandCtx { table, wasi }).await?;
108108
command
@@ -114,8 +114,8 @@ async fn args() -> Result<()> {
114114

115115
#[test_log::test(tokio::test(flavor = "multi_thread"))]
116116
async fn random() -> Result<()> {
117-
let mut table = Table::new();
118-
let wasi = WasiCtxBuilder::new().build(&mut table)?;
117+
let table = Table::new();
118+
let wasi = WasiCtxBuilder::new().build();
119119
let (mut store, command) =
120120
instantiate(get_component("random"), CommandCtx { table, wasi }).await?;
121121

@@ -157,11 +157,11 @@ async fn time() -> Result<()> {
157157
}
158158
}
159159

160-
let mut table = Table::new();
160+
let table = Table::new();
161161
let wasi = WasiCtxBuilder::new()
162162
.monotonic_clock(FakeMonotonicClock { now: Mutex::new(0) })
163163
.wall_clock(FakeWallClock)
164-
.build(&mut table)?;
164+
.build();
165165

166166
let (mut store, command) =
167167
instantiate(get_component("time"), CommandCtx { table, wasi }).await?;
@@ -175,13 +175,12 @@ async fn time() -> Result<()> {
175175

176176
#[test_log::test(tokio::test(flavor = "multi_thread"))]
177177
async fn stdin() -> Result<()> {
178-
let mut table = Table::new();
178+
let table = Table::new();
179179
let wasi = WasiCtxBuilder::new()
180-
.stdin(
181-
MemoryInputPipe::new("So rested he by the Tumtum tree".into()),
182-
IsATTY::No,
183-
)
184-
.build(&mut table)?;
180+
.stdin(MemoryInputPipe::new(
181+
"So rested he by the Tumtum tree".into(),
182+
))
183+
.build();
185184

186185
let (mut store, command) =
187186
instantiate(get_component("stdin"), CommandCtx { table, wasi }).await?;
@@ -195,13 +194,12 @@ async fn stdin() -> Result<()> {
195194

196195
#[test_log::test(tokio::test(flavor = "multi_thread"))]
197196
async fn poll_stdin() -> Result<()> {
198-
let mut table = Table::new();
197+
let table = Table::new();
199198
let wasi = WasiCtxBuilder::new()
200-
.stdin(
201-
MemoryInputPipe::new("So rested he by the Tumtum tree".into()),
202-
IsATTY::No,
203-
)
204-
.build(&mut table)?;
199+
.stdin(MemoryInputPipe::new(
200+
"So rested he by the Tumtum tree".into(),
201+
))
202+
.build();
205203

206204
let (mut store, command) =
207205
instantiate(get_component("poll_stdin"), CommandCtx { table, wasi }).await?;
@@ -215,11 +213,11 @@ async fn poll_stdin() -> Result<()> {
215213

216214
#[test_log::test(tokio::test(flavor = "multi_thread"))]
217215
async fn env() -> Result<()> {
218-
let mut table = Table::new();
216+
let table = Table::new();
219217
let wasi = WasiCtxBuilder::new()
220218
.env("frabjous", "day")
221219
.env("callooh", "callay")
222-
.build(&mut table)?;
220+
.build();
223221

224222
let (mut store, command) =
225223
instantiate(get_component("env"), CommandCtx { table, wasi }).await?;
@@ -239,10 +237,10 @@ async fn file_read() -> Result<()> {
239237

240238
let open_dir = Dir::open_ambient_dir(dir.path(), ambient_authority())?;
241239

242-
let mut table = Table::new();
240+
let table = Table::new();
243241
let wasi = WasiCtxBuilder::new()
244242
.preopened_dir(open_dir, DirPerms::all(), FilePerms::all(), "/")
245-
.build(&mut table)?;
243+
.build();
246244

247245
let (mut store, command) =
248246
instantiate(get_component("file_read"), CommandCtx { table, wasi }).await?;
@@ -263,10 +261,10 @@ async fn file_append() -> Result<()> {
263261

264262
let open_dir = Dir::open_ambient_dir(dir.path(), ambient_authority())?;
265263

266-
let mut table = Table::new();
264+
let table = Table::new();
267265
let wasi = WasiCtxBuilder::new()
268266
.preopened_dir(open_dir, DirPerms::all(), FilePerms::all(), "/")
269-
.build(&mut table)?;
267+
.build();
270268

271269
let (mut store, command) =
272270
instantiate(get_component("file_append"), CommandCtx { table, wasi }).await?;
@@ -296,10 +294,10 @@ async fn file_dir_sync() -> Result<()> {
296294

297295
let open_dir = Dir::open_ambient_dir(dir.path(), ambient_authority())?;
298296

299-
let mut table = Table::new();
297+
let table = Table::new();
300298
let wasi = WasiCtxBuilder::new()
301299
.preopened_dir(open_dir, DirPerms::all(), FilePerms::all(), "/")
302-
.build(&mut table)?;
300+
.build();
303301

304302
let (mut store, command) =
305303
instantiate(get_component("file_dir_sync"), CommandCtx { table, wasi }).await?;
@@ -313,8 +311,8 @@ async fn file_dir_sync() -> Result<()> {
313311

314312
#[test_log::test(tokio::test(flavor = "multi_thread"))]
315313
async fn exit_success() -> Result<()> {
316-
let mut table = Table::new();
317-
let wasi = WasiCtxBuilder::new().build(&mut table)?;
314+
let table = Table::new();
315+
let wasi = WasiCtxBuilder::new().build();
318316

319317
let (mut store, command) =
320318
instantiate(get_component("exit_success"), CommandCtx { table, wasi }).await?;
@@ -330,8 +328,8 @@ async fn exit_success() -> Result<()> {
330328

331329
#[test_log::test(tokio::test(flavor = "multi_thread"))]
332330
async fn exit_default() -> Result<()> {
333-
let mut table = Table::new();
334-
let wasi = WasiCtxBuilder::new().build(&mut table)?;
331+
let table = Table::new();
332+
let wasi = WasiCtxBuilder::new().build();
335333

336334
let (mut store, command) =
337335
instantiate(get_component("exit_default"), CommandCtx { table, wasi }).await?;
@@ -343,8 +341,8 @@ async fn exit_default() -> Result<()> {
343341

344342
#[test_log::test(tokio::test(flavor = "multi_thread"))]
345343
async fn exit_failure() -> Result<()> {
346-
let mut table = Table::new();
347-
let wasi = WasiCtxBuilder::new().build(&mut table)?;
344+
let table = Table::new();
345+
let wasi = WasiCtxBuilder::new().build();
348346

349347
let (mut store, command) =
350348
instantiate(get_component("exit_failure"), CommandCtx { table, wasi }).await?;
@@ -360,8 +358,8 @@ async fn exit_failure() -> Result<()> {
360358

361359
#[test_log::test(tokio::test(flavor = "multi_thread"))]
362360
async fn exit_panic() -> Result<()> {
363-
let mut table = Table::new();
364-
let wasi = WasiCtxBuilder::new().build(&mut table)?;
361+
let table = Table::new();
362+
let wasi = WasiCtxBuilder::new().build();
365363

366364
let (mut store, command) =
367365
instantiate(get_component("exit_panic"), CommandCtx { table, wasi }).await?;
@@ -388,12 +386,12 @@ async fn directory_list() -> Result<()> {
388386

389387
let open_dir = Dir::open_ambient_dir(dir.path(), ambient_authority())?;
390388

391-
let mut table = Table::new();
389+
let table = Table::new();
392390
let wasi = WasiCtxBuilder::new()
393391
.inherit_stdout()
394392
.inherit_stderr()
395393
.preopened_dir(open_dir, DirPerms::all(), FilePerms::all(), "/")
396-
.build(&mut table)?;
394+
.build();
397395

398396
let (mut store, command) =
399397
instantiate(get_component("directory_list"), CommandCtx { table, wasi }).await?;
@@ -407,8 +405,8 @@ async fn directory_list() -> Result<()> {
407405

408406
#[test_log::test(tokio::test(flavor = "multi_thread"))]
409407
async fn default_clocks() -> Result<()> {
410-
let mut table = Table::new();
411-
let wasi = WasiCtxBuilder::new().build(&mut table)?;
408+
let table = Table::new();
409+
let wasi = WasiCtxBuilder::new().build();
412410

413411
let (mut store, command) =
414412
instantiate(get_component("default_clocks"), CommandCtx { table, wasi }).await?;
@@ -422,8 +420,8 @@ async fn default_clocks() -> Result<()> {
422420

423421
#[test_log::test(tokio::test(flavor = "multi_thread"))]
424422
async fn export_cabi_realloc() -> Result<()> {
425-
let mut table = Table::new();
426-
let wasi = WasiCtxBuilder::new().build(&mut table)?;
423+
let table = Table::new();
424+
let wasi = WasiCtxBuilder::new().build();
427425
let (mut store, command) = instantiate(
428426
get_component("export_cabi_realloc"),
429427
CommandCtx { table, wasi },
@@ -444,11 +442,11 @@ async fn read_only() -> Result<()> {
444442
std::fs::File::create(dir.path().join("bar.txt"))?.write_all(b"And stood awhile in thought")?;
445443
std::fs::create_dir(dir.path().join("sub"))?;
446444

447-
let mut table = Table::new();
445+
let table = Table::new();
448446
let open_dir = Dir::open_ambient_dir(dir.path(), ambient_authority())?;
449447
let wasi = WasiCtxBuilder::new()
450448
.preopened_dir(open_dir, DirPerms::READ, FilePerms::READ, "/")
451-
.build(&mut table)?;
449+
.build();
452450

453451
let (mut store, command) =
454452
instantiate(get_component("read_only"), CommandCtx { table, wasi }).await?;
@@ -461,16 +459,15 @@ async fn read_only() -> Result<()> {
461459
}
462460

463461
#[test_log::test(tokio::test(flavor = "multi_thread"))]
464-
#[ignore] // FIXME: this calls get_stdin but it's already consumed
465462
async fn stream_pollable_lifetimes() -> Result<()> {
466463
// Test program has two modes, dispatching based on argument.
467464
{
468465
// Correct execution: should succeed
469-
let mut table = Table::new();
466+
let table = Table::new();
470467
let wasi = WasiCtxBuilder::new()
471468
.args(&["correct"])
472-
.stdin(MemoryInputPipe::new(" ".into()), IsATTY::No)
473-
.build(&mut table)?;
469+
.stdin(MemoryInputPipe::new(" ".into()))
470+
.build();
474471

475472
let (mut store, command) = instantiate(
476473
get_component("stream_pollable_lifetimes"),
@@ -486,11 +483,11 @@ async fn stream_pollable_lifetimes() -> Result<()> {
486483
}
487484
{
488485
// Incorrect execution: should trap with a TableError::HasChildren
489-
let mut table = Table::new();
486+
let table = Table::new();
490487
let wasi = WasiCtxBuilder::new()
491488
.args(&["trap"])
492-
.stdin(MemoryInputPipe::new(" ".into()), IsATTY::No)
493-
.build(&mut table)?;
489+
.stdin(MemoryInputPipe::new(" ".into()))
490+
.build();
494491

495492
let (mut store, command) = instantiate(
496493
get_component("stream_pollable_lifetimes"),

crates/test-programs/tests/reactor.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,8 @@ async fn instantiate(
8181

8282
#[test_log::test(tokio::test)]
8383
async fn reactor_tests() -> Result<()> {
84-
let mut table = Table::new();
85-
let wasi = WasiCtxBuilder::new()
86-
.env("GOOD_DOG", "gussie")
87-
.build(&mut table)?;
84+
let table = Table::new();
85+
let wasi = WasiCtxBuilder::new().env("GOOD_DOG", "gussie").build();
8886

8987
let (mut store, reactor) =
9088
instantiate(get_component("reactor_tests"), ReactorCtx { table, wasi }).await?;

crates/test-programs/tests/wasi-http-components-sync.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use wasmtime::{
44
Config, Engine, Store,
55
};
66
use wasmtime_wasi::preview2::{
7-
command::sync::Command, pipe::MemoryOutputPipe, IsATTY, Table, WasiCtx, WasiCtxBuilder,
7+
command::sync::Command, pipe::MemoryOutputPipe, Table, WasiCtx, WasiCtxBuilder,
88
WasiView,
99
};
1010
use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView};
@@ -71,18 +71,18 @@ fn run(name: &str) -> anyhow::Result<()> {
7171
let stdout = MemoryOutputPipe::new(4096);
7272
let stderr = MemoryOutputPipe::new(4096);
7373
let r = {
74-
let mut table = Table::new();
74+
let table = Table::new();
7575
let component = get_component(name);
7676

7777
// Create our wasi context.
7878
let mut builder = WasiCtxBuilder::new();
79-
builder.stdout(stdout.clone(), IsATTY::No);
80-
builder.stderr(stderr.clone(), IsATTY::No);
79+
builder.stdout(stdout.clone());
80+
builder.stderr(stderr.clone());
8181
builder.arg(name);
8282
for (var, val) in test_programs::wasi_tests_environment() {
8383
builder.env(var, val);
8484
}
85-
let wasi = builder.build(&mut table)?;
85+
let wasi = builder.build();
8686
let http = WasiHttpCtx {};
8787

8888
let (mut store, command) = instantiate_component(component, Ctx { table, wasi, http })?;

crates/test-programs/tests/wasi-http-components.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use wasmtime::{
44
Config, Engine, Store,
55
};
66
use wasmtime_wasi::preview2::{
7-
command::Command, pipe::MemoryOutputPipe, IsATTY, Table, WasiCtx, WasiCtxBuilder, WasiView,
7+
command::Command, pipe::MemoryOutputPipe, Table, WasiCtx, WasiCtxBuilder, WasiView,
88
};
99
use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView};
1010

@@ -70,18 +70,18 @@ async fn run(name: &str) -> anyhow::Result<()> {
7070
let stdout = MemoryOutputPipe::new(4096);
7171
let stderr = MemoryOutputPipe::new(4096);
7272
let r = {
73-
let mut table = Table::new();
73+
let table = Table::new();
7474
let component = get_component(name);
7575

7676
// Create our wasi context.
7777
let mut builder = WasiCtxBuilder::new();
78-
builder.stdout(stdout.clone(), IsATTY::No);
79-
builder.stderr(stderr.clone(), IsATTY::No);
78+
builder.stdout(stdout.clone());
79+
builder.stderr(stderr.clone());
8080
builder.arg(name);
8181
for (var, val) in test_programs::wasi_tests_environment() {
8282
builder.env(var, val);
8383
}
84-
let wasi = builder.build(&mut table)?;
84+
let wasi = builder.build();
8585
let http = WasiHttpCtx;
8686

8787
let (mut store, command) =

0 commit comments

Comments
 (0)