Skip to content

Commit 66239cb

Browse files
authored
More component OOM tests (#13074)
* Add OOM test for component InstancePre::instantiate * Add OOM test for component Func::call * Add OOM test for component TypedFunc::call * Add OOM test for component Linker::instantiate * Add OOM test for component ResourceAny::resource_drop * Add OOM test for component Linker::instantiate_pre * Add OOM test for component Linker::substituted_component_type
1 parent cb6f392 commit 66239cb

3 files changed

Lines changed: 265 additions & 0 deletions

File tree

crates/fuzzing/tests/oom/component_func.rs

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,121 @@ async fn component_typed_func_call_async() -> Result<()> {
128128
})
129129
.await
130130
}
131+
132+
#[test]
133+
fn component_instance_pre_instantiate() -> Result<()> {
134+
let component_bytes = {
135+
let mut config = Config::new();
136+
config.concurrency_support(false);
137+
let engine = Engine::new(&config)?;
138+
Component::new(
139+
&engine,
140+
r#"
141+
(component
142+
(core module $m
143+
(func (export "id") (param i32) (result i32) (local.get 0))
144+
)
145+
(core instance $i (instantiate $m))
146+
(func (export "id") (param "x" s32) (result s32)
147+
(canon lift (core func $i "id"))
148+
)
149+
)
150+
"#,
151+
)?
152+
.serialize()?
153+
};
154+
let mut config = Config::new();
155+
config.enable_compiler(false);
156+
config.concurrency_support(false);
157+
let engine = Engine::new(&config)?;
158+
let component = unsafe { Component::deserialize(&engine, &component_bytes)? };
159+
let linker = Linker::<()>::new(&engine);
160+
let instance_pre = linker.instantiate_pre(&component)?;
161+
162+
OomTest::new().test(|| {
163+
let mut store = Store::try_new(&engine, ())?;
164+
let _instance = instance_pre.instantiate(&mut store)?;
165+
Ok(())
166+
})
167+
}
168+
169+
#[test]
170+
fn component_func_call() -> Result<()> {
171+
let component_bytes = {
172+
let mut config = Config::new();
173+
config.concurrency_support(false);
174+
let engine = Engine::new(&config)?;
175+
Component::new(
176+
&engine,
177+
r#"
178+
(component
179+
(core module $m
180+
(func (export "id") (param i32) (result i32) (local.get 0))
181+
)
182+
(core instance $i (instantiate $m))
183+
(func (export "id") (param "x" s32) (result s32)
184+
(canon lift (core func $i "id"))
185+
)
186+
)
187+
"#,
188+
)?
189+
.serialize()?
190+
};
191+
let mut config = Config::new();
192+
config.enable_compiler(false);
193+
config.concurrency_support(false);
194+
let engine = Engine::new(&config)?;
195+
let component = unsafe { Component::deserialize(&engine, &component_bytes)? };
196+
let linker = Linker::<()>::new(&engine);
197+
let instance_pre = linker.instantiate_pre(&component)?;
198+
199+
OomTest::new().test(|| {
200+
let mut store = Store::try_new(&engine, ())?;
201+
let instance = instance_pre.instantiate(&mut store)?;
202+
let func = instance.get_func(&mut store, "id").unwrap();
203+
let mut results = [Val::S32(0)];
204+
func.call(&mut store, &[Val::S32(42)], &mut results)?;
205+
assert_eq!(results[0], Val::S32(42));
206+
Ok(())
207+
})
208+
}
209+
210+
#[test]
211+
fn component_typed_func_call() -> Result<()> {
212+
let component_bytes = {
213+
let mut config = Config::new();
214+
config.concurrency_support(false);
215+
let engine = Engine::new(&config)?;
216+
Component::new(
217+
&engine,
218+
r#"
219+
(component
220+
(core module $m
221+
(func (export "id") (param i32) (result i32) (local.get 0))
222+
)
223+
(core instance $i (instantiate $m))
224+
(func (export "id") (param "x" s32) (result s32)
225+
(canon lift (core func $i "id"))
226+
)
227+
)
228+
"#,
229+
)?
230+
.serialize()?
231+
};
232+
let mut config = Config::new();
233+
config.enable_compiler(false);
234+
config.concurrency_support(false);
235+
let engine = Engine::new(&config)?;
236+
let component = unsafe { Component::deserialize(&engine, &component_bytes)? };
237+
let linker = Linker::<()>::new(&engine);
238+
let instance_pre = linker.instantiate_pre(&component)?;
239+
240+
OomTest::new().test(|| {
241+
let mut store = Store::try_new(&engine, ())?;
242+
let instance = instance_pre.instantiate(&mut store)?;
243+
let id = instance.get_typed_func::<(i32,), (i32,)>(&mut store, "id")?;
244+
let result = id.call(&mut store, (42,))?;
245+
assert_eq!(result, (42,));
246+
Ok(())
247+
})
248+
}

crates/fuzzing/tests/oom/component_linker.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,109 @@ async fn component_linker_instantiate_async() -> Result<()> {
4141
})
4242
.await
4343
}
44+
45+
#[test]
46+
fn component_linker_instantiate() -> Result<()> {
47+
let component_bytes = {
48+
let mut config = Config::new();
49+
config.concurrency_support(false);
50+
let engine = Engine::new(&config)?;
51+
Component::new(
52+
&engine,
53+
r#"
54+
(component
55+
(core module $m
56+
(func (export "id") (param i32) (result i32) (local.get 0))
57+
)
58+
(core instance $i (instantiate $m))
59+
(func (export "id") (param "x" s32) (result s32)
60+
(canon lift (core func $i "id"))
61+
)
62+
)
63+
"#,
64+
)?
65+
.serialize()?
66+
};
67+
let mut config = Config::new();
68+
config.enable_compiler(false);
69+
config.concurrency_support(false);
70+
let engine = Engine::new(&config)?;
71+
let component = unsafe { Component::deserialize(&engine, &component_bytes)? };
72+
let linker = Linker::<()>::new(&engine);
73+
74+
OomTest::new().test(|| {
75+
let mut store = Store::try_new(&engine, ())?;
76+
let _instance = linker.instantiate(&mut store, &component)?;
77+
Ok(())
78+
})
79+
}
80+
81+
#[test]
82+
fn component_linker_instantiate_pre() -> Result<()> {
83+
let component_bytes = {
84+
let mut config = Config::new();
85+
config.concurrency_support(false);
86+
let engine = Engine::new(&config)?;
87+
Component::new(
88+
&engine,
89+
r#"
90+
(component
91+
(core module $m
92+
(func (export "id") (param i32) (result i32) (local.get 0))
93+
)
94+
(core instance $i (instantiate $m))
95+
(func (export "id") (param "x" s32) (result s32)
96+
(canon lift (core func $i "id"))
97+
)
98+
)
99+
"#,
100+
)?
101+
.serialize()?
102+
};
103+
let mut config = Config::new();
104+
config.enable_compiler(false);
105+
config.concurrency_support(false);
106+
let engine = Engine::new(&config)?;
107+
let component = unsafe { Component::deserialize(&engine, &component_bytes)? };
108+
let linker = Linker::<()>::new(&engine);
109+
110+
OomTest::new().test(|| {
111+
let _instance_pre = linker.instantiate_pre(&component)?;
112+
Ok(())
113+
})
114+
}
115+
116+
#[test]
117+
fn component_linker_substituted_component_type() -> Result<()> {
118+
let component_bytes = {
119+
let mut config = Config::new();
120+
config.concurrency_support(false);
121+
let engine = Engine::new(&config)?;
122+
Component::new(
123+
&engine,
124+
r#"
125+
(component
126+
(core module $m
127+
(func (export "id") (param i32) (result i32) (local.get 0))
128+
)
129+
(core instance $i (instantiate $m))
130+
(func (export "id") (param "x" s32) (result s32)
131+
(canon lift (core func $i "id"))
132+
)
133+
)
134+
"#,
135+
)?
136+
.serialize()?
137+
};
138+
let mut config = Config::new();
139+
config.enable_compiler(false);
140+
config.concurrency_support(false);
141+
let engine = Engine::new(&config)?;
142+
let component = unsafe { Component::deserialize(&engine, &component_bytes)? };
143+
let linker = Linker::<()>::new(&engine);
144+
145+
OomTest::new().test(|| {
146+
let _ty = linker.substituted_component_type(&component)?;
147+
Ok(())
148+
})
149+
}

crates/fuzzing/tests/oom/component_resource.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,44 @@ async fn component_resource_any_resource_drop_async() -> Result<()> {
4646
})
4747
.await
4848
}
49+
50+
#[test]
51+
fn component_resource_any_resource_drop() -> Result<()> {
52+
let component_bytes = {
53+
let mut config = Config::new();
54+
config.concurrency_support(false);
55+
let engine = Engine::new(&config)?;
56+
Component::new(
57+
&engine,
58+
r#"
59+
(component
60+
(type $t' (resource (rep i32)))
61+
(export $t "t" (type $t'))
62+
63+
(core func $new (canon resource.new $t))
64+
(func (export "mk") (param "r" u32) (result (own $t))
65+
(canon lift (core func $new))
66+
)
67+
)
68+
"#,
69+
)?
70+
.serialize()?
71+
};
72+
let mut config = Config::new();
73+
config.enable_compiler(false);
74+
config.concurrency_support(false);
75+
let engine = Engine::new(&config)?;
76+
let component = unsafe { Component::deserialize(&engine, &component_bytes)? };
77+
let linker = Linker::<()>::new(&engine);
78+
let instance_pre = linker.instantiate_pre(&component)?;
79+
80+
// Error propagation via anyhow allocates after OOM.
81+
OomTest::new().allow_alloc_after_oom(true).test(|| {
82+
let mut store = Store::try_new(&engine, ())?;
83+
let instance = instance_pre.instantiate(&mut store)?;
84+
let mk = instance.get_typed_func::<(u32,), (ResourceAny,)>(&mut store, "mk")?;
85+
let (resource,) = mk.call(&mut store, (42,))?;
86+
resource.resource_drop(&mut store)?;
87+
Ok(())
88+
})
89+
}

0 commit comments

Comments
 (0)