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

feat: Investigate Test Coverage Drop #427

Closed
wants to merge 16 commits into from
Closed

Conversation

0xNeshi
Copy link
Collaborator

@0xNeshi 0xNeshi commented Nov 29, 2024

Towards #426

Discussion

Reason for Coverage % Nosedive

Codecov shows that the % drop happened somewhere between October 28th and November 4th. Further investigation shows that the "problematic" commit was introduced by PR #379 (the commit is not actually "problematic", read further).

Below is the link to all the files for which coverage was affected in this commit:
https://app.codecov.io/github/OpenZeppelin/rust-contracts-stylus/commit/9c2b1b4b23145acddafb7b888e9e69a09fa6134c/indirect-changes

Explaining the coverage file diff on Codecov in case it helps (link above): the image below shows the coverage change for contracts/src/token/erc20/extensions/capped.rs - it shows that previously this motsu test was included in the coverage report (the highlighted left column shows line numbers included in previous coverage, while the non-highlighted right column shows line numbers now excluded from coverage).

image

In short, it seems that up until this commit, all motsu tests were included in the coverage %! This wrongly increased our coverage %. After this commit, the motsu tests were excluded from coverage. That means that the sudden 12% drop in coverage was not an anomaly, but a correction.

The commit did not manually change anything to affect coverage in this way. The reason why tests were magically excluded is not yet absolutely clear, but it seems most likely that this motsu::test implementation change, which no longer made the fn block wrapped by with_context, made llvm-cov (our coverage tool) aware that this is in fact test code, and that it shouldn't be a part of the coverage report.
There were also some changes to the llvm-cov dependencies in this period, which could've affected the coverage step in our CI, but this is much less likely imo.

Problems and Recommendations on Increasing Coverage %

Below is a list of problems affecting our test coverage and possible mitigation steps:

  1. Solidity code used in sol! macros (events, errors, storage) is included in test coverage (effect: high).
    • Mitigation 1: group Solidity code in an internal module annotated with #[cfg_attr(coverage, coverage(off))] (see example, and pseudo code is below).
    #[cfg_attr(coverage, coverage(off))]
    mod sol_defs {
        sol! {
            event SomeEvent();
            // ...
        }
    
        sol! {
            error SomeError();
            // ...
        }
    
        // NOTE: has to be included, as `SolidityError` affects coverage,
        // so has to be ignored
        #[derive(SolidityError, Debug)]
        pub enum Error {
            // ...
        }
    
        sol_storage! {
            pub struct State {
                // ...
            }
        }
    }
    
    // use in the contract and also reexport
    pub use sol_defs::{State, Error, SomeError, SomeEvent};
    The effect of this single change on VestingWallet is a ~6% increased coverage.
    • Mitigation 2: we kindly ask the alloy and stylus teams to update their macros to figure out a way to apply attributes to the generated code, and once they do, we annotate each of the problematic macros with coverage(off).
    • NOTE: I did just recommend we increase our code coverage by... ignoring code. The irony is not lost on me :kek:
  2. Missing unit tests for functions that interact with other contracts (effect: high).
  3. Missing tests for ./lib/motsu/, ./lib/motsu-proc/, ./lib/e2e/, and ./lib/e2e-proc/ (effect: high).
    • NOTE: only ./lib/e2e/ is not included in the coverage report, and the reason is that it is not included in Cargo.toml > default-members and we do not include it explicitly in our coverage command. This should be addressed.
    • Mitigation 1: add missing tests.
    • Mitigation 2: exclude ./lib/ from coverage.
  4. Re-exported functions missing unit tests (effect: medium/high).
    • Mitigation 1: duplicate missing unit tests.
    • Mitigation 2: annotate relevant functions with #[cfg_attr(coverage, coverage(off))].
  5. Missing unit tests for certain flows, and even whole functions in certain contracts and in contracts/src/utils (effect: medium).
    • Mitigation: add missing unit tests.
  6. Using internal functions instead of public ones (e.g. IErc20::transfer is tested by calling _update, causing code coverage to register transfer as "unconvered") (effect: medium).
    • Mitigation: test publicly exposed fns, not the internal ones.
  7. IErc165-related tests exist verifying the generated INTERFACE_ID value is correct, but no tests exist that call <ContractName>::supports_interface (effect: low).
    • Mitigation: add missing supports_interface tests.
  8. MethodError impls uncovered (effect: low).
    • Mitigation: annotate with #[cfg_attr(coverage, coverage(off))].
  9. #[public] attr is included in coverage (effect: low). - this PR solves this
  10. #[cfg(test)] mod tests (unit tests) are included in coverage (effect: none). NOTE: technically not a problem atm, as the effect of this is positive or neutral. If we still wanted to exclude them, see mitigation steps below.
  11. #[motsu::test] attributes included in test coverage (effect: unknown). - this PR solves this
    • Explanation: nothing from mod tests should be included in coverage (see previous point). However, since ./lib/motsu/, and ./lib/motsu-proc/ do not have their own tests (already covered in previous points), we are inadvertently covering those in this roundabout way. I think this is a bug though, and not a feature.
    • Mitigation: see previous point about ignoring mod tests.
    • NOTE: it seems switching llvm-cov to nightly in this PR removed this from coverage (e.g. see nonces.rs) 👀 But for some reason, motsu-proc crate code is still "covered".

Took the liberty to investigate why the number of ignored integration tests jumped 2->10, namely in Erc721 and Erc1155 contracts. The reason for this is that e2e does not support asserting that a call reverted with stylus_sdk::call::Error, which these tests are trying to assert.
This issue is already known and is being tracked here: #228

Copy link

netlify bot commented Nov 29, 2024

Deploy Preview for contracts-stylus ready!

Name Link
🔨 Latest commit 13e9842
🔍 Latest deploy log https://app.netlify.com/sites/contracts-stylus/deploys/6756af974c87490008e191d9
😎 Deploy Preview https://deploy-preview-427--contracts-stylus.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

codecov bot commented Dec 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 62.5%. Comparing base (6c4c5ec) to head (13e9842).

Additional details and impacted files

see 27 files with indirect coverage changes

@0xNeshi 0xNeshi requested a review from ggonzalez94 December 2, 2024 09:58
@0xNeshi 0xNeshi force-pushed the coverage/investigate branch from 861094c to 589c4ba Compare December 5, 2024 08:30
@0xNeshi 0xNeshi force-pushed the coverage/investigate branch from c59d562 to f84dfa1 Compare December 5, 2024 09:31
@0xNeshi 0xNeshi marked this pull request as ready for review December 5, 2024 09:31
@0xNeshi
Copy link
Collaborator Author

0xNeshi commented Dec 5, 2024

Made this PR ready for review, as merging it would immediately address points 9 (#[public] attr is included in coverage) and 11 (#[motsu::test] attributes included in test coverage).

@0xNeshi
Copy link
Collaborator Author

0xNeshi commented Dec 9, 2024

Closing this in favor of #438

@0xNeshi 0xNeshi closed this Dec 9, 2024
@0xNeshi 0xNeshi deleted the coverage/investigate branch December 9, 2024 10:25
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.

1 participant