Skip to content
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

WASI testing #713

Merged
merged 9 commits into from
Mar 10, 2021
Merged

WASI testing #713

merged 9 commits into from
Mar 10, 2021

Conversation

chfast
Copy link
Collaborator

@chfast chfast commented Feb 1, 2021

Closes #708

TODO

  • Separate wasm file loading from execution.
  • Consider separate unittest executable: fizzy-wasi-unittests. This relaxes WASI and TESTING CMake options dependencies. (resolution: It is fine for now; less CMake option combinations is good for development and nobody reported issues with compiling libuvwasi so far; the CMake option can always be added later).
  • Consider different location for fizzy::wasi library (resolution: it is fine where it is).
  • Create interface for WASI implementation / uvwasi. This allows mocking the implementation. (To be done in a separate PR later)

@chfast chfast requested review from axic and gumb0 February 1, 2021 20:25
@codecov
Copy link

codecov bot commented Feb 1, 2021

Codecov Report

Merging #713 (e550933) into master (a1280d6) will decrease coverage by 0.02%.
The diff coverage is 68.18%.

@@            Coverage Diff             @@
##           master     #713      +/-   ##
==========================================
- Coverage   99.26%   99.24%   -0.03%     
==========================================
  Files          74       76       +2     
  Lines       11462    11482      +20     
==========================================
+ Hits        11378    11395      +17     
- Misses         84       87       +3     
Flag Coverage Δ
rust 99.86% <ø> (ø)
spectests 90.55% <ø> (ø)
unittests 99.20% <68.18%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
tools/wasi/wasi.cpp 59.57% <64.70%> (+2.27%) ⬆️
tools/wasi/main.cpp 66.66% <66.66%> (ø)
test/unittests/wasi_test.cpp 100.00% <100.00%> (ø)

set(fizzy_include_dir ${PROJECT_SOURCE_DIR}/lib/fizzy)
add_library(wasi)
add_library(fizzy::wasi ALIAS wasi)
target_compile_features(wasi PUBLIC cxx_std_17)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed, fizzy:fizzy has it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fizzy::fizzy-internal is private dependency: the fizzy::wasi will be built with -std=c++17, but users of fizzy::wasi (e.g. fizzy-wasi tool) will not have this requirement.

Here it make sense to declare fizzy::wasi with C++17 because it uses a C++17 feature in the main header.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not relevant any more because fizzy::wasi now links fizzy::fizzy-internal publicly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not relevant any more because fizzy::wasi now links fizzy::fizzy-internal publicly.

Why does it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because now Fizzy is included in the wasi.hpp.

Copy link
Collaborator Author

@chfast chfast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: all necessary changes are done to allow writing "top-down" unit tests - you can provide input as wat2wasm comment and check result and error string. For full testability we need WASI interface abstraction, but this should be done in a separate PR.

Without WASI abstraction we still have some integration tests in CTest. These are also nice so we know that the basic features of libuvwasi are working fine.

Finally, some unit tests truly accessing filesystem can be done in GTest provided it has some helpers creating/deleting temporary files.

Also see updated description.


bool run(int argc, const char** argv)
std::optional<bytes> load_wasm_binary(const std::filesystem::path& path, std::ostream& err)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function has pretty bad API, but I'm not sure how exactly improve it right now.
Also current error reporting is in some middle ground: it provides some additional but not complete set of diagnostics. And finally, the std::ifstream can sometimes be in "fail" state but it can also throw an exception in other cases...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how filesystem::path works but maybe this function should take a string (provided by user) and create filesytem::path inside, handling the errors like invalid symbols in path.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered the following options and used the one which is the easiest to use at the moment.

  1. const char* - only literals and argv[] work really,
  2. const std::string& - specific string type used, conversion from const char* is needed.
  3. std::string_view - does not work with std::ifstream - conversion to std::string is needed.
  4. std::filesystem::path - works with everything, emphasize that this is path.

I agree that invalid path format should be also handled inside. In the some time, there are other error cases that are not handled explicitly.

So switch to some other type?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I imagined it like taking string_view then constucting path out of it, and then ifstream out of this path)

I'm fine to leave it like this for now. At some point exceptions thrown by path constructor will need to be handled (when we address @todo Make noexcept.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@chfast
Copy link
Collaborator Author

chfast commented Feb 23, 2021

Lastly, this has triggered a know bug in stdlibc++'s std::ostringstream implementation: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97415.

I think we should disable GCC sanitizer for GCC 10 and wait for GCC 11 release (or use experimental Debian package).

@chfast chfast marked this pull request as ready for review February 23, 2021 17:39
@chfast chfast requested a review from gumb0 February 23, 2021 17:39
@chfast
Copy link
Collaborator Author

chfast commented Feb 24, 2021

I think we should disable GCC sanitizer for GCC 10 and wait for GCC 11 release (or use experimental Debian package).

One ASan runtime option is disabled for current GCC runs.

tools/wasi/wasi.hpp Outdated Show resolved Hide resolved

bool run(int argc, const char** argv)
std::optional<bytes> load_wasm_binary(const std::filesystem::path& path, std::ostream& err)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how filesystem::path works but maybe this function should take a string (provided by user) and create filesytem::path inside, handling the errors like invalid symbols in path.

tools/wasi/wasi.hpp Outdated Show resolved Hide resolved
tools/wasi/wasi.cpp Outdated Show resolved Hide resolved
@chfast chfast force-pushed the wasi_testing branch 2 times, most recently from 9d76188 to 64f408d Compare March 1, 2021 13:45
Copy link
Collaborator

@gumb0 gumb0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

auto imports = fizzy::resolve_imported_functions(*module, wasi_functions);
auto instance = fizzy::instantiate(
std::move(module), std::move(imports), {}, {}, {}, fizzy::MemoryPagesValidationLimit);
auto module = parse(wasm_binary);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually liked having the explicit fizzy prefix on things here, but I'm fine either way.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not make sense when we are in fizzy::wasi.

// SPDX-License-Identifier: Apache-2.0

#include "wasi.hpp"
#include "execute.hpp"
#include "limits.hpp"
#include "parser.hpp"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the <iostream> header still needed here (since std::cerr is moved to main.cpp)?

@@ -99,7 +99,7 @@ ExecutionResult environ_sizes_get(Instance& instance, const Value* args, int)
}
} // namespace

bool run(int argc, const char** argv)
bool run(int argc, const char** argv, std::ostream& err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you say to make this noexcept, but if not noexcept we could consider just outputting error text as part of an exception? Or we want to pass stdout/stdin here too?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to be able to inspect the error messages, one step from using std::cerr implicitly inside. Further modifications are possible, but I'm not sure what's best.

tools/wasi/CMakeLists.txt Outdated Show resolved Hide resolved
target_include_directories(wasi PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(wasi PRIVATE fizzy::fizzy-internal uvwasi::uvwasi)
target_link_libraries(wasi PUBLIC fizzy::fizzy-internal PRIVATE uvwasi::uvwasi)
Copy link
Member

@axic axic Mar 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change below to the load_file commit?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because with this commit wasi.hpp started including fizzy headers.

/// @param err Error output stream.
/// @return False in case of error.
///
/// @todo Make noexcept.
bool run(int argc, const char** argv, std::ostream& err);
bool load_and_run(int argc, const char** argv, std::ostream& err);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you want to do this separation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have load_and_run() combo? There are some uses of it, previously run().

Copy link
Member

@axic axic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to address some of these comments, but I am also okay if not.

Downgrade GCC ASan detect_invalid_pointer_pairs check from 2 (comparisons/subtractions against null pointers are also invalid) to 1.
@chfast chfast merged commit 07f87db into master Mar 10, 2021
@chfast chfast deleted the wasi_testing branch March 10, 2021 22:33
@axic
Copy link
Member

axic commented Mar 10, 2021

We forgot one thing: the uvwasi_state must be moved into some context and can't stay as a static global now that this is librarized.

@chfast
Copy link
Collaborator Author

chfast commented Mar 11, 2021

This will be done with mocking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Split up wasi implementation into unit testable pieces
3 participants