ios unit test cleanup

This commit is contained in:
John Smith 2022-01-31 08:52:11 -05:00
parent 4bdcbbdec9
commit cc328d30fa
9 changed files with 751 additions and 555 deletions

View File

@ -11,7 +11,7 @@ crate-type = ["cdylib", "staticlib", "rlib"]
[features]
android_tests = []
ios_tests = []
ios_tests = [ "simplelog", "backtrace" ]
[dependencies]
capnp = { version = "^0", default_features = false }
@ -126,14 +126,10 @@ rtnetlink = { version = "^0", default-features = false, features = [ "smol_socke
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "^0", features = [ "iptypes", "iphlpapi" ] }
# Dependencies for MacOS and iOS
#[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
# XXX
# Dependencies for iOS
[target.'cfg(target_os = "ios")'.dependencies]
simplelog = { version = "^0" }
backtrace = { version = "^0" }
simplelog = { version = "^0", optional = true }
backtrace = { version = "^0", optional = true }
# Rusqlite configuration to ensure platforms that don't come with sqlite get it bundled
# Except WASM which doesn't use sqlite

View File

@ -25,8 +25,20 @@ do
echo Unsupported ARCH: $arch
continue
fi
HOMEBREW_DIR=$(dirname `which brew`)
CARGO_DIR=$(dirname `which cargo`)
env -i PATH=/usr/bin:/bin:/usr/local/bin:$HOMEBREW_DIR:$CARGO_DIR HOME="$HOME" USER="$USER" cargo $CARGO_TOOLCHAIN build $EXTRA_CARGO_OPTIONS --target $CARGO_TARGET --manifest-path $CARGO_MANIFEST_PATH
CARGO=`which cargo`
CARGO=${CARGO:=~/.cargo/bin/cargo}
CARGO_DIR=$(dirname $CARGO)
# Choose arm64 brew for unit tests by default if we are on M1
if [ -f /opt/homebrew/bin/brew ]; then
HOMEBREW_DIR=/opt/homebrew/bin
elif [ -f /usr/local/bin/brew ]; then
HOMEBREW_DIR=/usr/local/bin
else
HOMEBREW_DIR=$(dirname `which brew`)
fi
env -i PATH=/usr/bin:/bin:$HOMEBREW_DIR:$CARGO_DIR HOME="$HOME" USER="$USER" cargo $CARGO_TOOLCHAIN build $EXTRA_CARGO_OPTIONS --target $CARGO_TARGET --manifest-path $CARGO_MANIFEST_PATH
done

View File

@ -1,29 +1,22 @@
use crate::xx::*;
use backtrace::Backtrace;
use lazy_static::*;
use log::*;
use simplelog::*;
use std::fs::OpenOptions;
use std::panic;
use std::path::{Path, PathBuf};
pub struct IOSGlobals {}
lazy_static! {
pub static ref IOS_GLOBALS: Arc<Mutex<Option<IOSGlobals>>> = Arc::new(Mutex::new(None));
}
pub fn veilid_core_setup_ios<'a>(
pub fn veilid_core_setup<'a>(
log_tag: &'a str,
terminal_log: Option<Level>,
file_log: Option<(Level, &Path)>,
) {
if let Err(e) = veilid_core_setup_ios_internal(log_tag, terminal_log, file_log) {
if let Err(e) = veilid_core_setup_internal(log_tag, terminal_log, file_log) {
panic!("failed to set up veilid-core: {}", e);
}
}
fn veilid_core_setup_ios_internal<'a>(
fn veilid_core_setup_internal<'a>(
_log_tag: &'a str,
terminal_log: Option<Level>,
file_log: Option<(Level, &Path)>,
@ -94,6 +87,5 @@ fn veilid_core_setup_ios_internal<'a>(
error!("Backtrace:\n{:?}", bt);
}));
*IOS_GLOBALS.lock() = Some(IOSGlobals {});
Ok(())
}

View File

@ -1,5 +1,5 @@
#[cfg(target_os = "android")]
pub mod android;
#[cfg(target_os = "ios")]
pub mod ios;
pub mod ios_test_setup;
pub mod network_interfaces;

View File

@ -31,7 +31,7 @@ pub extern "C" fn run_veilid_core_tests() {
]
.iter()
.collect();
crate::intf::utils::ios::veilid_core_setup_ios(
crate::intf::utils::ios_test_setup::veilid_core_setup(
"veilid-core",
Some(Level::Trace),
Some((Level::Trace, log_path.as_path())),

View File

@ -13,6 +13,7 @@ flutter_rust_bridge = "^1"
parking_lot = "^0"
log = "^0"
anyhow = { version = "^1", features = ["backtrace"] }
cfg-if = "^1"
[build-dependencies]
cfg-if = "^1"

View File

@ -1,9 +1,9 @@
use std::sync::Arc;
use anyhow::*;
use async_std::sync::Mutex as AsyncMutex;
use flutter_rust_bridge::*;
use log::*;
use async_std::sync::Mutex as AsyncMutex;
use anyhow::*;
use std::fmt;
use std::sync::Arc;
// Globals
@ -14,9 +14,7 @@ async fn get_veilid_api() -> Result<veilid_core::VeilidAPI> {
None => {
return Err(anyhow!(VeilidAPIError::NotInitialized));
}
Some(api) => {
api.clone()
}
Some(api) => api.clone(),
};
Ok(veilid_api)
}
@ -26,14 +24,11 @@ async fn take_veilid_api() -> Result<veilid_core::VeilidAPI> {
None => {
return Err(anyhow!(VeilidAPIError::NotInitialized));
}
Some(api) => {
api
}
Some(api) => api,
};
Ok(veilid_api)
}
/////////////////////////////////////////
// Config Settings
// Not all settings available through Veilid API are available to Flutter applications
@ -123,53 +118,103 @@ pub struct VeilidConfig {
}
impl VeilidConfig {
pub fn get_by_str(&self, key: &str) -> std::result::Result<Box<dyn std::any::Any + Send + 'static>, String> {
pub fn get_by_str(
&self,
key: &str,
) -> std::result::Result<Box<dyn std::any::Any + Send + 'static>, String> {
let out: Box<dyn core::any::Any + Send> = match key {
"program_name" => Box::new(self.program_name.clone()),
"namespace" => Box::new(self.veilid_namespace.clone()),
"capabilities.protocol_udp" => Box::new(self.capabilities__protocol_udp.clone()),
"capabilities.protocol_connect_tcp" => Box::new(self.capabilities__protocol_connect_tcp.clone()),
"capabilities.protocol_accept_tcp" => Box::new(self.capabilities__protocol_accept_tcp.clone()),
"capabilities.protocol_connect_ws" => Box::new(self.capabilities__protocol_connect_ws.clone()),
"capabilities.protocol_accept_ws" => Box::new(self.capabilities__protocol_accept_ws.clone()),
"capabilities.protocol_connect_wss" => Box::new(self.capabilities__protocol_connect_wss.clone()),
"capabilities.protocol_accept_wss" => Box::new(self.capabilities__protocol_accept_wss.clone()),
"capabilities.protocol_connect_tcp" => {
Box::new(self.capabilities__protocol_connect_tcp.clone())
}
"capabilities.protocol_accept_tcp" => {
Box::new(self.capabilities__protocol_accept_tcp.clone())
}
"capabilities.protocol_connect_ws" => {
Box::new(self.capabilities__protocol_connect_ws.clone())
}
"capabilities.protocol_accept_ws" => {
Box::new(self.capabilities__protocol_accept_ws.clone())
}
"capabilities.protocol_connect_wss" => {
Box::new(self.capabilities__protocol_connect_wss.clone())
}
"capabilities.protocol_accept_wss" => {
Box::new(self.capabilities__protocol_accept_wss.clone())
}
"table_store.directory" => Box::new(self.table_store__directory.clone()),
"table_store.delete" => Box::new(self.table_store__delete.clone()),
"block_store.directory" => Box::new(self.block_store__directory.clone()),
"block_store.delete" => Box::new(self.block_store__delete.clone()),
"protected_store.allow_insecure_fallback" => Box::new(self.protected_store__allow_insecure_fallback.clone()),
"protected_store.always_use_insecure_storage" => Box::new(self.protected_store__always_use_insecure_storage.clone()),
"protected_store.insecure_fallback_directory" => Box::new(self.protected_store__insecure_fallback_directory.clone()),
"protected_store.allow_insecure_fallback" => {
Box::new(self.protected_store__allow_insecure_fallback.clone())
}
"protected_store.always_use_insecure_storage" => {
Box::new(self.protected_store__always_use_insecure_storage.clone())
}
"protected_store.insecure_fallback_directory" => {
Box::new(self.protected_store__insecure_fallback_directory.clone())
}
"protected_store.delete" => Box::new(self.protected_store__delete.clone()),
"network.node_id" => Box::new(self.network__node_id.clone()),
"network.node_id_secret" => Box::new(self.network__node_id_secret.clone()),
"network.max_connections" => Box::new(self.network__max_connections.clone()),
"network.connection_initial_timeout_ms" => Box::new(self.network__connection_initial_timeout_ms.clone()),
"network.connection_initial_timeout_ms" => {
Box::new(self.network__connection_initial_timeout_ms.clone())
}
"network.bootstrap" => Box::new(self.network__bootstrap.clone()),
"network.dht.resolve_node_timeout_ms" => Box::new(self.network__dht__resolve_node_timeout_ms.clone()),
"network.dht.resolve_node_count" => Box::new(self.network__dht__resolve_node_count.clone()),
"network.dht.resolve_node_fanout" => Box::new(self.network__dht__resolve_node_fanout.clone()),
"network.dht.max_find_node_count" => Box::new(self.network__dht__max_find_node_count.clone()),
"network.dht.get_value_timeout_ms" => Box::new(self.network__dht__get_value_timeout_ms.clone()),
"network.dht.resolve_node_timeout_ms" => {
Box::new(self.network__dht__resolve_node_timeout_ms.clone())
}
"network.dht.resolve_node_count" => {
Box::new(self.network__dht__resolve_node_count.clone())
}
"network.dht.resolve_node_fanout" => {
Box::new(self.network__dht__resolve_node_fanout.clone())
}
"network.dht.max_find_node_count" => {
Box::new(self.network__dht__max_find_node_count.clone())
}
"network.dht.get_value_timeout_ms" => {
Box::new(self.network__dht__get_value_timeout_ms.clone())
}
"network.dht.get_value_count" => Box::new(self.network__dht__get_value_count.clone()),
"network.dht.get_value_fanout" => Box::new(self.network__dht__get_value_fanout.clone()),
"network.dht.set_value_timeout_ms" => Box::new(self.network__dht__set_value_timeout_ms.clone()),
"network.dht.set_value_timeout_ms" => {
Box::new(self.network__dht__set_value_timeout_ms.clone())
}
"network.dht.set_value_count" => Box::new(self.network__dht__set_value_count.clone()),
"network.dht.set_value_fanout" => Box::new(self.network__dht__set_value_fanout.clone()),
"network.dht.min_peer_count" => Box::new(self.network__dht__min_peer_count.clone()),
"network.dht.min_peer_refresh_time_ms" => Box::new(self.network__dht__min_peer_refresh_time_ms.clone()),
"network.dht.validate_dial_info_receipt_time_ms" => Box::new(self.network__dht__validate_dial_info_receipt_time_ms.clone()),
"network.dht.min_peer_refresh_time_ms" => {
Box::new(self.network__dht__min_peer_refresh_time_ms.clone())
}
"network.dht.validate_dial_info_receipt_time_ms" => Box::new(
self.network__dht__validate_dial_info_receipt_time_ms
.clone(),
),
"network.rpc.concurrency" => Box::new(self.network__rpc__concurrency.clone()),
"network.rpc.queue_size" => Box::new(self.network__rpc__queue_size.clone()),
"network.rpc.max_timestamp_behind_ms" => Box::new(self.network__rpc__max_timestamp_behind_ms.clone()),
"network.rpc.max_timestamp_ahead_ms" => Box::new(self.network__rpc__max_timestamp_ahead_ms.clone()),
"network.rpc.max_timestamp_behind_ms" => {
Box::new(self.network__rpc__max_timestamp_behind_ms.clone())
}
"network.rpc.max_timestamp_ahead_ms" => {
Box::new(self.network__rpc__max_timestamp_ahead_ms.clone())
}
"network.rpc.timeout_ms" => Box::new(self.network__rpc__timeout_ms.clone()),
"network.rpc.max_route_hop_count" => Box::new(self.network__rpc__max_route_hop_count.clone()),
"network.rpc.max_route_hop_count" => {
Box::new(self.network__rpc__max_route_hop_count.clone())
}
"network.upnp" => Box::new(self.network__upnp.clone()),
"network.natpmp" => Box::new(self.network__natpmp.clone()),
"network.enable_local_peer_scope" => Box::new(self.network__enable_local_peer_scope.clone()),
"network.restricted_nat_retries" => Box::new(self.network__restricted_nat_retries.clone()),
"network.enable_local_peer_scope" => {
Box::new(self.network__enable_local_peer_scope.clone())
}
"network.restricted_nat_retries" => {
Box::new(self.network__restricted_nat_retries.clone())
}
"network.tls.certificate_path" => Box::new("".to_owned()),
"network.tls.private_key_path" => Box::new("".to_owned()),
"network.tls.connection_initial_timeout" => Box::new(0u32),
@ -181,34 +226,66 @@ impl VeilidConfig {
"network.application.http.listen_address" => Box::new("".to_owned()),
"network.application.http.path" => Box::new("".to_owned()),
"network.application.http.url" => Box::new(Option::<String>::None),
"network.protocol.udp.enabled" => Box::new(self.network__protocol__udp__enabled.clone()),
"network.protocol.udp.socket_pool_size" => Box::new(self.network__protocol__udp__socket_pool_size.clone()),
"network.protocol.udp.listen_address" => Box::new(self.network__protocol__udp__listen_address.clone()),
"network.protocol.udp.public_address" => Box::new(self.network__protocol__udp__public_address.clone()),
"network.protocol.tcp.connect" => Box::new(self.network__protocol__tcp__connect.clone()),
"network.protocol.udp.enabled" => {
Box::new(self.network__protocol__udp__enabled.clone())
}
"network.protocol.udp.socket_pool_size" => {
Box::new(self.network__protocol__udp__socket_pool_size.clone())
}
"network.protocol.udp.listen_address" => {
Box::new(self.network__protocol__udp__listen_address.clone())
}
"network.protocol.udp.public_address" => {
Box::new(self.network__protocol__udp__public_address.clone())
}
"network.protocol.tcp.connect" => {
Box::new(self.network__protocol__tcp__connect.clone())
}
"network.protocol.tcp.listen" => Box::new(self.network__protocol__tcp__listen.clone()),
"network.protocol.tcp.max_connections" => Box::new(self.network__protocol__tcp__max_connections.clone()),
"network.protocol.tcp.listen_address" => Box::new(self.network__protocol__tcp__listen_address.clone()),
"network.protocol.tcp.public_address" => Box::new(self.network__protocol__tcp__public_address.clone()),
"network.protocol.tcp.max_connections" => {
Box::new(self.network__protocol__tcp__max_connections.clone())
}
"network.protocol.tcp.listen_address" => {
Box::new(self.network__protocol__tcp__listen_address.clone())
}
"network.protocol.tcp.public_address" => {
Box::new(self.network__protocol__tcp__public_address.clone())
}
"network.protocol.ws.connect" => Box::new(self.network__protocol__ws__connect.clone()),
"network.protocol.ws.listen" => Box::new(self.network__protocol__ws__listen.clone()),
"network.protocol.ws.max_connections" => Box::new(self.network__protocol__ws__max_connections.clone()),
"network.protocol.ws.listen_address" => Box::new(self.network__protocol__ws__listen_address.clone()),
"network.protocol.ws.max_connections" => {
Box::new(self.network__protocol__ws__max_connections.clone())
}
"network.protocol.ws.listen_address" => {
Box::new(self.network__protocol__ws__listen_address.clone())
}
"network.protocol.ws.path" => Box::new(self.network__protocol__ws__path.clone()),
"network.protocol.ws.url" => Box::new(self.network__protocol__ws__url.clone()),
"network.protocol.wss.connect" => Box::new(self.network__protocol__wss__connect.clone()),
"network.protocol.wss.connect" => {
Box::new(self.network__protocol__wss__connect.clone())
}
"network.protocol.wss.listen" => Box::new(false),
"network.protocol.wss.max_connections" => Box::new(self.network__protocol__wss__max_connections.clone()),
"network.protocol.wss.max_connections" => {
Box::new(self.network__protocol__wss__max_connections.clone())
}
"network.protocol.wss.listen_address" => Box::new("".to_owned()),
"network.protocol.wss.path" => Box::new("".to_owned()),
"network.protocol.wss.url" => Box::new(Option::<String>::None),
"network.leases.max_server_signal_leases" => Box::new(self.network__leases__max_server_signal_leases.clone()),
"network.leases.max_server_relay_leases" => Box::new(self.network__leases__max_server_relay_leases.clone()),
"network.leases.max_client_signal_leases" => Box::new(self.network__leases__max_client_signal_leases.clone()),
"network.leases.max_client_relay_leases" => Box::new(self.network__leases__max_client_relay_leases.clone()),
"network.leases.max_server_signal_leases" => {
Box::new(self.network__leases__max_server_signal_leases.clone())
}
"network.leases.max_server_relay_leases" => {
Box::new(self.network__leases__max_server_relay_leases.clone())
}
"network.leases.max_client_signal_leases" => {
Box::new(self.network__leases__max_client_signal_leases.clone())
}
"network.leases.max_client_relay_leases" => {
Box::new(self.network__leases__max_client_relay_leases.clone())
}
_ => {
let err = format!("config key '{}' doesn't exist", key);
error!("{}",err);
error!("{}", err);
return Err(err);
}
};
@ -288,13 +365,37 @@ impl VeilidAPIError {
match api_error {
veilid_core::VeilidAPIError::Timeout => VeilidAPIError::Timeout,
veilid_core::VeilidAPIError::Shutdown => VeilidAPIError::Shutdown,
veilid_core::VeilidAPIError::NodeNotFound(node_id) => VeilidAPIError::NodeNotFound(format!("{}",node_id)),
veilid_core::VeilidAPIError::NoDialInfo(node_id) => VeilidAPIError::NodeNotFound(format!("{}",node_id)),
veilid_core::VeilidAPIError::NodeNotFound(node_id) => {
VeilidAPIError::NodeNotFound(format!("{}", node_id))
}
veilid_core::VeilidAPIError::NoDialInfo(node_id) => {
VeilidAPIError::NodeNotFound(format!("{}", node_id))
}
veilid_core::VeilidAPIError::Internal(msg) => VeilidAPIError::Internal(msg.clone()),
veilid_core::VeilidAPIError::Unimplemented(msg)=> VeilidAPIError::Unimplemented(msg.clone()),
veilid_core::VeilidAPIError::ParseError{message, value} => VeilidAPIError::ParseError{ message: message.clone(), value: value.clone() },
veilid_core::VeilidAPIError::InvalidArgument { context, argument, value } => VeilidAPIError::InvalidArgument{ context: context.clone(), argument: argument.clone(), value: value.clone() },
veilid_core::VeilidAPIError::MissingArgument {context, argument } => VeilidAPIError::MissingArgument{ context: context.clone(), argument: argument.clone() },
veilid_core::VeilidAPIError::Unimplemented(msg) => {
VeilidAPIError::Unimplemented(msg.clone())
}
veilid_core::VeilidAPIError::ParseError { message, value } => {
VeilidAPIError::ParseError {
message: message.clone(),
value: value.clone(),
}
}
veilid_core::VeilidAPIError::InvalidArgument {
context,
argument,
value,
} => VeilidAPIError::InvalidArgument {
context: context.clone(),
argument: argument.clone(),
value: value.clone(),
},
veilid_core::VeilidAPIError::MissingArgument { context, argument } => {
VeilidAPIError::MissingArgument {
context: context.clone(),
argument: argument.clone(),
}
}
}
}
}
@ -326,21 +427,21 @@ impl AttachmentState {
}
}
#[derive(Debug, Clone)]
pub enum VeilidUpdate {
Attachment (AttachmentState),
Attachment(AttachmentState),
}
impl VeilidUpdate {
fn from_core(veilid_update: veilid_core::VeilidUpdate) -> Self {
match veilid_update {
veilid_core::VeilidUpdate::Attachment(attachment) => Self::Attachment(AttachmentState::from_core(attachment))
veilid_core::VeilidUpdate::Attachment(attachment) => {
Self::Attachment(AttachmentState::from_core(attachment))
}
}
}
}
#[derive(Debug, Clone)]
pub struct VeilidState {
pub attachment: AttachmentState,
@ -349,20 +450,22 @@ pub struct VeilidState {
impl VeilidState {
fn from_core(veilid_state: veilid_core::VeilidState) -> Self {
Self {
attachment: AttachmentState::from_core(veilid_state.attachment)
attachment: AttachmentState::from_core(veilid_state.attachment),
}
}
}
/////////////////////////////////////////
pub fn startup_veilid_core(sink: StreamSink<VeilidUpdate>, config: VeilidConfig) -> Result<VeilidState> {
async_std::task::block_on( async {
pub fn startup_veilid_core(
sink: StreamSink<VeilidUpdate>,
config: VeilidConfig,
) -> Result<VeilidState> {
async_std::task::block_on(async {
let mut api_lock = VEILID_API.lock().await;
if api_lock.is_some() {
return Err(anyhow!(VeilidAPIError::AlreadyInitialized));
}
let core = veilid_core::VeilidCore::new();
let setup = veilid_core::VeilidCoreSetup {
@ -375,26 +478,31 @@ pub fn startup_veilid_core(sink: StreamSink<VeilidUpdate>, config: VeilidConfig)
}
})
},
),
config_callback: Arc::new(
move |key| {
config.get_by_str(&key)
}
),
};
config_callback: Arc::new(move |key| config.get_by_str(&key)),
};
let veilid_api = core.startup(setup).await.map_err(|e| VeilidAPIError::InvalidConfig(e.clone()))?;
let veilid_api = core
.startup(setup)
.await
.map_err(|e| VeilidAPIError::InvalidConfig(e.clone()))?;
*api_lock = Some(veilid_api.clone());
let core_state = veilid_api.get_state().await.map_err(VeilidAPIError::from_core)?;
let core_state = veilid_api
.get_state()
.await
.map_err(VeilidAPIError::from_core)?;
Ok(VeilidState::from_core(core_state))
})
}
pub fn get_veilid_state() -> Result<VeilidState> {
async_std::task::block_on( async {
async_std::task::block_on(async {
let veilid_api = get_veilid_api().await?;
let core_state = veilid_api.get_state().await.map_err(VeilidAPIError::from_core)?;
let core_state = veilid_api
.get_state()
.await
.map_err(VeilidAPIError::from_core)?;
Ok(VeilidState::from_core(core_state))
})
}
@ -402,9 +510,9 @@ pub fn get_veilid_state() -> Result<VeilidState> {
// xxx api functions
pub fn shutdown_veilid_core() -> Result<()> {
async_std::task::block_on( async {
async_std::task::block_on(async {
let veilid_api = get_veilid_api().await?;
veilid_api.shutdown().await;
veilid_api.shutdown().await;
Ok(())
})
}
@ -413,15 +521,17 @@ pub fn veilid_version_string() -> Result<String> {
Ok(veilid_core::veilid_version_string())
}
pub struct VeilidVersion{
pub struct VeilidVersion {
pub major: u32,
pub minor: u32,
pub patch: u32
pub minor: u32,
pub patch: u32,
}
pub fn veilid_version() -> Result<VeilidVersion> {
let (major, minor, patch) = veilid_core::veilid_version();
Ok(VeilidVersion {
major, minor, patch
major,
minor,
patch,
})
}

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,37 @@
mod api;
mod bridge_generated;
use cfg_if::*;
xxx make this work
#[cfg(all(target_os = "android", feature = "android_tests"))]
use jni::{objects::JClass, objects::JObject, JNIEnv};
#[cfg(all(target_os = "android", feature = "android_tests"))]
#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn Java_com_veilid_veilidcore_veilidcore_1android_1tests_MainActivity_run_1tests(
env: JNIEnv,
_class: JClass,
ctx: JObject,
) {
crate::intf::utils::android::veilid_core_setup_android(env, ctx, "veilid_core", Level::Trace);
}
#[cfg(target_os = "ios")]
#[no_mangle]
pub extern "C" fn run_veilid_core_tests(app_name: c_str) {
let log_path: std::path::PathBuf = [
std::env::var("HOME").unwrap().as_str(),
"Documents",
"veilid-core.log",
]
.iter()
.collect();
crate::intf::utils::setup::veilid_core_setup(
"veilid-core",
Some(Level::Trace),
Some((Level::Trace, log_path.as_path())),
);
}