blob: 848bee8e772ccf657b2a0ad44b5e6e70f0e6336b [file] [log] [blame]
// Copyright 2024 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.
//! common functions to be used by Criterion or integration test for the
/// Topology Test Daemon.
use anyhow::Result;
use fidl::endpoints::create_sync_proxy;
use fidl_fuchsia_power_broker as fbroker;
use fidl_fuchsia_power_topology_test as fpt;
use fuchsia_component::client::connect_to_protocol_sync;
use rand::Rng;
use std::sync::Arc;
#[inline(always)]
fn black_box<T>(placeholder: T) -> T {
criterion::black_box(placeholder)
}
fn work_func(
topology_control: &fpt::TopologyControlSynchronousProxy,
status_channel: &Arc<fbroker::StatusSynchronousProxy>,
) -> Result<()> {
// Acquire lease for C @ 5.
let _ = topology_control
.acquire_lease("C", 5, fbroker::LeaseStatus::Unknown, zx::MonotonicInstant::INFINITE)
.unwrap();
let level = status_channel
.watch_power_level(zx::MonotonicInstant::INFINITE)
.expect("Fidl call should work")
.expect("Result should be good");
assert_eq!(level, 5);
let _ = topology_control.drop_lease("C", zx::MonotonicInstant::INFINITE).unwrap();
let level = status_channel
.watch_power_level(zx::MonotonicInstant::INFINITE)
.expect("Fidl call should work")
.expect("Result should be good");
assert_eq!(level, 0);
Ok(())
}
pub(crate) fn prepare_work()
-> (Arc<fpt::TopologyControlSynchronousProxy>, Arc<fbroker::StatusSynchronousProxy>) {
// Current Criterion library doesn't support async call yet.
let topology_control = connect_to_protocol_sync::<fpt::TopologyControlMarker>().unwrap();
let elements: [fpt::Element; 2] = [
fpt::Element {
element_name: "C".to_string(),
initial_current_level: 0,
valid_levels: vec![0, 5],
dependencies: vec![fpt::LevelDependency {
dependent_level: 5,
requires_element: "P".to_string(),
requires_level: 50,
}],
},
fpt::Element {
element_name: "P".to_string(),
initial_current_level: 0,
valid_levels: vec![0, 30, 50],
dependencies: vec![],
},
];
let _ = topology_control.create(&elements, zx::MonotonicInstant::INFINITE).unwrap();
let (status_channel, server_channel) = create_sync_proxy::<fbroker::StatusMarker>();
let _ =
topology_control.open_status_channel("C", server_channel, zx::MonotonicInstant::INFINITE);
let level = status_channel
.watch_power_level(zx::MonotonicInstant::INFINITE)
.expect("Fidl call should work")
.expect("Result should be good");
assert_eq!(level, 0);
(Arc::new(topology_control), Arc::new(status_channel))
}
pub(crate) fn execute(
topology_control: &fpt::TopologyControlSynchronousProxy,
status_channel: &Arc<fbroker::StatusSynchronousProxy>,
) {
let _ = black_box(work_func(topology_control, status_channel));
}
fn acquire_and_drop_rand_lease_work_func(
topology_control: &fpt::TopologyControlSynchronousProxy,
num_elements: usize,
) -> Result<()> {
let mut rng = rand::rng();
let i = rng.random_range(0..num_elements);
let _ = topology_control
.acquire_lease(
&format!("element_{}", i),
1,
fbroker::LeaseStatus::Satisfied,
zx::MonotonicInstant::INFINITE,
)
.unwrap();
let _ = topology_control
.drop_lease(&format!("element_{}", i), zx::MonotonicInstant::INFINITE)
.unwrap();
Ok(())
}
pub(crate) fn prepare_large_topology(
num_elements: usize,
) -> Arc<fpt::TopologyControlSynchronousProxy> {
let topology_control = connect_to_protocol_sync::<fpt::TopologyControlMarker>().unwrap();
let mut elements = Vec::new();
for i in 0..num_elements {
let name = format!("element_{}", i);
let mut deps = Vec::new();
if i > 0 {
deps.push(fpt::LevelDependency {
dependent_level: 1,
requires_element: format!("element_{}", i - 1),
requires_level: 1,
});
// Multi-dependencies to trigger exponential explosions natively
if i > 1 {
deps.push(fpt::LevelDependency {
dependent_level: 1,
requires_element: format!("element_{}", i - 2),
requires_level: 1,
});
}
}
elements.push(fpt::Element {
element_name: name,
initial_current_level: 0,
valid_levels: vec![0, 1],
dependencies: deps,
});
}
let _ = topology_control.create(&elements, zx::MonotonicInstant::INFINITE).unwrap();
Arc::new(topology_control)
}
pub(crate) fn execute_acquire_and_drop_rand_lease(
topology_control: &fpt::TopologyControlSynchronousProxy,
num_elements: usize,
) {
let _ = black_box(acquire_and_drop_rand_lease_work_func(topology_control, num_elements));
}