blob: fb4832929241de81314fe67a06b1cc0f56f6439f [file] [edit]
// Copyright 2026 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![no_std]
#![cfg_attr(not(ktest), allow(unused_crate_dependencies))]
#[cfg(ktest)]
#[unittest::test_suite(name = "rust_ksync")]
/// Tests for Rust ksync bindings
mod ksync_tests {
use pin_init::{pin_init, stack_pin_init};
use unittest::{assert_true, expect_false, expect_ok, expect_true};
#[unsafe(no_mangle)]
pub extern "C" fn ksync_tests_link_helper() {}
#[ksync::guarded]
struct GuardedMutexObj {
#[mutex]
mu: ksync::KMutex,
#[guarded_by(mu)]
value: u32,
}
#[ksync::guarded]
struct GuardedSpinlockObj {
#[mutex]
mu: ksync::KMutex<ksync::RawSpinlock>,
#[guarded_by(mu)]
value: u32,
}
#[ksync::guarded]
struct GuardedCriticalMutexObj {
#[mutex]
mu: ksync::KMutex<ksync::RawCriticalMutex>,
#[guarded_by(mu)]
value: u32,
}
#[ksync::guarded]
struct GuardedBrwLockObj {
#[brwlock]
lock: ksync::BrwLockPi,
#[guarded_by(lock)]
value: u32,
}
unsafe extern "C" {
fn cpp_verify_mutex_id(
lock: *const core::ffi::c_void,
expected_id: *const core::ffi::c_void,
) -> bool;
fn cpp_verify_critical_mutex_id(
lock: *const core::ffi::c_void,
expected_id: *const core::ffi::c_void,
) -> bool;
fn cpp_verify_spinlock_id(
lock: *const core::ffi::c_void,
expected_id: *const core::ffi::c_void,
) -> bool;
fn cpp_verify_brwlock_id(
lock: *const core::ffi::c_void,
expected_id: *const core::ffi::c_void,
) -> bool;
}
/// test Rust KMutex ID
#[test]
fn mutex_id() {
stack_pin_init!(let obj = pin_init!(GuardedMutexObj {
mu <- ksync::KMutex::init(),
value: 0.into(),
}));
unsafe {
assert_true!(cpp_verify_mutex_id(
&obj.mu as *const _ as *const core::ffi::c_void,
<GuardedMutexObjMuClass as ksync::LockClass>::ID,
));
}
}
/// test Rust KCriticalMutex ID
#[test]
fn critical_mutex_id() {
stack_pin_init!(let obj = pin_init!(GuardedCriticalMutexObj {
mu <- ksync::KMutex::init(),
value: 0.into(),
}));
unsafe {
assert_true!(cpp_verify_critical_mutex_id(
&obj.mu as *const _ as *const core::ffi::c_void,
<GuardedCriticalMutexObjMuClass as ksync::LockClass>::ID,
));
}
}
/// test Rust KSpinlock ID
#[test]
fn spinlock_id() {
stack_pin_init!(let obj = pin_init!(GuardedSpinlockObj {
mu <- ksync::KMutex::init(),
value: 0.into(),
}));
unsafe {
assert_true!(cpp_verify_spinlock_id(
&obj.mu as *const _ as *const core::ffi::c_void,
<GuardedSpinlockObjMuClass as ksync::LockClass>::ID,
));
}
}
/// test Rust BrwLockPi ID
#[test]
fn brwlock_id() {
stack_pin_init!(let obj = pin_init!(GuardedBrwLockObj {
lock <- ksync::BrwLockPi::init(),
value: 0.into(),
}));
unsafe {
assert_true!(cpp_verify_brwlock_id(
&obj.lock as *const _ as *const core::ffi::c_void,
<GuardedBrwLockObjLockClass as ksync::LockClass>::ID,
));
}
}
/// test Rust KSpinlock
#[test]
fn spinlock() {
stack_pin_init!(let obj = pin_init!(GuardedSpinlockObj {
mu <- ksync::KMutex::init(),
value: 100.into(),
}));
{
ksync::lock!(let mut guard = obj.lock_mu());
expect_true!(*guard.value() == 100);
*guard.as_mut().value_mut() = 101;
}
{
ksync::lock!(let guard = obj.lock_mu());
expect_true!(*guard.value() == 101);
}
}
/// test Rust KMutex
#[test]
fn mutex() {
stack_pin_init!(let obj = pin_init!(GuardedMutexObj {
mu <- ksync::KMutex::init(),
value: 42.into(),
}));
{
ksync::lock!(let mut guard = obj.lock_mu());
expect_true!(*guard.value() == 42);
*guard.as_mut().value_mut() = 43;
}
{
ksync::lock!(let guard = obj.lock_mu());
expect_true!(*guard.value() == 43);
}
}
/// test Rust KEvent
#[test]
fn event() {
stack_pin_init!(let event = ksync::KEvent::init(false));
expect_false!(event.wait_deadline(0).is_ok());
event.signal();
expect_ok!(event.wait_deadline(0));
event.unsignal();
expect_false!(event.wait_deadline(0).is_ok());
}
/// test Rust BrwLockPi
#[test]
fn brwlock() {
stack_pin_init!(let obj = pin_init!(GuardedBrwLockObj {
lock <- ksync::BrwLockPi::init(),
value: 10.into(),
}));
{
ksync::lock!(let guard = obj.read_lock());
expect_true!(*guard.value() == 10);
}
{
ksync::lock!(let mut guard = obj.write_lock());
expect_true!(*guard.value() == 10);
*guard.as_mut().value_mut() = 20;
}
{
ksync::lock!(let guard = obj.read_lock());
expect_true!(*guard.value() == 20);
}
}
}