-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proof of concept of bindgen tests using componentize-py #234
Proof of concept of bindgen tests using componentize-py #234
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks awesome, thank you so much for pushing on this!
the tests still take around 5-10 seconds
One thing that might help a lot here is Wasmtime's incremental compilation feature. That being said this isn't currently exposed in the C API, but in Rust it would look something like this where all tests are derived from the same Engine
which has one large incremental cache.
If there's a significant amount of time taken in componentize-py though that wouldn't help much since that's just the wasmtime compilation side of things. @dicej do you have any suggestions for optimizing the runtime here for componentize-py perhaps?
tests/bindgen/__init__.py
Outdated
raise RuntimeError("Could not find componentize-py executable.") | ||
with tempfile.NamedTemporaryFile('w') as f: | ||
output_wasm = str(f.name + '.wasm') | ||
with chdir(testcase.app_dir): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the cwd is a global property of the process could this be done just for the subprocess.run
call with the cwd
keyword argument?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll get that updated, this was leftover from when I was importing componentize_py
directly, but I was running into issues with it affecting subsequent tests, so switching to an external process fixed the issue.
tests/bindgen/test_bindgen.py
Outdated
def test_bare_funcs(): | ||
testcase = BindgenTestCase( | ||
guest_code_dir='bare_funcs', | ||
world_name='barefuncs', | ||
) | ||
store, root = generate_bindings(testcase) | ||
assert root.foo(store, 10) == 11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to put these individual tests within each folder? For example keeping everything self-contained within each sub-folder to avoid a large listing of all tests here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll see if I can get that working. I had to configure pytest to ignore these directories to avoid issues with module name conflicts with app.py
, but there might be a way around this. Worst case, we can split them out into separate files in this directory, similar to the existing structure in codegen/
.
Creating a component with Another approach might be to add an option to |
Ah makes sense! Incremental compilation would help in this case I think because the python.wasm across multiple invocations of componentize-py are probably all the same or very similar. That would require cross-process caching though which could get nontrivial. Could componentize-py grow a flag for which which could be opted-in-to on x64 perhaps? That might be good to test here and see if it helps |
Yeah, or even just add something like if cfg!(target_arch = "x86_64") {
config.strategy(Strategy::Winch);
} |
BTW, the trick I use in |
The basic idea is that you define a wit file along with guest code in Python. We can then generate a wasm component using componentize-py, host bindings using `wasmtime.bindgen`, and then test that the generated bindings work as expected.
* Each test case is now in the same directory with the corresponding WIT file and guest code (app.py). * The helper functions for generating wasm components and host bindings is moved to a pytest fixture to avoid relative package issues when using direct imports. * Remove the use of changing the cwd in the test process.
a429569
to
08ca78b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again very much for this! I like the way this is shaping up and I'm happy enough with this that we can handle the slow-tests part down-the-road.
This is a sketch of the idea suggested in #232 (review) where instead of hand writing wat files, you can instead write a wit file and corresponding guest code in Python, and we then use
componentize-py
to generate a wasm component for which we then generate and test host bindings viawasmtime.bindgen
.Not intending for this to be merged, just putting something up to start a discussion.
I ported a couple of tests from
tests/codegen
to get a sense of what these tests look like (these are intests/bindgen/test_bindgen.py
).Essentially, create a subdirectory under
tests/bindgen
with the wit/guest code:Wit file:
Guest code:
You can then write a test for this using:
The
generate_bindings()
will build the wasm component viacomponentize-py
, generate bindings usingwasmtime.bindgen
, and then instantiate and return the root module back to the caller for testing (probably would want this to be optional).These tests are substantially slower than the existing tests (which we'd expect). These take about 20-30 seconds on my machine with just the three tests ported over. Even if we implement some mtime cache to skip the
componentize-py
generation, the tests still take around 5-10 seconds. I don't think this is a deal breaker necessarily, but something to consider.Let me know what you think. I can flesh the rest of this out if this seems like something worth pursuing.