Skip to content

Discover and run unit tests from check.py#1948

Merged
tlively merged 5 commits into
WebAssembly:masterfrom
tlively:unittest
Mar 20, 2019
Merged

Discover and run unit tests from check.py#1948
tlively merged 5 commits into
WebAssembly:masterfrom
tlively:unittest

Conversation

@tlively

@tlively tlively commented Mar 16, 2019

Copy link
Copy Markdown
Member

unittest is Python's standard testing framework, so this change allows
arbitrary tests to be written without introducing any new dependencies
or code in check.py. A new test that was not possible to write before
is also included. It is the first of many.

unittest is Python's standard testing framework, so this change allows
arbitrary tests to be written without introducing any new dependencies
or code in check.py. A new test that was not possible to write before
is also included. It is the first of many.
tlively added a commit to tlively/binaryen that referenced this pull request Mar 16, 2019
Refactors features into a new wasm-features.h file and updates the
validator to check that all types are allowed. Currently this is only
relevant for the v128 SIMD type, but new types will be added in the
future. The test for this change is in WebAssembly#1948.
tlively added a commit to tlively/binaryen that referenced this pull request Mar 16, 2019
This is necessary to write tests that don't require temporary files,
such as in WebAssembly#1948, and is generally useful.
Comment thread scripts/test/shared.py
result = Py2CompletedProcess(cmd, proc.returncode, stdout, stderr)
if check:
result.check_returncode()
return result

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is all copied from emscripten's shared.py. The only difference is that I added support for the capture_output parameter in run_process.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we add capture_output to emscripten's shared.py? (Not knowing what that enables in any detail)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It makes me sad that we need all this boilerplate..

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It would be great to upgrade to python3 instead, but that should probably be a separate discussion.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@jgravelle-google I think we can wait to add capture_output to emscripten's shared.py until someone wants to use it. All it does is store the process's stdout and stderr on the returned object so they can be programmatically inspected. Emscripten tends to store output in temporary files instead.

Comment thread check.py Outdated
print '\n[ ' + str(num_failures) + ' failures! ]'

return num_failures
return 0 if num_failures == 0 else 1

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This fixes a bug where if some multiple of 256 tests fail, the exit code would be 0 (on linux, anyway).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That should be a comment inline, because reversing this is exactly the sort of thing someone would think is a reasonable simplification

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Because I don't like python's ternary syntax (maybe I'm biased), how about moving the return 1 into the block above as an early out and then just return 0 at the end here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@jgravelle-google Good point. I'm not sure a comment makes sense anymore with the change @sbc100 suggested, though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yay to code changes to make comments not-needed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Huh, yeah merging it with the num_failures clause above makes that even nicer 👍

)
"""
p = run_process(WASM_OPT + ['--mvp-features', '--print'],
input=module, check=False, capture_output=True)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This depends on #1950 to run.

tlively added a commit that referenced this pull request Mar 19, 2019
This is necessary to write tests that don't require temporary files,
such as in #1948, and is generally useful.
tlively added a commit that referenced this pull request Mar 19, 2019
Refactors features into a new wasm-features.h file and updates the
validator to check that all types are allowed. Currently this is only
relevant for the v128 SIMD type, but new types will be added in the
future. The test for this change is in #1948.
@tlively

tlively commented Mar 19, 2019

Copy link
Copy Markdown
Member Author

@kripken This has no more outstanding dependencies.

@tlively tlively requested a review from kripken March 19, 2019 03:43

@kripken kripken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Overall lgtm but @sbc100 knows this stuff best.

Comment thread check.py Outdated
print '\n[ checking unit tests...]\n'

# equivalent to `python -m unittest discover -s . -v`
suite = unittest.defaultTestLoader.discover(os.path.dirname(__file__))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

would this look in all of binaryen? how about looking just in test/?

@kripken kripken requested a review from sbc100 March 19, 2019 16:46

@jgravelle-google jgravelle-google left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Generally lgtm, nice

Comment thread scripts/test/shared.py
result = Py2CompletedProcess(cmd, proc.returncode, stdout, stderr)
if check:
result.check_returncode()
return result

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we add capture_output to emscripten's shared.py? (Not knowing what that enables in any detail)

Comment thread check.py Outdated
# limitations under the License.

import os
import unittest

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Alphasort

Comment thread check.py Outdated


def run_unittest():
global num_failures

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm.. this seems odd. num_failures is a variable that is imported from scripts.test.shared but is a global in this file. Is this doing what you expect it to do? If we want changes to be visible in shared we would probably not use global by shared.num_failures.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looking at the details of how num_failures is currently used, I think you probably want to use a new local here.. either that or somehow hook into the existing shared.fail_with_error system.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, this is definitely doing what I expect it to do, which is count unittest failures as equivalent to any other failures. shared.num_failures is imported into the global namespace of this module, but shared is not, so using shared.num_failures instead of global num_failures would require a redundant import. Looking at shared.fail_with_error, it basically does the same thing but respects the abort_on_first_failure option. I will update this code to respect that option as well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

But the num_failures that is global the this module is different to one in shared isn't it?

Updating num_failures in shared won't effect this value and vice versa. I guess that bug already existed but this make it worse.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In python when you re-assign a global, it doesn't effect modules that have already imported that global.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Wow you're totally right. That's nuts. TIL. Fixing now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

... I take back some of the nice things I've said about Python

Comment thread check.py Outdated
print '\n[ ' + str(num_failures) + ' failures! ]'

return num_failures
return 0 if num_failures == 0 else 1

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Because I don't like python's ternary syntax (maybe I'm biased), how about moving the return 1 into the block above as an early out and then just return 0 at the end here?

Comment thread scripts/test/shared.py
result = Py2CompletedProcess(cmd, proc.returncode, stdout, stderr)
if check:
result.check_returncode()
return result

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It makes me sad that we need all this boilerplate..

@tlively

tlively commented Mar 20, 2019

Copy link
Copy Markdown
Member Author

Can I get an explicit lgtm on the new handling of options.abort_on_first_failure in run_unittest? Unfortunately I didn't see a good way to reuse the error handling in shared.py that properly counts the number of individual test failures.

@tlively tlively merged commit fe0b16a into WebAssembly:master Mar 20, 2019
@tlively tlively deleted the unittest branch April 24, 2020 23:26
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.

4 participants