Skip to content

Commit

Permalink
feat(wasm): Wasm Integration Tests working in CI (#197)
Browse files Browse the repository at this point in the history
* fix(wasm): Fix running wasm integration tests

* fix(wasm): Make logging work inside the wasm integration tests

* feat(wasm): working hashing integration test

* ci(wasm): align rust builds with cat-ci latest version

* feat(wasm): Add crypto wasm integration tests

* fix(hermes): Re-enable hermes full build after getting wasm integration tests working

* fix(wasm): silence the initial print inside wasm integration tests to prevent issues when running

* fix(wasm): remove unused import after silencing the wasm integration tester

* style(hermes): Fix code format

* fix(spelling): spelling issue

* fix(cbork): Align deny,toml with CI

* fix(wasm): Align deny.toml with CI

* Update hermes/bin/src/runtime_extensions/hermes/crypto/host.rs

Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com>

* Update hermes/bin/src/runtime_extensions/hermes/crypto/host.rs

Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com>

* feat: hermes-cron integration test cases (#199)

* feat(wip): stub hermes-cron integration test cases

* feat: add tests for cron api functions

* fix: compare returned string with expected

* feat(warm): Add Cardano Runtime Extension integration test skeleton (#198)

* feat(wasm): Add Cardano Runtime Extension integration tests skeleton

* feat(wasm): Use pallas to parse blocks in Cardano RTE integration test component

---------

Co-authored-by: Steven Johnson <stevenj@users.noreply.github.com>

* fix(wasm): remove commented obsolete code

* Update wasm/integration-test/crypto/crypto.c

Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com>

* test: time module (#200)

* feat: initial commit

* feat: simple function

* ci: add test

* test: restructure and add test to localtime

* fix: minor format

* refactor: remove localtime name

* fix: localtime issue

* feat: clocks test

* fix: test warms

* fix: use existing tests

* chore: earthfile tmp

* fix: builder

* fix: remove wall test

* chore: fmtfix

* fix(spelling): add to project words

* fix(wasm): remove generated bindings, try and use autogenerated ones

* chore(wasm): Fix Cardano RTE wasm integration test module (#204)

* fix(hermes): Update rust builders to the latest

---------

Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com>
Co-authored-by: Joaquín Rosales <joaquin.rosales@iohk.io>
Co-authored-by: Felipe Rosa <felipe.rosa@iohk.io>
Co-authored-by: Apisit Ritreungroj <38898766+apskhem@users.noreply.github.com>
  • Loading branch information
5 people committed Apr 9, 2024
1 parent 5a814ce commit 7f662dd
Show file tree
Hide file tree
Showing 39 changed files with 1,758 additions and 271 deletions.
1 change: 1 addition & 0 deletions .config/dictionaries/project.dic
Expand Up @@ -15,6 +15,7 @@ bmac
BROTLI
CHAINCODE
cardano
cdylib
chaincode
cbor
CBOR
Expand Down
33 changes: 27 additions & 6 deletions hermes/Earthfile
Expand Up @@ -4,15 +4,15 @@ VERSION 0.7

# Set up our target toolchains, and copy our files.
builder:
DO github.com/input-output-hk/catalyst-ci/earthly/rust:v2.10.3+SETUP
DO github.com/input-output-hk/catalyst-ci/earthly/rust:v2.11.2+SETUP
COPY --dir .cargo .config crates bin .
COPY Cargo.toml .
COPY clippy.toml deny.toml rustfmt.toml .

RUN mkdir /wasm
COPY --dir ../wasm+wasi-src/wasi /wasm/wasi
# Compiled WASM component for benchmarks
COPY ../wasm/c+build/component.wasm /wasm/c/bench_component.wasm
COPY ../wasm/stub-module+build/stub.wasm /wasm/stub-module/stub.wasm

# Expands `wasmtime::bindgen!` macro into the `bindings.rs` file
bindings-expand:
Expand Down Expand Up @@ -44,16 +44,37 @@ all-hosts-check:
build:
FROM +builder

# build wasm artifacts for testing
COPY (../wasm/c+build/component.wasm --c_files="integration-test.c") ../wasm/test-components/
# Directory where WASM test components go when we run wasm module integration tests.
RUN mkdir ../wasm/test-components

RUN /scripts/std_build.py --bench_flags="--features bench" \
--libs="cardano-chain-follower" \
--bins="hermes/hermes"
--bins="hermes/hermes" \
--verbose

SAVE ARTIFACT target/$TARGETARCH/doc doc
SAVE ARTIFACT target/$TARGETARCH/release/hermes hermes
SAVE ARTIFACT target/criterion
SAVE ARTIFACT target/criterion

test-wasm-integration:
FROM +build

# Copy all wasm module artifacts for testing
COPY ../wasm/integration-test/cron+build/cron.wasm ../wasm/test-components/
COPY ../wasm/integration-test/clocks+build/clocks.wasm ../wasm/test-components/
COPY ../wasm/integration-test/crypto+build/crypto.wasm ../wasm/test-components/
COPY ../wasm/integration-test/cardano+build/cardano.wasm ../wasm/test-components/
COPY ../wasm/integration-test/hashing+build/hashing.wasm ../wasm/test-components/
COPY ../wasm/integration-test/localtime+build/localtime.wasm ../wasm/test-components/
COPY ../wasm/integration-test/logger+build/logger.wasm ../wasm/test-components/
COPY ../wasm/integration-test/smoke-test+build/smoke-test.wasm ../wasm/test-components/

# List all WASM integration tests/benches and also run them.
#RUN cargo test --release --test wasm-component-integration-tests -- --help
RUN cargo test --release --test wasm-component-integration-tests -- --list
RUN cargo test --release --test wasm-component-integration-tests -- --test
RUN cargo test --release --test wasm-component-integration-tests -- --bench


# Test which runs check with all supported host tooling. Needs qemu or rosetta to run.
# Only used to validate tooling is working across host toolsets.
Expand Down
Expand Up @@ -198,6 +198,7 @@ mod tests_bip32_ed25519 {
#[test]
fn test_get_public_key() {
let xprv = XPrv::from_extended_and_chaincode(&XPRV1, &CHAINCODE1);
// 3986768884739312704, 9782938079688165927, 7977656244723921923, 12587033252467133758
let pubk_tuple = get_public_key(&xprv);
let pubk_hex = format!(
"{:x}{:x}{:x}{:x}",
Expand Down
11 changes: 6 additions & 5 deletions hermes/bin/src/runtime_extensions/hermes/crypto/host.rs
Expand Up @@ -36,13 +36,14 @@ impl HostBip32Ed25519 for HermesRuntimeContext {
match xprv {
Ok(xprv) => {
if let Some(id) = add_resource(self.app_name(), xprv) {
return Ok(Resource::new_own(id));
Ok(Resource::new_own(id))
} else {
// TODO(bkioshn): https://github.com/input-output-hk/hermes/issues/183
Err(wasmtime::Error::msg("Error creating new resource"))
}
},
Err(e) => return Err(wasmtime::Error::msg(e.to_string())),
};
// TODO(bkioshn): https://github.com/input-output-hk/hermes/issues/183
Err(wasmtime::Error::msg("Error creating new resource"))
Err(e) => Err(wasmtime::Error::msg(e.to_string())),
}
}

/// Get the public key for this private key.
Expand Down
2 changes: 1 addition & 1 deletion hermes/bin/src/runtime_extensions/hermes/crypto/mod.rs
Expand Up @@ -11,7 +11,7 @@ mod state;
pub(crate) fn new_context(ctx: &crate::runtime_context::HermesRuntimeContext) {
// check whether it exist
let state = get_state();
if state.contains_key(ctx.app_name()) {
if !state.contains_key(ctx.app_name()) {
set_state(ctx.app_name().clone());
}
}
39 changes: 6 additions & 33 deletions hermes/bin/src/runtime_extensions/hermes/localtime/host.rs
@@ -1,16 +1,11 @@
//! Localtime host implementation for WASM runtime.

use chrono::{Local, TimeZone};
use chrono_tz::Tz;

use super::time::{alt_localtime, get_localtime};
use crate::{
runtime_context::HermesRuntimeContext,
runtime_extensions::{
bindings::{
hermes::localtime::api::{Errno, Host, Localtime, Timezone},
wasi::clocks::wall_clock::Datetime,
},
hermes::localtime::get_tz,
runtime_extensions::bindings::{
hermes::localtime::api::{Errno, Host, Localtime, Timezone},
wasi::clocks::wall_clock::Datetime,
},
};

Expand All @@ -31,21 +26,7 @@ impl Host for HermesRuntimeContext {
fn get_localtime(
&mut self, when: Option<Datetime>, tz: Option<Timezone>,
) -> wasmtime::Result<Result<Localtime, Errno>> {
let timezone = get_tz(tz)?;
let local_naive = match when {
Some(Datetime {
seconds,
nanoseconds,
}) => {
let seconds = seconds.try_into().map_err(|_| Errno::InvalidLocaltime)?;
let utc_dt = chrono::DateTime::from_timestamp(seconds, nanoseconds)
.ok_or(Errno::InvalidLocaltime)?;
utc_dt.naive_utc()
},
None => Local::now().naive_utc(),
};
let local_date_time = timezone.from_utc_datetime(&local_naive);
Ok(local_date_time.try_into())
Ok(get_localtime(when, tz))
}

/// Get a new localtime from a localtime, by recalculating time for a new timezone.
Expand All @@ -63,15 +44,7 @@ impl Host for HermesRuntimeContext {
fn alt_localtime(
&mut self, time: Localtime, tz: Option<Timezone>,
) -> wasmtime::Result<Result<Localtime, Errno>> {
let local_date_time: chrono::DateTime<Tz> = time.try_into()?;
let alt_local_date_time = match tz {
Some(alt_tz) => {
let tz = get_tz(Some(alt_tz))?;
tz.from_utc_datetime(&local_date_time.naive_utc())
},
None => local_date_time,
};
Ok(alt_local_date_time.try_into())
Ok(alt_localtime(time, tz))
}

/// Get a datetime from a localtime.
Expand Down
1 change: 1 addition & 0 deletions hermes/bin/src/runtime_extensions/hermes/localtime/mod.rs
Expand Up @@ -9,6 +9,7 @@ use crate::runtime_extensions::bindings::{
};

mod host;
mod time;

/// Advise Runtime Extensions of a new context
pub(crate) fn new_context(_ctx: &crate::runtime_context::HermesRuntimeContext) {}
Expand Down
60 changes: 60 additions & 0 deletions hermes/bin/src/runtime_extensions/hermes/localtime/time.rs
@@ -0,0 +1,60 @@
//! Localtime host implementation for WASM runtime.

use chrono::{Local, TimeZone};
use chrono_tz::Tz;

use crate::runtime_extensions::{
bindings::{
hermes::localtime::api::{Errno, Localtime, Timezone},
wasi::clocks::wall_clock::Datetime,
},
hermes::localtime::get_tz,
};

/// (Implementation) Get localtime from a datetime or now.
pub(super) fn get_localtime(
when: Option<Datetime>, tz: Option<Timezone>,
) -> Result<Localtime, Errno> {
let timezone = get_tz(tz)?;
let local_naive = match when {
Some(Datetime {
seconds,
nanoseconds,
}) => {
let seconds = seconds.try_into().map_err(|_| Errno::InvalidLocaltime)?;
let utc_dt = chrono::DateTime::from_timestamp(seconds, nanoseconds)
.ok_or(Errno::InvalidLocaltime)?;
utc_dt.naive_utc()
},
None => Local::now().naive_utc(),
};
let local_date_time = timezone.from_utc_datetime(&local_naive);

local_date_time.try_into()
}

/// (Implementation) Get a new localtime from a localtime, by recalculating time for a new
/// timezone.
pub(super) fn alt_localtime(time: Localtime, tz: Option<Timezone>) -> Result<Localtime, Errno> {
let local_date_time: chrono::DateTime<Tz> = time.try_into()?;
let alt_local_date_time = match tz {
Some(alt_tz) => {
let tz = get_tz(Some(alt_tz))?;
tz.from_utc_datetime(&local_date_time.naive_utc())
},
None => local_date_time,
};

alt_local_date_time.try_into()
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_get_localtime_with_utc_offset() {
let result = get_localtime(None, Some(String::from("Europe/London")));
assert!(result.is_ok()); // Check if the function call was successful
}
}
3 changes: 1 addition & 2 deletions hermes/bin/src/wasm/module.rs
Expand Up @@ -162,8 +162,7 @@ pub mod bench {
}
}

let module =
Module::new(include_bytes!("../../../../wasm/c/bench_component.wasm")).unwrap();
let module = Module::new(include_bytes!("../../../../wasm/stub-module/stub.wasm")).unwrap();

b.iter(|| {
module
Expand Down

0 comments on commit 7f662dd

Please sign in to comment.