core fixes

This commit is contained in:
John Smith 2022-11-29 19:22:33 -05:00
parent f7582fabb2
commit 5c0a500971
60 changed files with 98 additions and 1160 deletions

2
Cargo.lock generated
View File

@ -5800,7 +5800,6 @@ dependencies = [
"rkyv",
"rtnetlink",
"rusqlite",
"rust-fsm",
"rustls",
"rustls-pemfile",
"secrecy",
@ -5945,6 +5944,7 @@ dependencies = [
"owo-colors",
"parking_lot 0.11.2",
"rand 0.7.3",
"rust-fsm",
"send_wrapper 0.6.0",
"serial_test",
"simplelog 0.12.0",

View File

@ -25,7 +25,6 @@ tracing-subscriber = "^0"
tracing-error = "^0"
eyre = "^0"
capnp = { version = "^0", default_features = false }
rust-fsm = "^0"
static_assertions = "^1"
cfg-if = "^1"
thiserror = "^1"

62
veilid-core/run_tests.sh Executable file
View File

@ -0,0 +1,62 @@
#!/bin/bash
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
pushd $SCRIPTDIR 2>/dev/null
if [[ "$1" == "wasm" ]]; then
WASM_BINDGEN_TEST_TIMEOUT=120 wasm-pack test --chrome --headless
elif [[ "$1" == "ios" ]]; then
SYMROOT=/tmp/testout
APPNAME=veilidcore-tests
BUNDLENAME=com.veilid.veilidcore-tests
ID="$2"
if [[ "$ID" == "" ]]; then
echo "No emulator ID specified"
exit 1
fi
# Build for simulator
xcrun xcodebuild -project src/tests/ios/$APPNAME/$APPNAME.xcodeproj/ -scheme $APPNAME -destination "generic/platform=iOS Simulator" SYMROOT=$SYMROOT
# Run in temporary simulator
xcrun simctl install $ID $SYMROOT/Debug-iphonesimulator/$APPNAME.app
xcrun simctl launch --console $ID $BUNDLENAME
# Clean up build output
rm -rf /tmp/testout
elif [[ "$1" == "android" ]]; then
ID="$2"
if [[ "$ID" == "" ]]; then
echo "No emulator ID specified"
exit 1
fi
APPNAME=veilidcore-tests
APPID=com.veilid.veilidcore_tests
ACTIVITYNAME=MainActivity
pushd src/tests/android/$APPNAME >/dev/null
# Build apk
./gradlew assembleDebug
# Wait for boot
adb -s $ID wait-for-device
# Install app
adb -s $ID install -r ./app/build/outputs/apk/debug/app-debug.apk
# Start activity
adb -s $ID shell am start-activity -W $APPID/.$ACTIVITYNAME
# Get the pid of the program
APP_PID=`adb -s $ID shell pidof -s $APPID`
# Print the logcat
adb -s $ID shell logcat -d veilid-core:V *:S &
# Wait for the pid to be done
while [ "$(adb -s $ID shell pidof -s $APPID)" != "" ]; do
sleep 1
done
# Terminate logcat
kill %1
# Finished
popd >/dev/null
else
cargo test --features=rt-tokio
cargo test --features=rt-async-std
fi
popd 2>/dev/null

View File

@ -1,6 +1,6 @@
use crate::core_context::*;
use crate::veilid_api::*;
use crate::xx::*;
use crate::*;
use core::fmt::Write;
use once_cell::sync::OnceCell;
use tracing_subscriber::*;

View File

@ -1,8 +1,6 @@
use crate::callback_state_machine::*;
use crate::crypto::Crypto;
use crate::network_manager::*;
use crate::routing_table::*;
use crate::xx::*;
use crate::*;
use core::convert::TryFrom;
use core::fmt;

View File

@ -3,7 +3,6 @@ use crate::attachment_manager::*;
use crate::crypto::Crypto;
use crate::veilid_api::*;
use crate::veilid_config::*;
use crate::xx::*;
use crate::*;
pub type UpdateCallback = Arc<dyn Fn(VeilidUpdate) + Send + Sync>;

View File

@ -2,7 +2,6 @@
#![allow(clippy::absurd_extreme_comparisons)]
use super::*;
use crate::routing_table::VersionRange;
use crate::xx::*;
use crate::*;
use core::convert::TryInto;

View File

@ -1,4 +1,3 @@
use crate::xx::*;
use crate::*;
use core::cmp::{Eq, Ord, PartialEq, PartialOrd};

View File

@ -13,7 +13,6 @@ pub use value::*;
pub const MIN_CRYPTO_VERSION: u8 = 0u8;
pub const MAX_CRYPTO_VERSION: u8 = 0u8;
use crate::xx::*;
use crate::*;
use chacha20::cipher::{KeyIvInit, StreamCipher};
use chacha20::XChaCha20;
@ -25,6 +24,7 @@ use ed25519_dalek as ed;
use hashlink::linked_hash_map::Entry;
use hashlink::LruCache;
use serde::{Deserialize, Serialize};
use x25519_dalek as xd;
pub type SharedSecret = [u8; 32];

View File

@ -1,7 +1,6 @@
#![allow(dead_code)]
#![allow(clippy::absurd_extreme_comparisons)]
use super::*;
use crate::xx::*;
use crate::*;
use core::convert::TryInto;
use data_encoding::BASE64URL_NOPAD;

View File

@ -1,6 +1,5 @@
use super::*;
use crate::tests::common::test_veilid_config::*;
use crate::xx::*;
static LOREM_IPSUM:&[u8] = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. ";

View File

@ -1,7 +1,6 @@
#![allow(clippy::bool_assert_comparison)]
use super::*;
use crate::xx::*;
use core::convert::TryFrom;
static LOREM_IPSUM:&str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. ";

View File

@ -1,6 +1,5 @@
use super::*;
use crate::tests::common::test_veilid_config::*;
use crate::xx::*;
pub async fn test_envelope_round_trip() {
info!("--- test envelope round trip ---");

View File

@ -1,5 +1,4 @@
use super::*;
use crate::xx::*;
pub fn get_files_dir() -> String {
let aglock = ANDROID_GLOBALS.lock();

View File

@ -6,7 +6,6 @@ mod get_directories;
pub use get_directories::*;
use crate::veilid_config::VeilidConfigLogLevel;
use crate::xx::*;
use crate::*;
use backtrace::Backtrace;
use jni::errors::Result as JniResult;

View File

@ -1,4 +1,3 @@
use crate::xx::*;
use crate::*;
struct BlockStoreInner {

View File

@ -1,4 +1,3 @@
use crate::xx::*;
use backtrace::Backtrace;
use log::*;
use simplelog::*;

View File

@ -2,9 +2,14 @@ mod block_store;
mod protected_store;
mod system;
mod table_store;
pub mod utils;
pub use block_store::*;
pub use protected_store::*;
pub use system::*;
pub use table_store::*;
#[cfg(target_os = "android")]
pub mod android;
#[cfg(all(target_os = "ios", feature = "ios_tests"))]
pub mod ios_test_setup;
pub mod network_interfaces;

View File

@ -1,5 +1,5 @@
use super::*;
use crate::*;
use libc::{
close, freeifaddrs, getifaddrs, if_nametoindex, ifaddrs, ioctl, pid_t, sockaddr, sockaddr_in6,
socket, sysctl, time_t, AF_INET6, CTL_NET, IFF_BROADCAST, IFF_LOOPBACK, IFF_RUNNING, IFNAMSIZ,

View File

@ -1,7 +1,7 @@
use crate::xx::*;
use core::fmt;
mod tools;
use crate::*;
cfg_if::cfg_if! {
if #[cfg(any(target_os = "linux", target_os = "android"))] {
mod netlink;

View File

@ -1,5 +1,4 @@
use super::*;
use crate::*;
use alloc::collections::btree_map::Entry;
use futures_util::stream::TryStreamExt;

View File

@ -63,7 +63,8 @@ impl PlatformSupportWindows {
// }
// Iterate all the interfaces
let windows_interfaces = WindowsInterfaces::new().wrap_err("failed to get windows interfaces")?;
let windows_interfaces =
WindowsInterfaces::new().wrap_err("failed to get windows interfaces")?;
for windows_interface in windows_interfaces.iter() {
// Get name
let intf_name = windows_interface.name();

View File

@ -1,4 +1,3 @@
use crate::xx::*;
use crate::*;
use data_encoding::BASE64URL_NOPAD;
use keyring_manager::*;

View File

@ -1,5 +1,6 @@
#![allow(dead_code)]
use crate::xx::*;
use crate::*;
pub async fn get_outbound_relay_peer() -> Option<crate::veilid_api::PeerInfo> {
panic!("Native Veilid should never require an outbound relay");

View File

@ -1,5 +1,4 @@
use crate::intf::table_db::*;
use crate::xx::*;
use crate::*;
use keyvaluedb_sqlite::*;
use std::path::PathBuf;

View File

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

View File

@ -1,4 +1,3 @@
use crate::xx::*;
use crate::*;
use rkyv::{Archive as RkyvArchive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};

View File

@ -1,5 +1,3 @@
use crate::xx::*;
use crate::*;
struct BlockStoreInner {

View File

@ -1,8 +1,8 @@
use super::*;
use crate::xx::*;
use crate::*;
use data_encoding::BASE64URL_NOPAD;
use rkyv::{Archive as RkyvArchive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
use web_sys::*;
#[derive(Clone)]

View File

@ -1,5 +1,3 @@
use crate::xx::*;
use async_executors::{Bindgen, LocalSpawnHandleExt, SpawnHandleExt, Timer};
use futures_util::future::{select, Either};
use js_sys::*;

View File

@ -1,7 +1,6 @@
use super::*;
use crate::intf::table_db::*;
use crate::xx::*;
use crate::*;
use keyvaluedb_web::*;

View File

@ -1 +0,0 @@

View File

@ -20,7 +20,6 @@ extern crate alloc;
mod api_tracing_layer;
mod attachment_manager;
mod callback_state_machine;
mod core_context;
mod crypto;
mod intf;
@ -84,3 +83,5 @@ pub static DEFAULT_LOG_IGNORE_LIST: [&str; 21] = [
"trust_dns_proto",
"attohttpc",
];
use veilid_tools::*;

View File

@ -1,4 +1,3 @@
use crate::xx::*;
use crate::*;
#[cfg(not(target_arch = "wasm32"))]

View File

@ -8,12 +8,12 @@ mod start_protocols;
use super::*;
use crate::routing_table::*;
use connection_manager::*;
use network_interfaces::*;
use network_tcp::*;
use protocol::tcp::RawTcpProtocolHandler;
use protocol::udp::RawUdpProtocolHandler;
use protocol::ws::WebsocketProtocolHandler;
pub use protocol::*;
use utils::network_interfaces::*;
use async_tls::TlsAcceptor;
use futures_util::StreamExt;

View File

@ -5,7 +5,6 @@ pub mod wrtc;
pub mod ws;
use super::*;
use crate::xx::*;
use std::io;
#[derive(Debug)]

View File

@ -1,4 +1,3 @@
use crate::xx::*;
use crate::*;
use async_io::Async;
use std::io;

View File

@ -5,7 +5,6 @@ use futures_util::stream::{FuturesUnordered, StreamExt};
use network_manager::*;
use routing_table::*;
use stop_token::future::FutureExt;
use xx::*;
#[derive(Clone, Debug)]
pub enum ReceiptEvent {

View File

@ -11,7 +11,6 @@ mod routing_table_inner;
mod stats_accounting;
mod tasks;
use crate::xx::*;
use crate::*;
use crate::crypto::*;

View File

@ -1,4 +1,3 @@
use crate::xx::*;
use crate::*;
use alloc::collections::VecDeque;

View File

@ -30,7 +30,6 @@ pub use rpc_status::*;
use super::*;
use crate::crypto::*;
use crate::xx::*;
use futures_util::StreamExt;
use network_manager::*;
use receipt_manager::*;

View File

@ -1,4 +1,3 @@
pub mod test_async_tag_lock;
pub mod test_host_interface;
pub mod test_protected_store;
pub mod test_table_store;

View File

@ -1,158 +0,0 @@
use crate::xx::*;
pub async fn test_simple_no_contention() {
info!("test_simple_no_contention");
let table = AsyncTagLockTable::new();
let a1 = SocketAddr::new("1.2.3.4".parse().unwrap(), 1234);
let a2 = SocketAddr::new("6.9.6.9".parse().unwrap(), 6969);
{
let g1 = table.lock_tag(a1).await;
let g2 = table.lock_tag(a2).await;
drop(g2);
drop(g1);
}
{
let g1 = table.lock_tag(a1).await;
let g2 = table.lock_tag(a2).await;
drop(g1);
drop(g2);
}
assert_eq!(table.len(), 0);
}
pub async fn test_simple_single_contention() {
info!("test_simple_single_contention");
let table = AsyncTagLockTable::new();
let a1 = SocketAddr::new("1.2.3.4".parse().unwrap(), 1234);
let g1 = table.lock_tag(a1).await;
info!("locked");
let t1 = spawn(async move {
// move the guard into the task
let _g1_take = g1;
// hold the guard for a bit
info!("waiting");
sleep(1000).await;
// release the guard
info!("released");
});
// wait to lock again, will contend until spawned task exits
let _g1_b = table.lock_tag(a1).await;
info!("locked");
// Ensure task is joined
t1.await;
assert_eq!(table.len(), 1);
}
pub async fn test_simple_double_contention() {
info!("test_simple_double_contention");
let table = AsyncTagLockTable::new();
let a1 = SocketAddr::new("1.2.3.4".parse().unwrap(), 1234);
let a2 = SocketAddr::new("6.9.6.9".parse().unwrap(), 6969);
let g1 = table.lock_tag(a1).await;
let g2 = table.lock_tag(a2).await;
info!("locked");
let t1 = spawn(async move {
// move the guard into the tas
let _g1_take = g1;
// hold the guard for a bit
info!("waiting");
sleep(1000).await;
// release the guard
info!("released");
});
let t2 = spawn(async move {
// move the guard into the task
let _g2_take = g2;
// hold the guard for a bit
info!("waiting");
sleep(500).await;
// release the guard
info!("released");
});
// wait to lock again, will contend until spawned task exits
let _g1_b = table.lock_tag(a1).await;
// wait to lock again, should complete immediately
let _g2_b = table.lock_tag(a2).await;
info!("locked");
// Ensure tasks are joined
t1.await;
t2.await;
assert_eq!(table.len(), 2);
}
pub async fn test_parallel_single_contention() {
info!("test_parallel_single_contention");
let table = AsyncTagLockTable::new();
let a1 = SocketAddr::new("1.2.3.4".parse().unwrap(), 1234);
let table1 = table.clone();
let t1 = spawn(async move {
// lock the tag
let _g = table1.lock_tag(a1).await;
info!("locked t1");
// hold the guard for a bit
info!("waiting t1");
sleep(500).await;
// release the guard
info!("released t1");
});
let table2 = table.clone();
let t2 = spawn(async move {
// lock the tag
let _g = table2.lock_tag(a1).await;
info!("locked t2");
// hold the guard for a bit
info!("waiting t2");
sleep(500).await;
// release the guard
info!("released t2");
});
let table3 = table.clone();
let t3 = spawn(async move {
// lock the tag
let _g = table3.lock_tag(a1).await;
info!("locked t3");
// hold the guard for a bit
info!("waiting t3");
sleep(500).await;
// release the guard
info!("released t3");
});
// Ensure tasks are joined
t1.await;
t2.await;
t3.await;
assert_eq!(table.len(), 0);
}
pub async fn test_all() {
test_simple_no_contention().await;
test_simple_single_contention().await;
test_parallel_single_contention().await;
}

View File

@ -1,469 +1,13 @@
use crate::xx::*;
use crate::*;
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
use js_sys::*;
} else {
use std::time::{Duration, SystemTime};
}
}
pub async fn test_log() {
info!("testing log");
}
pub async fn test_get_timestamp() {
info!("testing get_timestamp");
let t1 = get_timestamp();
let t2 = get_timestamp();
assert!(t2 >= t1);
}
pub async fn test_eventual() {
info!("testing Eventual");
{
let e1 = Eventual::new();
let i1 = e1.instance_clone(1u32);
let i2 = e1.instance_clone(2u32);
let i3 = e1.instance_clone(3u32);
drop(i3);
let i4 = e1.instance_clone(4u32);
drop(i2);
let jh = spawn(async move {
sleep(1000).await;
e1.resolve();
});
assert_eq!(i1.await, 1u32);
assert_eq!(i4.await, 4u32);
jh.await;
}
{
let e1 = Eventual::new();
let i1 = e1.instance_clone(1u32);
let i2 = e1.instance_clone(2u32);
let i3 = e1.instance_clone(3u32);
let i4 = e1.instance_clone(4u32);
let e1_c1 = e1.clone();
let jh = spawn(async move {
let i5 = e1.instance_clone(5u32);
let i6 = e1.instance_clone(6u32);
assert_eq!(i1.await, 1u32);
assert_eq!(i5.await, 5u32);
assert_eq!(i6.await, 6u32);
});
sleep(1000).await;
let resolved = e1_c1.resolve();
drop(i2);
drop(i3);
assert_eq!(i4.await, 4u32);
resolved.await;
jh.await;
}
{
let e1 = Eventual::new();
let i1 = e1.instance_clone(1u32);
let i2 = e1.instance_clone(2u32);
let e1_c1 = e1.clone();
let jh = spawn(async move {
assert_eq!(i1.await, 1u32);
assert_eq!(i2.await, 2u32);
});
sleep(1000).await;
e1_c1.resolve().await;
jh.await;
e1_c1.reset();
//
let j1 = e1.instance_clone(1u32);
let j2 = e1.instance_clone(2u32);
let jh = spawn(async move {
assert_eq!(j1.await, 1u32);
assert_eq!(j2.await, 2u32);
});
sleep(1000).await;
e1_c1.resolve().await;
jh.await;
e1_c1.reset();
}
}
pub async fn test_eventual_value() {
info!("testing Eventual Value");
{
let e1 = EventualValue::<u32>::new();
let i1 = e1.instance();
let i2 = e1.instance();
let i3 = e1.instance();
drop(i3);
let i4 = e1.instance();
drop(i2);
let e1_c1 = e1.clone();
let jh = spawn(async move {
sleep(1000).await;
e1_c1.resolve(3u32);
});
i1.await;
i4.await;
jh.await;
assert_eq!(e1.take_value(), Some(3u32));
}
{
let e1 = EventualValue::new();
let i1 = e1.instance();
let i2 = e1.instance();
let i3 = e1.instance();
let i4 = e1.instance();
let e1_c1 = e1.clone();
let jh = spawn(async move {
let i5 = e1.instance();
let i6 = e1.instance();
i1.await;
i5.await;
i6.await;
});
sleep(1000).await;
let resolved = e1_c1.resolve(4u16);
drop(i2);
drop(i3);
i4.await;
resolved.await;
jh.await;
assert_eq!(e1_c1.take_value(), Some(4u16));
}
{
let e1 = EventualValue::new();
assert_eq!(e1.take_value(), None);
let i1 = e1.instance();
let i2 = e1.instance();
let e1_c1 = e1.clone();
let jh = spawn(async move {
i1.await;
i2.await;
});
sleep(1000).await;
e1_c1.resolve(5u32).await;
jh.await;
assert_eq!(e1_c1.take_value(), Some(5u32));
e1_c1.reset();
assert_eq!(e1_c1.take_value(), None);
//
let j1 = e1.instance();
let j2 = e1.instance();
let jh = spawn(async move {
j1.await;
j2.await;
});
sleep(1000).await;
e1_c1.resolve(6u32).await;
jh.await;
assert_eq!(e1_c1.take_value(), Some(6u32));
e1_c1.reset();
assert_eq!(e1_c1.take_value(), None);
}
}
pub async fn test_eventual_value_clone() {
info!("testing Eventual Value Clone");
{
let e1 = EventualValueClone::<u32>::new();
let i1 = e1.instance();
let i2 = e1.instance();
let i3 = e1.instance();
drop(i3);
let i4 = e1.instance();
drop(i2);
let jh = spawn(async move {
sleep(1000).await;
e1.resolve(3u32);
});
assert_eq!(i1.await, 3);
assert_eq!(i4.await, 3);
jh.await;
}
{
let e1 = EventualValueClone::new();
let i1 = e1.instance();
let i2 = e1.instance();
let i3 = e1.instance();
let i4 = e1.instance();
let e1_c1 = e1.clone();
let jh = spawn(async move {
let i5 = e1.instance();
let i6 = e1.instance();
assert_eq!(i1.await, 4);
assert_eq!(i5.await, 4);
assert_eq!(i6.await, 4);
});
sleep(1000).await;
let resolved = e1_c1.resolve(4u16);
drop(i2);
drop(i3);
assert_eq!(i4.await, 4);
resolved.await;
jh.await;
}
{
let e1 = EventualValueClone::new();
let i1 = e1.instance();
let i2 = e1.instance();
let e1_c1 = e1.clone();
let jh = spawn(async move {
assert_eq!(i1.await, 5);
assert_eq!(i2.await, 5);
});
sleep(1000).await;
e1_c1.resolve(5u32).await;
jh.await;
e1_c1.reset();
//
let j1 = e1.instance();
let j2 = e1.instance();
let jh = spawn(async move {
assert_eq!(j1.await, 6);
assert_eq!(j2.await, 6);
});
sleep(1000).await;
e1_c1.resolve(6u32).await;
jh.await;
e1_c1.reset();
}
}
pub async fn test_interval() {
info!("testing interval");
let tick: Arc<Mutex<u32>> = Arc::new(Mutex::new(0u32));
let stopper = interval(1000, move || {
let tick = tick.clone();
async move {
let mut tick = tick.lock();
trace!("tick {}", tick);
*tick += 1;
}
});
sleep(5500).await;
stopper.await;
}
pub async fn test_timeout() {
info!("testing timeout");
let tick: Arc<Mutex<u32>> = Arc::new(Mutex::new(0u32));
let tick_1 = tick.clone();
assert!(
timeout(2500, async move {
let mut tick = tick_1.lock();
trace!("tick {}", tick);
sleep(1000).await;
*tick += 1;
trace!("tick {}", tick);
sleep(1000).await;
*tick += 1;
trace!("tick {}", tick);
sleep(1000).await;
*tick += 1;
trace!("tick {}", tick);
sleep(1000).await;
*tick += 1;
})
.await
.is_err(),
"should have timed out"
);
let ticks = *tick.lock();
assert!(ticks <= 2);
}
pub async fn test_sleep() {
info!("testing sleep");
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
let t1 = Date::now();
intf::sleep(1000).await;
let t2 = Date::now();
assert!((t2-t1) >= 1000.0);
} else {
let sys_time = SystemTime::now();
let one_sec = Duration::from_secs(1);
sleep(1000).await;
assert!(sys_time.elapsed().unwrap() >= one_sec);
}
}
}
macro_rules! assert_split_url {
($url:expr, $scheme:expr, $host:expr) => {
assert_eq!(
SplitUrl::from_str($url),
Ok(SplitUrl::new($scheme, None, $host, None, None))
);
};
($url:expr, $scheme:expr, $host:expr, $port:expr) => {
assert_eq!(
SplitUrl::from_str($url),
Ok(SplitUrl::new($scheme, None, $host, $port, None))
);
};
($url:expr, $scheme:expr, $host:expr, $port:expr, $path:expr) => {
assert_eq!(
SplitUrl::from_str($url),
Ok(SplitUrl::new(
$scheme,
None,
$host,
$port,
Some(SplitUrlPath::new(
$path,
Option::<String>::None,
Option::<String>::None
))
))
);
};
($url:expr, $scheme:expr, $host:expr, $port:expr, $path:expr, $frag:expr, $query:expr) => {
assert_eq!(
SplitUrl::from_str($url),
Ok(SplitUrl::new(
$scheme,
None,
$host,
$port,
Some(SplitUrlPath::new($path, $frag, $query))
))
);
};
}
macro_rules! assert_split_url_parse {
($url:expr) => {
let url = $url;
let su1 = SplitUrl::from_str(url).expect("should parse");
assert_eq!(su1.to_string(), url);
};
}
fn host<S: AsRef<str>>(s: S) -> SplitUrlHost {
SplitUrlHost::Hostname(s.as_ref().to_owned())
}
fn ip<S: AsRef<str>>(s: S) -> SplitUrlHost {
SplitUrlHost::IpAddr(IpAddr::from_str(s.as_ref()).unwrap())
}
pub async fn test_split_url() {
info!("testing split_url");
assert_split_url!("http://foo", "http", host("foo"));
assert_split_url!("http://foo:1234", "http", host("foo"), Some(1234));
assert_split_url!("http://foo:1234/", "http", host("foo"), Some(1234), "");
assert_split_url!(
"http://foo:1234/asdf/qwer",
"http",
host("foo"),
Some(1234),
"asdf/qwer"
);
assert_split_url!("http://foo/", "http", host("foo"), None, "");
assert_split_url!("http://11.2.3.144/", "http", ip("11.2.3.144"), None, "");
assert_split_url!("http://[1111::2222]/", "http", ip("1111::2222"), None, "");
assert_split_url!(
"http://[1111::2222]:123/",
"http",
ip("1111::2222"),
Some(123),
""
);
assert_split_url!(
"http://foo/asdf/qwer",
"http",
host("foo"),
None,
"asdf/qwer"
);
assert_split_url!(
"http://foo/asdf/qwer#3",
"http",
host("foo"),
None,
"asdf/qwer",
Some("3"),
Option::<String>::None
);
assert_split_url!(
"http://foo/asdf/qwer?xxx",
"http",
host("foo"),
None,
"asdf/qwer",
Option::<String>::None,
Some("xxx")
);
assert_split_url!(
"http://foo/asdf/qwer#yyy?xxx",
"http",
host("foo"),
None,
"asdf/qwer",
Some("yyy"),
Some("xxx")
);
assert_err!(SplitUrl::from_str("://asdf"));
assert_err!(SplitUrl::from_str(""));
assert_err!(SplitUrl::from_str("::"));
assert_err!(SplitUrl::from_str("://:"));
assert_err!(SplitUrl::from_str("a://:"));
assert_err!(SplitUrl::from_str("a://:1243"));
assert_err!(SplitUrl::from_str("a://:65536"));
assert_err!(SplitUrl::from_str("a://:-16"));
assert_err!(SplitUrl::from_str("a:///"));
assert_err!(SplitUrl::from_str("a:///qwer:"));
assert_err!(SplitUrl::from_str("a:///qwer://"));
assert_err!(SplitUrl::from_str("a://qwer://"));
assert_err!(SplitUrl::from_str("a://[1111::2222]:/"));
assert_err!(SplitUrl::from_str("a://[1111::2222]:"));
assert_split_url_parse!("sch://foo:bar@baz.com:1234/fnord#qux?zuz");
assert_split_url_parse!("sch://foo:bar@baz.com:1234/fnord#qux");
assert_split_url_parse!("sch://foo:bar@baz.com:1234/fnord?zuz");
assert_split_url_parse!("sch://foo:bar@baz.com:1234/fnord/");
assert_split_url_parse!("sch://foo:bar@baz.com:1234//");
assert_split_url_parse!("sch://foo:bar@baz.com:1234");
assert_split_url_parse!("sch://foo:bar@[1111::2222]:1234");
assert_split_url_parse!("sch://foo:bar@[::]:1234");
assert_split_url_parse!("sch://foo:bar@1.2.3.4:1234");
assert_split_url_parse!("sch://@baz.com:1234");
assert_split_url_parse!("sch://baz.com/asdf/asdf");
assert_split_url_parse!("sch://baz.com/");
assert_split_url_parse!("s://s");
}
cfg_if! {
if #[cfg(not(target_arch = "wasm32"))] {
use intf::network_interfaces::NetworkInterfaces;
pub async fn test_network_interfaces() {
info!("testing network interfaces");
let t1 = get_timestamp();
let interfaces = intf::utils::network_interfaces::NetworkInterfaces::new();
let interfaces = NetworkInterfaces::new();
let count = 100;
for x in 0..count {
info!("loop {}", x);
@ -479,99 +23,7 @@ cfg_if! {
}
}
pub async fn test_get_random_u64() {
info!("testing random number generator for u64");
let t1 = get_timestamp();
let count = 10000;
for _ in 0..count {
let _ = get_random_u64();
}
let t2 = get_timestamp();
let tdiff = ((t2 - t1) as f64) / 1000000.0f64;
info!(
"running network interface test with {} iterations took {} seconds",
count, tdiff
);
}
pub async fn test_get_random_u32() {
info!("testing random number generator for u32");
let t1 = get_timestamp();
let count = 10000;
for _ in 0..count {
let _ = get_random_u32();
}
let t2 = get_timestamp();
let tdiff = ((t2 - t1) as f64) / 1000000.0f64;
info!(
"running network interface test with {} iterations took {} seconds",
count, tdiff
);
}
pub async fn test_must_join_single_future() {
info!("testing must join single future");
let sf = MustJoinSingleFuture::<u32>::new();
assert_eq!(sf.check().await, Ok(None));
assert_eq!(
sf.single_spawn(async {
sleep(2000).await;
69
})
.await,
Ok((None, true))
);
assert_eq!(sf.check().await, Ok(None));
assert_eq!(sf.single_spawn(async { panic!() }).await, Ok((None, false)));
assert_eq!(sf.join().await, Ok(Some(69)));
assert_eq!(
sf.single_spawn(async {
sleep(1000).await;
37
})
.await,
Ok((None, true))
);
sleep(2000).await;
assert_eq!(
sf.single_spawn(async {
sleep(1000).await;
27
})
.await,
Ok((Some(37), true))
);
sleep(2000).await;
assert_eq!(sf.join().await, Ok(Some(27)));
assert_eq!(sf.check().await, Ok(None));
}
pub async fn test_tools() {
info!("testing retry_falloff_log");
let mut last_us = 0u64;
for x in 0..1024 {
let cur_us = x as u64 * 1000000u64;
if retry_falloff_log(last_us, cur_us, 10_000_000u64, 6_000_000_000u64, 2.0f64) {
info!(" retry at {} secs", timestamp_to_secs(cur_us));
last_us = cur_us;
}
}
}
pub async fn test_all() {
test_log().await;
test_get_timestamp().await;
test_tools().await;
test_split_url().await;
test_get_random_u64().await;
test_get_random_u32().await;
test_sleep().await;
#[cfg(not(target_arch = "wasm32"))]
test_network_interfaces().await; XXX KEEP THIS IN NATIVE TESTS
test_must_join_single_future().await;
test_eventual().await;
test_eventual_value().await;
test_eventual_value_clone().await;
test_interval().await;
test_timeout().await;
test_network_interfaces().await;
}

View File

@ -1,5 +1,4 @@
use super::test_veilid_config::*;
use crate::xx::*;
use crate::*;
async fn startup() -> VeilidAPI {