Skip to content

Commit

Permalink
Speed up CI and modernize tests (#140)
Browse files Browse the repository at this point in the history
* Improve tests

* Simplify CI/CD

* Linting

* Properly cache workspaces

* More optimization

* Cache all crates
  • Loading branch information
r-near authored Nov 26, 2024
1 parent f102462 commit 556e25c
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 128 deletions.
72 changes: 40 additions & 32 deletions .github/workflows/rust.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Rust testing and building
name: Rust CI

on:
push:
Expand All @@ -17,54 +17,62 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
component: [near]
check: [clippy, fmt]
component: [near] # Will be expanded with more components later
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Rust
uses: actions-rs/toolchain@v1
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.79.0
components: clippy, rustfmt
target: wasm32-unknown-unknown
override: true

- name: Run ${{ matrix.check }}
run: |
make ${{ matrix.check }}-${{ matrix.component }}
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
cache-all-crates: true
shared-key: "lint-${{ matrix.component }}"
workspaces: ${{ matrix.component }}

- name: Run clippy
run: make clippy-${{ matrix.component }}

- name: Run fmt
run: make fmt-${{ matrix.component }}

build:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Rust
uses: actions-rs/toolchain@v1
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.79.0
target: wasm32-unknown-unknown
override: true

- name: Build Near contract
run: |
make rust-build-near
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
cache-all-crates: true
shared-key: "build-test"
workspaces: near

test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Rust
uses: actions-rs/toolchain@v1
- name: Install nextest
uses: taiki-e/install-action@v2
with:
toolchain: 1.79.0
target: wasm32-unknown-unknown
override: true
tool: nextest

- name: Build token contract
run: make rust-build-near

- name: Build tests
run: cargo build --manifest-path ./near/Cargo.toml --tests --all-features

- name: Test Near contracts
run: |
make test-near
- name: Run tests
run: cargo nextest run --manifest-path ./near/Cargo.toml
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ rust-build-near: rust-build-token
RUSTFLAGS='$(RUSTFLAGS)' cargo build --target wasm32-unknown-unknown --release --manifest-path $(NEAR_MANIFEST)

test-near: rust-build-near
cargo test --manifest-path $(NEAR_MANIFEST)
cargo nextest run --manifest-path $(NEAR_MANIFEST)
42 changes: 42 additions & 0 deletions near/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions near/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ ethereum-types = { version = "0.15.1", default-features = false, features = ["rl
rlp = "0.6"
sha3 = "0.10.0"
alloy-sol-types = "0.8"
rstest = "0.18.2"
3 changes: 2 additions & 1 deletion near/omni-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ near-sdk.workspace = true
near-workspaces.workspace = true
tokio.workspace = true
anyhow.workspace = true
omni-types.workspace = true
omni-types.workspace = true
rstest.workspace = true
162 changes: 68 additions & 94 deletions near/omni-tests/src/fin_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,101 +11,75 @@ mod tests {
prover_result::{InitTransferMessage, ProverResult},
Fee, OmniAddress,
};

use rstest::rstest;

#[rstest]
#[case(vec![(account_1(), true), (relayer_account_id(), true)], 1000, 1, None)]
#[case(vec![(account_1(), true)], 1000, 0, None)]
#[case(
vec![
(account_1(), true),
(relayer_account_id(), true),
(account_2(), true),
(account_2(), true),
],
1000,
1,
Some("Invalid len of accounts for storage deposit")
)]
#[case(
vec![(relayer_account_id(), true), (account_1(), true)],
1000,
1,
Some("STORAGE_ERR: The transfer recipient is omitted")
)]
#[case(
vec![(account_1(), true)],
1000,
1,
Some("STORAGE_ERR: The fee recipient is omitted")
)]
#[case(vec![], 1000, 1, Some("STORAGE_ERR: The transfer recipient is omitted"))]
#[case(
vec![(account_1(), false), (relayer_account_id(), false)],
1000,
1,
Some("STORAGE_ERR: The transfer recipient is omitted")
)]
#[case(
vec![(account_1(), true), (relayer_account_id(), false)],
1000,
1,
Some("STORAGE_ERR: The fee recipient is omitted")
)]
#[case(
vec![(account_1(), false), (relayer_account_id(), true)],
1000,
1,
Some("STORAGE_ERR: The transfer recipient is omitted")
)]
#[tokio::test]
async fn test_storage_deposit_on_fin_transfer() {
struct TestStorageDeposit<'a> {
storage_deposit_accounts: Vec<(AccountId, bool)>,
amount: u128,
fee: u128,
error: Option<&'a str>,
}
let test_data = [
TestStorageDeposit {
storage_deposit_accounts: [(account_1(), true), (relayer_account_id(), true)]
.to_vec(),
amount: 1000,
fee: 1,
error: None,
},
TestStorageDeposit {
storage_deposit_accounts: [(account_1(), true)].to_vec(),
amount: 1000,
fee: 0,
error: None,
},
TestStorageDeposit {
storage_deposit_accounts: [
(account_1(), true),
(relayer_account_id(), true),
(account_2(), true),
(account_2(), true),
]
.to_vec(),
amount: 1000,
fee: 1,
error: Some("Invalid len of accounts for storage deposit"),
},
TestStorageDeposit {
storage_deposit_accounts: [(relayer_account_id(), true), (account_1(), true)]
.to_vec(),
amount: 1000,
fee: 1,
error: Some("STORAGE_ERR: The transfer recipient is omitted"),
},
TestStorageDeposit {
storage_deposit_accounts: [(account_1(), true)].to_vec(),
amount: 1000,
fee: 1,
error: Some("STORAGE_ERR: The fee recipient is omitted"),
},
TestStorageDeposit {
storage_deposit_accounts: [].to_vec(),
amount: 1000,
fee: 1,
error: Some("STORAGE_ERR: The transfer recipient is omitted"),
},
TestStorageDeposit {
storage_deposit_accounts: [(account_1(), false), (relayer_account_id(), false)]
.to_vec(),
amount: 1000,
fee: 1,
error: Some("STORAGE_ERR: The transfer recipient is omitted"),
},
TestStorageDeposit {
storage_deposit_accounts: [(account_1(), true), (relayer_account_id(), false)]
.to_vec(),
amount: 1000,
fee: 1,
error: Some("STORAGE_ERR: The fee recipient is omitted"),
},
TestStorageDeposit {
storage_deposit_accounts: [(account_1(), false), (relayer_account_id(), true)]
.to_vec(),
amount: 1000,
fee: 1,
error: Some("STORAGE_ERR: The transfer recipient is omitted"),
},
];

for (index, test) in test_data.into_iter().enumerate() {
let result =
test_fin_transfer(test.storage_deposit_accounts, test.amount, test.fee).await;

match result {
Ok(_) => assert!(test.error.is_none()),
Err(result_error) => match test.error {
Some(exepected_error) => {
assert!(
result_error.to_string().contains(exepected_error),
"Wrong error. Test index: {}, err: {}, expected: {}",
index,
result_error,
exepected_error
)
}
None => panic!("Test index: {}, err: {}", index, result_error),
},
async fn test_storage_deposit_on_fin_transfer(
#[case] storage_deposit_accounts: Vec<(AccountId, bool)>,
#[case] amount: u128,
#[case] fee: u128,
#[case] expected_error: Option<&str>,
) {
let result = test_fin_transfer(storage_deposit_accounts, amount, fee).await;

match result {
Ok(_) => assert!(
expected_error.is_none(),
"Expected an error but got success"
),
Err(result_error) => {
let error = expected_error.expect("Got an error when none was expected");
assert!(
result_error.to_string().contains(error),
"Wrong error. Got: {}, Expected: {}",
result_error,
error
);
}
}
}
Expand Down

0 comments on commit 556e25c

Please sign in to comment.