#![cfg(test)]
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::Semaphore;
use tokio_util::sync::CancellationToken;
use astrid_storage::ScopedKvStore;
use astrid_storage::secret::SecretStore;
use super::host::process::ProcessTracker;
use super::host_state::HostState;
use crate::capsule::CapsuleId;
pub(crate) fn mem_kv(namespace: &str) -> ScopedKvStore {
let store = Arc::new(astrid_storage::MemoryKvStore::new());
ScopedKvStore::new(store, namespace).expect("valid namespace")
}
pub(crate) fn mem_secret_store(
namespace: &str,
rt: tokio::runtime::Handle,
) -> Arc<dyn SecretStore> {
Arc::new(astrid_storage::KvSecretStore::new(mem_kv(namespace), rt))
}
pub(crate) fn open_log(path: &std::path::Path) -> Arc<std::sync::Mutex<std::fs::File>> {
let f = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(path)
.expect("open log file");
Arc::new(std::sync::Mutex::new(f))
}
pub(crate) fn minimal_host_state(rt: tokio::runtime::Handle) -> HostState {
let kv = mem_kv("capsule:test");
let secret_store: Arc<dyn SecretStore> =
Arc::new(astrid_storage::KvSecretStore::new(kv.clone(), rt.clone()));
HostState {
wasi_ctx: wasmtime_wasi::WasiCtxBuilder::new().build(),
resource_table: wasmtime::component::ResourceTable::new(),
store_meter: crate::memory_ledger::StoreMemoryMeter::new(
usize::MAX,
astrid_core::PrincipalId::default(),
crate::MemoryLedger::default(),
),
principal: astrid_core::PrincipalId::default(),
capsule_uuid: uuid::Uuid::new_v4(),
caller_context: None,
interceptor_active: false,
invocation_kv: None,
capsule_log: None,
capsule_id: CapsuleId::from_static("test"),
workspace_root: PathBuf::from("/tmp"),
vfs: Arc::new(astrid_vfs::HostVfs::new()),
vfs_root_handle: astrid_capabilities::DirHandle::new(),
home: None,
tmp: None,
invocation_home: None,
invocation_tmp: None,
invocation_secret_store: None,
invocation_capsule_log: None,
invocation_profile: None,
profile_cache: None,
invocation_env_overlay: None,
overlay_vfs: None,
upper_dir: None,
kv,
event_bus: astrid_events::EventBus::with_capacity(128),
ipc_limiter: Arc::new(astrid_events::ipc::IpcRateLimiter::new()),
config: HashMap::new(),
secret_env: std::collections::HashSet::new(),
ipc_publish_patterns: Vec::new(),
ipc_subscribe_patterns: Vec::new(),
security: None,
hook_manager: None,
capsule_registry: None,
runtime_handle: rt.clone(),
has_uplink_capability: false,
capability_names: Vec::new(),
audit_firehose: false,
inbound_tx: None,
registered_uplinks: Vec::new(),
cli_socket_listener: None,
active_http_streams: HashMap::new(),
next_http_stream_id: 1,
lifecycle_phase: None,
secret_store,
ready_tx: None,
blocking_semaphore: Arc::new(Semaphore::new(2)),
io_semaphore: Arc::new(Semaphore::new(2)),
cancel_token: CancellationToken::new(),
session_token: None,
interceptor_handles: Vec::new(),
allowance_store: None,
identity_store: None,
process_tracker: Arc::new(ProcessTracker::new()),
persistent_processes: Arc::new(
crate::engine::wasm::host::process::PersistentProcessRegistry::new(rt),
),
net_stream_count: 0,
subscription_count: 0,
process_count_total: 0,
process_count_by_principal: HashMap::new(),
recv_yielded: false,
no_yield_windows: 0,
}
}