Skip to content

Commit 7aafc04

Browse files
authored
Merge pull request #123 from wingo/wall-clock
Add tests for wasip3 wall_clock and for multiple outstanding wait_for invocations
2 parents 94444d2 + 49dd2b7 commit 7aafc04

2 files changed

Lines changed: 114 additions & 0 deletions

File tree

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
extern crate wit_bindgen;
2+
3+
wit_bindgen::generate!({
4+
inline: r"
5+
package test:test;
6+
7+
world test {
8+
include wasi:clocks/imports@0.3.0-rc-2025-09-16;
9+
include wasi:cli/command@0.3.0-rc-2025-09-16;
10+
}
11+
",
12+
// Work around https://github.com/bytecodealliance/wasm-tools/issues/2285.
13+
features:["clocks-timezone"],
14+
generate_all
15+
});
16+
17+
use core::task::{Context, Poll, Waker};
18+
use monotonic_clock::Instant;
19+
use std::future::Future;
20+
use wasi::clocks::monotonic_clock;
21+
22+
// Offsets relative to "now" at which to wait_until(), in nanoseconds.
23+
// These are 20 values chosen uniformly randomly over the range [-5
24+
// milliseconds, +10 milliseconds].
25+
const OFFSETS: &[i64] = &[
26+
6628081, 851815, 6208892, 1511472, -1206606, 8926559, 2828840, 4561077, 5375188, 8253693,
27+
2403137, 6055827, 5658461, -3972826, -561642, 6360445, 9966678, 2946734, 2012267, -3456550,
28+
];
29+
30+
fn add_offset(t: Instant, dt: i64) -> Instant {
31+
if dt < 0 {
32+
t.saturating_sub(-dt as u64)
33+
} else {
34+
t.saturating_add(dt as u64)
35+
}
36+
}
37+
38+
async fn test_multi_clock_wait() {
39+
let mut cx = Context::from_waker(Waker::noop());
40+
41+
let times: Vec<Instant> = {
42+
let start = monotonic_clock::now();
43+
OFFSETS.iter().map(|ns| add_offset(start, *ns)).collect()
44+
};
45+
46+
let mut completed: Vec<bool> = times.iter().map(|_| false).collect();
47+
let mut waitables: Vec<_> = times
48+
.iter()
49+
.map(|t| -> _ { Box::pin(monotonic_clock::wait_until(*t)) })
50+
.collect();
51+
52+
for i in 0..waitables.len() {
53+
if !completed[i] {
54+
waitables[i].as_mut().await;
55+
assert!(times[i] <= monotonic_clock::now());
56+
completed[i] = true;
57+
}
58+
59+
for j in (i + 1)..waitables.len() {
60+
if !completed[j] && times[j] <= times[i] {
61+
assert_eq!(
62+
waitables[j].as_mut().poll(&mut cx),
63+
Poll::Ready(()),
64+
"waitable that should fire in past is ready"
65+
);
66+
completed[j] = true;
67+
}
68+
}
69+
}
70+
}
71+
72+
struct Component;
73+
export!(Component);
74+
impl exports::wasi::cli::run::Guest for Component {
75+
async fn run() -> Result<(), ()> {
76+
test_multi_clock_wait().await;
77+
Ok(())
78+
}
79+
}
80+
81+
fn main() {
82+
unreachable!("main is a stub");
83+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
extern crate wit_bindgen;
2+
3+
wit_bindgen::generate!({
4+
inline: r"
5+
package test:test;
6+
7+
world test {
8+
include wasi:clocks/imports@0.3.0-rc-2025-09-16;
9+
}
10+
",
11+
// Work around https://github.com/bytecodealliance/wasm-tools/issues/2285.
12+
features:["clocks-timezone"],
13+
generate_all
14+
});
15+
16+
use wasi::clocks::wall_clock;
17+
18+
const NANOSECOND: u32 = 1;
19+
const MICROSECOND: u32 = NANOSECOND * 1_000;
20+
const MILLISECOND: u32 = MICROSECOND * 1_000;
21+
const SECOND: u32 = MILLISECOND * 1_000;
22+
23+
fn verify_datetime(t: wall_clock::Datetime) {
24+
assert!(t.nanoseconds < SECOND)
25+
}
26+
27+
fn main() {
28+
// Not much we can assert about wall-clock time.
29+
verify_datetime(wall_clock::now());
30+
verify_datetime(wall_clock::get_resolution());
31+
}

0 commit comments

Comments
 (0)