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: add compiled code size tests #412

Merged
merged 4 commits into from
May 17, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@ jobs:
- uses: Swatinem/rust-cache@v1
- name: Test Format
run: cargo fmt -- --check
- name: Add wasm32 target
run: rustup target add wasm32-unknown-unknown
Copy link
Contributor

Choose a reason for hiding this comment

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

If I am not mistaken, this should not be necessary? actions-rs/toolchain@v1 already installs this target, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah that's what I assumed, but there might be something internal which installs it for a different toolchain, not sure. Just added that as a workaround and was going to look into it today

Copy link
Contributor

Choose a reason for hiding this comment

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

obesrvation: this yml sets a horribly outdated toolchain at the start

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah this CI is something I would like to improve/rewrite in the future, as it only checks formatting and runs tests, to give some context into why I thought just to add a workaround for now. I can create an issue for this now, because I think it's a standard to at least check clippy as well.

- name: Test
run: cargo test --all
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ members = [
exclude = [
"examples/cross-contract-high-level",
"examples/fungible-token",
"examples/lockable-fungible-token",
"examples/cross-contract-low-level",
"examples/mission-control",
"examples/status-message",
"examples/status-message-collections",
"examples/test-contract",
]

# Special triple # comment for ci.
Expand Down
37 changes: 37 additions & 0 deletions near-sdk/tests/code_size.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/// Compiles contract to wasm with release configuration and returns the code size.
fn check_example_size(example: &str) -> usize {
let status = std::process::Command::new("cargo")
Comment on lines +2 to +3
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd add Command::new("rustup").args(&["target", "add", "wasm32-unknown-unknown"]).status().unwrap() here, so that the test just works in more cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hmm, that seems like a bad implication to update a user's toolchain unknowingly through running a test, maybe if this test was ignored by default?

Copy link
Contributor

@matklad matklad May 11, 2021

Choose a reason for hiding this comment

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

It seems so, but I don't think that's the case. Like, when you run cargo test, cargo automatically updates the index and downloads crates, and that doesn't cause problems. Similarly, if you run cargo test in a project with rustup-toolchain, rustup automatically downloads the toolchain without asking for confirmation.

Really, cargo build --target xxx should just work. The reason it doesn't is a sad historical incident -- target management was implemented in rustup, while it really belongs to cargo. So this pattern is a work-around for a bug in the toolchain.

Empirically, I've been using rustup commands in CI in various projects (example from rust-analyzer: https://github.com/rust-analyzer/rust-analyzer/blob/master/xtask/src/main.rs#L80-L89), and it never caused problems.

But maybe I am biased -- I am pretty found of various toolchain hacks which streamline workflows :D

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, that's a fair point. I'll make this change

.env("RUSTFLAGS", "-C link-arg=-s")
.args(&["build", "--release", "--target", "wasm32-unknown-unknown", "--manifest-path"])
.arg(format!("../examples/{}/Cargo.toml", example))
.status()
.unwrap();
if !status.success() {
panic!("building wasm example returned non-zero code {}", status);
}

let wasm = std::fs::read(format!(
"../examples/{}/target/wasm32-unknown-unknown/release/{}.wasm",
example,
example.replace("-", "_")
))
.unwrap();

wasm.len()
}

#[test]
fn lock_fungible_code_size_check() {
let size = check_example_size("lockable-fungible-token");

// Current contract size at the time of writing this test is 164_433, giving about ~10% buffer.
assert!(size < 180_000);
}

#[test]
fn status_message_code_size_check() {
let size = check_example_size("status-message");

// Currently 140823.
assert!(size < 155_000);
}