Skip to content

Commit

Permalink
Implemented functions for event logging
Browse files Browse the repository at this point in the history
  • Loading branch information
rasmus-kirk committed Oct 17, 2024
1 parent b4d6213 commit 1973a62
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
3 changes: 3 additions & 0 deletions concordium-std/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
- `set_receive_self_address`
- `set_receive_self_balance`
- `set_parameter`
- `get_event`
- `get_event_size`

- Added a more user-friendly interface `TestEnv` that allows users to build
a test host environment using method chaining and proper types. It supports
Expand All @@ -15,6 +17,7 @@
- `set_receive_balance`
- `set_receive_self_address`
- `set_parameter`
- `get_event`

## concordium-std 10.1.0 (2024-04-04)

Expand Down
10 changes: 10 additions & 0 deletions concordium-std/src/prims.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,16 @@ extern "C" {
#[cfg(all(feature = "wasm-test", target_arch = "wasm32"))]
pub(crate) fn set_parameter(i: u32, start: *const u8, length: u32);

/// Gets event number `i` in the smart contract state. Returns `-1` if `i`
/// is an invalid index. Otherwise returns bytes written.
#[cfg(all(feature = "wasm-test", target_arch = "wasm32"))]
pub(crate) fn get_event(i: u32, start: *const u8) -> i32;

/// Gets the size of event number `i` in the smart contract state. Returns `-1` if `i`
/// is an invalid index.
#[cfg(all(feature = "wasm-test", target_arch = "wasm32"))]
pub(crate) fn get_event_size(i: u32) -> i32;

#[cfg(feature = "debug")]
/// Emit text together with the source location.
/// This is used as the equivalent of the `dbg!` macro when the
Expand Down
81 changes: 81 additions & 0 deletions concordium-std/src/test_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,50 @@ use crate::{prims, to_bytes};
struct TestEnv;

impl TestEnv {
/// Set the slot time in milliseconds.
/// The slot time represents the beginning of the smart contract's block.
pub fn set_slot_time(self, slot_time: SlotTime) -> Self {
unsafe { prims::set_slot_time(slot_time.timestamp_millis()) };
self
}

/// Sets the current balance of this smart contract
pub fn set_receive_balance(self, balance: Amount) -> Self {
unsafe { prims::set_receive_self_balance(balance.micro_ccd) };
self
}

/// Sets the address of this smart contract
pub fn set_receive_self_address(self, address: ContractAddress) -> Self {
unsafe { prims::set_receive_self_address(to_bytes(&address).as_ptr()) };
self
}

/// Sets parameter with `param_index` of the smart contract to the given
/// value.
pub fn set_parameter(self, param_index: u32, bytes: &[u8]) -> Self {
unsafe { prims::set_parameter(param_index, bytes.as_ptr(), bytes.len() as u32) };
self
}

/// Gets event number `i` in the smart contract state. Returns None if `i`
/// is an invalid index.
pub fn get_event(self, index: u32) -> Option<Vec<u8>> {
let event_len = unsafe { prims::get_event_size(index) };

if event_len < 0 {
return None;
}

let mut buf = vec![0; event_len.try_into().unwrap()];
let bytes_written = unsafe { prims::get_event(index, buf.as_mut_ptr()) };

if bytes_written < 0 {
return None;
} else {
Some(buf)
}
}
}

#[cfg(feature = "internal-wasm-test")]
Expand Down Expand Up @@ -104,4 +129,60 @@ mod wasm_test {
claim_eq!(buf, expected);
claim_eq!(bytes_written, 7);
}

#[concordium_test]
fn get_empty_parameter() {
let i = 1;
let mut buf = vec![0u8; 10];

let param_size = unsafe { prims::get_parameter_size(i) };
let bytes_written = unsafe { prims::get_parameter_section(i, buf.as_mut_ptr(), 5, 2) };

claim_eq!(param_size, -1);
claim_eq!(param_size, bytes_written);
}

#[concordium_test]
fn set_get_events() {
// Testing primitive calls
let event_prim = vec![1u8, 2, 3, 4];
let store_status =
unsafe { prims::log_event(event_prim.as_ptr(), event_prim.len().try_into().unwrap()) };
let event_size = unsafe { prims::get_event_size(0) };

claim_eq!(store_status, 1);
claim_eq!(event_size, event_prim.len().try_into().unwrap());

let mut buf = vec![0; event_prim.len()];
let bytes_written = unsafe { prims::get_event(0, buf.as_mut_ptr()) };

claim_eq!(bytes_written as usize, event_prim.len());
claim_eq!(buf, event_prim);

// Use the external call to test the actual function that would be called in
// most real scenarios
let mut logger = Logger::default();
let event1 = "Hello, World!".to_owned();
let event2 = "How are you today?".to_owned();

logger.log(&event1).unwrap();
logger.log(&event2).unwrap();

let stored1 = TestEnv.get_event(1).unwrap();
let stored2 = TestEnv.get_event(2).unwrap();

let mut expected1 = Vec::new();
let mut expected2 = Vec::new();
event1.serial(&mut expected1).unwrap();
event2.serial(&mut expected2).unwrap();

claim_eq!(stored1, expected1);
claim_eq!(stored2, expected2);
}

#[concordium_test]
fn get_empty_events() {
let stored = TestEnv.get_event(0);
claim_eq!(stored, None);
}
}

0 comments on commit 1973a62

Please sign in to comment.