Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
121 changes: 107 additions & 14 deletions .github/workflows/linux-ci-rust.yml → .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Linux CI Rust
name: Rust CI

on:
push:
Expand All @@ -16,7 +16,7 @@ concurrency:

jobs:
# Check formatting, clippy warnings, run tests and check code coverage.
build-and-test:
rust-lints:
permissions:
contents: read
checks: write
Expand Down Expand Up @@ -51,18 +51,6 @@ jobs:
cargo clippy -- -D warnings
working-directory: rust

- name: Run tests
run: |
tools/rust-coverage

- name: Gather and check Rust code coverage
run: |
tools/check-coverage rust/coverage.stats rust/coverage.info

- name: Run Doc tests
run: |
tools/rust-test doc

# Run Rust tests in WASM.
test-wasm:
runs-on: ubuntu-24.04
Expand Down Expand Up @@ -163,3 +151,108 @@ jobs:
comment-author: 'github-actions[bot]'
edit-mode: replace
body-path: 'report-diff.md'

memory-profiler:
runs-on: ubuntu-24.04
if: github.event.pull_request.draft == false
steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Run sccache-cache
uses: mozilla-actions/sccache-action@v0.0.8

- name: Cache Rust
uses: Swatinem/rust-cache@v2
with:
workspaces: |
rust

- name: Install llvm
run: |
# to get the symbolizer for debug symbol resolution
sudo apt install llvm

- name: Install nightly
uses: dtolnay/rust-toolchain@nightly

- name: Enable debug symbols
run: |
cd rust
# to fix buggy leak analyzer:
# https://github.com/japaric/rust-san#unrealiable-leaksanitizer
# ensure there's a profile.dev section
if ! grep -qE '^[ \t]*[profile.dev]' Cargo.toml; then
echo >> Cargo.toml
echo '[profile.dev]' >> Cargo.toml
fi
# remove pre-existing opt-levels in profile.dev
sed -i '/^\s*\[profile.dev\]/,/^\s*\[/ {/^\s*opt-level/d}' Cargo.toml
# now set opt-level to 1
sed -i '/^\s*\[profile.dev\]/a opt-level = 1' Cargo.toml
cat Cargo.toml

- name: cargo test -Zsanitizer=address
# only --lib --tests b/c of https://github.com/rust-lang/rust/issues/53945
run: |
cd rust
cargo test --lib --tests --all-features --target x86_64-unknown-linux-gnu
env:
ASAN_OPTIONS: "detect_odr_violation=0:detect_leaks=0"
RUSTFLAGS: "-Z sanitizer=address"

- name: cargo test -Zsanitizer=leak
if: always()
run: |
cd rust
cargo test --all-features --target x86_64-unknown-linux-gnu
env:
RUSTFLAGS: "-Z sanitizer=leak"

coverage:
runs-on: ubuntu-24.04
if: github.event.pull_request.draft == false

steps:
- uses: actions/checkout@v4
with:
submodules: true
run: |
tools/install-sys-dependencies-linux

- name: Install stable
uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview

- name: cargo install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov

- name: cargo generate-lockfile
if: hashFiles('Cargo.lock') == ''
run: |
cd rust
cargo generate-lockfile

- name: Run tests
run: |
tools/rust-coverage

- name: Run Doc tests
run: |
tools/rust-test doc

- name: Record Rust version
run: echo "RUST=$(rustc --version)" >> "$GITHUB_ENV"

- name: Upload to codecov.io
uses: codecov/codecov-action@v5
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
env_vars: OS,RUST

- name: Gather and check Rust code coverage
run: |
tools/check-coverage rust/coverage.stats rust/lcov.info
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ emsdk/
wasm-build/

# Code coverage files
lcov.info
coverage.info
coverage/
swift/test_output/
Expand Down
2 changes: 1 addition & 1 deletion android/gradlew

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

2 changes: 1 addition & 1 deletion bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ if isHelp; then
fi

echo "#### Installing system dependencies ... ####"
if [[ $(uname) == "Darwin" ]]; then
if [[ $(uname -s) == "Darwin" ]]; then
tools/install-sys-dependencies-mac
else
tools/install-sys-dependencies-linux
Expand Down
2 changes: 1 addition & 1 deletion kotlin/gradlew

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

20 changes: 12 additions & 8 deletions rust/tw_encoding/tests/base32_ffi_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ use tw_encoding::ffi::{decode_base32, encode_base32};
/// equals to `expected`.
#[track_caller]
fn test_base32_encode_helper(input: &[u8], expected: &str, alphabet: Option<&str>, padding: bool) {
let alphabet = alphabet
.map(|alphabet| CString::new(alphabet).unwrap().into_raw())
.unwrap_or_else(std::ptr::null_mut);
let alphabet_cstring = alphabet.map(|alphabet| CString::new(alphabet).unwrap());
let alphabet_ptr = alphabet_cstring
.as_ref()
.map(|s| s.as_ptr())
.unwrap_or_else(std::ptr::null);

let result_ptr =
unsafe { encode_base32(input.as_ptr(), input.len(), alphabet, padding) }.unwrap();
unsafe { encode_base32(input.as_ptr(), input.len(), alphabet_ptr, padding) }.unwrap();
let result = unsafe { CString::from_raw(result_ptr) };
assert_eq!(result.to_str().unwrap(), expected);
}
Expand All @@ -24,12 +26,14 @@ fn test_base32_encode_helper(input: &[u8], expected: &str, alphabet: Option<&str
#[track_caller]
fn test_base32_decode_helper(input: &str, expected: &[u8], alphabet: Option<&str>, padding: bool) {
let input = CString::new(input).unwrap();
let alphabet = alphabet
.map(|alphabet| CString::new(alphabet).unwrap().into_raw())
.unwrap_or_else(std::ptr::null_mut);
let alphabet_cstring = alphabet.map(|alphabet| CString::new(alphabet).unwrap());
let alphabet_ptr = alphabet_cstring
.as_ref()
.map(|s| s.as_ptr())
.unwrap_or_else(std::ptr::null);

let decoded = unsafe {
decode_base32(input.as_ptr(), alphabet, padding)
decode_base32(input.as_ptr(), alphabet_ptr, padding)
.unwrap()
.into_vec()
};
Expand Down
31 changes: 18 additions & 13 deletions rust/tw_encoding/tests/base64_ffi_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@
//
// Copyright © 2017 Trust Wallet.

use std::ffi::{CStr, CString};
use std::ffi::CString;
use tw_encoding::ffi::{decode_base64, encode_base64};

#[test]
fn test_encode_base64() {
let data = b"hello world";
let encoded = unsafe { CStr::from_ptr(encode_base64(data.as_ptr(), data.len(), false)) };
let result_ptr = unsafe { encode_base64(data.as_ptr(), data.len(), false) };
let result = unsafe { CString::from_raw(result_ptr) };
let expected = "aGVsbG8gd29ybGQ=";
assert_eq!(encoded.to_str().unwrap(), expected);
assert_eq!(result.to_str().unwrap(), expected);
}

#[test]
fn test_encode_base64_url() {
let data = b"+'?ab";
let encoded = unsafe { CStr::from_ptr(encode_base64(data.as_ptr(), data.len(), true)) };
let result_ptr = unsafe { encode_base64(data.as_ptr(), data.len(), true) };
let result = unsafe { CString::from_raw(result_ptr) };
let expected = "Kyc_YWI=";
assert_eq!(encoded.to_str().unwrap(), expected);
assert_eq!(result.to_str().unwrap(), expected);
}

#[test]
Expand All @@ -27,9 +29,11 @@ fn test_decode_base64_url() {
let expected = b"+'?ab";

let encoded_c_str = CString::new(encoded).unwrap();
let encoded_ptr = encoded_c_str.as_ptr();

let decoded = unsafe { decode_base64(encoded_ptr, true).unwrap().into_vec() };
let decoded = unsafe {
decode_base64(encoded_c_str.as_ptr(), true)
.unwrap()
.into_vec()
};
assert_eq!(decoded, expected);
}

Expand All @@ -39,17 +43,18 @@ fn test_decode_base64() {
let expected = b"hello world!";

let encoded_c_str = CString::new(encoded).unwrap();
let encoded_ptr = encoded_c_str.as_ptr();

let decoded = unsafe { decode_base64(encoded_ptr, false).unwrap().into_vec() };
let decoded = unsafe {
decode_base64(encoded_c_str.as_ptr(), false)
.unwrap()
.into_vec()
};
assert_eq!(decoded, expected);
}

#[test]
fn test_decode_base64_invalid() {
let invalid_encoded = "_This_is_an_invalid_base64_";
let encoded_c_str = CString::new(invalid_encoded).unwrap();
let encoded_ptr = encoded_c_str.as_ptr();
let res = unsafe { decode_base64(encoded_ptr, false) };
let res = unsafe { decode_base64(encoded_c_str.as_ptr(), false) };
assert!(res.is_err());
}
20 changes: 9 additions & 11 deletions rust/tw_encoding/tests/hex_ffi_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,33 @@
//
// Copyright © 2017 Trust Wallet.

use std::ffi::{CStr, CString};
use std::ffi::CString;
use tw_encoding::ffi::{decode_hex, encode_hex};

#[test]
fn test_encode_hex_without_prefix() {
let data = b"hello world";
let encoded = unsafe { CStr::from_ptr(encode_hex(data.as_ptr(), data.len(), false)) };
let result_ptr = unsafe { encode_hex(data.as_ptr(), data.len(), false) };
let result = unsafe { CString::from_raw(result_ptr) };
let expected = "68656c6c6f20776f726c64";
assert_eq!(encoded.to_str().unwrap(), expected);
assert_eq!(result.to_str().unwrap(), expected);
}

#[test]
fn test_encode_hex_with_prefix() {
let data = b"hello world";
let encoded = unsafe { CStr::from_ptr(encode_hex(data.as_ptr(), data.len(), true)) };
let result_ptr = unsafe { encode_hex(data.as_ptr(), data.len(), true) };
let result = unsafe { CString::from_raw(result_ptr) };
let expected = "0x68656c6c6f20776f726c64";
assert_eq!(encoded.to_str().unwrap(), expected);
assert_eq!(result.to_str().unwrap(), expected);
}

#[test]
fn test_decode_hex() {
let encoded = "68656c6c6f20776f726c64";

let encoded_c_str = CString::new(encoded).unwrap();
let encoded_ptr = encoded_c_str.as_ptr();

let decoded: Vec<_> = unsafe { decode_hex(encoded_ptr).unwrap().into_vec() };
let decoded: Vec<_> = unsafe { decode_hex(encoded_c_str.as_ptr()).unwrap().into_vec() };
assert_eq!(decoded, b"hello world");
}

Expand All @@ -37,8 +37,6 @@ fn test_decode_hex_with_prefix() {
let encoded = "0x68656c6c6f20776f726c64";

let encoded_c_str = CString::new(encoded).unwrap();
let encoded_ptr = encoded_c_str.as_ptr();

let decoded: Vec<_> = unsafe { decode_hex(encoded_ptr).unwrap().into_vec() };
let decoded: Vec<_> = unsafe { decode_hex(encoded_c_str.as_ptr()).unwrap().into_vec() };
assert_eq!(decoded, b"hello world");
}
6 changes: 5 additions & 1 deletion rust/tw_tests/tests/utils/bit_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use tw_encoding::hex::{DecodeHex, ToHex};
use tw_memory::test_utils::tw_data_helper::TWDataHelper;
use wallet_core_rs::ffi::utils::bit_reader_ffi::{
tw_bit_reader_create, tw_bit_reader_finished, tw_bit_reader_read_u8,
tw_bit_reader_create, tw_bit_reader_delete, tw_bit_reader_finished, tw_bit_reader_read_u8,
tw_bit_reader_read_u8_slice, CBitReaderCode,
};

Expand Down Expand Up @@ -37,6 +37,8 @@ fn test_tw_bit_reader_success() {
);

assert!(unsafe { tw_bit_reader_finished(reader) });

unsafe { tw_bit_reader_delete(reader) };
}

#[test]
Expand Down Expand Up @@ -66,4 +68,6 @@ fn test_tw_bit_reader_error() {
res.into_result().unwrap_err(),
CBitReaderCode::NotEnoughData as i32
);

unsafe { tw_bit_reader_delete(reader) };
}
Loading
Loading