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

Add a #[test(should_revert)] attribute to indicate a unit test should revert #3260

Closed
mitchmindtree opened this issue Nov 3, 2022 · 2 comments · Fixed by #3490
Closed

Add a #[test(should_revert)] attribute to indicate a unit test should revert #3260

mitchmindtree opened this issue Nov 3, 2022 · 2 comments · Fixed by #3490
Assignees
Labels
compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen compiler General compiler. Should eventually become more specific as the issue is triaged forc forc-test Everything related to the `forc-test` lib and `forc test` command.

Comments

@mitchmindtree
Copy link
Contributor

Tests decorated with #[test(should_revert)] should "pass" in the case that they exited with ProgramState::Revert(_).

@mitchmindtree mitchmindtree added compiler General compiler. Should eventually become more specific as the issue is triaged forc compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen forc-test Everything related to the `forc-test` lib and `forc test` command. labels Nov 3, 2022
mitchmindtree added a commit that referenced this issue Nov 4, 2022
OK, this should be good to go!

## Highlights

- Adds support for multiple entry points to IR. Adds a tests for
serializing entry functions to/from IR.
- Enables ASM generation for libraries (to support test function entry
points).
- Track entry points through ASM generation so we can return entry point
metadata as a part of the compilation result. This doesn't affect ASM
generation, but allows tools using `sway-core` as a library to work with
different entry points.
- Updated E2E test harness with a new test category "UnitTestsPass".
- Added E2E tests with multiple unit tests for each type of Sway program
(library, script, predicate, contract).
- Gets `forc test` working with pretty output!

Here's the output from the new `lib_multi_test`:

![Screenshot from 2022-11-03
19-00-57](https://user-images.githubusercontent.com/4587373/199700362-ba32f90d-1f0f-4f76-bf89-b191de9589af.png)


## Test running implementation

Currently, it seems like there's no publicly accessible approach to
execute a script directly from a custom entry point. As a result, for
each test, we patch the bytecode with a `JI` instruction that jumps from
after the data section setup to the test's entry point. This is a bit
hairy, but works for now!

As a follow-up, we may want to consider adding support upstream in
`fuel-vm` for executing scripts directly from a given entry point. Even
if this was only exposed from the interpreter API, this would make the
`forc-test` implementation quite a bit cleaner and avoid the need to
patch the bytecode.

Alternatively, when building projects we could return more metadata
along with the compiled output (whether in memory or bytecode header) to
indicate how to work with different entry points in a more reliable
manner (rather than the magic const offset currently used in
`forc-test`).

# TODO

- [x] Add `include_tests` flag to `BuildConfig`, allowing `forc` to
trigger compilation of test functions.
- [x] Include `#[test]` fns as entry points within dead code analysis.
- [x] IR and ASM generation for test entry points.
- [x] Add `forc build --tests`.
- [x] Add `forc test`.
- [x] Always include test fns in `TyProgram` (for DCA), but omit from IR
if not building tests.
- [x] Work out how to iterate over different entry points during `forc
test`.
- [x] Only generate tests for top-level "members" (not all
dependencies).

### Follow-up:

- #3260
- #3261
- #3262
- #3263
- #3264
- #3265
- #3266
- #3267
- #3268

Closes #1832.
@kayagokalp kayagokalp self-assigned this Nov 25, 2022
@mitchmindtree
Copy link
Contributor Author

mitchmindtree commented Nov 28, 2022

cc @kayagokalp IIRC, using the IR metadata could be the way to go here w.r.t. passing "revertness" information through to the compiled asm result.

#3266 is related, in that it's also about passing info through to the asm-gen stage.

Perhaps ideally, we'd have some way of mapping the generated test entry points to their matching function declarations - then rather than having to pass loads of information through IR metadata, we would just need to pass through the TypeId or the DeclId or something like that, and then use that ID to look up that function.

cc @otrho in case you have any thoughts/tips on this :)

In implementing basic initial support for #[test] and forc test, I managed to get through without dealing with this as it turned out to be potentially useful to have entry information in the IR itself, so in the end I just detected tests by finding entry points that weren't main or abi methods 🥲 This issue however will require thinking more seriously about how to get arbitrary info through to the asm-gen stage.

@kayagokalp
Copy link
Member

kayagokalp commented Nov 28, 2022

Perhaps ideally, we'd have some way of mapping the generated test entry points to their matching function declarations

Nice, I was basically implementing this but collecting the whole declaration struct, collecting type/decl id instead sounds cool! cc @mitchmindtree

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen compiler General compiler. Should eventually become more specific as the issue is triaged forc forc-test Everything related to the `forc-test` lib and `forc test` command.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants