-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Implement open() in library_wasmfs.js #18919
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
Implement open() in library_wasmfs.js #18919
Conversation
Added FS.open() to library_wasmfs.js and wrote tests to make sure files are being opened with different flags.
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.
Looks pretty good, thanks! A couple notes/questions:
- It looks like test_open_wasmfs.out should at least have "success" in it.
- Are there existing tests that use
FS.open
that we can already run with WasmFS enabled instead of adding a new test?
test/fs/test_open_wasmfs.c
Outdated
@@ -0,0 +1,37 @@ | |||
/* | |||
* Copyright 2018 The Emscripten Authors. All rights reserved. |
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.
* Copyright 2018 The Emscripten Authors. All rights reserved. | |
* Copyright 2023 The Emscripten Authors. All rights reserved. |
src/library_wasmfs.js
Outdated
// According to the existing File System docs, Emscripten does not | ||
// support user permissions | ||
|
||
// "The underlying implementation does not support user | ||
// or group permissions. The file permissions set in mode | ||
// are only used if the file is created. The caller is always | ||
// treated as the owner of the file, and only those permissions apply." | ||
|
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.
// According to the existing File System docs, Emscripten does not | |
// support user permissions | |
// "The underlying implementation does not support user | |
// or group permissions. The file permissions set in mode | |
// are only used if the file is created. The caller is always | |
// treated as the owner of the file, and only those permissions apply." | |
Quoting the docs here probably isn't necessary, and runs the risk of going stale.
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 really appreciate your code review. Thank you. I have answered your questions below.
- I remember I originally created test_open_wasmfs.out because of a "file not found" error when I was running a different test. It looks like the method
self.do_runf()
takes in an expected output that it checks on stdout without any need to create out files.
Lines 1280 to 1281 in 496a4f4
def do_runf(self, filename, expected_output=None, **kwargs): return self._build_and_run(filename, expected_output, **kwargs)
I think the .out file is necessary for running tests with self.do_run_in_out_file_test"
, so I deleted the .out
file and the test still passed. I'm calling test_fs_open_wasmfs
with self.do_runf()
(The one above).
Lines 1287 to 1298 in 496a4f4
def do_run_in_out_file_test(self, *path, **kwargs): | |
srcfile = test_file(*path) | |
out_suffix = kwargs.pop('out_suffix', '') | |
outfile = shared.unsuffixed(srcfile) + out_suffix + '.out' | |
if EMTEST_REBASELINE: | |
expected = None | |
else: | |
expected = read_file(outfile) | |
output = self._build_and_run(srcfile, expected, **kwargs) | |
if EMTEST_REBASELINE: | |
write_file(outfile, output) | |
return output |
- I did find some other test files that have
FS.open()
:test_llseek.c
,test_nodefs.c
, andtest_write.cpp
. All three tests call some fs functions that aren't yet inlibrary_wasmfs.js
yet so the tests all failed.
Note - I noticed that my pull request code fails the test-wasm64
in circleci due to
TypeError: Cannot convert 65488 to a BigInt
at /tmp/emtest_89oyqghg/emscripten_test_wasm64l_4uf_hulx/test_open_wasmfs.js:909:22
From what I'm understanding, this seems to be an error with the way I wrote my test, rather than the wasmfs library. However, is it possible that my actual wasmfs code has some issues?
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, adding a new test file sounds good to me, then.
I'm not sure off the top of my head what could be going wrong with the wasm64 test. It would be good to dig into that more. Can you at least reproduce the problem locally?
Edited comments in test_open_wasmfs.c and library_wasmfs.js Added additional test for test_write_wasmfs that currently will not pass
test/test_core.py
Outdated
def test_fs_write_wasmfs(self): | ||
self.emcc_args += ['-sWASMFS'] | ||
self.emcc_args += ['-sFORCE_FILESYSTEM'] | ||
self.do_run_in_out_file_test('fs/test_write.cpp') |
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.
There is an @also_with_wasmfs_js
decorator you can attach to the previous test function instead of having to write a new test function 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.
Nice work!
Looks good aside from the open comments and discussion.
test/fs/test_open_wasmfs.c
Outdated
|
||
int main() { | ||
EM_ASM( | ||
FS.writeFile('testfile', 'a=1\nb=2\n'); // writeFile already works with WasmFS |
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.
FS.writeFile('testfile', 'a=1\nb=2\n'); // writeFile already works with WasmFS | |
FS.writeFile('testfile', 'a=1\nb=2\n'); |
(that comment helps read this PR, but it doesn't seem like it would be useful after this PR lands, so it could've been in the PR as a comment and not in the source code)
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've removed this comment. I'll make sure to keep this in mind going forward!
@tlively @kripken Lines 1076 to 1086 in 2f70f77
I found this after trying the I think this means that the |
@jameshu15869, good point. Exactly mimicking the stream objects from the legacy API would be a lot of work, but is also necessary for full compatibility for existing code. Maybe we can add a TODO about that and land this PR, then handle that work in a follow-up? |
+1 for @tlively 's comment. Also, I'd say that in general there is an open question here about how much we should match the old JS API. Emitting JS objects that look identical to before would seem like the obvious thing to do, but it might not be necessary and might also be very difficult to do (some might require more calls into wasm to get info, and the info might need reshaping perhaps). Seeing what the current tests require and doing the minimum for them might be ok. But we can also discuss each case specifically to find the best approach, and we'll be flexible here. |
Cleaned up remaining discussion comment in test_open_wasmfs.c Combined writeFile tests for JS and WasmFS into 1 test using @also_with_wasmfs
@tlively @kripken I wasn't able to reproduce the CI error locally. Does CircleCI just run the testing files "as-is"? Or does it run against some kind of larger input or something? I've tried searching for 65488 (The integer that causes an error) in the code and there seems to be not relevant results. |
Yeah, CircleCI runs the same tests you should be able to run locally. When you try to reproduce, are you using To debug this further, I would run with |
@tlively |
Added to64 wrapper around buffer to solve problem with wasm64l testing locally.
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.
LGTM, thanks!
self.emcc_args += ['-sWASMFS'] | ||
self.emcc_args += ['-sFORCE_FILESYSTEM'] | ||
self.do_run_in_out_file_test('fs/test_writeFile.cpp') | ||
self.do_runf(test_file('fs/test_open_wasmfs.c'), 'success') |
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.
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.
James wrote,
I did find some other test files that have FS.open(): test_llseek.c, test_nodefs.c, and test_write.cpp. All three tests call some fs functions that aren't yet in library_wasmfs.js yet so the tests all failed.
So we have a bootstrapping problem with our tests. Once we have better API coverage we will be able to stop writing new tests and will be able to consolidate our existing tests.
We had/have similar test bootstrapping problems with the WasmFS syscall API as well.
@jameshu15869, thanks for your work on this! I'm glad you enjoyed it. Yes, you can go ahead and delete the branch. |
Implemented FS.open() in library_wasmfs.js
Added tests to test FS.open() with different flags.